diff options
Diffstat (limited to '')
651 files changed, 92945 insertions, 0 deletions
diff --git a/js/xpconnect/crashtests/117307-1.html b/js/xpconnect/crashtests/117307-1.html new file mode 100644 index 0000000000..427ab16559 --- /dev/null +++ b/js/xpconnect/crashtests/117307-1.html @@ -0,0 +1,20 @@ +<!--/*
+Crash in error handler on invalid JavaScript
+http://bugzilla.mozilla.org/show_bug.cgi?id=117307
+*/-->
+
+<HTML><HEAD><TITLE>Bug 117307</title><SCRIPT>
+
+window.onerror=f;
+function f() {f.caller;}
+
+</script></head><BODY><SCRIPT>
+
+function syntaxError() {1=2;}
+
+</script><SCRIPT>
+
+runtimeError();
+function runtimeError() {d.d.d;}
+
+</script></body></html>
diff --git a/js/xpconnect/crashtests/1577573.html b/js/xpconnect/crashtests/1577573.html new file mode 100644 index 0000000000..075662ebe5 --- /dev/null +++ b/js/xpconnect/crashtests/1577573.html @@ -0,0 +1,6 @@ +<script> + function f() {} + var p = new Proxy(f, {}); + SpecialPowers.Cu.exportFunction(f, window).name; + SpecialPowers.Cu.exportFunction(p, window).name; +</script> diff --git a/js/xpconnect/crashtests/193710.html b/js/xpconnect/crashtests/193710.html new file mode 100644 index 0000000000..1320e51356 --- /dev/null +++ b/js/xpconnect/crashtests/193710.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <script type="text/javascript">window.onerror=new Function("return True")</script> + <script type="text/javascript" src="nonexistent.js"></script> +</head> + +<body></body> + +</html> + diff --git a/js/xpconnect/crashtests/290162-1.html b/js/xpconnect/crashtests/290162-1.html new file mode 100644 index 0000000000..09be69d3b0 --- /dev/null +++ b/js/xpconnect/crashtests/290162-1.html @@ -0,0 +1,5 @@ +<script> + InstallTrigger.install.call(document,"a","a"); +</script> + + diff --git a/js/xpconnect/crashtests/326615-1.html b/js/xpconnect/crashtests/326615-1.html new file mode 100644 index 0000000000..5e6684a195 --- /dev/null +++ b/js/xpconnect/crashtests/326615-1.html @@ -0,0 +1,16 @@ +<html> +<head> +</head> +<body> + +<script> + +try { + document.body.compareDocumentPosition(<foo/>); +} catch (e) { +} + +</script> + +</body> +</html> diff --git a/js/xpconnect/crashtests/328553-1.html b/js/xpconnect/crashtests/328553-1.html new file mode 100644 index 0000000000..0e29ee3cf3 --- /dev/null +++ b/js/xpconnect/crashtests/328553-1.html @@ -0,0 +1,13 @@ +<html> +<head> +<script type="text/javascript"> + +x = Ci.nsITableEditor; +x.__proto__ = Components; +x.QueryInterface; + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/346258-1.html b/js/xpconnect/crashtests/346258-1.html new file mode 100644 index 0000000000..c7a54d5c61 --- /dev/null +++ b/js/xpconnect/crashtests/346258-1.html @@ -0,0 +1,12 @@ +<html> +<head> +<script type="text/javascript"> + +var sg = document.__lookupGetter__("styleSheets"); +sg.call(document, undefined); + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/346512-1-frame1.xhtml b/js/xpconnect/crashtests/346512-1-frame1.xhtml new file mode 100644 index 0000000000..bdc38c8a6d --- /dev/null +++ b/js/xpconnect/crashtests/346512-1-frame1.xhtml @@ -0,0 +1,16 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> +</head> + +<body> + + +<div id="empty1"></div> + +<div id="movemychild"><hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/></div> + + + +</body> +</html> diff --git a/js/xpconnect/crashtests/346512-1-frame2.xhtml b/js/xpconnect/crashtests/346512-1-frame2.xhtml new file mode 100644 index 0000000000..4667128308 --- /dev/null +++ b/js/xpconnect/crashtests/346512-1-frame2.xhtml @@ -0,0 +1,15 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> +</head> + +<body> + +<div id="empty2"></div> + + + + + +</body> +</html> diff --git a/js/xpconnect/crashtests/346512-1.xhtml b/js/xpconnect/crashtests/346512-1.xhtml new file mode 100644 index 0000000000..1c8b6ba6dc --- /dev/null +++ b/js/xpconnect/crashtests/346512-1.xhtml @@ -0,0 +1,30 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script> +<![CDATA[ +function foopy() +{ + var doc1 = document.getElementById("doc1").contentDocument; + var doc2 = document.getElementById("doc2").contentDocument; + + var empty2 = doc2.getElementById("empty2"); + var hbox1 = doc1.getElementById("movemychild").firstChild; + var empty1 = doc1.getElementById("empty1"); + + aC(empty2, doc2.adoptNode(hbox1)); + aC(empty1, doc1.adoptNode(empty2)); +} + +function aC(q,r) { q.appendChild(r); } + +]]> +</script> +</head> + +<body onload="foopy();"> + +<iframe id="doc1" src="346512-1-frame1.xhtml" /> +<iframe id="doc2" src="346512-1-frame2.xhtml" /> + +</body> +</html> diff --git a/js/xpconnect/crashtests/382133-1.html b/js/xpconnect/crashtests/382133-1.html new file mode 100644 index 0000000000..511ec96bc2 --- /dev/null +++ b/js/xpconnect/crashtests/382133-1.html @@ -0,0 +1,3 @@ +<script> +(function(){}).apply.ee = <foo/>; +</script> diff --git a/js/xpconnect/crashtests/386680-1.html b/js/xpconnect/crashtests/386680-1.html new file mode 100644 index 0000000000..3949730e47 --- /dev/null +++ b/js/xpconnect/crashtests/386680-1.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> + +<script> + +function boom() +{ + o = {}; + o.__proto__ = o.constructor; + p = o.constructor.prototype; + p.__proto__ = window; + null.__proto__ = {}; +} + +</script> +</head> + +<body onload="boom()"> + +</body> +</html> diff --git a/js/xpconnect/crashtests/394810-1.html b/js/xpconnect/crashtests/394810-1.html new file mode 100644 index 0000000000..a5a5ebf14e --- /dev/null +++ b/js/xpconnect/crashtests/394810-1.html @@ -0,0 +1,4 @@ +<script> +Object.prototype.__defineGetter__("x", Object.prototype.toSource); +window.x; +</script> diff --git a/js/xpconnect/crashtests/400349-1.html b/js/xpconnect/crashtests/400349-1.html new file mode 100644 index 0000000000..48846c8c9b --- /dev/null +++ b/js/xpconnect/crashtests/400349-1.html @@ -0,0 +1,20 @@ +<html> +<head> + +<script> + +function init() { + window.removeEventListener("load", init); + + var fr = document.getElementsByTagName("iframe")[0]; + var b = fr.contentDocument.body; + + fr.remove(); + b.parentNode; +} + +window.addEventListener("load", init); + +</script> + +</head><body><iframe></iframe></body></html>
\ No newline at end of file diff --git a/js/xpconnect/crashtests/403356-1.html b/js/xpconnect/crashtests/403356-1.html new file mode 100644 index 0000000000..a6a2adbf62 --- /dev/null +++ b/js/xpconnect/crashtests/403356-1.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> +try { + document.documentElement.appendChild.call(new XPCNativeWrapper(window)); +} catch(e) { +} +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/418139-1.svg b/js/xpconnect/crashtests/418139-1.svg new file mode 100644 index 0000000000..0c878f7c84 --- /dev/null +++ b/js/xpconnect/crashtests/418139-1.svg @@ -0,0 +1,22 @@ +<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="boom();">
+
+<script type="text/javascript">
+
+function boom()
+{
+ document.getElementById("b").style.position = "absolute";
+ document.getElementById("a").style.color = "green";
+}
+
+</script>
+
+<defs>
+ <g id="a"><xul:listbox/></g>
+</defs>
+
+<g id="b"><use xlink:href="#a"/></g>
+
+</svg>
diff --git a/js/xpconnect/crashtests/420513-1.html b/js/xpconnect/crashtests/420513-1.html new file mode 100644 index 0000000000..ed0981c1c9 --- /dev/null +++ b/js/xpconnect/crashtests/420513-1.html @@ -0,0 +1,11 @@ +<html> +<head> +<script type="text/javascript"> + +(new XPCNativeWrapper(document.documentElement))(); + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/453935-1.html b/js/xpconnect/crashtests/453935-1.html new file mode 100644 index 0000000000..9c9bab3d74 --- /dev/null +++ b/js/xpconnect/crashtests/453935-1.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + var a = []; + a[31] = undefined; + a[40] = undefined; + a[44] = {}; + a[45] = new XMLHttpRequest(); + a[48] = new XMLHttpRequest(); + a[53] = XMLHttpRequest.prototype; + a[53].__proto__ = {}; + a[53].nodeType = 100; + search(a, 41); +} + + +function search(a, start) +{ + var N = a.length; + + for (var j = start; j < N; ++j) { + var e = a[j]; + if (typeof e == "object" && "nodeType" in e && e.nodeType == 99) + return j; + } + + return null; +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/467693-1.html b/js/xpconnect/crashtests/467693-1.html new file mode 100644 index 0000000000..4775abea56 --- /dev/null +++ b/js/xpconnect/crashtests/467693-1.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<script type="text/javascript"> + +function boom() +{ + ({})[document.createElement('unsupported').tagName]; + uneval(Ci.nsIWebNavigationInfo); +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/468552-1.html b/js/xpconnect/crashtests/468552-1.html new file mode 100644 index 0000000000..0ce2e3eb40 --- /dev/null +++ b/js/xpconnect/crashtests/468552-1.html @@ -0,0 +1,18 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script type="text/javascript"> + +function boom() +{ + var dp = document.__proto__; + dp.__proto__ = new XPCNativeWrapper(new XMLSerializer); + try { + dp.replaceChild(); + } catch(e) { } +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/475185-1.html b/js/xpconnect/crashtests/475185-1.html new file mode 100644 index 0000000000..a599c37b03 --- /dev/null +++ b/js/xpconnect/crashtests/475185-1.html @@ -0,0 +1,13 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<head> +<script type="text/javascript"> + +function boom() +{ + document.body.__lookupSetter__("textContent").call(document.body); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/475291-1.html b/js/xpconnect/crashtests/475291-1.html new file mode 100644 index 0000000000..e5658f74b1 --- /dev/null +++ b/js/xpconnect/crashtests/475291-1.html @@ -0,0 +1,14 @@ +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<head> +<script type="text/javascript"> + +function boom() +{ + window[14] = 14; + window.__lookupSetter__(14); +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/503286-1.html b/js/xpconnect/crashtests/503286-1.html new file mode 100644 index 0000000000..ca14f49490 --- /dev/null +++ b/js/xpconnect/crashtests/503286-1.html @@ -0,0 +1,23 @@ +<html><head><title>Firefox 3.5 crash</title> + +<script language=JavaScript> + +function escapeData(data){ + var escData=''; + for(var i=0;i<data.length;i++) { + var c=data.charAt(i); + if( c==' ') c = escape(c); + escData+=c; + } + return escData; +} + +var a = ["a", "a ", "a", "a "] + +var html = ""; +for (i=0;i<a.length;i++){ + html += escapeData("a")+escapeData(a[i]) +} +</script> +</body></html> + diff --git a/js/xpconnect/crashtests/504000-1.html b/js/xpconnect/crashtests/504000-1.html new file mode 100644 index 0000000000..a909eb34a0 --- /dev/null +++ b/js/xpconnect/crashtests/504000-1.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<head> +<script> + + +function f() { + for (var j in { a:1, b:2, c:3, d:4, e:5 }) { + } +} + +function boom() +{ + f(); + Function.prototype.__defineGetter__("xxx", function(){}); +} + +</script></head> + +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/509075-1.html b/js/xpconnect/crashtests/509075-1.html new file mode 100644 index 0000000000..77e8e62fc8 --- /dev/null +++ b/js/xpconnect/crashtests/509075-1.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <script> + + var txt = document.createTextNode(""); + var b = document.createElement("b"); + var w = b["watch"]; + var txtdg = txt["__lookupGetter__"]; + w["__defineGetter__"]("toString",txtdg); + var obj = { + variable: 910, + fun: function() { + w["toString"](); + } + }; + + function vuln() + { + window.status = "" + obj.variable; + try{ + obj.fun(); + }catch(er){} + return obj; + } + + var ret = vuln(); + </script> +</html> diff --git a/js/xpconnect/crashtests/512815-1.html b/js/xpconnect/crashtests/512815-1.html new file mode 100644 index 0000000000..09903ad3b9 --- /dev/null +++ b/js/xpconnect/crashtests/512815-1.html @@ -0,0 +1,21 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<script type="text/javascript"> + +function boom() { + var ns = document.createElementNS("http://www.w3.org/1999/xhtml", "script"); + var nt = document.createTextNode("bang();"); + ns.appendChild(nt); + document.getElementById("v").appendChild(ns); +} + +function bang() +{ + var scriptElement = document.getElementById("v").lastElementChild; + "" + scriptElement; +} + +</script> +</head> +<body onload="boom();"><div id="v"></div></body> +</html> diff --git a/js/xpconnect/crashtests/515726-1.html b/js/xpconnect/crashtests/515726-1.html new file mode 100644 index 0000000000..3bf73d42ca --- /dev/null +++ b/js/xpconnect/crashtests/515726-1.html @@ -0,0 +1,26 @@ +<html> +<head> +<script> + +function boom() +{ + var frame = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe"); + + document.documentElement.appendChild(frame); + var framedoc = frame.contentDocument; + document.documentElement.removeChild(frame); + + framedoc.removeChild(framedoc.documentElement); + framedoc.appendChild(frame); + + try { frame.appendChild(undefined); } catch(e) { } + + document.removeChild(document.documentElement); + document.appendChild(frame); +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/545291-1.html b/js/xpconnect/crashtests/545291-1.html new file mode 100644 index 0000000000..ed50900db1 --- /dev/null +++ b/js/xpconnect/crashtests/545291-1.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> +<head> +<script> + +var textNode = document.createTextNode("x"); +textNode.__proto__.__proto__ = Components; +textNode.__lookupSetter__("canCallMethod")(); + +</script> +</head> +</html> diff --git a/js/xpconnect/crashtests/558979.html b/js/xpconnect/crashtests/558979.html new file mode 100644 index 0000000000..404748c42a --- /dev/null +++ b/js/xpconnect/crashtests/558979.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="text/javascript"> + +var div = document.createElement("div"); +for (var i in div) { } +div.__proto__ = document.createTextNode(" "); +div.appendChild(document.createTextNode(" ")); + +</script> +</head> +</html> diff --git a/js/xpconnect/crashtests/601284-1.html b/js/xpconnect/crashtests/601284-1.html new file mode 100644 index 0000000000..3bd3b2bef9 --- /dev/null +++ b/js/xpconnect/crashtests/601284-1.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + var frameRoot = document.getElementById("f").contentDocument.documentElement; + var marquee = frameRoot.getElementsByTagName("marquee")[0]; + marquee.__proto__ = []; + frameRoot.appendChild(marquee); +} + +</script> +</head> + +<body onload="boom();"> + +<iframe id="f" src="data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><marquee></marquee></body></html>"></iframe> + +</body> +</html> diff --git a/js/xpconnect/crashtests/603146-1.html b/js/xpconnect/crashtests/603146-1.html new file mode 100644 index 0000000000..74b103004b --- /dev/null +++ b/js/xpconnect/crashtests/603146-1.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script> + +delete XMLHttpRequest.prototype.mozResponseArrayBuffer; +(new XMLHttpRequest).mozResponseArrayBuffer; + +</script> diff --git a/js/xpconnect/crashtests/603858-1.html b/js/xpconnect/crashtests/603858-1.html new file mode 100644 index 0000000000..8a48bbda82 --- /dev/null +++ b/js/xpconnect/crashtests/603858-1.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<script> +if (typeof window.XML === 'function') + setTimeout(XML, 0); +setTimeout(function(){document.documentElement.removeAttribute("class");}, 0); +</script> +</html> diff --git a/js/xpconnect/crashtests/608963.html b/js/xpconnect/crashtests/608963.html new file mode 100644 index 0000000000..ef2e5bbfcf --- /dev/null +++ b/js/xpconnect/crashtests/608963.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<script> +Object.create(location).constructor; +</script> + diff --git a/js/xpconnect/crashtests/616930-1.html b/js/xpconnect/crashtests/616930-1.html new file mode 100644 index 0000000000..e34fbca6c7 --- /dev/null +++ b/js/xpconnect/crashtests/616930-1.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + window.__proto__.__proto__ = InstallTrigger; + window.DOMParser; +} + +</script> +</head> +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/639737-1.html b/js/xpconnect/crashtests/639737-1.html new file mode 100644 index 0000000000..b461cc02bb --- /dev/null +++ b/js/xpconnect/crashtests/639737-1.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function b() { + try { sset("u"); } catch(e) { } + try { [0].map(b); } catch(e) { } +} + +var sset = document.documentElement.style.__lookupSetter__("textIndent"); +b(); + +</script> +</head> + +<body></body> +</html> + diff --git a/js/xpconnect/crashtests/648206-1.html b/js/xpconnect/crashtests/648206-1.html new file mode 100644 index 0000000000..5f5ed4b7c7 --- /dev/null +++ b/js/xpconnect/crashtests/648206-1.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script> + +InstallTrigger.__proto__ = window.getComputedStyle(document.documentElement); +InstallTrigger[0] = 0; + +</script> diff --git a/js/xpconnect/crashtests/720305-1.html b/js/xpconnect/crashtests/720305-1.html new file mode 100644 index 0000000000..84f1c62670 --- /dev/null +++ b/js/xpconnect/crashtests/720305-1.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<script> + +var c = document.getElementsByClassName("x"); +Object.defineProperty(c, "length", {set: void 0}); +Array.prototype.shift.call(c); + +</script> diff --git a/js/xpconnect/crashtests/721910.html b/js/xpconnect/crashtests/721910.html new file mode 100644 index 0000000000..d2d7bbeb42 --- /dev/null +++ b/js/xpconnect/crashtests/721910.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +a = Int8Array(0x01000000); +p = Proxy.create({ get: function(r, name) { return a[name]; } }); +try { Int8Array(p); } catch(e) { } + +</script> +</head> + +<body></body> +</html> diff --git a/js/xpconnect/crashtests/723465.html b/js/xpconnect/crashtests/723465.html new file mode 100644 index 0000000000..0f810b963b --- /dev/null +++ b/js/xpconnect/crashtests/723465.html @@ -0,0 +1,19 @@ +<html> +<head> + +<script> + +function boom() +{ + var f = document.getElementById("f"); + var fd = f.contentDocument; + fd.querySelectorAll("*"); + fd.documentElement.innerHTML = "3"; + document.body.removeChild(f); +} + +</script> +</head> + +<body onload="boom();"><iframe id="f" src="data:text/html,<html><head onfocus=2>"></iframe></body> +</html> diff --git a/js/xpconnect/crashtests/732870.html b/js/xpconnect/crashtests/732870.html new file mode 100644 index 0000000000..00823142d0 --- /dev/null +++ b/js/xpconnect/crashtests/732870.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function boom() +{ + var frameDoc = document.getElementById("f").contentDocument; + var elem = frameDoc.documentElement; + elem.dataset; + document.adoptNode(elem); + frameDoc.write("0"); + frameDoc.close(); + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="boom();"> +<iframe id="f" srcdoc="<html>1</html>"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/751995.html b/js/xpconnect/crashtests/751995.html new file mode 100644 index 0000000000..9f2758faf6 --- /dev/null +++ b/js/xpconnect/crashtests/751995.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function frameDoc() { return document.getElementById("f").contentDocument; } + +function arm() { + // Create an element in the iframe. + var div = frameDoc().createElement("div"); + + // Force a wrapper to be created for .style. + var style = div.style; + style.color = "green"; + + // Adopt the element out of the iframe, leaving the |style| behind. + document.adoptNode(div); +} + +function boom() +{ + // Create an orphan. + arm(); + + // Force an iteration over all the wrappers in frameDoc's scope, causing + // us to notice the orphan. + frameDoc().write("2"); + + // All done. + document.documentElement.removeAttribute("class"); +} + +</script> +</head> +<body onload="boom();"><iframe id="f" srcdoc="1"></iframe></body> +</html> diff --git a/js/xpconnect/crashtests/752038-iframe.html b/js/xpconnect/crashtests/752038-iframe.html new file mode 100644 index 0000000000..fc14c16f80 --- /dev/null +++ b/js/xpconnect/crashtests/752038-iframe.html @@ -0,0 +1,11 @@ + +<script> +function boom() +{ + document.location.hash = "#1"; + document.open(); + window.parent.postMessage({}, '*'); +} +</script> + +<body onload="boom();"></body> diff --git a/js/xpconnect/crashtests/752038.html b/js/xpconnect/crashtests/752038.html new file mode 100644 index 0000000000..c2fe7ab637 --- /dev/null +++ b/js/xpconnect/crashtests/752038.html @@ -0,0 +1,28 @@ +<html class="reftest-wait"> +<head> +<script> + +// document.write() doesn't play well with reftest-wait, so we need to use an +// iframe. +// +// This test is designed to trigger an assertion, but that assertion depends on +// non-deterministic hashtable iteration ordering. The assertion seems to happen +// around 80% of the time, so we just run the operation 10 times. + +var i = 0; +function iterate() { + ++i; + if (i < 10) { + document.getElementById("f").src = "752038-iframe.html"; + } else { + document.documentElement.removeAttribute("class"); + } +} +window.addEventListener('message', iterate); + +</script> +</head> +<body> +<iframe id="f" src="752038-iframe.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/753162.html b/js/xpconnect/crashtests/753162.html new file mode 100644 index 0000000000..c633488ea2 --- /dev/null +++ b/js/xpconnect/crashtests/753162.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + var frameDoc = document.getElementById("f").contentDocument; + frameDoc.write("2"); + var f = function(event) { + frameDoc.removeEventListener("DOMAttrModified", f); + Math.sin(2.10); + frameDoc.write("4"); + }; + frameDoc.addEventListener("DOMAttrModified", f); + frameDoc.write("<html d>"); +} + +</script> +</head> + +<body onload="boom();"><iframe id="f" srcdoc="1"></iframe></body> +</html> diff --git a/js/xpconnect/crashtests/754311-iframe.html b/js/xpconnect/crashtests/754311-iframe.html new file mode 100644 index 0000000000..002817fa94 --- /dev/null +++ b/js/xpconnect/crashtests/754311-iframe.html @@ -0,0 +1,21 @@ +<html> +<head> +<script type="application/javascript"> + +function boom() { + // Don't crash when transplanting wrappers with cyclic references. + document.documentElement.dataset.xml = document.documentElement.dataset; + document.open(); + + // Tell the parent window that we're done. + window.parent.allDone(); +} + +// This needs to do a round-trip through the event loop to work right. +window.onload = function() { setTimeout(boom, 0); }; + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/754311.html b/js/xpconnect/crashtests/754311.html new file mode 100644 index 0000000000..36d603fd7f --- /dev/null +++ b/js/xpconnect/crashtests/754311.html @@ -0,0 +1,16 @@ +<html class="reftest-wait"> +<head> +<script type="application/javascript"> + +// The actual crashing code does document.write, which doesn't play +// well with |reftest-wait|. So we load it in an iframe. + +function allDone() { + window.document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body> + <iframe src="754311-iframe.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/761831.html b/js/xpconnect/crashtests/761831.html new file mode 100644 index 0000000000..60fdd6d983 --- /dev/null +++ b/js/xpconnect/crashtests/761831.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +function boom() +{ + function removeRoot() { + window.removeEventListener("DOMNodeRemoved", removeRoot, true); + document.open(); + } + + window.addEventListener("DOMNodeRemoved", removeRoot, true); + + var r = document.documentElement; + document.removeChild(r); +} + +</script> +</head> + +<body onload="boom();"></body> +</html> diff --git a/js/xpconnect/crashtests/786142-iframe.html b/js/xpconnect/crashtests/786142-iframe.html new file mode 100644 index 0000000000..80c129dab6 --- /dev/null +++ b/js/xpconnect/crashtests/786142-iframe.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +// Morph a slim wrapper into an XPCWN by generating a cross-compartment wrapper +// for it (we Morph in WrapperFactory::PrepareForWrapping). +function makeNonSlim(elem) { + window.parent.someCCW = elem; + delete window.parent.someCCW; +} + +function doTest() { + + // Get a slim wrapper for |form|. This lives in scope 1. + var form = document.getElementById('myform'); + + // The gist here is that we want to create an input element that isn't part + // of a form, so that its PreCreate hook will cause it to be parented to the + // document. However, there are several considerations that make this more + // complicted. + // + // First, the crashtest becomes non-deterministics if we morph |form| before + // getting to scope 3 (as explained below). This means that we can't trigger + // the PreCreate hook for |input|, because that will call WrapNativeParent + // (Well... No, it won't: there is no WrapNativeParent, but there are also no + // more pre-create hooks, slimwrappers, parenting to the form, or any of the + // stuff this test is trying to test.) + // on the form, which will end up making a cross-compartment wrapper, which + // will morph form. But this puts us in a pickle, because appendChild returns + // the apppended child, which will trigger the PreCreate hook in + // NativeInterface2JSObject. So we do this little hack where we append a buch + // of dummy <div> children to the form, and use replaceChild (which returns + // the replacer, not the replacee) to stick the input elements as children of + // the form. + // + // Second, the crashtest can also be non-deterministics if the final call to + // MoveWrappers iterates over the hashtable in such a way that it fixes up + // the Document before it fixes up the Input. If so, the Input will become + // orphaned, and we'll detect it and fix things up at the top of MoveWrapper. + // Since we can't control the hashtable ordering here, we just make 100 input + // elements, to make it a near-certainty (statistically) that we'll encounter + // one of them during iteration before encountering the Document. + // + // With all this, this testcase deterministically crashes on my machine. Whew! + + // Create an input element. This isn't part of a form right now, so it gets + // parented to the document. + var inputs = []; + var placeHolders = []; + for (var i = 0; i < 100; ++i) { + var dummyDiv = form.appendChild(document.createElement('div')); + var input = document.createElement('input'); + makeNonSlim(input); + inputs.push(input); + placeHolders.push(dummyDiv); + } + + // Blow away the document, forcing a transplan of all the XPCWNs in scope. This + // will transplant |input|, but |form| stays in the old scope (since it's slim). + document.open(); + document.close(); + + // Now we're in scope 2. Associate |input| with |form| so that the next call to + // PreCreate will parent |input| to |form| rather than the document. But make + // sure to do it with replaceChild, rather than appendChild, so that we don't + // end up triggering the PreCreate hook for |form| in scope 2, which would make + // make it non-slim. If we didn't, the ensuing call to MoveWrappers might find + // |form| before |input| while iterating over the hashtable. If so, |form| + // would be rescued as an orphan and everything would be fixed before getting to // |input|. + for (var i = 0; i < inputs.length; ++i) + form.replaceChild(inputs[i], placeHolders[i]); + + // Blow away the document a second time. This should cause the crash in + // unpatched builds. + document.open(); + document.close(); +} +</script> +</head> +<body> +<form id="myform"></form> +</body> +</html> diff --git a/js/xpconnect/crashtests/786142.html b/js/xpconnect/crashtests/786142.html new file mode 100644 index 0000000000..d98d39dd3f --- /dev/null +++ b/js/xpconnect/crashtests/786142.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> +function go() { + // document.open() doesn't play well with reftest-wait, so we use an iframe. + var ifr = document.getElementById('ifr'); + ifr.contentWindow.doTest(); + document.documentElement.removeAttribute("class"); +} +</script> +</head> +<body> + <iframe id="ifr" onload="go()" src="786142-iframe.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/797583.html b/js/xpconnect/crashtests/797583.html new file mode 100644 index 0000000000..f6aaf01c22 --- /dev/null +++ b/js/xpconnect/crashtests/797583.html @@ -0,0 +1,6 @@ +<script> + +var ww = Object.create(window); +ww.Components; + +</script> diff --git a/js/xpconnect/crashtests/806751.html b/js/xpconnect/crashtests/806751.html new file mode 100644 index 0000000000..0163cd4ae0 --- /dev/null +++ b/js/xpconnect/crashtests/806751.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> + +function boom() +{ + var frame = document.getElementById("frame"); + var frameWin = frame.contentWindow; + var frameWinner = Object.create(frameWin); + var v = frameWinner.captureEvents.bind(frameWinner); + frame.src = "local-file-not-found"; + setTimeout(function() { setTimeout(finish); v(0); }); +} + +function finish() { + document.documentElement.removeAttribute('class'); +} + +</script> +</head> + +<body onload="boom();"> +<iframe id="frame" srcdoc="1"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/833856.html b/js/xpconnect/crashtests/833856.html new file mode 100644 index 0000000000..ca2bfc378f --- /dev/null +++ b/js/xpconnect/crashtests/833856.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<script> +function go() { + window.location = "javascript: foopy();"; + setTimeout(function(){document.documentElement.removeAttribute("class");}, 0); +} + +</script> +</head> +<body onload="go()"> +</body> +</html> diff --git a/js/xpconnect/crashtests/851418.html b/js/xpconnect/crashtests/851418.html new file mode 100644 index 0000000000..ef2a12bf97 --- /dev/null +++ b/js/xpconnect/crashtests/851418.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var frameDoc = document.getElementById("f").contentDocument; + var frameRoot = frameDoc.documentElement; + frameDoc.write(""); + frameRoot.setAttribute("onload", ""); + frameRoot.onload; + document.documentElement.removeAttribute("class"); +} + +</script> +</head> + +<body onload="boom();"> +<iframe id="f" srcdoc="1"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/854139.html b/js/xpconnect/crashtests/854139.html new file mode 100644 index 0000000000..dd3833e9db --- /dev/null +++ b/js/xpconnect/crashtests/854139.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> +<script> +performance.timing instanceof SpecialPowers.Ci.nsISupports; +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/854604.html b/js/xpconnect/crashtests/854604.html new file mode 100644 index 0000000000..41c028bc2d --- /dev/null +++ b/js/xpconnect/crashtests/854604.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> +<script> + SpecialPowers.wrap(SpecialPowers.Components).toString(); +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/crashtests/898939.html b/js/xpconnect/crashtests/898939.html new file mode 100644 index 0000000000..7cb238498a --- /dev/null +++ b/js/xpconnect/crashtests/898939.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + document.documentElement.appendChild(document.getElementById("f").contentDocument.getElementById("m")); + document.documentElement.removeAttribute("class"); +} + +</script> +</head> +<body onload="boom();"> +<iframe id="f" srcdoc="<!DOCTYPE html><body><marquee id=m>"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/905523.html b/js/xpconnect/crashtests/905523.html new file mode 100644 index 0000000000..73ca9fda1d --- /dev/null +++ b/js/xpconnect/crashtests/905523.html @@ -0,0 +1,24904 @@ +<html> +<script> + +// This will crash once we call it at the end of this file. +function __Z30TestFunc_TestFileNormalizePathR4Test($0) { + var label = 0; + var sp = STACKTOP; STACKTOP = (STACKTOP + 10320)|0; (assert((STACKTOP|0) < (STACK_MAX|0))|0); + label = 1; + while(1) { + switch(label) { + case 1: + var $2; + var $3; + var $4; + var $5; + var $6; + var $7; + var $8; + var $9; + var $10; + var $11; + var $12; + var $13; + var $14; + var $15; + var $16; + var $17; + var $18; + var $19; + var $20; + var $21; + var $22; + var $23; + var $24; + var $25; + var $26; + var $27; + var $28; + var $29; + var $30; + var $31; + var $32; + var $__a_i_i_i1_i_i_i576; + var $__i_i_i_i2_i_i_i577; + var $33; + var $34; + var $35; + var $36; + var $37; + var $38; + var $39; + var $40; + var $41; + var $__a_i_i_i_i_i_i578; + var $__i_i_i_i_i_i_i579; + var $42; + var $43; + var $44; + var $45; + var $46; + var $47; + var $48; + var $49; + var $50; + var $51; + var $52=sp; + var $53; + var $54; + var $55; + var $56; + var $57; + var $58; + var $59; + var $60; + var $61; + var $62; + var $63; + var $64; + var $65; + var $66; + var $67; + var $68; + var $69; + var $70; + var $71; + var $72; + var $73; + var $74; + var $75; + var $76; + var $77; + var $78; + var $79; + var $80; + var $81; + var $82; + var $83; + var $84; + var $85; + var $86; + var $87; + var $88; + var $89; + var $90; + var $91; + var $__a_i_i_i1_i_i_i563; + var $__i_i_i_i2_i_i_i564; + var $92; + var $93; + var $94; + var $95; + var $96; + var $97; + var $98; + var $99; + var $100; + var $__a_i_i_i_i_i_i565; + var $__i_i_i_i_i_i_i566; + var $101; + var $102; + var $103; + var $104; + var $105; + var $106; + var $107; + var $108; + var $109; + var $110; + var $111=(sp)+(16); + var $112; + var $113; + var $114; + var $115; + var $116; + var $117; + var $118; + var $119; + var $120; + var $121; + var $122; + var $123; + var $124; + var $125; + var $126; + var $127; + var $128; + var $129; + var $130; + var $131; + var $132; + var $133; + var $134; + var $135; + var $136; + var $137; + var $138; + var $139; + var $140; + var $141; + var $142; + var $143; + var $144; + var $145; + var $146; + var $147; + var $148; + var $149; + var $150; + var $__a_i_i_i1_i_i_i550; + var $__i_i_i_i2_i_i_i551; + var $151; + var $152; + var $153; + var $154; + var $155; + var $156; + var $157; + var $158; + var $159; + var $__a_i_i_i_i_i_i552; + var $__i_i_i_i_i_i_i553; + var $160; + var $161; + var $162; + var $163; + var $164; + var $165; + var $166; + var $167; + var $168; + var $169; + var $170=(sp)+(32); + var $171; + var $172; + var $173; + var $174; + var $175; + var $176; + var $177; + var $178; + var $179; + var $180; + var $181; + var $182; + var $183; + var $184; + var $185; + var $186; + var $187; + var $188; + var $189; + var $190; + var $191; + var $192; + var $193; + var $194; + var $195; + var $196; + var $197; + var $198; + var $199; + var $200; + var $201; + var $202; + var $203; + var $204; + var $205; + var $206; + var $207; + var $208; + var $209; + var $__a_i_i_i1_i_i_i537; + var $__i_i_i_i2_i_i_i538; + var $210; + var $211; + var $212; + var $213; + var $214; + var $215; + var $216; + var $217; + var $218; + var $__a_i_i_i_i_i_i539; + var $__i_i_i_i_i_i_i540; + var $219; + var $220; + var $221; + var $222; + var $223; + var $224; + var $225; + var $226; + var $227; + var $228; + var $229=(sp)+(48); + var $230; + var $231; + var $232; + var $233; + var $234; + var $235; + var $236; + var $237; + var $238; + var $239; + var $240; + var $241; + var $242; + var $243; + var $244; + var $245; + var $246; + var $247; + var $248; + var $249; + var $250; + var $251; + var $252; + var $253; + var $254; + var $255; + var $256; + var $257; + var $258; + var $259; + var $260; + var $261; + var $262; + var $263; + var $264; + var $265; + var $266; + var $267; + var $268; + var $__a_i_i_i1_i_i_i524; + var $__i_i_i_i2_i_i_i525; + var $269; + var $270; + var $271; + var $272; + var $273; + var $274; + var $275; + var $276; + var $277; + var $__a_i_i_i_i_i_i526; + var $__i_i_i_i_i_i_i527; + var $278; + var $279; + var $280; + var $281; + var $282; + var $283; + var $284; + var $285; + var $286; + var $287; + var $288=(sp)+(64); + var $289; + var $290; + var $291; + var $292; + var $293; + var $294; + var $295; + var $296; + var $297; + var $298; + var $299; + var $300; + var $301; + var $302; + var $303; + var $304; + var $305; + var $306; + var $307; + var $308; + var $309; + var $310; + var $311; + var $312; + var $313; + var $314; + var $315; + var $316; + var $317; + var $318; + var $319; + var $320; + var $321; + var $322; + var $323; + var $324; + var $325; + var $326; + var $327; + var $__a_i_i_i1_i_i_i511; + var $__i_i_i_i2_i_i_i512; + var $328; + var $329; + var $330; + var $331; + var $332; + var $333; + var $334; + var $335; + var $336; + var $__a_i_i_i_i_i_i513; + var $__i_i_i_i_i_i_i514; + var $337; + var $338; + var $339; + var $340; + var $341; + var $342; + var $343; + var $344; + var $345; + var $346; + var $347=(sp)+(80); + var $348; + var $349; + var $350; + var $351; + var $352; + var $353; + var $354; + var $355; + var $356; + var $357; + var $358; + var $359; + var $360; + var $361; + var $362; + var $363; + var $364; + var $365; + var $366; + var $367; + var $368; + var $369; + var $370; + var $371; + var $372; + var $373; + var $374; + var $375; + var $376; + var $377; + var $378; + var $379; + var $380; + var $381; + var $382; + var $383; + var $384; + var $385; + var $386; + var $__a_i_i_i1_i_i_i498; + var $__i_i_i_i2_i_i_i499; + var $387; + var $388; + var $389; + var $390; + var $391; + var $392; + var $393; + var $394; + var $395; + var $__a_i_i_i_i_i_i500; + var $__i_i_i_i_i_i_i501; + var $396; + var $397; + var $398; + var $399; + var $400; + var $401; + var $402; + var $403; + var $404; + var $405; + var $406=(sp)+(96); + var $407; + var $408; + var $409; + var $410; + var $411; + var $412; + var $413; + var $414; + var $415; + var $416; + var $417; + var $418; + var $419; + var $420; + var $421; + var $422; + var $423; + var $424; + var $425; + var $426; + var $427; + var $428; + var $429; + var $430; + var $431; + var $432; + var $433; + var $434; + var $435; + var $436; + var $437; + var $438; + var $439; + var $440; + var $441; + var $442; + var $443; + var $444; + var $445; + var $__a_i_i_i1_i_i_i485; + var $__i_i_i_i2_i_i_i486; + var $446; + var $447; + var $448; + var $449; + var $450; + var $451; + var $452; + var $453; + var $454; + var $__a_i_i_i_i_i_i487; + var $__i_i_i_i_i_i_i488; + var $455; + var $456; + var $457; + var $458; + var $459; + var $460; + var $461; + var $462; + var $463; + var $464; + var $465=(sp)+(112); + var $466; + var $467; + var $468; + var $469; + var $470; + var $471; + var $472; + var $473; + var $474; + var $475; + var $476; + var $477; + var $478; + var $479; + var $480; + var $481; + var $482; + var $483; + var $484; + var $485; + var $486; + var $487; + var $488; + var $489; + var $490; + var $491; + var $492; + var $493; + var $494; + var $495; + var $496; + var $497; + var $498; + var $499; + var $500; + var $501; + var $502; + var $503; + var $504; + var $__a_i_i_i1_i_i_i472; + var $__i_i_i_i2_i_i_i473; + var $505; + var $506; + var $507; + var $508; + var $509; + var $510; + var $511; + var $512; + var $513; + var $__a_i_i_i_i_i_i474; + var $__i_i_i_i_i_i_i475; + var $514; + var $515; + var $516; + var $517; + var $518; + var $519; + var $520; + var $521; + var $522; + var $523; + var $524=(sp)+(128); + var $525; + var $526; + var $527; + var $528; + var $529; + var $530; + var $531; + var $532; + var $533; + var $534; + var $535; + var $536; + var $537; + var $538; + var $539; + var $540; + var $541; + var $542; + var $543; + var $544; + var $545; + var $546; + var $547; + var $548; + var $549; + var $550; + var $551; + var $552; + var $553; + var $554; + var $555; + var $556; + var $557; + var $558; + var $559; + var $560; + var $561; + var $562; + var $563; + var $__a_i_i_i1_i_i_i459; + var $__i_i_i_i2_i_i_i460; + var $564; + var $565; + var $566; + var $567; + var $568; + var $569; + var $570; + var $571; + var $572; + var $__a_i_i_i_i_i_i461; + var $__i_i_i_i_i_i_i462; + var $573; + var $574; + var $575; + var $576; + var $577; + var $578; + var $579; + var $580; + var $581; + var $582; + var $583=(sp)+(144); + var $584; + var $585; + var $586; + var $587; + var $588; + var $589; + var $590; + var $591; + var $592; + var $593; + var $594; + var $595; + var $596; + var $597; + var $598; + var $599; + var $600; + var $601; + var $602; + var $603; + var $604; + var $605; + var $606; + var $607; + var $608; + var $609; + var $610; + var $611; + var $612; + var $613; + var $614; + var $615; + var $616; + var $617; + var $618; + var $619; + var $620; + var $621; + var $622; + var $__a_i_i_i1_i_i_i446; + var $__i_i_i_i2_i_i_i447; + var $623; + var $624; + var $625; + var $626; + var $627; + var $628; + var $629; + var $630; + var $631; + var $__a_i_i_i_i_i_i448; + var $__i_i_i_i_i_i_i449; + var $632; + var $633; + var $634; + var $635; + var $636; + var $637; + var $638; + var $639; + var $640; + var $641; + var $642=(sp)+(160); + var $643; + var $644; + var $645; + var $646; + var $647; + var $648; + var $649; + var $650; + var $651; + var $652; + var $653; + var $654; + var $655; + var $656; + var $657; + var $658; + var $659; + var $660; + var $661; + var $662; + var $663; + var $664; + var $665; + var $666; + var $667; + var $668; + var $669; + var $670; + var $671; + var $672; + var $673; + var $674; + var $675; + var $676; + var $677; + var $678; + var $679; + var $680; + var $681; + var $__a_i_i_i1_i_i_i433; + var $__i_i_i_i2_i_i_i434; + var $682; + var $683; + var $684; + var $685; + var $686; + var $687; + var $688; + var $689; + var $690; + var $__a_i_i_i_i_i_i435; + var $__i_i_i_i_i_i_i436; + var $691; + var $692; + var $693; + var $694; + var $695; + var $696; + var $697; + var $698; + var $699; + var $700; + var $701=(sp)+(176); + var $702; + var $703; + var $704; + var $705; + var $706; + var $707; + var $708; + var $709; + var $710; + var $711; + var $712; + var $713; + var $714; + var $715; + var $716; + var $717; + var $718; + var $719; + var $720; + var $721; + var $722; + var $723; + var $724; + var $725; + var $726; + var $727; + var $728; + var $729; + var $730; + var $731; + var $732; + var $733; + var $734; + var $735; + var $736; + var $737; + var $738; + var $739; + var $740; + var $__a_i_i_i1_i_i_i420; + var $__i_i_i_i2_i_i_i421; + var $741; + var $742; + var $743; + var $744; + var $745; + var $746; + var $747; + var $748; + var $749; + var $__a_i_i_i_i_i_i422; + var $__i_i_i_i_i_i_i423; + var $750; + var $751; + var $752; + var $753; + var $754; + var $755; + var $756; + var $757; + var $758; + var $759; + var $760=(sp)+(192); + var $761; + var $762; + var $763; + var $764; + var $765; + var $766; + var $767; + var $768; + var $769; + var $770; + var $771; + var $772; + var $773; + var $774; + var $775; + var $776; + var $777; + var $778; + var $779; + var $780; + var $781; + var $782; + var $783; + var $784; + var $785; + var $786; + var $787; + var $788; + var $789; + var $790; + var $791; + var $792; + var $793; + var $794; + var $795; + var $796; + var $797; + var $798; + var $799; + var $__a_i_i_i1_i_i_i407; + var $__i_i_i_i2_i_i_i408; + var $800; + var $801; + var $802; + var $803; + var $804; + var $805; + var $806; + var $807; + var $808; + var $__a_i_i_i_i_i_i409; + var $__i_i_i_i_i_i_i410; + var $809; + var $810; + var $811; + var $812; + var $813; + var $814; + var $815; + var $816; + var $817; + var $818; + var $819=(sp)+(208); + var $820; + var $821; + var $822; + var $823; + var $824; + var $825; + var $826; + var $827; + var $828; + var $829; + var $830; + var $831; + var $832; + var $833; + var $834; + var $835; + var $836; + var $837; + var $838; + var $839; + var $840; + var $841; + var $842; + var $843; + var $844; + var $845; + var $846; + var $847; + var $848; + var $849; + var $850; + var $851; + var $852; + var $853; + var $854; + var $855; + var $856; + var $857; + var $858; + var $__a_i_i_i1_i_i_i394; + var $__i_i_i_i2_i_i_i395; + var $859; + var $860; + var $861; + var $862; + var $863; + var $864; + var $865; + var $866; + var $867; + var $__a_i_i_i_i_i_i396; + var $__i_i_i_i_i_i_i397; + var $868; + var $869; + var $870; + var $871; + var $872; + var $873; + var $874; + var $875; + var $876; + var $877; + var $878=(sp)+(224); + var $879; + var $880; + var $881; + var $882; + var $883; + var $884; + var $885; + var $886; + var $887; + var $888; + var $889; + var $890; + var $891; + var $892; + var $893; + var $894; + var $895; + var $896; + var $897; + var $898; + var $899; + var $900; + var $901; + var $902; + var $903; + var $904; + var $905; + var $906; + var $907; + var $908; + var $909; + var $910; + var $911; + var $912; + var $913; + var $914; + var $915; + var $916; + var $917; + var $__a_i_i_i1_i_i_i381; + var $__i_i_i_i2_i_i_i382; + var $918; + var $919; + var $920; + var $921; + var $922; + var $923; + var $924; + var $925; + var $926; + var $__a_i_i_i_i_i_i383; + var $__i_i_i_i_i_i_i384; + var $927; + var $928; + var $929; + var $930; + var $931; + var $932; + var $933; + var $934; + var $935; + var $936; + var $937=(sp)+(240); + var $938; + var $939; + var $940; + var $941; + var $942; + var $943; + var $944; + var $945; + var $946; + var $947; + var $948; + var $949; + var $950; + var $951; + var $952; + var $953; + var $954; + var $955; + var $956; + var $957; + var $958; + var $959; + var $960; + var $961; + var $962; + var $963; + var $964; + var $965; + var $966; + var $967; + var $968; + var $969; + var $970; + var $971; + var $972; + var $973; + var $974; + var $975; + var $976; + var $__a_i_i_i1_i_i_i368; + var $__i_i_i_i2_i_i_i369; + var $977; + var $978; + var $979; + var $980; + var $981; + var $982; + var $983; + var $984; + var $985; + var $__a_i_i_i_i_i_i370; + var $__i_i_i_i_i_i_i371; + var $986; + var $987; + var $988; + var $989; + var $990; + var $991; + var $992; + var $993; + var $994; + var $995; + var $996=(sp)+(256); + var $997; + var $998; + var $999; + var $1000; + var $1001; + var $1002; + var $1003; + var $1004; + var $1005; + var $1006; + var $1007; + var $1008; + var $1009; + var $1010; + var $1011; + var $1012; + var $1013; + var $1014; + var $1015; + var $1016; + var $1017; + var $1018; + var $1019; + var $1020; + var $1021; + var $1022; + var $1023; + var $1024; + var $1025; + var $1026; + var $1027; + var $1028; + var $1029; + var $1030; + var $1031; + var $1032; + var $1033; + var $1034; + var $1035; + var $__a_i_i_i1_i_i_i355; + var $__i_i_i_i2_i_i_i356; + var $1036; + var $1037; + var $1038; + var $1039; + var $1040; + var $1041; + var $1042; + var $1043; + var $1044; + var $__a_i_i_i_i_i_i357; + var $__i_i_i_i_i_i_i358; + var $1045; + var $1046; + var $1047; + var $1048; + var $1049; + var $1050; + var $1051; + var $1052; + var $1053; + var $1054; + var $1055=(sp)+(272); + var $1056; + var $1057; + var $1058; + var $1059; + var $1060; + var $1061; + var $1062; + var $1063; + var $1064; + var $1065; + var $1066; + var $1067; + var $1068; + var $1069; + var $1070; + var $1071; + var $1072; + var $1073; + var $1074; + var $1075; + var $1076; + var $1077; + var $1078; + var $1079; + var $1080; + var $1081; + var $1082; + var $1083; + var $1084; + var $1085; + var $1086; + var $1087; + var $1088; + var $1089; + var $1090; + var $1091; + var $1092; + var $1093; + var $1094; + var $__a_i_i_i1_i_i_i342; + var $__i_i_i_i2_i_i_i343; + var $1095; + var $1096; + var $1097; + var $1098; + var $1099; + var $1100; + var $1101; + var $1102; + var $1103; + var $__a_i_i_i_i_i_i344; + var $__i_i_i_i_i_i_i345; + var $1104; + var $1105; + var $1106; + var $1107; + var $1108; + var $1109; + var $1110; + var $1111; + var $1112; + var $1113; + var $1114=(sp)+(288); + var $1115; + var $1116; + var $1117; + var $1118; + var $1119; + var $1120; + var $1121; + var $1122; + var $1123; + var $1124; + var $1125; + var $1126; + var $1127; + var $1128; + var $1129; + var $1130; + var $1131; + var $1132; + var $1133; + var $1134; + var $1135; + var $1136; + var $1137; + var $1138; + var $1139; + var $1140; + var $1141; + var $1142; + var $1143; + var $1144; + var $1145; + var $1146; + var $1147; + var $1148; + var $1149; + var $1150; + var $1151; + var $1152; + var $1153; + var $__a_i_i_i1_i_i_i329; + var $__i_i_i_i2_i_i_i330; + var $1154; + var $1155; + var $1156; + var $1157; + var $1158; + var $1159; + var $1160; + var $1161; + var $1162; + var $__a_i_i_i_i_i_i331; + var $__i_i_i_i_i_i_i332; + var $1163; + var $1164; + var $1165; + var $1166; + var $1167; + var $1168; + var $1169; + var $1170; + var $1171; + var $1172; + var $1173=(sp)+(304); + var $1174; + var $1175; + var $1176; + var $1177; + var $1178; + var $1179; + var $1180; + var $1181; + var $1182; + var $1183; + var $1184; + var $1185; + var $1186; + var $1187; + var $1188; + var $1189; + var $1190; + var $1191; + var $1192; + var $1193; + var $1194; + var $1195; + var $1196; + var $1197; + var $1198; + var $1199; + var $1200; + var $1201; + var $1202; + var $1203; + var $1204; + var $1205; + var $1206; + var $1207; + var $1208; + var $1209; + var $1210; + var $1211; + var $1212; + var $__a_i_i_i1_i_i_i316; + var $__i_i_i_i2_i_i_i317; + var $1213; + var $1214; + var $1215; + var $1216; + var $1217; + var $1218; + var $1219; + var $1220; + var $1221; + var $__a_i_i_i_i_i_i318; + var $__i_i_i_i_i_i_i319; + var $1222; + var $1223; + var $1224; + var $1225; + var $1226; + var $1227; + var $1228; + var $1229; + var $1230; + var $1231; + var $1232=(sp)+(320); + var $1233; + var $1234; + var $1235; + var $1236; + var $1237; + var $1238; + var $1239; + var $1240; + var $1241; + var $1242; + var $1243; + var $1244; + var $1245; + var $1246; + var $1247; + var $1248; + var $1249; + var $1250; + var $1251; + var $1252; + var $1253; + var $1254; + var $1255; + var $1256; + var $1257; + var $1258; + var $1259; + var $1260; + var $1261; + var $1262; + var $1263; + var $1264; + var $1265; + var $1266; + var $1267; + var $1268; + var $1269; + var $1270; + var $1271; + var $__a_i_i_i1_i_i_i303; + var $__i_i_i_i2_i_i_i304; + var $1272; + var $1273; + var $1274; + var $1275; + var $1276; + var $1277; + var $1278; + var $1279; + var $1280; + var $__a_i_i_i_i_i_i305; + var $__i_i_i_i_i_i_i306; + var $1281; + var $1282; + var $1283; + var $1284; + var $1285; + var $1286; + var $1287; + var $1288; + var $1289; + var $1290; + var $1291=(sp)+(336); + var $1292; + var $1293; + var $1294; + var $1295; + var $1296; + var $1297; + var $1298; + var $1299; + var $1300; + var $1301; + var $1302; + var $1303; + var $1304; + var $1305; + var $1306; + var $1307; + var $1308; + var $1309; + var $1310; + var $1311; + var $1312; + var $1313; + var $1314; + var $1315; + var $1316; + var $1317; + var $1318; + var $1319; + var $1320; + var $1321; + var $1322; + var $1323; + var $1324; + var $1325; + var $1326; + var $1327; + var $1328; + var $1329; + var $1330; + var $__a_i_i_i1_i_i_i290; + var $__i_i_i_i2_i_i_i291; + var $1331; + var $1332; + var $1333; + var $1334; + var $1335; + var $1336; + var $1337; + var $1338; + var $1339; + var $__a_i_i_i_i_i_i292; + var $__i_i_i_i_i_i_i293; + var $1340; + var $1341; + var $1342; + var $1343; + var $1344; + var $1345; + var $1346; + var $1347; + var $1348; + var $1349; + var $1350=(sp)+(352); + var $1351; + var $1352; + var $1353; + var $1354; + var $1355; + var $1356; + var $1357; + var $1358; + var $1359; + var $1360; + var $1361; + var $1362; + var $1363; + var $1364; + var $1365; + var $1366; + var $1367; + var $1368; + var $1369; + var $1370; + var $1371; + var $1372; + var $1373; + var $1374; + var $1375; + var $1376; + var $1377; + var $1378; + var $1379; + var $1380; + var $1381; + var $1382; + var $1383; + var $1384; + var $1385; + var $1386; + var $1387; + var $1388; + var $1389; + var $__a_i_i_i1_i_i_i277; + var $__i_i_i_i2_i_i_i278; + var $1390; + var $1391; + var $1392; + var $1393; + var $1394; + var $1395; + var $1396; + var $1397; + var $1398; + var $__a_i_i_i_i_i_i279; + var $__i_i_i_i_i_i_i280; + var $1399; + var $1400; + var $1401; + var $1402; + var $1403; + var $1404; + var $1405; + var $1406; + var $1407; + var $1408; + var $1409=(sp)+(368); + var $1410; + var $1411; + var $1412; + var $1413; + var $1414; + var $1415; + var $1416; + var $1417; + var $1418; + var $1419; + var $1420; + var $1421; + var $1422; + var $1423; + var $1424; + var $1425; + var $1426; + var $1427; + var $1428; + var $1429; + var $1430; + var $1431; + var $1432; + var $1433; + var $1434; + var $1435; + var $1436; + var $1437; + var $1438; + var $1439; + var $1440; + var $1441; + var $1442; + var $1443; + var $1444; + var $1445; + var $1446; + var $1447; + var $1448; + var $__a_i_i_i1_i_i_i264; + var $__i_i_i_i2_i_i_i265; + var $1449; + var $1450; + var $1451; + var $1452; + var $1453; + var $1454; + var $1455; + var $1456; + var $1457; + var $__a_i_i_i_i_i_i266; + var $__i_i_i_i_i_i_i267; + var $1458; + var $1459; + var $1460; + var $1461; + var $1462; + var $1463; + var $1464; + var $1465; + var $1466; + var $1467; + var $1468=(sp)+(384); + var $1469; + var $1470; + var $1471; + var $1472; + var $1473; + var $1474; + var $1475; + var $1476; + var $1477; + var $1478; + var $1479; + var $1480; + var $1481; + var $1482; + var $1483; + var $1484; + var $1485; + var $1486; + var $1487; + var $1488; + var $1489; + var $1490; + var $1491; + var $1492; + var $1493; + var $1494; + var $1495; + var $1496; + var $1497; + var $1498; + var $1499; + var $1500; + var $1501; + var $1502; + var $1503; + var $1504; + var $1505; + var $1506; + var $1507; + var $__a_i_i_i1_i_i_i251; + var $__i_i_i_i2_i_i_i252; + var $1508; + var $1509; + var $1510; + var $1511; + var $1512; + var $1513; + var $1514; + var $1515; + var $1516; + var $__a_i_i_i_i_i_i253; + var $__i_i_i_i_i_i_i254; + var $1517; + var $1518; + var $1519; + var $1520; + var $1521; + var $1522; + var $1523; + var $1524; + var $1525; + var $1526; + var $1527=(sp)+(400); + var $1528; + var $1529; + var $1530; + var $1531; + var $1532; + var $1533; + var $1534; + var $1535; + var $1536; + var $1537; + var $1538; + var $1539; + var $1540; + var $1541; + var $1542; + var $1543; + var $1544; + var $1545; + var $1546; + var $1547; + var $1548; + var $1549; + var $1550; + var $1551; + var $1552; + var $1553; + var $1554; + var $1555; + var $1556; + var $1557; + var $1558; + var $1559; + var $1560; + var $1561; + var $1562; + var $1563; + var $1564; + var $1565; + var $1566; + var $__a_i_i_i1_i_i_i238; + var $__i_i_i_i2_i_i_i239; + var $1567; + var $1568; + var $1569; + var $1570; + var $1571; + var $1572; + var $1573; + var $1574; + var $1575; + var $__a_i_i_i_i_i_i240; + var $__i_i_i_i_i_i_i241; + var $1576; + var $1577; + var $1578; + var $1579; + var $1580; + var $1581; + var $1582; + var $1583; + var $1584; + var $1585; + var $1586=(sp)+(416); + var $1587; + var $1588; + var $1589; + var $1590; + var $1591; + var $1592; + var $1593; + var $1594; + var $1595; + var $1596; + var $1597; + var $1598; + var $1599; + var $1600; + var $1601; + var $1602; + var $1603; + var $1604; + var $1605; + var $1606; + var $1607; + var $1608; + var $1609; + var $1610; + var $1611; + var $1612; + var $1613; + var $1614; + var $1615; + var $1616; + var $1617; + var $1618; + var $1619; + var $1620; + var $1621; + var $1622; + var $1623; + var $1624; + var $1625; + var $__a_i_i_i1_i_i_i225; + var $__i_i_i_i2_i_i_i226; + var $1626; + var $1627; + var $1628; + var $1629; + var $1630; + var $1631; + var $1632; + var $1633; + var $1634; + var $__a_i_i_i_i_i_i227; + var $__i_i_i_i_i_i_i228; + var $1635; + var $1636; + var $1637; + var $1638; + var $1639; + var $1640; + var $1641; + var $1642; + var $1643; + var $1644; + var $1645=(sp)+(432); + var $1646; + var $1647; + var $1648; + var $1649; + var $1650; + var $1651; + var $1652; + var $1653; + var $1654; + var $1655; + var $1656; + var $1657; + var $1658; + var $1659; + var $1660; + var $1661; + var $1662; + var $1663; + var $1664; + var $1665; + var $1666; + var $1667; + var $1668; + var $1669; + var $1670; + var $1671; + var $1672; + var $1673; + var $1674; + var $1675; + var $1676; + var $1677; + var $1678; + var $1679; + var $1680; + var $1681; + var $1682; + var $1683; + var $1684; + var $__a_i_i_i1_i_i_i212; + var $__i_i_i_i2_i_i_i213; + var $1685; + var $1686; + var $1687; + var $1688; + var $1689; + var $1690; + var $1691; + var $1692; + var $1693; + var $__a_i_i_i_i_i_i214; + var $__i_i_i_i_i_i_i215; + var $1694; + var $1695; + var $1696; + var $1697; + var $1698; + var $1699; + var $1700; + var $1701; + var $1702; + var $1703; + var $1704=(sp)+(448); + var $1705; + var $1706; + var $1707; + var $1708; + var $1709; + var $1710; + var $1711; + var $1712; + var $1713; + var $1714; + var $1715; + var $1716; + var $1717; + var $1718; + var $1719; + var $1720; + var $1721; + var $1722; + var $1723; + var $1724; + var $1725; + var $1726; + var $1727; + var $1728; + var $1729; + var $1730; + var $1731; + var $1732; + var $1733; + var $1734; + var $1735; + var $1736; + var $1737; + var $1738; + var $1739; + var $1740; + var $1741; + var $1742; + var $1743; + var $__a_i_i_i1_i_i_i199; + var $__i_i_i_i2_i_i_i200; + var $1744; + var $1745; + var $1746; + var $1747; + var $1748; + var $1749; + var $1750; + var $1751; + var $1752; + var $__a_i_i_i_i_i_i201; + var $__i_i_i_i_i_i_i202; + var $1753; + var $1754; + var $1755; + var $1756; + var $1757; + var $1758; + var $1759; + var $1760; + var $1761; + var $1762; + var $1763=(sp)+(464); + var $1764; + var $1765; + var $1766; + var $1767; + var $1768; + var $1769; + var $1770; + var $1771; + var $1772; + var $1773; + var $1774; + var $1775; + var $1776; + var $1777; + var $1778; + var $1779; + var $1780; + var $1781; + var $1782; + var $1783; + var $1784; + var $1785; + var $1786; + var $1787; + var $1788; + var $1789; + var $1790; + var $1791; + var $1792; + var $1793; + var $1794; + var $1795; + var $1796; + var $1797; + var $1798; + var $1799; + var $1800; + var $1801; + var $1802; + var $__a_i_i_i1_i_i_i186; + var $__i_i_i_i2_i_i_i187; + var $1803; + var $1804; + var $1805; + var $1806; + var $1807; + var $1808; + var $1809; + var $1810; + var $1811; + var $__a_i_i_i_i_i_i188; + var $__i_i_i_i_i_i_i189; + var $1812; + var $1813; + var $1814; + var $1815; + var $1816; + var $1817; + var $1818; + var $1819; + var $1820; + var $1821; + var $1822=(sp)+(480); + var $1823; + var $1824; + var $1825; + var $1826; + var $1827; + var $1828; + var $1829; + var $1830; + var $1831; + var $1832; + var $1833; + var $1834; + var $1835; + var $1836; + var $1837; + var $1838; + var $1839; + var $1840; + var $1841; + var $1842; + var $1843; + var $1844; + var $1845; + var $1846; + var $1847; + var $1848; + var $1849; + var $1850; + var $1851; + var $1852; + var $1853; + var $1854; + var $1855; + var $1856; + var $1857; + var $1858; + var $1859; + var $1860; + var $1861; + var $__a_i_i_i1_i_i_i173; + var $__i_i_i_i2_i_i_i174; + var $1862; + var $1863; + var $1864; + var $1865; + var $1866; + var $1867; + var $1868; + var $1869; + var $1870; + var $__a_i_i_i_i_i_i175; + var $__i_i_i_i_i_i_i176; + var $1871; + var $1872; + var $1873; + var $1874; + var $1875; + var $1876; + var $1877; + var $1878; + var $1879; + var $1880; + var $1881=(sp)+(496); + var $1882; + var $1883; + var $1884; + var $1885; + var $1886; + var $1887; + var $1888; + var $1889; + var $1890; + var $1891; + var $1892; + var $1893; + var $1894; + var $1895; + var $1896; + var $1897; + var $1898; + var $1899; + var $1900; + var $1901; + var $1902; + var $1903; + var $1904; + var $1905; + var $1906; + var $1907; + var $1908; + var $1909; + var $1910; + var $1911; + var $1912; + var $1913; + var $1914; + var $1915; + var $1916; + var $1917; + var $1918; + var $1919; + var $1920; + var $__a_i_i_i1_i_i_i160; + var $__i_i_i_i2_i_i_i161; + var $1921; + var $1922; + var $1923; + var $1924; + var $1925; + var $1926; + var $1927; + var $1928; + var $1929; + var $__a_i_i_i_i_i_i162; + var $__i_i_i_i_i_i_i163; + var $1930; + var $1931; + var $1932; + var $1933; + var $1934; + var $1935; + var $1936; + var $1937; + var $1938; + var $1939; + var $1940=(sp)+(512); + var $1941; + var $1942; + var $1943; + var $1944; + var $1945; + var $1946; + var $1947; + var $1948; + var $1949; + var $1950; + var $1951; + var $1952; + var $1953; + var $1954; + var $1955; + var $1956; + var $1957; + var $1958; + var $1959; + var $1960; + var $1961; + var $1962; + var $1963; + var $1964; + var $1965; + var $1966; + var $1967; + var $1968; + var $1969; + var $1970; + var $1971; + var $1972; + var $1973; + var $1974; + var $1975; + var $1976; + var $1977; + var $1978; + var $1979; + var $__a_i_i_i1_i_i_i147; + var $__i_i_i_i2_i_i_i148; + var $1980; + var $1981; + var $1982; + var $1983; + var $1984; + var $1985; + var $1986; + var $1987; + var $1988; + var $__a_i_i_i_i_i_i149; + var $__i_i_i_i_i_i_i150; + var $1989; + var $1990; + var $1991; + var $1992; + var $1993; + var $1994; + var $1995; + var $1996; + var $1997; + var $1998; + var $1999=(sp)+(528); + var $2000; + var $2001; + var $2002; + var $2003; + var $2004; + var $2005; + var $2006; + var $2007; + var $2008; + var $2009; + var $2010; + var $2011; + var $2012; + var $2013; + var $2014; + var $2015; + var $2016; + var $2017; + var $2018; + var $2019; + var $2020; + var $2021; + var $2022; + var $2023; + var $2024; + var $2025; + var $2026; + var $2027; + var $2028; + var $2029; + var $2030; + var $2031; + var $2032; + var $2033; + var $2034; + var $2035; + var $2036; + var $2037; + var $2038; + var $__a_i_i_i1_i_i_i134; + var $__i_i_i_i2_i_i_i135; + var $2039; + var $2040; + var $2041; + var $2042; + var $2043; + var $2044; + var $2045; + var $2046; + var $2047; + var $__a_i_i_i_i_i_i136; + var $__i_i_i_i_i_i_i137; + var $2048; + var $2049; + var $2050; + var $2051; + var $2052; + var $2053; + var $2054; + var $2055; + var $2056; + var $2057; + var $2058=(sp)+(544); + var $2059; + var $2060; + var $2061; + var $2062; + var $2063; + var $2064; + var $2065; + var $2066; + var $2067; + var $2068; + var $2069; + var $2070; + var $2071; + var $2072; + var $2073; + var $2074; + var $2075; + var $2076; + var $2077; + var $2078; + var $2079; + var $2080; + var $2081; + var $2082; + var $2083; + var $2084; + var $2085; + var $2086; + var $2087; + var $2088; + var $2089; + var $2090; + var $2091; + var $2092; + var $2093; + var $2094; + var $2095; + var $2096; + var $2097; + var $__a_i_i_i1_i_i_i121; + var $__i_i_i_i2_i_i_i122; + var $2098; + var $2099; + var $2100; + var $2101; + var $2102; + var $2103; + var $2104; + var $2105; + var $2106; + var $__a_i_i_i_i_i_i123; + var $__i_i_i_i_i_i_i124; + var $2107; + var $2108; + var $2109; + var $2110; + var $2111; + var $2112; + var $2113; + var $2114; + var $2115; + var $2116; + var $2117=(sp)+(560); + var $2118; + var $2119; + var $2120; + var $2121; + var $2122; + var $2123; + var $2124; + var $2125; + var $2126; + var $2127; + var $2128; + var $2129; + var $2130; + var $2131; + var $2132; + var $2133; + var $2134; + var $2135; + var $2136; + var $2137; + var $2138; + var $2139; + var $2140; + var $2141; + var $2142; + var $2143; + var $2144; + var $2145; + var $2146; + var $2147; + var $2148; + var $2149; + var $2150; + var $2151; + var $2152; + var $2153; + var $2154; + var $2155; + var $2156; + var $__a_i_i_i1_i_i_i108; + var $__i_i_i_i2_i_i_i109; + var $2157; + var $2158; + var $2159; + var $2160; + var $2161; + var $2162; + var $2163; + var $2164; + var $2165; + var $__a_i_i_i_i_i_i110; + var $__i_i_i_i_i_i_i111; + var $2166; + var $2167; + var $2168; + var $2169; + var $2170; + var $2171; + var $2172; + var $2173; + var $2174; + var $2175; + var $2176=(sp)+(576); + var $2177; + var $2178; + var $2179; + var $2180; + var $2181; + var $2182; + var $2183; + var $2184; + var $2185; + var $2186; + var $2187; + var $2188; + var $2189; + var $2190; + var $2191; + var $2192; + var $2193; + var $2194; + var $2195; + var $2196; + var $2197; + var $2198; + var $2199; + var $2200; + var $2201; + var $2202; + var $2203; + var $2204; + var $2205; + var $2206; + var $2207; + var $2208; + var $2209; + var $2210; + var $2211; + var $2212; + var $2213; + var $2214; + var $2215; + var $__a_i_i_i1_i_i_i95; + var $__i_i_i_i2_i_i_i96; + var $2216; + var $2217; + var $2218; + var $2219; + var $2220; + var $2221; + var $2222; + var $2223; + var $2224; + var $__a_i_i_i_i_i_i97; + var $__i_i_i_i_i_i_i98; + var $2225; + var $2226; + var $2227; + var $2228; + var $2229; + var $2230; + var $2231; + var $2232; + var $2233; + var $2234; + var $2235=(sp)+(592); + var $2236; + var $2237; + var $2238; + var $2239; + var $2240; + var $2241; + var $2242; + var $2243; + var $2244; + var $2245; + var $2246; + var $2247; + var $2248; + var $2249; + var $2250; + var $2251; + var $2252; + var $2253; + var $2254; + var $2255; + var $2256; + var $2257; + var $2258; + var $2259; + var $2260; + var $2261; + var $2262; + var $2263; + var $2264; + var $2265; + var $2266; + var $2267; + var $2268; + var $2269; + var $2270; + var $2271; + var $2272; + var $2273; + var $2274; + var $__a_i_i_i1_i_i_i82; + var $__i_i_i_i2_i_i_i83; + var $2275; + var $2276; + var $2277; + var $2278; + var $2279; + var $2280; + var $2281; + var $2282; + var $2283; + var $__a_i_i_i_i_i_i84; + var $__i_i_i_i_i_i_i85; + var $2284; + var $2285; + var $2286; + var $2287; + var $2288; + var $2289; + var $2290; + var $2291; + var $2292; + var $2293; + var $2294=(sp)+(608); + var $2295; + var $2296; + var $2297; + var $2298; + var $2299; + var $2300; + var $2301; + var $2302; + var $2303; + var $2304; + var $2305; + var $2306; + var $2307; + var $2308; + var $2309; + var $2310; + var $2311; + var $2312; + var $2313; + var $2314; + var $2315; + var $2316; + var $2317; + var $2318; + var $2319; + var $2320; + var $2321; + var $2322; + var $2323; + var $2324; + var $2325; + var $2326; + var $2327; + var $2328; + var $2329; + var $2330; + var $2331; + var $2332; + var $2333; + var $__a_i_i_i1_i_i_i69; + var $__i_i_i_i2_i_i_i70; + var $2334; + var $2335; + var $2336; + var $2337; + var $2338; + var $2339; + var $2340; + var $2341; + var $2342; + var $__a_i_i_i_i_i_i71; + var $__i_i_i_i_i_i_i72; + var $2343; + var $2344; + var $2345; + var $2346; + var $2347; + var $2348; + var $2349; + var $2350; + var $2351; + var $2352; + var $2353=(sp)+(624); + var $2354; + var $2355; + var $2356; + var $2357; + var $2358; + var $2359; + var $2360; + var $2361; + var $2362; + var $2363; + var $2364; + var $2365; + var $2366; + var $2367; + var $2368; + var $2369; + var $2370; + var $2371; + var $2372; + var $2373; + var $2374; + var $2375; + var $2376; + var $2377; + var $2378; + var $2379; + var $2380; + var $2381; + var $2382; + var $2383; + var $2384; + var $2385; + var $2386; + var $2387; + var $2388; + var $2389; + var $2390; + var $2391; + var $2392; + var $__a_i_i_i1_i_i_i56; + var $__i_i_i_i2_i_i_i57; + var $2393; + var $2394; + var $2395; + var $2396; + var $2397; + var $2398; + var $2399; + var $2400; + var $2401; + var $__a_i_i_i_i_i_i58; + var $__i_i_i_i_i_i_i59; + var $2402; + var $2403; + var $2404; + var $2405; + var $2406; + var $2407; + var $2408; + var $2409; + var $2410; + var $2411; + var $2412=(sp)+(640); + var $2413; + var $2414; + var $2415; + var $2416; + var $2417; + var $2418; + var $2419; + var $2420; + var $2421; + var $2422; + var $2423; + var $2424; + var $2425; + var $2426; + var $2427; + var $2428; + var $2429; + var $2430; + var $2431; + var $2432; + var $2433; + var $2434; + var $2435; + var $2436; + var $2437; + var $2438; + var $2439; + var $2440; + var $2441; + var $2442; + var $2443; + var $2444; + var $2445; + var $2446; + var $2447; + var $2448; + var $2449; + var $2450; + var $2451; + var $__a_i_i_i1_i_i_i43; + var $__i_i_i_i2_i_i_i44; + var $2452; + var $2453; + var $2454; + var $2455; + var $2456; + var $2457; + var $2458; + var $2459; + var $2460; + var $__a_i_i_i_i_i_i45; + var $__i_i_i_i_i_i_i46; + var $2461; + var $2462; + var $2463; + var $2464; + var $2465; + var $2466; + var $2467; + var $2468; + var $2469; + var $2470; + var $2471=(sp)+(656); + var $2472; + var $2473; + var $2474; + var $2475; + var $2476; + var $2477; + var $2478; + var $2479; + var $2480; + var $2481; + var $2482; + var $2483; + var $2484; + var $2485; + var $2486; + var $2487; + var $2488; + var $2489; + var $2490; + var $2491; + var $2492; + var $2493; + var $2494; + var $2495; + var $2496; + var $2497; + var $2498; + var $2499; + var $2500; + var $2501; + var $2502; + var $2503; + var $2504; + var $2505; + var $2506; + var $2507; + var $2508; + var $2509; + var $2510; + var $__a_i_i_i1_i_i_i; + var $__i_i_i_i2_i_i_i; + var $2511; + var $2512; + var $2513; + var $2514; + var $2515; + var $2516; + var $2517; + var $2518; + var $2519; + var $__a_i_i_i_i_i_i; + var $__i_i_i_i_i_i_i; + var $2520; + var $2521; + var $2522; + var $2523; + var $2524; + var $2525; + var $2526; + var $2527; + var $2528; + var $2529; + var $2530=(sp)+(672); + var $2531; + var $2532; + var $2533; + var $2534; + var $2535; + var $2536; + var $2537; + var $2538; + var $2539; + var $2540=(sp)+(688); + var $2541=(sp)+(704); + var $2542; + var $2543; + var $std_stringstream=(sp)+(720); + var $2544=(sp)+(864); + var $2545=(sp)+(880); + var $2546=(sp)+(896); + var $2547; + var $2548=(sp)+(912); + var $2549=(sp)+(928); + var $std_stringstream1=(sp)+(944); + var $2550=(sp)+(1088); + var $2551=(sp)+(1104); + var $2552=(sp)+(1120); + var $2553; + var $2554=(sp)+(1136); + var $2555=(sp)+(1152); + var $std_stringstream2=(sp)+(1168); + var $2556=(sp)+(1312); + var $2557=(sp)+(1328); + var $2558=(sp)+(1344); + var $2559; + var $2560=(sp)+(1360); + var $2561=(sp)+(1376); + var $std_stringstream3=(sp)+(1392); + var $2562=(sp)+(1536); + var $2563=(sp)+(1552); + var $2564=(sp)+(1568); + var $2565; + var $2566=(sp)+(1584); + var $2567=(sp)+(1600); + var $std_stringstream4=(sp)+(1616); + var $2568=(sp)+(1760); + var $2569=(sp)+(1776); + var $2570=(sp)+(1792); + var $2571; + var $2572=(sp)+(1808); + var $2573=(sp)+(1824); + var $std_stringstream5=(sp)+(1840); + var $2574=(sp)+(1984); + var $2575=(sp)+(2000); + var $2576=(sp)+(2016); + var $2577; + var $2578=(sp)+(2032); + var $2579=(sp)+(2048); + var $std_stringstream6=(sp)+(2064); + var $2580=(sp)+(2208); + var $2581=(sp)+(2224); + var $2582=(sp)+(2240); + var $2583; + var $2584=(sp)+(2256); + var $2585=(sp)+(2272); + var $std_stringstream7=(sp)+(2288); + var $2586=(sp)+(2432); + var $2587=(sp)+(2448); + var $2588=(sp)+(2464); + var $2589; + var $2590=(sp)+(2480); + var $2591=(sp)+(2496); + var $std_stringstream8=(sp)+(2512); + var $2592=(sp)+(2656); + var $2593=(sp)+(2672); + var $2594=(sp)+(2688); + var $2595; + var $2596=(sp)+(2704); + var $2597=(sp)+(2720); + var $std_stringstream9=(sp)+(2736); + var $2598=(sp)+(2880); + var $2599=(sp)+(2896); + var $2600=(sp)+(2912); + var $2601; + var $2602=(sp)+(2928); + var $2603=(sp)+(2944); + var $std_stringstream10=(sp)+(2960); + var $2604=(sp)+(3104); + var $2605=(sp)+(3120); + var $2606=(sp)+(3136); + var $2607; + var $2608=(sp)+(3152); + var $2609=(sp)+(3168); + var $std_stringstream11=(sp)+(3184); + var $2610=(sp)+(3328); + var $2611=(sp)+(3344); + var $2612=(sp)+(3360); + var $2613; + var $2614=(sp)+(3376); + var $2615=(sp)+(3392); + var $std_stringstream12=(sp)+(3408); + var $2616=(sp)+(3552); + var $2617=(sp)+(3568); + var $2618=(sp)+(3584); + var $2619; + var $2620=(sp)+(3600); + var $2621=(sp)+(3616); + var $std_stringstream13=(sp)+(3632); + var $2622=(sp)+(3776); + var $2623=(sp)+(3792); + var $2624=(sp)+(3808); + var $2625; + var $2626=(sp)+(3824); + var $2627=(sp)+(3840); + var $std_stringstream14=(sp)+(3856); + var $2628=(sp)+(4000); + var $2629=(sp)+(4016); + var $2630=(sp)+(4032); + var $2631; + var $2632=(sp)+(4048); + var $2633=(sp)+(4064); + var $std_stringstream15=(sp)+(4080); + var $2634=(sp)+(4224); + var $2635=(sp)+(4240); + var $2636=(sp)+(4256); + var $2637; + var $2638=(sp)+(4272); + var $2639=(sp)+(4288); + var $std_stringstream16=(sp)+(4304); + var $2640=(sp)+(4448); + var $2641=(sp)+(4464); + var $2642=(sp)+(4480); + var $2643; + var $2644=(sp)+(4496); + var $2645=(sp)+(4512); + var $std_stringstream17=(sp)+(4528); + var $2646=(sp)+(4672); + var $2647=(sp)+(4688); + var $2648=(sp)+(4704); + var $2649; + var $2650=(sp)+(4720); + var $2651=(sp)+(4736); + var $std_stringstream18=(sp)+(4752); + var $2652=(sp)+(4896); + var $2653=(sp)+(4912); + var $2654=(sp)+(4928); + var $2655; + var $2656=(sp)+(4944); + var $2657=(sp)+(4960); + var $std_stringstream19=(sp)+(4976); + var $2658=(sp)+(5120); + var $2659=(sp)+(5136); + var $2660=(sp)+(5152); + var $2661; + var $2662=(sp)+(5168); + var $2663=(sp)+(5184); + var $std_stringstream20=(sp)+(5200); + var $2664=(sp)+(5344); + var $2665=(sp)+(5360); + var $2666=(sp)+(5376); + var $2667; + var $2668=(sp)+(5392); + var $2669=(sp)+(5408); + var $std_stringstream21=(sp)+(5424); + var $2670=(sp)+(5568); + var $2671=(sp)+(5584); + var $2672=(sp)+(5600); + var $2673; + var $2674=(sp)+(5616); + var $2675=(sp)+(5632); + var $std_stringstream22=(sp)+(5648); + var $2676=(sp)+(5792); + var $2677=(sp)+(5808); + var $2678=(sp)+(5824); + var $2679; + var $2680=(sp)+(5840); + var $2681=(sp)+(5856); + var $std_stringstream23=(sp)+(5872); + var $2682=(sp)+(6016); + var $2683=(sp)+(6032); + var $2684=(sp)+(6048); + var $2685; + var $2686=(sp)+(6064); + var $2687=(sp)+(6080); + var $std_stringstream24=(sp)+(6096); + var $2688=(sp)+(6240); + var $2689=(sp)+(6256); + var $2690=(sp)+(6272); + var $2691; + var $2692=(sp)+(6288); + var $2693=(sp)+(6304); + var $std_stringstream25=(sp)+(6320); + var $2694=(sp)+(6464); + var $2695=(sp)+(6480); + var $2696=(sp)+(6496); + var $2697; + var $2698=(sp)+(6512); + var $2699=(sp)+(6528); + var $std_stringstream26=(sp)+(6544); + var $2700=(sp)+(6688); + var $2701=(sp)+(6704); + var $2702=(sp)+(6720); + var $2703; + var $2704=(sp)+(6736); + var $2705=(sp)+(6752); + var $std_stringstream27=(sp)+(6768); + var $2706=(sp)+(6912); + var $2707=(sp)+(6928); + var $2708=(sp)+(6944); + var $2709; + var $2710=(sp)+(6960); + var $2711=(sp)+(6976); + var $std_stringstream28=(sp)+(6992); + var $2712=(sp)+(7136); + var $2713=(sp)+(7152); + var $2714=(sp)+(7168); + var $2715; + var $2716=(sp)+(7184); + var $2717=(sp)+(7200); + var $std_stringstream29=(sp)+(7216); + var $2718=(sp)+(7360); + var $2719=(sp)+(7376); + var $2720=(sp)+(7392); + var $2721; + var $2722=(sp)+(7408); + var $2723=(sp)+(7424); + var $std_stringstream30=(sp)+(7440); + var $2724=(sp)+(7584); + var $2725=(sp)+(7600); + var $2726=(sp)+(7616); + var $2727; + var $2728=(sp)+(7632); + var $2729=(sp)+(7648); + var $std_stringstream31=(sp)+(7664); + var $2730=(sp)+(7808); + var $2731=(sp)+(7824); + var $2732=(sp)+(7840); + var $2733; + var $2734=(sp)+(7856); + var $2735=(sp)+(7872); + var $std_stringstream32=(sp)+(7888); + var $2736=(sp)+(8032); + var $2737=(sp)+(8048); + var $2738=(sp)+(8064); + var $2739; + var $2740=(sp)+(8080); + var $2741=(sp)+(8096); + var $std_stringstream33=(sp)+(8112); + var $2742=(sp)+(8256); + var $2743=(sp)+(8272); + var $2744=(sp)+(8288); + var $2745; + var $2746=(sp)+(8304); + var $2747=(sp)+(8320); + var $std_stringstream34=(sp)+(8336); + var $2748=(sp)+(8480); + var $2749=(sp)+(8496); + var $2750=(sp)+(8512); + var $2751; + var $2752=(sp)+(8528); + var $2753=(sp)+(8544); + var $std_stringstream35=(sp)+(8560); + var $2754=(sp)+(8704); + var $2755=(sp)+(8720); + var $2756=(sp)+(8736); + var $2757; + var $2758=(sp)+(8752); + var $2759=(sp)+(8768); + var $std_stringstream36=(sp)+(8784); + var $2760=(sp)+(8928); + var $2761=(sp)+(8944); + var $2762=(sp)+(8960); + var $2763; + var $2764=(sp)+(8976); + var $2765=(sp)+(8992); + var $std_stringstream37=(sp)+(9008); + var $2766=(sp)+(9152); + var $2767=(sp)+(9168); + var $2768=(sp)+(9184); + var $2769; + var $2770=(sp)+(9200); + var $2771=(sp)+(9216); + var $std_stringstream38=(sp)+(9232); + var $2772=(sp)+(9376); + var $2773=(sp)+(9392); + var $2774=(sp)+(9408); + var $2775; + var $2776=(sp)+(9424); + var $2777=(sp)+(9440); + var $std_stringstream39=(sp)+(9456); + var $2778=(sp)+(9600); + var $2779=(sp)+(9616); + var $2780=(sp)+(9632); + var $2781; + var $2782=(sp)+(9648); + var $2783=(sp)+(9664); + var $std_stringstream40=(sp)+(9680); + var $2784=(sp)+(9824); + var $2785=(sp)+(9840); + var $2786=(sp)+(9856); + var $2787; + var $2788=(sp)+(9872); + var $2789=(sp)+(9888); + var $std_stringstream41=(sp)+(9904); + var $2790=(sp)+(10048); + var $2791=(sp)+(10064); + var $2792=(sp)+(10080); + var $2793; + var $2794=(sp)+(10096); + var $2795=(sp)+(10112); + var $std_stringstream42=(sp)+(10128); + var $2796=(sp)+(10272); + var $2797=(sp)+(10288); + var $2798=(sp)+(10304); + var $2799; + $2539=$0; + label = 2; + break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2: + __ZN6StringC1EPKc($2541, ((14584)|0)); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2540, $2541, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 3; break; } else { label = 47; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 3: + var $2802 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2540, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 4; break; } else { label = 48; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 4: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2540) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 5; break; } else { label = 47; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 5: + __ZN6StringD1Ev($2541); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($2802) { label = 6; break; } else { label = 66; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 6: + $2535=$std_stringstream; + $2536=24; + var $2806=$2535; + var $2807=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2808=(($2807+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2809=$2808; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2534=$2809; + var $2810=$2534; + var $2811=$2810; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2533=$2811; + var $2812=$2533; + var $2813=$2812; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($2813)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $2814=$2810; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2814)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $2815=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2815)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2816=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2817=(($2816+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2818=$2817; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2818)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2819=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2820=(($2819+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2821=$2820; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2821)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2822=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2823=(($2806+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2824=$2823; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2503=$2822; + $2504=((109796)|0); + $2505=$2824; + var $2825=$2503; + var $2826=$2504; + var $2827=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2828=(($2826+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2829=$2505; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2500=$2827; + $2501=$2828; + $2502=$2829; + var $2830=$2500; + var $2831=$2501; + var $2832=HEAP32[(($2831)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2833=$2830; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2833)>>2)]=$2832; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2834=(($2831+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2835=HEAP32[(($2834)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2836=$2830; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2837=HEAP32[(($2836)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2838=((($2837)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2839=$2838; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2840=HEAP32[(($2839)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2841=$2830; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2842=(($2841+$2840)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2843=$2842; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2843)>>2)]=$2835; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2844=(($2830+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2844)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $2845=$2830; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2846=HEAP32[(($2845)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2847=((($2846)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2848=$2847; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2849=HEAP32[(($2848)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2850=$2830; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2851=(($2850+$2849)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2852=$2851; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $2853=$2502; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2498=$2852; + $2499=$2853; + var $2854=$2498; + var $2855=$2854; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $2856=$2499; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $2857=$2856; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($2855, $2857) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 7; break; } else { label = 23; break; } + case 7: + var $2858=(($2854+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($2858)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $2859=(($2854+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($2859)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $2860=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2861=(($2860+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2862=$2861; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2863=(($2826+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2496=$2862; + $2497=$2863; + var $2864=$2496; + var $2865=$2497; + var $2866=HEAP32[(($2865)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2867=$2864; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2867)>>2)]=$2866; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2868=(($2865+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2869=HEAP32[(($2868)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2870=$2864; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2871=HEAP32[(($2870)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2872=((($2871)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2873=$2872; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2874=HEAP32[(($2873)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2875=$2864; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2876=(($2875+$2874)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2877=$2876; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2877)>>2)]=$2869; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $2878=HEAP32[(($2826)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2879=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2879)>>2)]=$2878; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2880=(($2826+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2881=HEAP32[(($2880)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2882=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2883=HEAP32[(($2882)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2884=((($2883)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2885=$2884; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2886=HEAP32[(($2885)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2887=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2888=(($2887+$2886)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2889=$2888; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2889)>>2)]=$2881; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2890=(($2826+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2891=HEAP32[(($2890)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2892=$2825; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2893=(($2892+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2894=$2893; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2894)>>2)]=$2891; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $2895=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2895)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2896=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2897=(($2896+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2898=$2897; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2898)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2899=$2806; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2900=(($2899+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2901=$2900; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2901)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2902=(($2806+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2903=$2536; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2531=$2902; + $2532=$2903; + var $2904=$2531; + var $2905=$2532; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2526=$2904; + $2527=$2905; + var $2906=$2526; + var $2907=$2906; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($2907) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 8; break; } else { label = 24; break; } + case 8: + var $2908=$2906; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2908)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $2909=(($2906+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2525=$2909; + var $2910=$2525; + $2524=$2910; + var $2911=$2524; + var $2912=$2911; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $2913=(($2911)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2523=$2913; + var $2914=$2523; + $2522=$2914; + var $2915=$2522; + var $2916=$2915; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2521=$2916; + var $2917=$2521; + var $2918=$2917; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2520=$2918; + var $2919=$2520; + var $2920=(($2917)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2519=$2911; + var $2921=$2519; + var $2922=(($2921)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2518=$2922; + var $2923=$2518; + var $2924=$2923; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2517=$2924; + var $2925=$2517; + var $2926=(($2925)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $2927=(($2926)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $2928=$2927; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $2929=(($2928)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i=$2929; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 9; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 9: + var $2931=$__i_i_i_i_i_i_i; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $2932=(($2931)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($2932) { label = 10; break; } else { label = 11; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 10: + var $2934=$__i_i_i_i_i_i_i; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2935=$__a_i_i_i_i_i_i; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2936=(($2935+($2934<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($2936)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2937=$__i_i_i_i_i_i_i; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $2938=((($2937)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i=$2938; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 9; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 11: + var $2939=(($2906+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2939)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $2940=(($2906+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $2941=$2527; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($2940)>>2)]=$2941; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2516=$2530; + var $2942=$2516; + $2515=$2942; + var $2943=$2515; + var $2944=$2943; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $2945=(($2943)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2514=$2945; + var $2946=$2514; + $2513=$2946; + var $2947=$2513; + var $2948=$2947; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2512=$2948; + var $2949=$2512; + var $2950=$2949; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2511=$2950; + var $2951=$2511; + var $2952=(($2949)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2510=$2943; + var $2953=$2510; + var $2954=(($2953)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2509=$2954; + var $2955=$2509; + var $2956=$2955; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2508=$2956; + var $2957=$2508; + var $2958=(($2957)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $2959=(($2958)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $2960=$2959; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $2961=(($2960)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i=$2961; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 12; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 12: + var $2963=$__i_i_i_i2_i_i_i; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $2964=(($2963)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($2964) { label = 13; break; } else { label = 14; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 13: + var $2966=$__i_i_i_i2_i_i_i; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2967=$__a_i_i_i1_i_i_i; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2968=(($2967+($2966<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($2968)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $2969=$__i_i_i_i2_i_i_i; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $2970=((($2969)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i=$2970; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 12; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 14: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($2906, $2530) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 15; break; } else { label = 17; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 15: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2530) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 30; break; } else { label = 16; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 16: + var $2973$0 = ___cxa_find_matching_catch(-1, -1); $2973$1 = tempRet0; + var $2974=$2973$0; + $2528=$2974; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $2975=$2973$1; + $2529=$2975; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 19; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 17: + var $2977$0 = ___cxa_find_matching_catch(-1, -1); $2977$1 = tempRet0; + var $2978=$2977$0; + $2528=$2978; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $2979=$2977$1; + $2529=$2979; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2530) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 18; break; } else { label = 22; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 18: + label = 19; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 19: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2909) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 20; break; } else { label = 22; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 20: + var $2983=$2906; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($2983) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 21; break; } else { label = 22; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 21: + var $2985=$2528; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $2986=$2529; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $2987$0=$2985; + var $2987$1=0; + var $2988$0=$2987$0; + var $2988$1=$2986; + var $eh_lpad_body_i$1 = $2988$1;var $eh_lpad_body_i$0 = $2988$0;label = 25; break; + case 22: + var $2990$0 = ___cxa_find_matching_catch(-1, -1,0); $2990$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 23: + var $2992$0 = ___cxa_find_matching_catch(-1, -1); $2992$1 = tempRet0; + var $2993=$2992$0; + $2537=$2993; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2994=$2992$1; + $2538=$2994; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 27; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 24: + var $2996$0 = ___cxa_find_matching_catch(-1, -1); $2996$1 = tempRet0; + var $eh_lpad_body_i$1 = $2996$1;var $eh_lpad_body_i$0 = $2996$0;label = 25; break; + case 25: + var $eh_lpad_body_i$0; + var $eh_lpad_body_i$1; + var $2997=$eh_lpad_body_i$0; + $2537=$2997; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2998=$eh_lpad_body_i$1; + $2538=$2998; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $2999=$2806; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($2999, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 26; break; } else { label = 29; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 26: + label = 27; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 27: + var $3002=$2806; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3003=(($3002+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3004=$3003; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($3004) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 28; break; } else { label = 29; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 28: + var $3006=$2537; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3007=$2538; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3008$0=$3006; + var $3008$1=0; + var $3009$0=$3008$0; + var $3009$1=$3007; + ___resumeException($3009$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 29: + var $3011$0 = ___cxa_find_matching_catch(-1, -1,0); $3011$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 30: + var $3012=$std_stringstream; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3013=(($3012+8)|0); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3014=$3013; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3015 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3014, ((13856)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 31; break; } else { label = 52; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 31: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2545, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 32; break; } else { label = 52; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 32: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2544, $2545, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 33; break; } else { label = 53; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 33: + var $3019 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($3015, $2544) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 34; break; } else { label = 54; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 34: + var $3021 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3019, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 35; break; } else { label = 54; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 35: + var $3023 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3021, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 36; break; } else { label = 54; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 36: + var $3025 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3023, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 37; break; } else { label = 54; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 37: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2544) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 38; break; } else { label = 53; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 38: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2545) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 39; break; } else { label = 52; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 39: + var $3029=___cxa_allocate_exception(8); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2547=1; + var $3030=$3029; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2495=$std_stringstream; + var $3031=$2495; + var $3032=(($3031+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2546, $3032) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 40; break; } else { label = 58; break; } + case 40: + label = 41; break; + case 41: + $2494=$2546; + var $3034=$2494; + $2493=$3034; + var $3035=$2493; + $2492=$3035; + var $3036=$2492; + $2491=$3036; + var $3037=$2491; + var $3038=(($3037)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2490=$3038; + var $3039=$2490; + var $3040=$3039; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2489=$3040; + var $3041=$2489; + var $3042=(($3041)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3043=(($3042)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3044=$3043; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3045=(($3044)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3046=$3045; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3047=HEAP8[($3046)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3048=(($3047)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3049=$3048 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3050=(($3049)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($3050) { label = 42; break; } else { label = 43; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 42: + $2483=$3036; + var $3052=$2483; + var $3053=(($3052)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2482=$3053; + var $3054=$2482; + var $3055=$3054; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2481=$3055; + var $3056=$2481; + var $3057=(($3056)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3058=(($3057)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3059=$3058; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3060=(($3059+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3061=HEAP32[(($3060)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3075 = $3061;label = 44; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 43: + $2488=$3036; + var $3063=$2488; + var $3064=(($3063)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2487=$3064; + var $3065=$2487; + var $3066=$3065; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2486=$3066; + var $3067=$2486; + var $3068=(($3067)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3069=(($3068)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3070=$3069; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3071=(($3070+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3072=(($3071)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2485=$3072; + var $3073=$2485; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2484=$3073; + var $3074=$2484; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $3075 = $3074;label = 44; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 44: + var $3075; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2480=$3075; + var $3076=$2480; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($3030, $3076) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 45; break; } else { label = 59; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 45: + $2547=0; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($3029, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 59; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2546) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 46; break; } else { label = 58; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 46: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 66; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 47: + var $3081$0 = ___cxa_find_matching_catch(-1, -1); $3081$1 = tempRet0; + var $3082=$3081$0; + $2542=$3082; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3083=$3081$1; + $2543=$3083; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 50; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 48: + var $3085$0 = ___cxa_find_matching_catch(-1, -1); $3085$1 = tempRet0; + var $3086=$3085$0; + $2542=$3086; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3087=$3085$1; + $2543=$3087; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2540) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 49; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 49: + label = 50; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 50: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2541) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 51; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 51: + label = 2840; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 52: + var $3092$0 = ___cxa_find_matching_catch(-1, -1); $3092$1 = tempRet0; + var $3093=$3092$0; + $2542=$3093; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3094=$3092$1; + $2543=$3094; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 64; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 53: + var $3096$0 = ___cxa_find_matching_catch(-1, -1); $3096$1 = tempRet0; + var $3097=$3096$0; + $2542=$3097; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3098=$3096$1; + $2543=$3098; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 56; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 54: + var $3100$0 = ___cxa_find_matching_catch(-1, -1); $3100$1 = tempRet0; + var $3101=$3100$0; + $2542=$3101; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3102=$3100$1; + $2543=$3102; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2544) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 55; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 55: + label = 56; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 56: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2545) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 57; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 57: + label = 64; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 58: + var $3107$0 = ___cxa_find_matching_catch(-1, -1); $3107$1 = tempRet0; + var $3108=$3107$0; + $2542=$3108; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3109=$3107$1; + $2543=$3109; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 61; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 59: + var $3111$0 = ___cxa_find_matching_catch(-1, -1); $3111$1 = tempRet0; + var $3112=$3111$0; + $2542=$3112; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3113=$3111$1; + $2543=$3113; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2546) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 60; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 60: + label = 61; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 61: + var $3116=$2547; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3116) { label = 62; break; } else { label = 63; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 62: + ___cxa_free_exception($3029); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 63; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 63: + label = 64; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 64: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 65; break; } else { label = 2841; break; } //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 65: + label = 2840; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 66: + label = 67; break; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 67: + label = 68; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 68: + __ZN6StringC1EPKc($2549, ((13320)|0)); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2548, $2549, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 69; break; } else { label = 113; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 69: + var $3125 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2548, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 70; break; } else { label = 114; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 70: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2548) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 71; break; } else { label = 113; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 71: + __ZN6StringD1Ev($2549); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3125) { label = 72; break; } else { label = 132; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 72: + $2476=$std_stringstream1; + $2477=24; + var $3129=$2476; + var $3130=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3131=(($3130+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3132=$3131; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2475=$3132; + var $3133=$2475; + var $3134=$3133; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2474=$3134; + var $3135=$2474; + var $3136=$3135; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3136)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $3137=$3133; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3137)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $3138=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3138)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3139=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3140=(($3139+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3141=$3140; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3141)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3142=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3143=(($3142+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3144=$3143; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3144)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3145=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3146=(($3129+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3147=$3146; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2444=$3145; + $2445=((109796)|0); + $2446=$3147; + var $3148=$2444; + var $3149=$2445; + var $3150=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3151=(($3149+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3152=$2446; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2441=$3150; + $2442=$3151; + $2443=$3152; + var $3153=$2441; + var $3154=$2442; + var $3155=HEAP32[(($3154)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3156=$3153; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3156)>>2)]=$3155; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3157=(($3154+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3158=HEAP32[(($3157)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3159=$3153; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3160=HEAP32[(($3159)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3161=((($3160)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3162=$3161; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3163=HEAP32[(($3162)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3164=$3153; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3165=(($3164+$3163)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3166=$3165; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3166)>>2)]=$3158; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3167=(($3153+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3167)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3168=$3153; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3169=HEAP32[(($3168)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3170=((($3169)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3171=$3170; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3172=HEAP32[(($3171)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3173=$3153; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3174=(($3173+$3172)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3175=$3174; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3176=$2443; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2439=$3175; + $2440=$3176; + var $3177=$2439; + var $3178=$3177; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3179=$2440; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3180=$3179; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($3178, $3180) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 73; break; } else { label = 89; break; } + case 73: + var $3181=(($3177+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3181)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $3182=(($3177+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3182)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $3183=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3184=(($3183+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3185=$3184; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3186=(($3149+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2437=$3185; + $2438=$3186; + var $3187=$2437; + var $3188=$2438; + var $3189=HEAP32[(($3188)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3190=$3187; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3190)>>2)]=$3189; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3191=(($3188+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3192=HEAP32[(($3191)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3193=$3187; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3194=HEAP32[(($3193)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3195=((($3194)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3196=$3195; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3197=HEAP32[(($3196)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3198=$3187; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3199=(($3198+$3197)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3200=$3199; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3200)>>2)]=$3192; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3201=HEAP32[(($3149)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3202=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3202)>>2)]=$3201; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3203=(($3149+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3204=HEAP32[(($3203)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3205=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3206=HEAP32[(($3205)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3207=((($3206)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3208=$3207; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3209=HEAP32[(($3208)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3210=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3211=(($3210+$3209)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3212=$3211; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3212)>>2)]=$3204; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3213=(($3149+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3214=HEAP32[(($3213)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3215=$3148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3216=(($3215+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3217=$3216; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3217)>>2)]=$3214; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3218=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3218)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3219=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3220=(($3219+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3221=$3220; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3221)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3222=$3129; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3223=(($3222+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3224=$3223; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3224)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3225=(($3129+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3226=$2477; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2472=$3225; + $2473=$3226; + var $3227=$2472; + var $3228=$2473; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2467=$3227; + $2468=$3228; + var $3229=$2467; + var $3230=$3229; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($3230) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 74; break; } else { label = 90; break; } + case 74: + var $3231=$3229; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3231)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3232=(($3229+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2466=$3232; + var $3233=$2466; + $2465=$3233; + var $3234=$2465; + var $3235=$3234; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3236=(($3234)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2464=$3236; + var $3237=$2464; + $2463=$3237; + var $3238=$2463; + var $3239=$3238; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2462=$3239; + var $3240=$2462; + var $3241=$3240; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2461=$3241; + var $3242=$2461; + var $3243=(($3240)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2460=$3234; + var $3244=$2460; + var $3245=(($3244)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2459=$3245; + var $3246=$2459; + var $3247=$3246; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2458=$3247; + var $3248=$2458; + var $3249=(($3248)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3250=(($3249)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3251=$3250; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3252=(($3251)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i45=$3252; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i46=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 75; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 75: + var $3254=$__i_i_i_i_i_i_i46; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3255=(($3254)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3255) { label = 76; break; } else { label = 77; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 76: + var $3257=$__i_i_i_i_i_i_i46; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3258=$__a_i_i_i_i_i_i45; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3259=(($3258+($3257<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3259)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3260=$__i_i_i_i_i_i_i46; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3261=((($3260)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i46=$3261; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 75; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 77: + var $3262=(($3229+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3262)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3263=(($3229+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3264=$2468; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3263)>>2)]=$3264; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2457=$2471; + var $3265=$2457; + $2456=$3265; + var $3266=$2456; + var $3267=$3266; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3268=(($3266)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2455=$3268; + var $3269=$2455; + $2454=$3269; + var $3270=$2454; + var $3271=$3270; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2453=$3271; + var $3272=$2453; + var $3273=$3272; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2452=$3273; + var $3274=$2452; + var $3275=(($3272)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2451=$3266; + var $3276=$2451; + var $3277=(($3276)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2450=$3277; + var $3278=$2450; + var $3279=$3278; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2449=$3279; + var $3280=$2449; + var $3281=(($3280)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3282=(($3281)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3283=$3282; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3284=(($3283)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i43=$3284; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i44=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 78; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 78: + var $3286=$__i_i_i_i2_i_i_i44; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3287=(($3286)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3287) { label = 79; break; } else { label = 80; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 79: + var $3289=$__i_i_i_i2_i_i_i44; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3290=$__a_i_i_i1_i_i_i43; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3291=(($3290+($3289<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3291)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3292=$__i_i_i_i2_i_i_i44; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3293=((($3292)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i44=$3293; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 78; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 80: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($3229, $2471) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 81; break; } else { label = 83; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 81: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2471) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 96; break; } else { label = 82; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 82: + var $3296$0 = ___cxa_find_matching_catch(-1, -1); $3296$1 = tempRet0; + var $3297=$3296$0; + $2469=$3297; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3298=$3296$1; + $2470=$3298; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 85; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 83: + var $3300$0 = ___cxa_find_matching_catch(-1, -1); $3300$1 = tempRet0; + var $3301=$3300$0; + $2469=$3301; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3302=$3300$1; + $2470=$3302; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2471) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 84; break; } else { label = 88; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 84: + label = 85; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 85: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($3232) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 86; break; } else { label = 88; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 86: + var $3306=$3229; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($3306) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 87; break; } else { label = 88; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 87: + var $3308=$2469; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3309=$2470; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3310$0=$3308; + var $3310$1=0; + var $3311$0=$3310$0; + var $3311$1=$3309; + var $eh_lpad_body_i51$1 = $3311$1;var $eh_lpad_body_i51$0 = $3311$0;label = 91; break; + case 88: + var $3313$0 = ___cxa_find_matching_catch(-1, -1,0); $3313$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 89: + var $3315$0 = ___cxa_find_matching_catch(-1, -1); $3315$1 = tempRet0; + var $3316=$3315$0; + $2478=$3316; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3317=$3315$1; + $2479=$3317; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 93; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 90: + var $3319$0 = ___cxa_find_matching_catch(-1, -1); $3319$1 = tempRet0; + var $eh_lpad_body_i51$1 = $3319$1;var $eh_lpad_body_i51$0 = $3319$0;label = 91; break; + case 91: + var $eh_lpad_body_i51$0; + var $eh_lpad_body_i51$1; + var $3320=$eh_lpad_body_i51$0; + $2478=$3320; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3321=$eh_lpad_body_i51$1; + $2479=$3321; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3322=$3129; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($3322, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 92; break; } else { label = 95; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 92: + label = 93; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 93: + var $3325=$3129; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3326=(($3325+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3327=$3326; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($3327) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 94; break; } else { label = 95; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 94: + var $3329=$2478; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3330=$2479; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3331$0=$3329; + var $3331$1=0; + var $3332$0=$3331$0; + var $3332$1=$3330; + ___resumeException($3332$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 95: + var $3334$0 = ___cxa_find_matching_catch(-1, -1,0); $3334$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 96: + var $3335=$std_stringstream1; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3336=(($3335+8)|0); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3337=$3336; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3338 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3337, ((12784)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 97; break; } else { label = 118; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 97: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2551, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 98; break; } else { label = 118; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 98: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2550, $2551, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 99; break; } else { label = 119; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 99: + var $3342 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($3338, $2550) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 100; break; } else { label = 120; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 100: + var $3344 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3342, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 101; break; } else { label = 120; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 101: + var $3346 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3344, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 102; break; } else { label = 120; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 102: + var $3348 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3346, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 103; break; } else { label = 120; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 103: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2550) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 104; break; } else { label = 119; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 104: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2551) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 105; break; } else { label = 118; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 105: + var $3352=___cxa_allocate_exception(8); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2553=1; + var $3353=$3352; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2436=$std_stringstream1; + var $3354=$2436; + var $3355=(($3354+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2552, $3355) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 106; break; } else { label = 124; break; } + case 106: + label = 107; break; + case 107: + $2435=$2552; + var $3357=$2435; + $2434=$3357; + var $3358=$2434; + $2433=$3358; + var $3359=$2433; + $2432=$3359; + var $3360=$2432; + var $3361=(($3360)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2431=$3361; + var $3362=$2431; + var $3363=$3362; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2430=$3363; + var $3364=$2430; + var $3365=(($3364)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3366=(($3365)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3367=$3366; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3368=(($3367)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3369=$3368; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3370=HEAP8[($3369)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3371=(($3370)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3372=$3371 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3373=(($3372)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($3373) { label = 108; break; } else { label = 109; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 108: + $2424=$3359; + var $3375=$2424; + var $3376=(($3375)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2423=$3376; + var $3377=$2423; + var $3378=$3377; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2422=$3378; + var $3379=$2422; + var $3380=(($3379)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3381=(($3380)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3382=$3381; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3383=(($3382+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3384=HEAP32[(($3383)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3398 = $3384;label = 110; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 109: + $2429=$3359; + var $3386=$2429; + var $3387=(($3386)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2428=$3387; + var $3388=$2428; + var $3389=$3388; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2427=$3389; + var $3390=$2427; + var $3391=(($3390)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3392=(($3391)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3393=$3392; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3394=(($3393+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3395=(($3394)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2426=$3395; + var $3396=$2426; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2425=$3396; + var $3397=$2425; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $3398 = $3397;label = 110; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 110: + var $3398; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2421=$3398; + var $3399=$2421; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($3353, $3399) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 111; break; } else { label = 125; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 111: + $2553=0; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($3352, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 125; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2552) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 112; break; } else { label = 124; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 112: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream1); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 132; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 113: + var $3404$0 = ___cxa_find_matching_catch(-1, -1); $3404$1 = tempRet0; + var $3405=$3404$0; + $2542=$3405; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3406=$3404$1; + $2543=$3406; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 116; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 114: + var $3408$0 = ___cxa_find_matching_catch(-1, -1); $3408$1 = tempRet0; + var $3409=$3408$0; + $2542=$3409; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3410=$3408$1; + $2543=$3410; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2548) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 115; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 115: + label = 116; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 116: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2549) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 117; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 117: + label = 2840; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 118: + var $3415$0 = ___cxa_find_matching_catch(-1, -1); $3415$1 = tempRet0; + var $3416=$3415$0; + $2542=$3416; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3417=$3415$1; + $2543=$3417; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 130; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 119: + var $3419$0 = ___cxa_find_matching_catch(-1, -1); $3419$1 = tempRet0; + var $3420=$3419$0; + $2542=$3420; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3421=$3419$1; + $2543=$3421; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 122; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 120: + var $3423$0 = ___cxa_find_matching_catch(-1, -1); $3423$1 = tempRet0; + var $3424=$3423$0; + $2542=$3424; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3425=$3423$1; + $2543=$3425; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2550) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 121; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 121: + label = 122; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 122: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2551) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 123; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 123: + label = 130; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 124: + var $3430$0 = ___cxa_find_matching_catch(-1, -1); $3430$1 = tempRet0; + var $3431=$3430$0; + $2542=$3431; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3432=$3430$1; + $2543=$3432; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 127; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 125: + var $3434$0 = ___cxa_find_matching_catch(-1, -1); $3434$1 = tempRet0; + var $3435=$3434$0; + $2542=$3435; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3436=$3434$1; + $2543=$3436; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2552) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 126; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 126: + label = 127; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 127: + var $3439=$2553; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3439) { label = 128; break; } else { label = 129; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 128: + ___cxa_free_exception($3352); //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 129; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 129: + label = 130; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 130: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream1) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 131; break; } else { label = 2841; break; } //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 131: + label = 2840; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 132: + label = 133; break; //@line 137 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 133: + label = 134; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 134: + __ZN6StringC1EPKc($2555, ((11736)|0)); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2554, $2555, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 135; break; } else { label = 179; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 135: + var $3448 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2554, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 136; break; } else { label = 180; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 136: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2554) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 137; break; } else { label = 179; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 137: + __ZN6StringD1Ev($2555); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3448) { label = 138; break; } else { label = 198; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 138: + $2417=$std_stringstream2; + $2418=24; + var $3452=$2417; + var $3453=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3454=(($3453+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3455=$3454; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2416=$3455; + var $3456=$2416; + var $3457=$3456; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2415=$3457; + var $3458=$2415; + var $3459=$3458; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3459)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $3460=$3456; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3460)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $3461=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3461)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3462=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3463=(($3462+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3464=$3463; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3464)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3465=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3466=(($3465+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3467=$3466; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3467)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3468=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3469=(($3452+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3470=$3469; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2385=$3468; + $2386=((109796)|0); + $2387=$3470; + var $3471=$2385; + var $3472=$2386; + var $3473=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3474=(($3472+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3475=$2387; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2382=$3473; + $2383=$3474; + $2384=$3475; + var $3476=$2382; + var $3477=$2383; + var $3478=HEAP32[(($3477)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3479=$3476; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3479)>>2)]=$3478; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3480=(($3477+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3481=HEAP32[(($3480)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3482=$3476; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3483=HEAP32[(($3482)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3484=((($3483)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3485=$3484; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3486=HEAP32[(($3485)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3487=$3476; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3488=(($3487+$3486)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3489=$3488; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3489)>>2)]=$3481; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3490=(($3476+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3490)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3491=$3476; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3492=HEAP32[(($3491)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3493=((($3492)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3494=$3493; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3495=HEAP32[(($3494)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3496=$3476; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3497=(($3496+$3495)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3498=$3497; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3499=$2384; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2380=$3498; + $2381=$3499; + var $3500=$2380; + var $3501=$3500; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3502=$2381; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3503=$3502; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($3501, $3503) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 139; break; } else { label = 155; break; } + case 139: + var $3504=(($3500+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3504)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $3505=(($3500+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3505)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $3506=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3507=(($3506+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3508=$3507; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3509=(($3472+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2378=$3508; + $2379=$3509; + var $3510=$2378; + var $3511=$2379; + var $3512=HEAP32[(($3511)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3513=$3510; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3513)>>2)]=$3512; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3514=(($3511+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3515=HEAP32[(($3514)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3516=$3510; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3517=HEAP32[(($3516)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3518=((($3517)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3519=$3518; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3520=HEAP32[(($3519)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3521=$3510; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3522=(($3521+$3520)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3523=$3522; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3523)>>2)]=$3515; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3524=HEAP32[(($3472)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3525=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3525)>>2)]=$3524; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3526=(($3472+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3527=HEAP32[(($3526)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3528=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3529=HEAP32[(($3528)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3530=((($3529)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3531=$3530; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3532=HEAP32[(($3531)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3533=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3534=(($3533+$3532)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3535=$3534; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3535)>>2)]=$3527; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3536=(($3472+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3537=HEAP32[(($3536)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3538=$3471; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3539=(($3538+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3540=$3539; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3540)>>2)]=$3537; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3541=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3541)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3542=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3543=(($3542+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3544=$3543; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3544)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3545=$3452; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3546=(($3545+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3547=$3546; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3547)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3548=(($3452+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3549=$2418; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2413=$3548; + $2414=$3549; + var $3550=$2413; + var $3551=$2414; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2408=$3550; + $2409=$3551; + var $3552=$2408; + var $3553=$3552; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($3553) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 140; break; } else { label = 156; break; } + case 140: + var $3554=$3552; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3554)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3555=(($3552+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2407=$3555; + var $3556=$2407; + $2406=$3556; + var $3557=$2406; + var $3558=$3557; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3559=(($3557)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2405=$3559; + var $3560=$2405; + $2404=$3560; + var $3561=$2404; + var $3562=$3561; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2403=$3562; + var $3563=$2403; + var $3564=$3563; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2402=$3564; + var $3565=$2402; + var $3566=(($3563)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2401=$3557; + var $3567=$2401; + var $3568=(($3567)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2400=$3568; + var $3569=$2400; + var $3570=$3569; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2399=$3570; + var $3571=$2399; + var $3572=(($3571)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3573=(($3572)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3574=$3573; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3575=(($3574)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i58=$3575; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i59=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 141; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 141: + var $3577=$__i_i_i_i_i_i_i59; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3578=(($3577)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3578) { label = 142; break; } else { label = 143; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 142: + var $3580=$__i_i_i_i_i_i_i59; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3581=$__a_i_i_i_i_i_i58; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3582=(($3581+($3580<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3582)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3583=$__i_i_i_i_i_i_i59; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3584=((($3583)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i59=$3584; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 141; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 143: + var $3585=(($3552+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3585)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3586=(($3552+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3587=$2409; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3586)>>2)]=$3587; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2398=$2412; + var $3588=$2398; + $2397=$3588; + var $3589=$2397; + var $3590=$3589; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3591=(($3589)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2396=$3591; + var $3592=$2396; + $2395=$3592; + var $3593=$2395; + var $3594=$3593; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2394=$3594; + var $3595=$2394; + var $3596=$3595; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2393=$3596; + var $3597=$2393; + var $3598=(($3595)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2392=$3589; + var $3599=$2392; + var $3600=(($3599)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2391=$3600; + var $3601=$2391; + var $3602=$3601; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2390=$3602; + var $3603=$2390; + var $3604=(($3603)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3605=(($3604)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3606=$3605; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3607=(($3606)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i56=$3607; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i57=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 144; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 144: + var $3609=$__i_i_i_i2_i_i_i57; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3610=(($3609)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3610) { label = 145; break; } else { label = 146; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 145: + var $3612=$__i_i_i_i2_i_i_i57; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3613=$__a_i_i_i1_i_i_i56; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3614=(($3613+($3612<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3614)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3615=$__i_i_i_i2_i_i_i57; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3616=((($3615)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i57=$3616; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 144; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 146: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($3552, $2412) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 147; break; } else { label = 149; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 147: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2412) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 162; break; } else { label = 148; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 148: + var $3619$0 = ___cxa_find_matching_catch(-1, -1); $3619$1 = tempRet0; + var $3620=$3619$0; + $2410=$3620; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3621=$3619$1; + $2411=$3621; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 151; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 149: + var $3623$0 = ___cxa_find_matching_catch(-1, -1); $3623$1 = tempRet0; + var $3624=$3623$0; + $2410=$3624; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3625=$3623$1; + $2411=$3625; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2412) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 150; break; } else { label = 154; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 150: + label = 151; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 151: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($3555) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 152; break; } else { label = 154; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 152: + var $3629=$3552; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($3629) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 153; break; } else { label = 154; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 153: + var $3631=$2410; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3632=$2411; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3633$0=$3631; + var $3633$1=0; + var $3634$0=$3633$0; + var $3634$1=$3632; + var $eh_lpad_body_i64$1 = $3634$1;var $eh_lpad_body_i64$0 = $3634$0;label = 157; break; + case 154: + var $3636$0 = ___cxa_find_matching_catch(-1, -1,0); $3636$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 155: + var $3638$0 = ___cxa_find_matching_catch(-1, -1); $3638$1 = tempRet0; + var $3639=$3638$0; + $2419=$3639; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3640=$3638$1; + $2420=$3640; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 159; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 156: + var $3642$0 = ___cxa_find_matching_catch(-1, -1); $3642$1 = tempRet0; + var $eh_lpad_body_i64$1 = $3642$1;var $eh_lpad_body_i64$0 = $3642$0;label = 157; break; + case 157: + var $eh_lpad_body_i64$0; + var $eh_lpad_body_i64$1; + var $3643=$eh_lpad_body_i64$0; + $2419=$3643; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3644=$eh_lpad_body_i64$1; + $2420=$3644; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3645=$3452; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($3645, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 158; break; } else { label = 161; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 158: + label = 159; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 159: + var $3648=$3452; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3649=(($3648+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3650=$3649; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($3650) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 160; break; } else { label = 161; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 160: + var $3652=$2419; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3653=$2420; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3654$0=$3652; + var $3654$1=0; + var $3655$0=$3654$0; + var $3655$1=$3653; + ___resumeException($3655$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 161: + var $3657$0 = ___cxa_find_matching_catch(-1, -1,0); $3657$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 162: + var $3658=$std_stringstream2; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3659=(($3658+8)|0); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3660=$3659; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3661 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3660, ((10896)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 163; break; } else { label = 184; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 163: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2557, ((11736)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 164; break; } else { label = 184; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 164: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2556, $2557, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 165; break; } else { label = 185; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 165: + var $3665 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($3661, $2556) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 166; break; } else { label = 186; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 166: + var $3667 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3665, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 167; break; } else { label = 186; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 167: + var $3669 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3667, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 168; break; } else { label = 186; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 168: + var $3671 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3669, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 169; break; } else { label = 186; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 169: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2556) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 170; break; } else { label = 185; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 170: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2557) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 171; break; } else { label = 184; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 171: + var $3675=___cxa_allocate_exception(8); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2559=1; + var $3676=$3675; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2377=$std_stringstream2; + var $3677=$2377; + var $3678=(($3677+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2558, $3678) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 172; break; } else { label = 190; break; } + case 172: + label = 173; break; + case 173: + $2376=$2558; + var $3680=$2376; + $2375=$3680; + var $3681=$2375; + $2374=$3681; + var $3682=$2374; + $2373=$3682; + var $3683=$2373; + var $3684=(($3683)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2372=$3684; + var $3685=$2372; + var $3686=$3685; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2371=$3686; + var $3687=$2371; + var $3688=(($3687)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3689=(($3688)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3690=$3689; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3691=(($3690)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3692=$3691; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3693=HEAP8[($3692)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3694=(($3693)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3695=$3694 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $3696=(($3695)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($3696) { label = 174; break; } else { label = 175; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 174: + $2365=$3682; + var $3698=$2365; + var $3699=(($3698)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2364=$3699; + var $3700=$2364; + var $3701=$3700; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2363=$3701; + var $3702=$2363; + var $3703=(($3702)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3704=(($3703)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3705=$3704; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3706=(($3705+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3707=HEAP32[(($3706)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $3721 = $3707;label = 176; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 175: + $2370=$3682; + var $3709=$2370; + var $3710=(($3709)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2369=$3710; + var $3711=$2369; + var $3712=$3711; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2368=$3712; + var $3713=$2368; + var $3714=(($3713)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $3715=(($3714)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3716=$3715; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3717=(($3716+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $3718=(($3717)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2367=$3718; + var $3719=$2367; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2366=$3719; + var $3720=$2366; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $3721 = $3720;label = 176; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 176: + var $3721; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2362=$3721; + var $3722=$2362; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($3676, $3722) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 177; break; } else { label = 191; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 177: + $2559=0; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($3675, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 191; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2558) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 178; break; } else { label = 190; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 178: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream2); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 198; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 179: + var $3727$0 = ___cxa_find_matching_catch(-1, -1); $3727$1 = tempRet0; + var $3728=$3727$0; + $2542=$3728; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3729=$3727$1; + $2543=$3729; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 182; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 180: + var $3731$0 = ___cxa_find_matching_catch(-1, -1); $3731$1 = tempRet0; + var $3732=$3731$0; + $2542=$3732; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3733=$3731$1; + $2543=$3733; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2554) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 181; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 181: + label = 182; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 182: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2555) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 183; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 183: + label = 2840; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 184: + var $3738$0 = ___cxa_find_matching_catch(-1, -1); $3738$1 = tempRet0; + var $3739=$3738$0; + $2542=$3739; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3740=$3738$1; + $2543=$3740; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 196; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 185: + var $3742$0 = ___cxa_find_matching_catch(-1, -1); $3742$1 = tempRet0; + var $3743=$3742$0; + $2542=$3743; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3744=$3742$1; + $2543=$3744; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 188; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 186: + var $3746$0 = ___cxa_find_matching_catch(-1, -1); $3746$1 = tempRet0; + var $3747=$3746$0; + $2542=$3747; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3748=$3746$1; + $2543=$3748; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2556) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 187; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 187: + label = 188; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 188: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2557) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 189; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 189: + label = 196; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 190: + var $3753$0 = ___cxa_find_matching_catch(-1, -1); $3753$1 = tempRet0; + var $3754=$3753$0; + $2542=$3754; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3755=$3753$1; + $2543=$3755; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 193; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 191: + var $3757$0 = ___cxa_find_matching_catch(-1, -1); $3757$1 = tempRet0; + var $3758=$3757$0; + $2542=$3758; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3759=$3757$1; + $2543=$3759; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2558) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 192; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 192: + label = 193; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 193: + var $3762=$2559; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3762) { label = 194; break; } else { label = 195; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 194: + ___cxa_free_exception($3675); //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 195; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 195: + label = 196; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 196: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream2) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 197; break; } else { label = 2841; break; } //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 197: + label = 2840; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 198: + label = 199; break; //@line 138 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 199: + label = 200; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 200: + __ZN6StringC1EPKc($2561, ((10608)|0)); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2560, $2561, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 201; break; } else { label = 245; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 201: + var $3771 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2560, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 202; break; } else { label = 246; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 202: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2560) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 203; break; } else { label = 245; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 203: + __ZN6StringD1Ev($2561); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($3771) { label = 204; break; } else { label = 264; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 204: + $2358=$std_stringstream3; + $2359=24; + var $3775=$2358; + var $3776=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3777=(($3776+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3778=$3777; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2357=$3778; + var $3779=$2357; + var $3780=$3779; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2356=$3780; + var $3781=$2356; + var $3782=$3781; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3782)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $3783=$3779; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3783)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $3784=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3784)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3785=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3786=(($3785+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3787=$3786; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3787)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3788=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3789=(($3788+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3790=$3789; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3790)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3791=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3792=(($3775+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3793=$3792; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2326=$3791; + $2327=((109796)|0); + $2328=$3793; + var $3794=$2326; + var $3795=$2327; + var $3796=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3797=(($3795+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3798=$2328; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2323=$3796; + $2324=$3797; + $2325=$3798; + var $3799=$2323; + var $3800=$2324; + var $3801=HEAP32[(($3800)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3802=$3799; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3802)>>2)]=$3801; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3803=(($3800+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3804=HEAP32[(($3803)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3805=$3799; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3806=HEAP32[(($3805)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3807=((($3806)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3808=$3807; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3809=HEAP32[(($3808)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3810=$3799; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3811=(($3810+$3809)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3812=$3811; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3812)>>2)]=$3804; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3813=(($3799+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3813)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $3814=$3799; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3815=HEAP32[(($3814)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3816=((($3815)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3817=$3816; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3818=HEAP32[(($3817)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3819=$3799; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3820=(($3819+$3818)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3821=$3820; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $3822=$2325; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2321=$3821; + $2322=$3822; + var $3823=$2321; + var $3824=$3823; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3825=$2322; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $3826=$3825; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($3824, $3826) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 205; break; } else { label = 221; break; } + case 205: + var $3827=(($3823+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3827)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $3828=(($3823+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($3828)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $3829=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3830=(($3829+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3831=$3830; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3832=(($3795+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2319=$3831; + $2320=$3832; + var $3833=$2319; + var $3834=$2320; + var $3835=HEAP32[(($3834)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3836=$3833; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3836)>>2)]=$3835; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3837=(($3834+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3838=HEAP32[(($3837)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3839=$3833; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3840=HEAP32[(($3839)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3841=((($3840)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3842=$3841; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3843=HEAP32[(($3842)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3844=$3833; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3845=(($3844+$3843)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3846=$3845; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3846)>>2)]=$3838; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $3847=HEAP32[(($3795)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3848=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3848)>>2)]=$3847; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3849=(($3795+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3850=HEAP32[(($3849)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3851=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3852=HEAP32[(($3851)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3853=((($3852)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3854=$3853; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3855=HEAP32[(($3854)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3856=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3857=(($3856+$3855)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3858=$3857; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3858)>>2)]=$3850; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3859=(($3795+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3860=HEAP32[(($3859)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3861=$3794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3862=(($3861+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3863=$3862; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3863)>>2)]=$3860; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $3864=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3864)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3865=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3866=(($3865+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3867=$3866; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3867)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3868=$3775; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3869=(($3868+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3870=$3869; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3870)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3871=(($3775+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3872=$2359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2354=$3871; + $2355=$3872; + var $3873=$2354; + var $3874=$2355; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2349=$3873; + $2350=$3874; + var $3875=$2349; + var $3876=$3875; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($3876) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 206; break; } else { label = 222; break; } + case 206: + var $3877=$3875; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3877)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3878=(($3875+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2348=$3878; + var $3879=$2348; + $2347=$3879; + var $3880=$2347; + var $3881=$3880; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3882=(($3880)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2346=$3882; + var $3883=$2346; + $2345=$3883; + var $3884=$2345; + var $3885=$3884; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2344=$3885; + var $3886=$2344; + var $3887=$3886; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2343=$3887; + var $3888=$2343; + var $3889=(($3886)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2342=$3880; + var $3890=$2342; + var $3891=(($3890)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2341=$3891; + var $3892=$2341; + var $3893=$3892; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2340=$3893; + var $3894=$2340; + var $3895=(($3894)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3896=(($3895)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3897=$3896; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3898=(($3897)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i71=$3898; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i72=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 207; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 207: + var $3900=$__i_i_i_i_i_i_i72; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3901=(($3900)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3901) { label = 208; break; } else { label = 209; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 208: + var $3903=$__i_i_i_i_i_i_i72; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3904=$__a_i_i_i_i_i_i71; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3905=(($3904+($3903<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3905)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3906=$__i_i_i_i_i_i_i72; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3907=((($3906)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i72=$3907; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 207; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 209: + var $3908=(($3875+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3908)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3909=(($3875+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $3910=$2350; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($3909)>>2)]=$3910; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2339=$2353; + var $3911=$2339; + $2338=$3911; + var $3912=$2338; + var $3913=$3912; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $3914=(($3912)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2337=$3914; + var $3915=$2337; + $2336=$3915; + var $3916=$2336; + var $3917=$3916; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2335=$3917; + var $3918=$2335; + var $3919=$3918; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2334=$3919; + var $3920=$2334; + var $3921=(($3918)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2333=$3912; + var $3922=$2333; + var $3923=(($3922)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2332=$3923; + var $3924=$2332; + var $3925=$3924; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2331=$3925; + var $3926=$2331; + var $3927=(($3926)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $3928=(($3927)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3929=$3928; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $3930=(($3929)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i69=$3930; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i70=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 210; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 210: + var $3932=$__i_i_i_i2_i_i_i70; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3933=(($3932)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($3933) { label = 211; break; } else { label = 212; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 211: + var $3935=$__i_i_i_i2_i_i_i70; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3936=$__a_i_i_i1_i_i_i69; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3937=(($3936+($3935<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($3937)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $3938=$__i_i_i_i2_i_i_i70; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $3939=((($3938)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i70=$3939; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 210; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 212: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($3875, $2353) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 213; break; } else { label = 215; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 213: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2353) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 228; break; } else { label = 214; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 214: + var $3942$0 = ___cxa_find_matching_catch(-1, -1); $3942$1 = tempRet0; + var $3943=$3942$0; + $2351=$3943; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3944=$3942$1; + $2352=$3944; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 217; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 215: + var $3946$0 = ___cxa_find_matching_catch(-1, -1); $3946$1 = tempRet0; + var $3947=$3946$0; + $2351=$3947; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $3948=$3946$1; + $2352=$3948; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2353) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 216; break; } else { label = 220; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 216: + label = 217; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 217: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($3878) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 218; break; } else { label = 220; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 218: + var $3952=$3875; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($3952) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 219; break; } else { label = 220; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 219: + var $3954=$2351; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3955=$2352; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $3956$0=$3954; + var $3956$1=0; + var $3957$0=$3956$0; + var $3957$1=$3955; + var $eh_lpad_body_i77$1 = $3957$1;var $eh_lpad_body_i77$0 = $3957$0;label = 223; break; + case 220: + var $3959$0 = ___cxa_find_matching_catch(-1, -1,0); $3959$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 221: + var $3961$0 = ___cxa_find_matching_catch(-1, -1); $3961$1 = tempRet0; + var $3962=$3961$0; + $2360=$3962; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3963=$3961$1; + $2361=$3963; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 225; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 222: + var $3965$0 = ___cxa_find_matching_catch(-1, -1); $3965$1 = tempRet0; + var $eh_lpad_body_i77$1 = $3965$1;var $eh_lpad_body_i77$0 = $3965$0;label = 223; break; + case 223: + var $eh_lpad_body_i77$0; + var $eh_lpad_body_i77$1; + var $3966=$eh_lpad_body_i77$0; + $2360=$3966; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3967=$eh_lpad_body_i77$1; + $2361=$3967; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $3968=$3775; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($3968, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 224; break; } else { label = 227; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 224: + label = 225; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 225: + var $3971=$3775; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3972=(($3971+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3973=$3972; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($3973) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 226; break; } else { label = 227; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 226: + var $3975=$2360; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3976=$2361; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $3977$0=$3975; + var $3977$1=0; + var $3978$0=$3977$0; + var $3978$1=$3976; + ___resumeException($3978$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 227: + var $3980$0 = ___cxa_find_matching_catch(-1, -1,0); $3980$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 228: + var $3981=$std_stringstream3; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3982=(($3981+8)|0); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3983=$3982; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $3984 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3983, ((10208)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 229; break; } else { label = 250; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 229: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2563, ((10608)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 230; break; } else { label = 250; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 230: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2562, $2563, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 231; break; } else { label = 251; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 231: + var $3988 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($3984, $2562) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 232; break; } else { label = 252; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 232: + var $3990 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3988, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 233; break; } else { label = 252; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 233: + var $3992 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3990, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 234; break; } else { label = 252; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 234: + var $3994 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($3992, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 235; break; } else { label = 252; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 235: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2562) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 236; break; } else { label = 251; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 236: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2563) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 237; break; } else { label = 250; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 237: + var $3998=___cxa_allocate_exception(8); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2565=1; + var $3999=$3998; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2318=$std_stringstream3; + var $4000=$2318; + var $4001=(($4000+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2564, $4001) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 238; break; } else { label = 256; break; } + case 238: + label = 239; break; + case 239: + $2317=$2564; + var $4003=$2317; + $2316=$4003; + var $4004=$2316; + $2315=$4004; + var $4005=$2315; + $2314=$4005; + var $4006=$2314; + var $4007=(($4006)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2313=$4007; + var $4008=$2313; + var $4009=$4008; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2312=$4009; + var $4010=$2312; + var $4011=(($4010)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4012=(($4011)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4013=$4012; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4014=(($4013)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4015=$4014; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4016=HEAP8[($4015)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4017=(($4016)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4018=$4017 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4019=(($4018)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($4019) { label = 240; break; } else { label = 241; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 240: + $2306=$4005; + var $4021=$2306; + var $4022=(($4021)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2305=$4022; + var $4023=$2305; + var $4024=$4023; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2304=$4024; + var $4025=$2304; + var $4026=(($4025)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4027=(($4026)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4028=$4027; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4029=(($4028+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4030=HEAP32[(($4029)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4044 = $4030;label = 242; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 241: + $2311=$4005; + var $4032=$2311; + var $4033=(($4032)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2310=$4033; + var $4034=$2310; + var $4035=$4034; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2309=$4035; + var $4036=$2309; + var $4037=(($4036)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4038=(($4037)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4039=$4038; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4040=(($4039+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4041=(($4040)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2308=$4041; + var $4042=$2308; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2307=$4042; + var $4043=$2307; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $4044 = $4043;label = 242; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 242: + var $4044; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2303=$4044; + var $4045=$2303; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($3999, $4045) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 243; break; } else { label = 257; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 243: + $2565=0; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($3998, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 257; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2564) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 244; break; } else { label = 256; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 244: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream3); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 264; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 245: + var $4050$0 = ___cxa_find_matching_catch(-1, -1); $4050$1 = tempRet0; + var $4051=$4050$0; + $2542=$4051; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4052=$4050$1; + $2543=$4052; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 248; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 246: + var $4054$0 = ___cxa_find_matching_catch(-1, -1); $4054$1 = tempRet0; + var $4055=$4054$0; + $2542=$4055; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4056=$4054$1; + $2543=$4056; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2560) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 247; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 247: + label = 248; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 248: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2561) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 249; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 249: + label = 2840; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 250: + var $4061$0 = ___cxa_find_matching_catch(-1, -1); $4061$1 = tempRet0; + var $4062=$4061$0; + $2542=$4062; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4063=$4061$1; + $2543=$4063; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 262; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 251: + var $4065$0 = ___cxa_find_matching_catch(-1, -1); $4065$1 = tempRet0; + var $4066=$4065$0; + $2542=$4066; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4067=$4065$1; + $2543=$4067; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 254; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 252: + var $4069$0 = ___cxa_find_matching_catch(-1, -1); $4069$1 = tempRet0; + var $4070=$4069$0; + $2542=$4070; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4071=$4069$1; + $2543=$4071; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2562) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 253; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 253: + label = 254; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 254: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2563) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 255; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 255: + label = 262; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 256: + var $4076$0 = ___cxa_find_matching_catch(-1, -1); $4076$1 = tempRet0; + var $4077=$4076$0; + $2542=$4077; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4078=$4076$1; + $2543=$4078; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 259; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 257: + var $4080$0 = ___cxa_find_matching_catch(-1, -1); $4080$1 = tempRet0; + var $4081=$4080$0; + $2542=$4081; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4082=$4080$1; + $2543=$4082; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2564) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 258; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 258: + label = 259; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 259: + var $4085=$2565; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4085) { label = 260; break; } else { label = 261; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 260: + ___cxa_free_exception($3998); //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 261; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 261: + label = 262; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 262: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream3) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 263; break; } else { label = 2841; break; } //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 263: + label = 2840; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 264: + label = 265; break; //@line 139 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 265: + label = 266; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 266: + __ZN6StringC1EPKc($2567, ((9904)|0)); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2566, $2567, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 267; break; } else { label = 311; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 267: + var $4094 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2566, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 268; break; } else { label = 312; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 268: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2566) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 269; break; } else { label = 311; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 269: + __ZN6StringD1Ev($2567); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4094) { label = 270; break; } else { label = 330; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 270: + $2299=$std_stringstream4; + $2300=24; + var $4098=$2299; + var $4099=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4100=(($4099+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4101=$4100; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2298=$4101; + var $4102=$2298; + var $4103=$4102; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2297=$4103; + var $4104=$2297; + var $4105=$4104; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4105)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $4106=$4102; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4106)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $4107=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4107)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4108=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4109=(($4108+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4110=$4109; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4110)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4111=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4112=(($4111+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4113=$4112; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4113)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4114=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4115=(($4098+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4116=$4115; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2267=$4114; + $2268=((109796)|0); + $2269=$4116; + var $4117=$2267; + var $4118=$2268; + var $4119=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4120=(($4118+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4121=$2269; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2264=$4119; + $2265=$4120; + $2266=$4121; + var $4122=$2264; + var $4123=$2265; + var $4124=HEAP32[(($4123)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4125=$4122; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4125)>>2)]=$4124; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4126=(($4123+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4127=HEAP32[(($4126)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4128=$4122; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4129=HEAP32[(($4128)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4130=((($4129)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4131=$4130; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4132=HEAP32[(($4131)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4133=$4122; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4134=(($4133+$4132)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4135=$4134; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4135)>>2)]=$4127; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4136=(($4122+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4136)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4137=$4122; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4138=HEAP32[(($4137)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4139=((($4138)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4140=$4139; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4141=HEAP32[(($4140)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4142=$4122; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4143=(($4142+$4141)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4144=$4143; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4145=$2266; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2262=$4144; + $2263=$4145; + var $4146=$2262; + var $4147=$4146; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4148=$2263; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4149=$4148; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($4147, $4149) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 271; break; } else { label = 287; break; } + case 271: + var $4150=(($4146+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4150)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $4151=(($4146+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4151)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $4152=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4153=(($4152+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4154=$4153; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4155=(($4118+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2260=$4154; + $2261=$4155; + var $4156=$2260; + var $4157=$2261; + var $4158=HEAP32[(($4157)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4159=$4156; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4159)>>2)]=$4158; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4160=(($4157+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4161=HEAP32[(($4160)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4162=$4156; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4163=HEAP32[(($4162)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4164=((($4163)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4165=$4164; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4166=HEAP32[(($4165)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4167=$4156; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4168=(($4167+$4166)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4169=$4168; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4169)>>2)]=$4161; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4170=HEAP32[(($4118)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4171=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4171)>>2)]=$4170; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4172=(($4118+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4173=HEAP32[(($4172)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4174=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4175=HEAP32[(($4174)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4176=((($4175)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4177=$4176; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4178=HEAP32[(($4177)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4179=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4180=(($4179+$4178)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4181=$4180; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4181)>>2)]=$4173; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4182=(($4118+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4183=HEAP32[(($4182)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4184=$4117; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4185=(($4184+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4186=$4185; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4186)>>2)]=$4183; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4187=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4187)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4188=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4189=(($4188+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4190=$4189; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4190)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4191=$4098; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4192=(($4191+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4193=$4192; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4193)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4194=(($4098+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4195=$2300; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2295=$4194; + $2296=$4195; + var $4196=$2295; + var $4197=$2296; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2290=$4196; + $2291=$4197; + var $4198=$2290; + var $4199=$4198; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($4199) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 272; break; } else { label = 288; break; } + case 272: + var $4200=$4198; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4200)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4201=(($4198+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2289=$4201; + var $4202=$2289; + $2288=$4202; + var $4203=$2288; + var $4204=$4203; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4205=(($4203)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2287=$4205; + var $4206=$2287; + $2286=$4206; + var $4207=$2286; + var $4208=$4207; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2285=$4208; + var $4209=$2285; + var $4210=$4209; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2284=$4210; + var $4211=$2284; + var $4212=(($4209)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2283=$4203; + var $4213=$2283; + var $4214=(($4213)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2282=$4214; + var $4215=$2282; + var $4216=$4215; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2281=$4216; + var $4217=$2281; + var $4218=(($4217)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4219=(($4218)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4220=$4219; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4221=(($4220)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i84=$4221; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i85=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 273; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 273: + var $4223=$__i_i_i_i_i_i_i85; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4224=(($4223)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4224) { label = 274; break; } else { label = 275; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 274: + var $4226=$__i_i_i_i_i_i_i85; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4227=$__a_i_i_i_i_i_i84; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4228=(($4227+($4226<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4228)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4229=$__i_i_i_i_i_i_i85; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4230=((($4229)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i85=$4230; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 273; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 275: + var $4231=(($4198+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4231)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4232=(($4198+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4233=$2291; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4232)>>2)]=$4233; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2280=$2294; + var $4234=$2280; + $2279=$4234; + var $4235=$2279; + var $4236=$4235; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4237=(($4235)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2278=$4237; + var $4238=$2278; + $2277=$4238; + var $4239=$2277; + var $4240=$4239; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2276=$4240; + var $4241=$2276; + var $4242=$4241; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2275=$4242; + var $4243=$2275; + var $4244=(($4241)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2274=$4235; + var $4245=$2274; + var $4246=(($4245)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2273=$4246; + var $4247=$2273; + var $4248=$4247; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2272=$4248; + var $4249=$2272; + var $4250=(($4249)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4251=(($4250)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4252=$4251; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4253=(($4252)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i82=$4253; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i83=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 276; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 276: + var $4255=$__i_i_i_i2_i_i_i83; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4256=(($4255)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4256) { label = 277; break; } else { label = 278; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 277: + var $4258=$__i_i_i_i2_i_i_i83; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4259=$__a_i_i_i1_i_i_i82; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4260=(($4259+($4258<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4260)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4261=$__i_i_i_i2_i_i_i83; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4262=((($4261)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i83=$4262; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 276; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 278: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($4198, $2294) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 279; break; } else { label = 281; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 279: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2294) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 294; break; } else { label = 280; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 280: + var $4265$0 = ___cxa_find_matching_catch(-1, -1); $4265$1 = tempRet0; + var $4266=$4265$0; + $2292=$4266; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4267=$4265$1; + $2293=$4267; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 283; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 281: + var $4269$0 = ___cxa_find_matching_catch(-1, -1); $4269$1 = tempRet0; + var $4270=$4269$0; + $2292=$4270; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4271=$4269$1; + $2293=$4271; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2294) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 282; break; } else { label = 286; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 282: + label = 283; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 283: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($4201) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 284; break; } else { label = 286; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 284: + var $4275=$4198; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($4275) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 285; break; } else { label = 286; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 285: + var $4277=$2292; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4278=$2293; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4279$0=$4277; + var $4279$1=0; + var $4280$0=$4279$0; + var $4280$1=$4278; + var $eh_lpad_body_i90$1 = $4280$1;var $eh_lpad_body_i90$0 = $4280$0;label = 289; break; + case 286: + var $4282$0 = ___cxa_find_matching_catch(-1, -1,0); $4282$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 287: + var $4284$0 = ___cxa_find_matching_catch(-1, -1); $4284$1 = tempRet0; + var $4285=$4284$0; + $2301=$4285; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4286=$4284$1; + $2302=$4286; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 291; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 288: + var $4288$0 = ___cxa_find_matching_catch(-1, -1); $4288$1 = tempRet0; + var $eh_lpad_body_i90$1 = $4288$1;var $eh_lpad_body_i90$0 = $4288$0;label = 289; break; + case 289: + var $eh_lpad_body_i90$0; + var $eh_lpad_body_i90$1; + var $4289=$eh_lpad_body_i90$0; + $2301=$4289; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4290=$eh_lpad_body_i90$1; + $2302=$4290; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4291=$4098; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($4291, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 290; break; } else { label = 293; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 290: + label = 291; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 291: + var $4294=$4098; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4295=(($4294+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4296=$4295; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($4296) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 292; break; } else { label = 293; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 292: + var $4298=$2301; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4299=$2302; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4300$0=$4298; + var $4300$1=0; + var $4301$0=$4300$0; + var $4301$1=$4299; + ___resumeException($4301$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 293: + var $4303$0 = ___cxa_find_matching_catch(-1, -1,0); $4303$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 294: + var $4304=$std_stringstream4; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4305=(($4304+8)|0); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4306=$4305; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4307 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4306, ((9600)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 295; break; } else { label = 316; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 295: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2569, ((9904)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 296; break; } else { label = 316; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 296: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2568, $2569, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 297; break; } else { label = 317; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 297: + var $4311 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($4307, $2568) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 298; break; } else { label = 318; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 298: + var $4313 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4311, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 299; break; } else { label = 318; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 299: + var $4315 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4313, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 300; break; } else { label = 318; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 300: + var $4317 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4315, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 301; break; } else { label = 318; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 301: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2568) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 302; break; } else { label = 317; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 302: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2569) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 303; break; } else { label = 316; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 303: + var $4321=___cxa_allocate_exception(8); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2571=1; + var $4322=$4321; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2259=$std_stringstream4; + var $4323=$2259; + var $4324=(($4323+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2570, $4324) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 304; break; } else { label = 322; break; } + case 304: + label = 305; break; + case 305: + $2258=$2570; + var $4326=$2258; + $2257=$4326; + var $4327=$2257; + $2256=$4327; + var $4328=$2256; + $2255=$4328; + var $4329=$2255; + var $4330=(($4329)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2254=$4330; + var $4331=$2254; + var $4332=$4331; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2253=$4332; + var $4333=$2253; + var $4334=(($4333)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4335=(($4334)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4336=$4335; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4337=(($4336)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4338=$4337; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4339=HEAP8[($4338)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4340=(($4339)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4341=$4340 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4342=(($4341)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($4342) { label = 306; break; } else { label = 307; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 306: + $2247=$4328; + var $4344=$2247; + var $4345=(($4344)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2246=$4345; + var $4346=$2246; + var $4347=$4346; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2245=$4347; + var $4348=$2245; + var $4349=(($4348)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4350=(($4349)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4351=$4350; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4352=(($4351+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4353=HEAP32[(($4352)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4367 = $4353;label = 308; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 307: + $2252=$4328; + var $4355=$2252; + var $4356=(($4355)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2251=$4356; + var $4357=$2251; + var $4358=$4357; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2250=$4358; + var $4359=$2250; + var $4360=(($4359)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4361=(($4360)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4362=$4361; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4363=(($4362+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4364=(($4363)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2249=$4364; + var $4365=$2249; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2248=$4365; + var $4366=$2248; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $4367 = $4366;label = 308; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 308: + var $4367; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2244=$4367; + var $4368=$2244; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($4322, $4368) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 309; break; } else { label = 323; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 309: + $2571=0; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($4321, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 323; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2570) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 310; break; } else { label = 322; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 310: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream4); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 330; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 311: + var $4373$0 = ___cxa_find_matching_catch(-1, -1); $4373$1 = tempRet0; + var $4374=$4373$0; + $2542=$4374; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4375=$4373$1; + $2543=$4375; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 314; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 312: + var $4377$0 = ___cxa_find_matching_catch(-1, -1); $4377$1 = tempRet0; + var $4378=$4377$0; + $2542=$4378; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4379=$4377$1; + $2543=$4379; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2566) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 313; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 313: + label = 314; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 314: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2567) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 315; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 315: + label = 2840; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 316: + var $4384$0 = ___cxa_find_matching_catch(-1, -1); $4384$1 = tempRet0; + var $4385=$4384$0; + $2542=$4385; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4386=$4384$1; + $2543=$4386; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 328; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 317: + var $4388$0 = ___cxa_find_matching_catch(-1, -1); $4388$1 = tempRet0; + var $4389=$4388$0; + $2542=$4389; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4390=$4388$1; + $2543=$4390; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 320; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 318: + var $4392$0 = ___cxa_find_matching_catch(-1, -1); $4392$1 = tempRet0; + var $4393=$4392$0; + $2542=$4393; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4394=$4392$1; + $2543=$4394; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2568) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 319; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 319: + label = 320; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 320: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2569) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 321; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 321: + label = 328; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 322: + var $4399$0 = ___cxa_find_matching_catch(-1, -1); $4399$1 = tempRet0; + var $4400=$4399$0; + $2542=$4400; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4401=$4399$1; + $2543=$4401; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 325; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 323: + var $4403$0 = ___cxa_find_matching_catch(-1, -1); $4403$1 = tempRet0; + var $4404=$4403$0; + $2542=$4404; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4405=$4403$1; + $2543=$4405; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2570) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 324; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 324: + label = 325; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 325: + var $4408=$2571; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4408) { label = 326; break; } else { label = 327; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 326: + ___cxa_free_exception($4321); //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 327; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 327: + label = 328; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 328: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream4) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 329; break; } else { label = 2841; break; } //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 329: + label = 2840; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 330: + label = 331; break; //@line 140 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 331: + label = 332; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 332: + __ZN6StringC1EPKc($2573, ((9192)|0)); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2572, $2573, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 333; break; } else { label = 377; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 333: + var $4417 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2572, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 334; break; } else { label = 378; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 334: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2572) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 335; break; } else { label = 377; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 335: + __ZN6StringD1Ev($2573); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4417) { label = 336; break; } else { label = 396; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 336: + $2240=$std_stringstream5; + $2241=24; + var $4421=$2240; + var $4422=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4423=(($4422+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4424=$4423; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2239=$4424; + var $4425=$2239; + var $4426=$4425; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2238=$4426; + var $4427=$2238; + var $4428=$4427; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4428)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $4429=$4425; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4429)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $4430=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4430)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4431=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4432=(($4431+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4433=$4432; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4433)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4434=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4435=(($4434+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4436=$4435; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4436)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4437=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4438=(($4421+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4439=$4438; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2208=$4437; + $2209=((109796)|0); + $2210=$4439; + var $4440=$2208; + var $4441=$2209; + var $4442=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4443=(($4441+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4444=$2210; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2205=$4442; + $2206=$4443; + $2207=$4444; + var $4445=$2205; + var $4446=$2206; + var $4447=HEAP32[(($4446)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4448=$4445; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4448)>>2)]=$4447; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4449=(($4446+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4450=HEAP32[(($4449)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4451=$4445; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4452=HEAP32[(($4451)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4453=((($4452)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4454=$4453; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4455=HEAP32[(($4454)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4456=$4445; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4457=(($4456+$4455)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4458=$4457; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4458)>>2)]=$4450; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4459=(($4445+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4459)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4460=$4445; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4461=HEAP32[(($4460)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4462=((($4461)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4463=$4462; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4464=HEAP32[(($4463)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4465=$4445; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4466=(($4465+$4464)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4467=$4466; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4468=$2207; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2203=$4467; + $2204=$4468; + var $4469=$2203; + var $4470=$4469; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4471=$2204; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4472=$4471; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($4470, $4472) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 337; break; } else { label = 353; break; } + case 337: + var $4473=(($4469+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4473)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $4474=(($4469+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4474)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $4475=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4476=(($4475+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4477=$4476; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4478=(($4441+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2201=$4477; + $2202=$4478; + var $4479=$2201; + var $4480=$2202; + var $4481=HEAP32[(($4480)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4482=$4479; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4482)>>2)]=$4481; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4483=(($4480+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4484=HEAP32[(($4483)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4485=$4479; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4486=HEAP32[(($4485)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4487=((($4486)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4488=$4487; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4489=HEAP32[(($4488)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4490=$4479; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4491=(($4490+$4489)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4492=$4491; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4492)>>2)]=$4484; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4493=HEAP32[(($4441)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4494=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4494)>>2)]=$4493; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4495=(($4441+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4496=HEAP32[(($4495)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4497=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4498=HEAP32[(($4497)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4499=((($4498)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4500=$4499; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4501=HEAP32[(($4500)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4502=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4503=(($4502+$4501)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4504=$4503; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4504)>>2)]=$4496; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4505=(($4441+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4506=HEAP32[(($4505)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4507=$4440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4508=(($4507+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4509=$4508; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4509)>>2)]=$4506; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4510=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4510)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4511=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4512=(($4511+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4513=$4512; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4513)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4514=$4421; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4515=(($4514+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4516=$4515; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4516)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4517=(($4421+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4518=$2241; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2236=$4517; + $2237=$4518; + var $4519=$2236; + var $4520=$2237; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2231=$4519; + $2232=$4520; + var $4521=$2231; + var $4522=$4521; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($4522) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 338; break; } else { label = 354; break; } + case 338: + var $4523=$4521; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4523)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4524=(($4521+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2230=$4524; + var $4525=$2230; + $2229=$4525; + var $4526=$2229; + var $4527=$4526; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4528=(($4526)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2228=$4528; + var $4529=$2228; + $2227=$4529; + var $4530=$2227; + var $4531=$4530; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2226=$4531; + var $4532=$2226; + var $4533=$4532; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2225=$4533; + var $4534=$2225; + var $4535=(($4532)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2224=$4526; + var $4536=$2224; + var $4537=(($4536)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2223=$4537; + var $4538=$2223; + var $4539=$4538; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2222=$4539; + var $4540=$2222; + var $4541=(($4540)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4542=(($4541)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4543=$4542; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4544=(($4543)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i97=$4544; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i98=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 339; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 339: + var $4546=$__i_i_i_i_i_i_i98; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4547=(($4546)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4547) { label = 340; break; } else { label = 341; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 340: + var $4549=$__i_i_i_i_i_i_i98; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4550=$__a_i_i_i_i_i_i97; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4551=(($4550+($4549<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4551)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4552=$__i_i_i_i_i_i_i98; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4553=((($4552)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i98=$4553; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 339; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 341: + var $4554=(($4521+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4554)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4555=(($4521+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4556=$2232; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4555)>>2)]=$4556; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2221=$2235; + var $4557=$2221; + $2220=$4557; + var $4558=$2220; + var $4559=$4558; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4560=(($4558)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2219=$4560; + var $4561=$2219; + $2218=$4561; + var $4562=$2218; + var $4563=$4562; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2217=$4563; + var $4564=$2217; + var $4565=$4564; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2216=$4565; + var $4566=$2216; + var $4567=(($4564)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2215=$4558; + var $4568=$2215; + var $4569=(($4568)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2214=$4569; + var $4570=$2214; + var $4571=$4570; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2213=$4571; + var $4572=$2213; + var $4573=(($4572)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4574=(($4573)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4575=$4574; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4576=(($4575)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i95=$4576; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i96=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 342; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 342: + var $4578=$__i_i_i_i2_i_i_i96; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4579=(($4578)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4579) { label = 343; break; } else { label = 344; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 343: + var $4581=$__i_i_i_i2_i_i_i96; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4582=$__a_i_i_i1_i_i_i95; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4583=(($4582+($4581<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4583)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4584=$__i_i_i_i2_i_i_i96; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4585=((($4584)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i96=$4585; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 342; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 344: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($4521, $2235) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 345; break; } else { label = 347; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 345: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2235) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 360; break; } else { label = 346; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 346: + var $4588$0 = ___cxa_find_matching_catch(-1, -1); $4588$1 = tempRet0; + var $4589=$4588$0; + $2233=$4589; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4590=$4588$1; + $2234=$4590; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 349; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 347: + var $4592$0 = ___cxa_find_matching_catch(-1, -1); $4592$1 = tempRet0; + var $4593=$4592$0; + $2233=$4593; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4594=$4592$1; + $2234=$4594; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2235) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 348; break; } else { label = 352; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 348: + label = 349; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 349: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($4524) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 350; break; } else { label = 352; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 350: + var $4598=$4521; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($4598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 351; break; } else { label = 352; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 351: + var $4600=$2233; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4601=$2234; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4602$0=$4600; + var $4602$1=0; + var $4603$0=$4602$0; + var $4603$1=$4601; + var $eh_lpad_body_i103$1 = $4603$1;var $eh_lpad_body_i103$0 = $4603$0;label = 355; break; + case 352: + var $4605$0 = ___cxa_find_matching_catch(-1, -1,0); $4605$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 353: + var $4607$0 = ___cxa_find_matching_catch(-1, -1); $4607$1 = tempRet0; + var $4608=$4607$0; + $2242=$4608; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4609=$4607$1; + $2243=$4609; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 357; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 354: + var $4611$0 = ___cxa_find_matching_catch(-1, -1); $4611$1 = tempRet0; + var $eh_lpad_body_i103$1 = $4611$1;var $eh_lpad_body_i103$0 = $4611$0;label = 355; break; + case 355: + var $eh_lpad_body_i103$0; + var $eh_lpad_body_i103$1; + var $4612=$eh_lpad_body_i103$0; + $2242=$4612; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4613=$eh_lpad_body_i103$1; + $2243=$4613; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4614=$4421; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($4614, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 356; break; } else { label = 359; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 356: + label = 357; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 357: + var $4617=$4421; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4618=(($4617+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4619=$4618; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($4619) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 358; break; } else { label = 359; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 358: + var $4621=$2242; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4622=$2243; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4623$0=$4621; + var $4623$1=0; + var $4624$0=$4623$0; + var $4624$1=$4622; + ___resumeException($4624$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 359: + var $4626$0 = ___cxa_find_matching_catch(-1, -1,0); $4626$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 360: + var $4627=$std_stringstream5; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4628=(($4627+8)|0); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4629=$4628; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4630 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4629, ((8792)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 361; break; } else { label = 382; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 361: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2575, ((9192)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 362; break; } else { label = 382; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 362: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2574, $2575, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 363; break; } else { label = 383; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 363: + var $4634 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($4630, $2574) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 364; break; } else { label = 384; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 364: + var $4636 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4634, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 365; break; } else { label = 384; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 365: + var $4638 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4636, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 366; break; } else { label = 384; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 366: + var $4640 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4638, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 367; break; } else { label = 384; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 367: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2574) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 368; break; } else { label = 383; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 368: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2575) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 369; break; } else { label = 382; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 369: + var $4644=___cxa_allocate_exception(8); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2577=1; + var $4645=$4644; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2200=$std_stringstream5; + var $4646=$2200; + var $4647=(($4646+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2576, $4647) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 370; break; } else { label = 388; break; } + case 370: + label = 371; break; + case 371: + $2199=$2576; + var $4649=$2199; + $2198=$4649; + var $4650=$2198; + $2197=$4650; + var $4651=$2197; + $2196=$4651; + var $4652=$2196; + var $4653=(($4652)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2195=$4653; + var $4654=$2195; + var $4655=$4654; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2194=$4655; + var $4656=$2194; + var $4657=(($4656)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4658=(($4657)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4659=$4658; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4660=(($4659)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4661=$4660; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4662=HEAP8[($4661)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4663=(($4662)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4664=$4663 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4665=(($4664)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($4665) { label = 372; break; } else { label = 373; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 372: + $2188=$4651; + var $4667=$2188; + var $4668=(($4667)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2187=$4668; + var $4669=$2187; + var $4670=$4669; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2186=$4670; + var $4671=$2186; + var $4672=(($4671)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4673=(($4672)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4674=$4673; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4675=(($4674+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4676=HEAP32[(($4675)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4690 = $4676;label = 374; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 373: + $2193=$4651; + var $4678=$2193; + var $4679=(($4678)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2192=$4679; + var $4680=$2192; + var $4681=$4680; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2191=$4681; + var $4682=$2191; + var $4683=(($4682)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4684=(($4683)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4685=$4684; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4686=(($4685+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $4687=(($4686)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2190=$4687; + var $4688=$2190; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2189=$4688; + var $4689=$2189; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $4690 = $4689;label = 374; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 374: + var $4690; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2185=$4690; + var $4691=$2185; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($4645, $4691) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 375; break; } else { label = 389; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 375: + $2577=0; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($4644, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 389; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2576) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 376; break; } else { label = 388; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 376: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream5); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 396; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 377: + var $4696$0 = ___cxa_find_matching_catch(-1, -1); $4696$1 = tempRet0; + var $4697=$4696$0; + $2542=$4697; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4698=$4696$1; + $2543=$4698; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 380; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 378: + var $4700$0 = ___cxa_find_matching_catch(-1, -1); $4700$1 = tempRet0; + var $4701=$4700$0; + $2542=$4701; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4702=$4700$1; + $2543=$4702; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2572) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 379; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 379: + label = 380; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 380: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2573) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 381; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 381: + label = 2840; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 382: + var $4707$0 = ___cxa_find_matching_catch(-1, -1); $4707$1 = tempRet0; + var $4708=$4707$0; + $2542=$4708; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4709=$4707$1; + $2543=$4709; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 394; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 383: + var $4711$0 = ___cxa_find_matching_catch(-1, -1); $4711$1 = tempRet0; + var $4712=$4711$0; + $2542=$4712; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4713=$4711$1; + $2543=$4713; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 386; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 384: + var $4715$0 = ___cxa_find_matching_catch(-1, -1); $4715$1 = tempRet0; + var $4716=$4715$0; + $2542=$4716; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4717=$4715$1; + $2543=$4717; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2574) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 385; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 385: + label = 386; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 386: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2575) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 387; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 387: + label = 394; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 388: + var $4722$0 = ___cxa_find_matching_catch(-1, -1); $4722$1 = tempRet0; + var $4723=$4722$0; + $2542=$4723; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4724=$4722$1; + $2543=$4724; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 391; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 389: + var $4726$0 = ___cxa_find_matching_catch(-1, -1); $4726$1 = tempRet0; + var $4727=$4726$0; + $2542=$4727; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4728=$4726$1; + $2543=$4728; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2576) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 390; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 390: + label = 391; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 391: + var $4731=$2577; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4731) { label = 392; break; } else { label = 393; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 392: + ___cxa_free_exception($4644); //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 393; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 393: + label = 394; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 394: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream5) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 395; break; } else { label = 2841; break; } //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 395: + label = 2840; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 396: + label = 397; break; //@line 141 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 397: + label = 398; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 398: + __ZN6StringC1EPKc($2579, ((8536)|0)); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2578, $2579, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 399; break; } else { label = 443; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 399: + var $4740 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2578, ((8272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 400; break; } else { label = 444; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 400: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2578) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 401; break; } else { label = 443; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 401: + __ZN6StringD1Ev($2579); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($4740) { label = 402; break; } else { label = 462; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 402: + $2181=$std_stringstream6; + $2182=24; + var $4744=$2181; + var $4745=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4746=(($4745+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4747=$4746; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2180=$4747; + var $4748=$2180; + var $4749=$4748; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2179=$4749; + var $4750=$2179; + var $4751=$4750; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4751)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $4752=$4748; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4752)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $4753=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4753)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4754=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4755=(($4754+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4756=$4755; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4756)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4757=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4758=(($4757+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4759=$4758; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4759)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4760=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4761=(($4744+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4762=$4761; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2149=$4760; + $2150=((109796)|0); + $2151=$4762; + var $4763=$2149; + var $4764=$2150; + var $4765=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4766=(($4764+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4767=$2151; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2146=$4765; + $2147=$4766; + $2148=$4767; + var $4768=$2146; + var $4769=$2147; + var $4770=HEAP32[(($4769)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4771=$4768; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4771)>>2)]=$4770; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4772=(($4769+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4773=HEAP32[(($4772)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4774=$4768; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4775=HEAP32[(($4774)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4776=((($4775)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4777=$4776; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4778=HEAP32[(($4777)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4779=$4768; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4780=(($4779+$4778)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4781=$4780; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4781)>>2)]=$4773; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4782=(($4768+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4782)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $4783=$4768; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4784=HEAP32[(($4783)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4785=((($4784)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4786=$4785; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4787=HEAP32[(($4786)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4788=$4768; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4789=(($4788+$4787)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4790=$4789; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $4791=$2148; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2144=$4790; + $2145=$4791; + var $4792=$2144; + var $4793=$4792; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4794=$2145; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $4795=$4794; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($4793, $4795) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 403; break; } else { label = 419; break; } + case 403: + var $4796=(($4792+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4796)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $4797=(($4792+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($4797)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $4798=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4799=(($4798+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4800=$4799; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4801=(($4764+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2142=$4800; + $2143=$4801; + var $4802=$2142; + var $4803=$2143; + var $4804=HEAP32[(($4803)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4805=$4802; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4805)>>2)]=$4804; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4806=(($4803+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4807=HEAP32[(($4806)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4808=$4802; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4809=HEAP32[(($4808)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4810=((($4809)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4811=$4810; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4812=HEAP32[(($4811)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4813=$4802; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4814=(($4813+$4812)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4815=$4814; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4815)>>2)]=$4807; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $4816=HEAP32[(($4764)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4817=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4817)>>2)]=$4816; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4818=(($4764+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4819=HEAP32[(($4818)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4820=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4821=HEAP32[(($4820)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4822=((($4821)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4823=$4822; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4824=HEAP32[(($4823)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4825=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4826=(($4825+$4824)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4827=$4826; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4827)>>2)]=$4819; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4828=(($4764+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4829=HEAP32[(($4828)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4830=$4763; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4831=(($4830+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4832=$4831; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4832)>>2)]=$4829; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $4833=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4833)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4834=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4835=(($4834+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4836=$4835; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4836)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4837=$4744; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4838=(($4837+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4839=$4838; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4839)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4840=(($4744+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4841=$2182; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2177=$4840; + $2178=$4841; + var $4842=$2177; + var $4843=$2178; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2172=$4842; + $2173=$4843; + var $4844=$2172; + var $4845=$4844; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($4845) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 404; break; } else { label = 420; break; } + case 404: + var $4846=$4844; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4846)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4847=(($4844+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2171=$4847; + var $4848=$2171; + $2170=$4848; + var $4849=$2170; + var $4850=$4849; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4851=(($4849)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2169=$4851; + var $4852=$2169; + $2168=$4852; + var $4853=$2168; + var $4854=$4853; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2167=$4854; + var $4855=$2167; + var $4856=$4855; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2166=$4856; + var $4857=$2166; + var $4858=(($4855)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2165=$4849; + var $4859=$2165; + var $4860=(($4859)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2164=$4860; + var $4861=$2164; + var $4862=$4861; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2163=$4862; + var $4863=$2163; + var $4864=(($4863)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4865=(($4864)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4866=$4865; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4867=(($4866)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i110=$4867; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i111=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 405; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 405: + var $4869=$__i_i_i_i_i_i_i111; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4870=(($4869)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4870) { label = 406; break; } else { label = 407; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 406: + var $4872=$__i_i_i_i_i_i_i111; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4873=$__a_i_i_i_i_i_i110; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4874=(($4873+($4872<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4874)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4875=$__i_i_i_i_i_i_i111; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4876=((($4875)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i111=$4876; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 405; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 407: + var $4877=(($4844+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4877)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4878=(($4844+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $4879=$2173; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($4878)>>2)]=$4879; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2162=$2176; + var $4880=$2162; + $2161=$4880; + var $4881=$2161; + var $4882=$4881; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $4883=(($4881)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2160=$4883; + var $4884=$2160; + $2159=$4884; + var $4885=$2159; + var $4886=$4885; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2158=$4886; + var $4887=$2158; + var $4888=$4887; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2157=$4888; + var $4889=$2157; + var $4890=(($4887)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2156=$4881; + var $4891=$2156; + var $4892=(($4891)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2155=$4892; + var $4893=$2155; + var $4894=$4893; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2154=$4894; + var $4895=$2154; + var $4896=(($4895)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $4897=(($4896)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4898=$4897; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $4899=(($4898)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i108=$4899; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i109=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 408; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 408: + var $4901=$__i_i_i_i2_i_i_i109; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4902=(($4901)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($4902) { label = 409; break; } else { label = 410; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 409: + var $4904=$__i_i_i_i2_i_i_i109; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4905=$__a_i_i_i1_i_i_i108; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4906=(($4905+($4904<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($4906)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $4907=$__i_i_i_i2_i_i_i109; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $4908=((($4907)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i109=$4908; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 408; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 410: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($4844, $2176) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 411; break; } else { label = 413; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 411: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2176) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 426; break; } else { label = 412; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 412: + var $4911$0 = ___cxa_find_matching_catch(-1, -1); $4911$1 = tempRet0; + var $4912=$4911$0; + $2174=$4912; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4913=$4911$1; + $2175=$4913; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 415; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 413: + var $4915$0 = ___cxa_find_matching_catch(-1, -1); $4915$1 = tempRet0; + var $4916=$4915$0; + $2174=$4916; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $4917=$4915$1; + $2175=$4917; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2176) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 414; break; } else { label = 418; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 414: + label = 415; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 415: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($4847) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 416; break; } else { label = 418; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 416: + var $4921=$4844; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($4921) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 417; break; } else { label = 418; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 417: + var $4923=$2174; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4924=$2175; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $4925$0=$4923; + var $4925$1=0; + var $4926$0=$4925$0; + var $4926$1=$4924; + var $eh_lpad_body_i116$1 = $4926$1;var $eh_lpad_body_i116$0 = $4926$0;label = 421; break; + case 418: + var $4928$0 = ___cxa_find_matching_catch(-1, -1,0); $4928$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 419: + var $4930$0 = ___cxa_find_matching_catch(-1, -1); $4930$1 = tempRet0; + var $4931=$4930$0; + $2183=$4931; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4932=$4930$1; + $2184=$4932; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 423; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 420: + var $4934$0 = ___cxa_find_matching_catch(-1, -1); $4934$1 = tempRet0; + var $eh_lpad_body_i116$1 = $4934$1;var $eh_lpad_body_i116$0 = $4934$0;label = 421; break; + case 421: + var $eh_lpad_body_i116$0; + var $eh_lpad_body_i116$1; + var $4935=$eh_lpad_body_i116$0; + $2183=$4935; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4936=$eh_lpad_body_i116$1; + $2184=$4936; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $4937=$4744; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($4937, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 422; break; } else { label = 425; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 422: + label = 423; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 423: + var $4940=$4744; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4941=(($4940+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4942=$4941; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($4942) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 424; break; } else { label = 425; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 424: + var $4944=$2183; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4945=$2184; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $4946$0=$4944; + var $4946$1=0; + var $4947$0=$4946$0; + var $4947$1=$4945; + ___resumeException($4947$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 425: + var $4949$0 = ___cxa_find_matching_catch(-1, -1,0); $4949$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 426: + var $4950=$std_stringstream6; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4951=(($4950+8)|0); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4952=$4951; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $4953 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4952, ((7488)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 427; break; } else { label = 448; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 427: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2581, ((8536)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 428; break; } else { label = 448; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 428: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2580, $2581, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 429; break; } else { label = 449; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 429: + var $4957 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($4953, $2580) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 430; break; } else { label = 450; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 430: + var $4959 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4957, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 431; break; } else { label = 450; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 431: + var $4961 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4959, ((8272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 432; break; } else { label = 450; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 432: + var $4963 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($4961, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 433; break; } else { label = 450; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 433: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2580) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 434; break; } else { label = 449; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 434: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2581) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 435; break; } else { label = 448; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 435: + var $4967=___cxa_allocate_exception(8); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2583=1; + var $4968=$4967; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2141=$std_stringstream6; + var $4969=$2141; + var $4970=(($4969+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2582, $4970) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 436; break; } else { label = 454; break; } + case 436: + label = 437; break; + case 437: + $2140=$2582; + var $4972=$2140; + $2139=$4972; + var $4973=$2139; + $2138=$4973; + var $4974=$2138; + $2137=$4974; + var $4975=$2137; + var $4976=(($4975)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2136=$4976; + var $4977=$2136; + var $4978=$4977; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2135=$4978; + var $4979=$2135; + var $4980=(($4979)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4981=(($4980)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4982=$4981; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4983=(($4982)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4984=$4983; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4985=HEAP8[($4984)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4986=(($4985)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4987=$4986 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $4988=(($4987)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($4988) { label = 438; break; } else { label = 439; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 438: + $2129=$4974; + var $4990=$2129; + var $4991=(($4990)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2128=$4991; + var $4992=$2128; + var $4993=$4992; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2127=$4993; + var $4994=$2127; + var $4995=(($4994)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $4996=(($4995)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4997=$4996; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4998=(($4997+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $4999=HEAP32[(($4998)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5013 = $4999;label = 440; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 439: + $2134=$4974; + var $5001=$2134; + var $5002=(($5001)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2133=$5002; + var $5003=$2133; + var $5004=$5003; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2132=$5004; + var $5005=$2132; + var $5006=(($5005)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5007=(($5006)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5008=$5007; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5009=(($5008+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5010=(($5009)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2131=$5010; + var $5011=$2131; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2130=$5011; + var $5012=$2130; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $5013 = $5012;label = 440; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 440: + var $5013; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2126=$5013; + var $5014=$2126; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($4968, $5014) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 441; break; } else { label = 455; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 441: + $2583=0; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($4967, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 455; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2582) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 442; break; } else { label = 454; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 442: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream6); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 462; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 443: + var $5019$0 = ___cxa_find_matching_catch(-1, -1); $5019$1 = tempRet0; + var $5020=$5019$0; + $2542=$5020; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5021=$5019$1; + $2543=$5021; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 446; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 444: + var $5023$0 = ___cxa_find_matching_catch(-1, -1); $5023$1 = tempRet0; + var $5024=$5023$0; + $2542=$5024; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5025=$5023$1; + $2543=$5025; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2578) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 445; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 445: + label = 446; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 446: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2579) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 447; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 447: + label = 2840; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 448: + var $5030$0 = ___cxa_find_matching_catch(-1, -1); $5030$1 = tempRet0; + var $5031=$5030$0; + $2542=$5031; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5032=$5030$1; + $2543=$5032; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 460; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 449: + var $5034$0 = ___cxa_find_matching_catch(-1, -1); $5034$1 = tempRet0; + var $5035=$5034$0; + $2542=$5035; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5036=$5034$1; + $2543=$5036; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 452; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 450: + var $5038$0 = ___cxa_find_matching_catch(-1, -1); $5038$1 = tempRet0; + var $5039=$5038$0; + $2542=$5039; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5040=$5038$1; + $2543=$5040; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2580) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 451; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 451: + label = 452; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 452: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2581) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 453; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 453: + label = 460; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 454: + var $5045$0 = ___cxa_find_matching_catch(-1, -1); $5045$1 = tempRet0; + var $5046=$5045$0; + $2542=$5046; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5047=$5045$1; + $2543=$5047; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 457; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 455: + var $5049$0 = ___cxa_find_matching_catch(-1, -1); $5049$1 = tempRet0; + var $5050=$5049$0; + $2542=$5050; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5051=$5049$1; + $2543=$5051; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2582) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 456; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 456: + label = 457; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 457: + var $5054=$2583; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5054) { label = 458; break; } else { label = 459; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 458: + ___cxa_free_exception($4967); //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 459; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 459: + label = 460; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 460: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream6) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 461; break; } else { label = 2841; break; } //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 461: + label = 2840; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 462: + label = 463; break; //@line 142 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 463: + label = 464; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 464: + __ZN6StringC1EPKc($2585, ((7048)|0)); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2584, $2585, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 465; break; } else { label = 509; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 465: + var $5063 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2584, ((8272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 466; break; } else { label = 510; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 466: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2584) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 467; break; } else { label = 509; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 467: + __ZN6StringD1Ev($2585); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5063) { label = 468; break; } else { label = 528; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 468: + $2122=$std_stringstream7; + $2123=24; + var $5067=$2122; + var $5068=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5069=(($5068+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5070=$5069; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2121=$5070; + var $5071=$2121; + var $5072=$5071; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2120=$5072; + var $5073=$2120; + var $5074=$5073; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5074)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $5075=$5071; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5075)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $5076=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5076)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5077=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5078=(($5077+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5079=$5078; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5079)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5080=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5081=(($5080+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5082=$5081; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5082)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5083=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5084=(($5067+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5085=$5084; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2090=$5083; + $2091=((109796)|0); + $2092=$5085; + var $5086=$2090; + var $5087=$2091; + var $5088=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5089=(($5087+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5090=$2092; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2087=$5088; + $2088=$5089; + $2089=$5090; + var $5091=$2087; + var $5092=$2088; + var $5093=HEAP32[(($5092)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5094=$5091; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5094)>>2)]=$5093; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5095=(($5092+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5096=HEAP32[(($5095)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5097=$5091; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5098=HEAP32[(($5097)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5099=((($5098)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5100=$5099; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5101=HEAP32[(($5100)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5102=$5091; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5103=(($5102+$5101)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5104=$5103; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5104)>>2)]=$5096; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5105=(($5091+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5105)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5106=$5091; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5107=HEAP32[(($5106)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5108=((($5107)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5109=$5108; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5110=HEAP32[(($5109)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5111=$5091; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5112=(($5111+$5110)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5113=$5112; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5114=$2089; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2085=$5113; + $2086=$5114; + var $5115=$2085; + var $5116=$5115; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5117=$2086; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5118=$5117; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($5116, $5118) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 469; break; } else { label = 485; break; } + case 469: + var $5119=(($5115+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5119)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $5120=(($5115+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5120)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $5121=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5122=(($5121+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5123=$5122; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5124=(($5087+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2083=$5123; + $2084=$5124; + var $5125=$2083; + var $5126=$2084; + var $5127=HEAP32[(($5126)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5128=$5125; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5128)>>2)]=$5127; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5129=(($5126+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5130=HEAP32[(($5129)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5131=$5125; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5132=HEAP32[(($5131)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5133=((($5132)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5134=$5133; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5135=HEAP32[(($5134)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5136=$5125; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5137=(($5136+$5135)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5138=$5137; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5138)>>2)]=$5130; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5139=HEAP32[(($5087)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5140=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5140)>>2)]=$5139; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5141=(($5087+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5142=HEAP32[(($5141)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5143=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5144=HEAP32[(($5143)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5145=((($5144)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5146=$5145; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5147=HEAP32[(($5146)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5148=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5149=(($5148+$5147)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5150=$5149; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5150)>>2)]=$5142; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5151=(($5087+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5152=HEAP32[(($5151)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5153=$5086; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5154=(($5153+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5155=$5154; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5155)>>2)]=$5152; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5156=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5156)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5157=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5158=(($5157+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5159=$5158; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5159)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5160=$5067; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5161=(($5160+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5162=$5161; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5162)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5163=(($5067+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5164=$2123; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2118=$5163; + $2119=$5164; + var $5165=$2118; + var $5166=$2119; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2113=$5165; + $2114=$5166; + var $5167=$2113; + var $5168=$5167; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($5168) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 470; break; } else { label = 486; break; } + case 470: + var $5169=$5167; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5169)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5170=(($5167+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2112=$5170; + var $5171=$2112; + $2111=$5171; + var $5172=$2111; + var $5173=$5172; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5174=(($5172)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2110=$5174; + var $5175=$2110; + $2109=$5175; + var $5176=$2109; + var $5177=$5176; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2108=$5177; + var $5178=$2108; + var $5179=$5178; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2107=$5179; + var $5180=$2107; + var $5181=(($5178)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2106=$5172; + var $5182=$2106; + var $5183=(($5182)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2105=$5183; + var $5184=$2105; + var $5185=$5184; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2104=$5185; + var $5186=$2104; + var $5187=(($5186)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5188=(($5187)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5189=$5188; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5190=(($5189)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i123=$5190; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i124=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 471; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 471: + var $5192=$__i_i_i_i_i_i_i124; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5193=(($5192)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5193) { label = 472; break; } else { label = 473; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 472: + var $5195=$__i_i_i_i_i_i_i124; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5196=$__a_i_i_i_i_i_i123; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5197=(($5196+($5195<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5197)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5198=$__i_i_i_i_i_i_i124; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5199=((($5198)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i124=$5199; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 471; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 473: + var $5200=(($5167+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5200)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5201=(($5167+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5202=$2114; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5201)>>2)]=$5202; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2103=$2117; + var $5203=$2103; + $2102=$5203; + var $5204=$2102; + var $5205=$5204; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5206=(($5204)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2101=$5206; + var $5207=$2101; + $2100=$5207; + var $5208=$2100; + var $5209=$5208; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2099=$5209; + var $5210=$2099; + var $5211=$5210; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2098=$5211; + var $5212=$2098; + var $5213=(($5210)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2097=$5204; + var $5214=$2097; + var $5215=(($5214)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2096=$5215; + var $5216=$2096; + var $5217=$5216; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2095=$5217; + var $5218=$2095; + var $5219=(($5218)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5220=(($5219)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5221=$5220; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5222=(($5221)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i121=$5222; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i122=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 474; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 474: + var $5224=$__i_i_i_i2_i_i_i122; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5225=(($5224)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5225) { label = 475; break; } else { label = 476; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 475: + var $5227=$__i_i_i_i2_i_i_i122; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5228=$__a_i_i_i1_i_i_i121; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5229=(($5228+($5227<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5229)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5230=$__i_i_i_i2_i_i_i122; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5231=((($5230)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i122=$5231; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 474; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 476: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($5167, $2117) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 477; break; } else { label = 479; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 477: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2117) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 492; break; } else { label = 478; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 478: + var $5234$0 = ___cxa_find_matching_catch(-1, -1); $5234$1 = tempRet0; + var $5235=$5234$0; + $2115=$5235; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5236=$5234$1; + $2116=$5236; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 481; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 479: + var $5238$0 = ___cxa_find_matching_catch(-1, -1); $5238$1 = tempRet0; + var $5239=$5238$0; + $2115=$5239; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5240=$5238$1; + $2116=$5240; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2117) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 480; break; } else { label = 484; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 480: + label = 481; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 481: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($5170) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 482; break; } else { label = 484; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 482: + var $5244=$5167; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($5244) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 483; break; } else { label = 484; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 483: + var $5246=$2115; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5247=$2116; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5248$0=$5246; + var $5248$1=0; + var $5249$0=$5248$0; + var $5249$1=$5247; + var $eh_lpad_body_i129$1 = $5249$1;var $eh_lpad_body_i129$0 = $5249$0;label = 487; break; + case 484: + var $5251$0 = ___cxa_find_matching_catch(-1, -1,0); $5251$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 485: + var $5253$0 = ___cxa_find_matching_catch(-1, -1); $5253$1 = tempRet0; + var $5254=$5253$0; + $2124=$5254; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5255=$5253$1; + $2125=$5255; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 489; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 486: + var $5257$0 = ___cxa_find_matching_catch(-1, -1); $5257$1 = tempRet0; + var $eh_lpad_body_i129$1 = $5257$1;var $eh_lpad_body_i129$0 = $5257$0;label = 487; break; + case 487: + var $eh_lpad_body_i129$0; + var $eh_lpad_body_i129$1; + var $5258=$eh_lpad_body_i129$0; + $2124=$5258; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5259=$eh_lpad_body_i129$1; + $2125=$5259; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5260=$5067; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($5260, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 488; break; } else { label = 491; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 488: + label = 489; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 489: + var $5263=$5067; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5264=(($5263+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5265=$5264; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($5265) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 490; break; } else { label = 491; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 490: + var $5267=$2124; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5268=$2125; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5269$0=$5267; + var $5269$1=0; + var $5270$0=$5269$0; + var $5270$1=$5268; + ___resumeException($5270$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 491: + var $5272$0 = ___cxa_find_matching_catch(-1, -1,0); $5272$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 492: + var $5273=$std_stringstream7; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5274=(($5273+8)|0); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5275=$5274; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5276 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5275, ((6640)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 493; break; } else { label = 514; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 493: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2587, ((7048)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 494; break; } else { label = 514; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 494: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2586, $2587, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 495; break; } else { label = 515; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 495: + var $5280 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($5276, $2586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 496; break; } else { label = 516; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 496: + var $5282 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5280, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 497; break; } else { label = 516; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 497: + var $5284 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5282, ((8272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 498; break; } else { label = 516; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 498: + var $5286 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5284, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 499; break; } else { label = 516; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 499: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 500; break; } else { label = 515; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 500: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2587) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 501; break; } else { label = 514; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 501: + var $5290=___cxa_allocate_exception(8); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2589=1; + var $5291=$5290; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2082=$std_stringstream7; + var $5292=$2082; + var $5293=(($5292+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2588, $5293) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 502; break; } else { label = 520; break; } + case 502: + label = 503; break; + case 503: + $2081=$2588; + var $5295=$2081; + $2080=$5295; + var $5296=$2080; + $2079=$5296; + var $5297=$2079; + $2078=$5297; + var $5298=$2078; + var $5299=(($5298)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2077=$5299; + var $5300=$2077; + var $5301=$5300; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2076=$5301; + var $5302=$2076; + var $5303=(($5302)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5304=(($5303)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5305=$5304; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5306=(($5305)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5307=$5306; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5308=HEAP8[($5307)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5309=(($5308)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5310=$5309 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5311=(($5310)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($5311) { label = 504; break; } else { label = 505; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 504: + $2070=$5297; + var $5313=$2070; + var $5314=(($5313)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2069=$5314; + var $5315=$2069; + var $5316=$5315; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2068=$5316; + var $5317=$2068; + var $5318=(($5317)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5319=(($5318)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5320=$5319; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5321=(($5320+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5322=HEAP32[(($5321)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5336 = $5322;label = 506; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 505: + $2075=$5297; + var $5324=$2075; + var $5325=(($5324)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2074=$5325; + var $5326=$2074; + var $5327=$5326; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2073=$5327; + var $5328=$2073; + var $5329=(($5328)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5330=(($5329)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5331=$5330; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5332=(($5331+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5333=(($5332)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2072=$5333; + var $5334=$2072; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2071=$5334; + var $5335=$2071; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $5336 = $5335;label = 506; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 506: + var $5336; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2067=$5336; + var $5337=$2067; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($5291, $5337) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 507; break; } else { label = 521; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 507: + $2589=0; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($5290, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 521; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2588) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 508; break; } else { label = 520; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 508: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream7); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 528; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 509: + var $5342$0 = ___cxa_find_matching_catch(-1, -1); $5342$1 = tempRet0; + var $5343=$5342$0; + $2542=$5343; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5344=$5342$1; + $2543=$5344; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 512; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 510: + var $5346$0 = ___cxa_find_matching_catch(-1, -1); $5346$1 = tempRet0; + var $5347=$5346$0; + $2542=$5347; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5348=$5346$1; + $2543=$5348; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2584) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 511; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 511: + label = 512; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 512: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2585) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 513; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 513: + label = 2840; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 514: + var $5353$0 = ___cxa_find_matching_catch(-1, -1); $5353$1 = tempRet0; + var $5354=$5353$0; + $2542=$5354; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5355=$5353$1; + $2543=$5355; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 526; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 515: + var $5357$0 = ___cxa_find_matching_catch(-1, -1); $5357$1 = tempRet0; + var $5358=$5357$0; + $2542=$5358; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5359=$5357$1; + $2543=$5359; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 518; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 516: + var $5361$0 = ___cxa_find_matching_catch(-1, -1); $5361$1 = tempRet0; + var $5362=$5361$0; + $2542=$5362; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5363=$5361$1; + $2543=$5363; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 517; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 517: + label = 518; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 518: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2587) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 519; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 519: + label = 526; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 520: + var $5368$0 = ___cxa_find_matching_catch(-1, -1); $5368$1 = tempRet0; + var $5369=$5368$0; + $2542=$5369; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5370=$5368$1; + $2543=$5370; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 523; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 521: + var $5372$0 = ___cxa_find_matching_catch(-1, -1); $5372$1 = tempRet0; + var $5373=$5372$0; + $2542=$5373; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5374=$5372$1; + $2543=$5374; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2588) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 522; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 522: + label = 523; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 523: + var $5377=$2589; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5377) { label = 524; break; } else { label = 525; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 524: + ___cxa_free_exception($5290); //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 525; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 525: + label = 526; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 526: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream7) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 527; break; } else { label = 2841; break; } //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 527: + label = 2840; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 528: + label = 529; break; //@line 143 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 529: + label = 530; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 530: + __ZN6StringC1EPKc($2591, ((6288)|0)); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2590, $2591, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 531; break; } else { label = 575; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 531: + var $5386 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2590, ((5960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 532; break; } else { label = 576; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 532: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2590) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 533; break; } else { label = 575; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 533: + __ZN6StringD1Ev($2591); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5386) { label = 534; break; } else { label = 594; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 534: + $2063=$std_stringstream8; + $2064=24; + var $5390=$2063; + var $5391=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5392=(($5391+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5393=$5392; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2062=$5393; + var $5394=$2062; + var $5395=$5394; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2061=$5395; + var $5396=$2061; + var $5397=$5396; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5397)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $5398=$5394; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5398)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $5399=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5399)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5400=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5401=(($5400+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5402=$5401; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5402)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5403=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5404=(($5403+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5405=$5404; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5405)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5406=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5407=(($5390+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5408=$5407; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2031=$5406; + $2032=((109796)|0); + $2033=$5408; + var $5409=$2031; + var $5410=$2032; + var $5411=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5412=(($5410+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5413=$2033; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2028=$5411; + $2029=$5412; + $2030=$5413; + var $5414=$2028; + var $5415=$2029; + var $5416=HEAP32[(($5415)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5417=$5414; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5417)>>2)]=$5416; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5418=(($5415+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5419=HEAP32[(($5418)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5420=$5414; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5421=HEAP32[(($5420)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5422=((($5421)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5423=$5422; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5424=HEAP32[(($5423)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5425=$5414; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5426=(($5425+$5424)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5427=$5426; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5427)>>2)]=$5419; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5428=(($5414+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5428)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5429=$5414; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5430=HEAP32[(($5429)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5431=((($5430)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5432=$5431; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5433=HEAP32[(($5432)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5434=$5414; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5435=(($5434+$5433)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5436=$5435; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5437=$2030; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $2026=$5436; + $2027=$5437; + var $5438=$2026; + var $5439=$5438; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5440=$2027; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5441=$5440; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($5439, $5441) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 535; break; } else { label = 551; break; } + case 535: + var $5442=(($5438+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5442)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $5443=(($5438+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5443)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $5444=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5445=(($5444+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5446=$5445; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5447=(($5410+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $2024=$5446; + $2025=$5447; + var $5448=$2024; + var $5449=$2025; + var $5450=HEAP32[(($5449)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5451=$5448; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5451)>>2)]=$5450; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5452=(($5449+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5453=HEAP32[(($5452)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5454=$5448; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5455=HEAP32[(($5454)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5456=((($5455)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5457=$5456; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5458=HEAP32[(($5457)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5459=$5448; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5460=(($5459+$5458)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5461=$5460; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5461)>>2)]=$5453; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5462=HEAP32[(($5410)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5463=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5463)>>2)]=$5462; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5464=(($5410+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5465=HEAP32[(($5464)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5466=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5467=HEAP32[(($5466)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5468=((($5467)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5469=$5468; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5470=HEAP32[(($5469)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5471=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5472=(($5471+$5470)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5473=$5472; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5473)>>2)]=$5465; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5474=(($5410+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5475=HEAP32[(($5474)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5476=$5409; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5477=(($5476+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5478=$5477; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5478)>>2)]=$5475; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5479=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5479)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5480=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5481=(($5480+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5482=$5481; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5482)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5483=$5390; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5484=(($5483+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5485=$5484; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5485)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5486=(($5390+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5487=$2064; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2059=$5486; + $2060=$5487; + var $5488=$2059; + var $5489=$2060; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $2054=$5488; + $2055=$5489; + var $5490=$2054; + var $5491=$5490; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($5491) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 536; break; } else { label = 552; break; } + case 536: + var $5492=$5490; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5492)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5493=(($5490+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2053=$5493; + var $5494=$2053; + $2052=$5494; + var $5495=$2052; + var $5496=$5495; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5497=(($5495)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2051=$5497; + var $5498=$2051; + $2050=$5498; + var $5499=$2050; + var $5500=$5499; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2049=$5500; + var $5501=$2049; + var $5502=$5501; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2048=$5502; + var $5503=$2048; + var $5504=(($5501)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2047=$5495; + var $5505=$2047; + var $5506=(($5505)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2046=$5506; + var $5507=$2046; + var $5508=$5507; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2045=$5508; + var $5509=$2045; + var $5510=(($5509)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5511=(($5510)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5512=$5511; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5513=(($5512)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i136=$5513; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i137=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 537; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 537: + var $5515=$__i_i_i_i_i_i_i137; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5516=(($5515)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5516) { label = 538; break; } else { label = 539; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 538: + var $5518=$__i_i_i_i_i_i_i137; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5519=$__a_i_i_i_i_i_i136; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5520=(($5519+($5518<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5520)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5521=$__i_i_i_i_i_i_i137; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5522=((($5521)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i137=$5522; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 537; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 539: + var $5523=(($5490+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5523)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5524=(($5490+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5525=$2055; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5524)>>2)]=$5525; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $2044=$2058; + var $5526=$2044; + $2043=$5526; + var $5527=$2043; + var $5528=$5527; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5529=(($5527)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $2042=$5529; + var $5530=$2042; + $2041=$5530; + var $5531=$2041; + var $5532=$5531; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $2040=$5532; + var $5533=$2040; + var $5534=$5533; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2039=$5534; + var $5535=$2039; + var $5536=(($5533)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $2038=$5527; + var $5537=$2038; + var $5538=(($5537)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $2037=$5538; + var $5539=$2037; + var $5540=$5539; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $2036=$5540; + var $5541=$2036; + var $5542=(($5541)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5543=(($5542)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5544=$5543; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5545=(($5544)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i134=$5545; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i135=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 540; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 540: + var $5547=$__i_i_i_i2_i_i_i135; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5548=(($5547)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5548) { label = 541; break; } else { label = 542; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 541: + var $5550=$__i_i_i_i2_i_i_i135; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5551=$__a_i_i_i1_i_i_i134; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5552=(($5551+($5550<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5552)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5553=$__i_i_i_i2_i_i_i135; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5554=((($5553)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i135=$5554; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 540; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 542: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($5490, $2058) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 543; break; } else { label = 545; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 543: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2058) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 558; break; } else { label = 544; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 544: + var $5557$0 = ___cxa_find_matching_catch(-1, -1); $5557$1 = tempRet0; + var $5558=$5557$0; + $2056=$5558; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5559=$5557$1; + $2057=$5559; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 547; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 545: + var $5561$0 = ___cxa_find_matching_catch(-1, -1); $5561$1 = tempRet0; + var $5562=$5561$0; + $2056=$5562; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5563=$5561$1; + $2057=$5563; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2058) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 546; break; } else { label = 550; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 546: + label = 547; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 547: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($5493) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 548; break; } else { label = 550; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 548: + var $5567=$5490; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($5567) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 549; break; } else { label = 550; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 549: + var $5569=$2056; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5570=$2057; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5571$0=$5569; + var $5571$1=0; + var $5572$0=$5571$0; + var $5572$1=$5570; + var $eh_lpad_body_i142$1 = $5572$1;var $eh_lpad_body_i142$0 = $5572$0;label = 553; break; + case 550: + var $5574$0 = ___cxa_find_matching_catch(-1, -1,0); $5574$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 551: + var $5576$0 = ___cxa_find_matching_catch(-1, -1); $5576$1 = tempRet0; + var $5577=$5576$0; + $2065=$5577; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5578=$5576$1; + $2066=$5578; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 555; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 552: + var $5580$0 = ___cxa_find_matching_catch(-1, -1); $5580$1 = tempRet0; + var $eh_lpad_body_i142$1 = $5580$1;var $eh_lpad_body_i142$0 = $5580$0;label = 553; break; + case 553: + var $eh_lpad_body_i142$0; + var $eh_lpad_body_i142$1; + var $5581=$eh_lpad_body_i142$0; + $2065=$5581; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5582=$eh_lpad_body_i142$1; + $2066=$5582; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5583=$5390; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($5583, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 554; break; } else { label = 557; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 554: + label = 555; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 555: + var $5586=$5390; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5587=(($5586+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5588=$5587; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($5588) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 556; break; } else { label = 557; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 556: + var $5590=$2065; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5591=$2066; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5592$0=$5590; + var $5592$1=0; + var $5593$0=$5592$0; + var $5593$1=$5591; + ___resumeException($5593$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 557: + var $5595$0 = ___cxa_find_matching_catch(-1, -1,0); $5595$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 558: + var $5596=$std_stringstream8; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5597=(($5596+8)|0); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5598=$5597; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5599 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5598, ((5584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 559; break; } else { label = 580; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 559: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2593, ((6288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 560; break; } else { label = 580; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 560: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2592, $2593, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 561; break; } else { label = 581; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 561: + var $5603 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($5599, $2592) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 562; break; } else { label = 582; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 562: + var $5605 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5603, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 563; break; } else { label = 582; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 563: + var $5607 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5605, ((5960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 564; break; } else { label = 582; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 564: + var $5609 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5607, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 565; break; } else { label = 582; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 565: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2592) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 566; break; } else { label = 581; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 566: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2593) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 567; break; } else { label = 580; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 567: + var $5613=___cxa_allocate_exception(8); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2595=1; + var $5614=$5613; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2023=$std_stringstream8; + var $5615=$2023; + var $5616=(($5615+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2594, $5616) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 568; break; } else { label = 586; break; } + case 568: + label = 569; break; + case 569: + $2022=$2594; + var $5618=$2022; + $2021=$5618; + var $5619=$2021; + $2020=$5619; + var $5620=$2020; + $2019=$5620; + var $5621=$2019; + var $5622=(($5621)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $2018=$5622; + var $5623=$2018; + var $5624=$5623; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2017=$5624; + var $5625=$2017; + var $5626=(($5625)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5627=(($5626)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5628=$5627; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5629=(($5628)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5630=$5629; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5631=HEAP8[($5630)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5632=(($5631)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5633=$5632 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5634=(($5633)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($5634) { label = 570; break; } else { label = 571; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 570: + $2011=$5620; + var $5636=$2011; + var $5637=(($5636)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $2010=$5637; + var $5638=$2010; + var $5639=$5638; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2009=$5639; + var $5640=$2009; + var $5641=(($5640)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5642=(($5641)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5643=$5642; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5644=(($5643+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5645=HEAP32[(($5644)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5659 = $5645;label = 572; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 571: + $2016=$5620; + var $5647=$2016; + var $5648=(($5647)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2015=$5648; + var $5649=$2015; + var $5650=$5649; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $2014=$5650; + var $5651=$2014; + var $5652=(($5651)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5653=(($5652)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5654=$5653; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5655=(($5654+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5656=(($5655)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $2013=$5656; + var $5657=$2013; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $2012=$5657; + var $5658=$2012; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $5659 = $5658;label = 572; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 572: + var $5659; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2008=$5659; + var $5660=$2008; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($5614, $5660) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 573; break; } else { label = 587; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 573: + $2595=0; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($5613, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 587; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2594) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 574; break; } else { label = 586; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 574: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream8); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 594; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 575: + var $5665$0 = ___cxa_find_matching_catch(-1, -1); $5665$1 = tempRet0; + var $5666=$5665$0; + $2542=$5666; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5667=$5665$1; + $2543=$5667; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 578; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 576: + var $5669$0 = ___cxa_find_matching_catch(-1, -1); $5669$1 = tempRet0; + var $5670=$5669$0; + $2542=$5670; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5671=$5669$1; + $2543=$5671; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2590) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 577; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 577: + label = 578; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 578: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2591) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 579; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 579: + label = 2840; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 580: + var $5676$0 = ___cxa_find_matching_catch(-1, -1); $5676$1 = tempRet0; + var $5677=$5676$0; + $2542=$5677; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5678=$5676$1; + $2543=$5678; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 592; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 581: + var $5680$0 = ___cxa_find_matching_catch(-1, -1); $5680$1 = tempRet0; + var $5681=$5680$0; + $2542=$5681; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5682=$5680$1; + $2543=$5682; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 584; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 582: + var $5684$0 = ___cxa_find_matching_catch(-1, -1); $5684$1 = tempRet0; + var $5685=$5684$0; + $2542=$5685; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5686=$5684$1; + $2543=$5686; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2592) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 583; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 583: + label = 584; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 584: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2593) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 585; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 585: + label = 592; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 586: + var $5691$0 = ___cxa_find_matching_catch(-1, -1); $5691$1 = tempRet0; + var $5692=$5691$0; + $2542=$5692; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5693=$5691$1; + $2543=$5693; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 589; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 587: + var $5695$0 = ___cxa_find_matching_catch(-1, -1); $5695$1 = tempRet0; + var $5696=$5695$0; + $2542=$5696; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5697=$5695$1; + $2543=$5697; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2594) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 588; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 588: + label = 589; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 589: + var $5700=$2595; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5700) { label = 590; break; } else { label = 591; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 590: + ___cxa_free_exception($5613); //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 591; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 591: + label = 592; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 592: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream8) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 593; break; } else { label = 2841; break; } //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 593: + label = 2840; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 594: + label = 595; break; //@line 144 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 595: + label = 596; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 596: + __ZN6StringC1EPKc($2597, ((5368)|0)); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2596, $2597, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 597; break; } else { label = 641; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 597: + var $5709 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2596, ((5960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 598; break; } else { label = 642; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 598: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2596) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 599; break; } else { label = 641; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 599: + __ZN6StringD1Ev($2597); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($5709) { label = 600; break; } else { label = 660; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 600: + $2004=$std_stringstream9; + $2005=24; + var $5713=$2004; + var $5714=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5715=(($5714+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5716=$5715; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2003=$5716; + var $5717=$2003; + var $5718=$5717; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $2002=$5718; + var $5719=$2002; + var $5720=$5719; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5720)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $5721=$5717; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5721)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $5722=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5722)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5723=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5724=(($5723+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5725=$5724; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5725)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5726=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5727=(($5726+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5728=$5727; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5728)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5729=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5730=(($5713+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5731=$5730; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1972=$5729; + $1973=((109796)|0); + $1974=$5731; + var $5732=$1972; + var $5733=$1973; + var $5734=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5735=(($5733+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5736=$1974; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1969=$5734; + $1970=$5735; + $1971=$5736; + var $5737=$1969; + var $5738=$1970; + var $5739=HEAP32[(($5738)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5740=$5737; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5740)>>2)]=$5739; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5741=(($5738+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5742=HEAP32[(($5741)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5743=$5737; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5744=HEAP32[(($5743)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5745=((($5744)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5746=$5745; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5747=HEAP32[(($5746)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5748=$5737; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5749=(($5748+$5747)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5750=$5749; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5750)>>2)]=$5742; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5751=(($5737+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5751)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $5752=$5737; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5753=HEAP32[(($5752)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5754=((($5753)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5755=$5754; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5756=HEAP32[(($5755)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5757=$5737; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5758=(($5757+$5756)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5759=$5758; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $5760=$1971; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1967=$5759; + $1968=$5760; + var $5761=$1967; + var $5762=$5761; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5763=$1968; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $5764=$5763; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($5762, $5764) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 601; break; } else { label = 617; break; } + case 601: + var $5765=(($5761+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5765)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $5766=(($5761+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($5766)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $5767=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5768=(($5767+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5769=$5768; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5770=(($5733+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1965=$5769; + $1966=$5770; + var $5771=$1965; + var $5772=$1966; + var $5773=HEAP32[(($5772)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5774=$5771; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5774)>>2)]=$5773; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5775=(($5772+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5776=HEAP32[(($5775)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5777=$5771; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5778=HEAP32[(($5777)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5779=((($5778)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5780=$5779; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5781=HEAP32[(($5780)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5782=$5771; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5783=(($5782+$5781)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5784=$5783; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5784)>>2)]=$5776; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $5785=HEAP32[(($5733)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5786=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5786)>>2)]=$5785; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5787=(($5733+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5788=HEAP32[(($5787)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5789=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5790=HEAP32[(($5789)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5791=((($5790)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5792=$5791; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5793=HEAP32[(($5792)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5794=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5795=(($5794+$5793)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5796=$5795; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5796)>>2)]=$5788; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5797=(($5733+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5798=HEAP32[(($5797)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5799=$5732; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5800=(($5799+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5801=$5800; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5801)>>2)]=$5798; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $5802=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5802)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5803=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5804=(($5803+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5805=$5804; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5805)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5806=$5713; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5807=(($5806+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5808=$5807; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5808)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5809=(($5713+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5810=$2005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $2000=$5809; + $2001=$5810; + var $5811=$2000; + var $5812=$2001; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1995=$5811; + $1996=$5812; + var $5813=$1995; + var $5814=$5813; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($5814) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 602; break; } else { label = 618; break; } + case 602: + var $5815=$5813; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5815)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5816=(($5813+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1994=$5816; + var $5817=$1994; + $1993=$5817; + var $5818=$1993; + var $5819=$5818; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5820=(($5818)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1992=$5820; + var $5821=$1992; + $1991=$5821; + var $5822=$1991; + var $5823=$5822; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1990=$5823; + var $5824=$1990; + var $5825=$5824; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1989=$5825; + var $5826=$1989; + var $5827=(($5824)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1988=$5818; + var $5828=$1988; + var $5829=(($5828)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1987=$5829; + var $5830=$1987; + var $5831=$5830; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1986=$5831; + var $5832=$1986; + var $5833=(($5832)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5834=(($5833)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5835=$5834; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5836=(($5835)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i149=$5836; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i150=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 603; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 603: + var $5838=$__i_i_i_i_i_i_i150; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5839=(($5838)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5839) { label = 604; break; } else { label = 605; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 604: + var $5841=$__i_i_i_i_i_i_i150; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5842=$__a_i_i_i_i_i_i149; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5843=(($5842+($5841<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5843)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5844=$__i_i_i_i_i_i_i150; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5845=((($5844)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i150=$5845; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 603; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 605: + var $5846=(($5813+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5846)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5847=(($5813+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $5848=$1996; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($5847)>>2)]=$5848; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1985=$1999; + var $5849=$1985; + $1984=$5849; + var $5850=$1984; + var $5851=$5850; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $5852=(($5850)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1983=$5852; + var $5853=$1983; + $1982=$5853; + var $5854=$1982; + var $5855=$5854; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1981=$5855; + var $5856=$1981; + var $5857=$5856; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1980=$5857; + var $5858=$1980; + var $5859=(($5856)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1979=$5850; + var $5860=$1979; + var $5861=(($5860)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1978=$5861; + var $5862=$1978; + var $5863=$5862; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1977=$5863; + var $5864=$1977; + var $5865=(($5864)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $5866=(($5865)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5867=$5866; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $5868=(($5867)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i147=$5868; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i148=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 606; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 606: + var $5870=$__i_i_i_i2_i_i_i148; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5871=(($5870)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($5871) { label = 607; break; } else { label = 608; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 607: + var $5873=$__i_i_i_i2_i_i_i148; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5874=$__a_i_i_i1_i_i_i147; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5875=(($5874+($5873<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($5875)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $5876=$__i_i_i_i2_i_i_i148; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $5877=((($5876)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i148=$5877; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 606; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 608: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($5813, $1999) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 609; break; } else { label = 611; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 609: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1999) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 624; break; } else { label = 610; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 610: + var $5880$0 = ___cxa_find_matching_catch(-1, -1); $5880$1 = tempRet0; + var $5881=$5880$0; + $1997=$5881; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5882=$5880$1; + $1998=$5882; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 613; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 611: + var $5884$0 = ___cxa_find_matching_catch(-1, -1); $5884$1 = tempRet0; + var $5885=$5884$0; + $1997=$5885; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $5886=$5884$1; + $1998=$5886; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1999) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 612; break; } else { label = 616; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 612: + label = 613; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 613: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($5816) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 614; break; } else { label = 616; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 614: + var $5890=$5813; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($5890) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 615; break; } else { label = 616; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 615: + var $5892=$1997; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5893=$1998; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $5894$0=$5892; + var $5894$1=0; + var $5895$0=$5894$0; + var $5895$1=$5893; + var $eh_lpad_body_i155$1 = $5895$1;var $eh_lpad_body_i155$0 = $5895$0;label = 619; break; + case 616: + var $5897$0 = ___cxa_find_matching_catch(-1, -1,0); $5897$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 617: + var $5899$0 = ___cxa_find_matching_catch(-1, -1); $5899$1 = tempRet0; + var $5900=$5899$0; + $2006=$5900; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5901=$5899$1; + $2007=$5901; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 621; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 618: + var $5903$0 = ___cxa_find_matching_catch(-1, -1); $5903$1 = tempRet0; + var $eh_lpad_body_i155$1 = $5903$1;var $eh_lpad_body_i155$0 = $5903$0;label = 619; break; + case 619: + var $eh_lpad_body_i155$0; + var $eh_lpad_body_i155$1; + var $5904=$eh_lpad_body_i155$0; + $2006=$5904; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5905=$eh_lpad_body_i155$1; + $2007=$5905; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $5906=$5713; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($5906, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 620; break; } else { label = 623; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 620: + label = 621; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 621: + var $5909=$5713; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5910=(($5909+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5911=$5910; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($5911) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 622; break; } else { label = 623; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 622: + var $5913=$2006; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5914=$2007; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $5915$0=$5913; + var $5915$1=0; + var $5916$0=$5915$0; + var $5916$1=$5914; + ___resumeException($5916$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 623: + var $5918$0 = ___cxa_find_matching_catch(-1, -1,0); $5918$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 624: + var $5919=$std_stringstream9; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5920=(($5919+8)|0); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5921=$5920; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5922 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5921, ((4880)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 625; break; } else { label = 646; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 625: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2599, ((5368)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 626; break; } else { label = 646; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 626: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2598, $2599, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 627; break; } else { label = 647; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 627: + var $5926 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($5922, $2598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 628; break; } else { label = 648; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 628: + var $5928 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5926, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 629; break; } else { label = 648; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 629: + var $5930 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5928, ((5960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 630; break; } else { label = 648; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 630: + var $5932 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($5930, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 631; break; } else { label = 648; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 631: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 632; break; } else { label = 647; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 632: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2599) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 633; break; } else { label = 646; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 633: + var $5936=___cxa_allocate_exception(8); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2601=1; + var $5937=$5936; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1964=$std_stringstream9; + var $5938=$1964; + var $5939=(($5938+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2600, $5939) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 634; break; } else { label = 652; break; } + case 634: + label = 635; break; + case 635: + $1963=$2600; + var $5941=$1963; + $1962=$5941; + var $5942=$1962; + $1961=$5942; + var $5943=$1961; + $1960=$5943; + var $5944=$1960; + var $5945=(($5944)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1959=$5945; + var $5946=$1959; + var $5947=$5946; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1958=$5947; + var $5948=$1958; + var $5949=(($5948)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5950=(($5949)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5951=$5950; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5952=(($5951)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5953=$5952; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5954=HEAP8[($5953)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5955=(($5954)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5956=$5955 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $5957=(($5956)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($5957) { label = 636; break; } else { label = 637; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 636: + $1952=$5943; + var $5959=$1952; + var $5960=(($5959)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1951=$5960; + var $5961=$1951; + var $5962=$5961; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1950=$5962; + var $5963=$1950; + var $5964=(($5963)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5965=(($5964)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5966=$5965; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5967=(($5966+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5968=HEAP32[(($5967)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $5982 = $5968;label = 638; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 637: + $1957=$5943; + var $5970=$1957; + var $5971=(($5970)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1956=$5971; + var $5972=$1956; + var $5973=$5972; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1955=$5973; + var $5974=$1955; + var $5975=(($5974)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $5976=(($5975)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5977=$5976; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5978=(($5977+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $5979=(($5978)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1954=$5979; + var $5980=$1954; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1953=$5980; + var $5981=$1953; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $5982 = $5981;label = 638; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 638: + var $5982; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1949=$5982; + var $5983=$1949; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($5937, $5983) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 639; break; } else { label = 653; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 639: + $2601=0; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($5936, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 653; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2600) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 640; break; } else { label = 652; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 640: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream9); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 660; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 641: + var $5988$0 = ___cxa_find_matching_catch(-1, -1); $5988$1 = tempRet0; + var $5989=$5988$0; + $2542=$5989; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5990=$5988$1; + $2543=$5990; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 644; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 642: + var $5992$0 = ___cxa_find_matching_catch(-1, -1); $5992$1 = tempRet0; + var $5993=$5992$0; + $2542=$5993; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $5994=$5992$1; + $2543=$5994; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2596) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 643; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 643: + label = 644; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 644: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2597) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 645; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 645: + label = 2840; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 646: + var $5999$0 = ___cxa_find_matching_catch(-1, -1); $5999$1 = tempRet0; + var $6000=$5999$0; + $2542=$6000; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6001=$5999$1; + $2543=$6001; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 658; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 647: + var $6003$0 = ___cxa_find_matching_catch(-1, -1); $6003$1 = tempRet0; + var $6004=$6003$0; + $2542=$6004; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6005=$6003$1; + $2543=$6005; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 650; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 648: + var $6007$0 = ___cxa_find_matching_catch(-1, -1); $6007$1 = tempRet0; + var $6008=$6007$0; + $2542=$6008; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6009=$6007$1; + $2543=$6009; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 649; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 649: + label = 650; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 650: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2599) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 651; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 651: + label = 658; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 652: + var $6014$0 = ___cxa_find_matching_catch(-1, -1); $6014$1 = tempRet0; + var $6015=$6014$0; + $2542=$6015; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6016=$6014$1; + $2543=$6016; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 655; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 653: + var $6018$0 = ___cxa_find_matching_catch(-1, -1); $6018$1 = tempRet0; + var $6019=$6018$0; + $2542=$6019; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6020=$6018$1; + $2543=$6020; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2600) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 654; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 654: + label = 655; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 655: + var $6023=$2601; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6023) { label = 656; break; } else { label = 657; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 656: + ___cxa_free_exception($5936); //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 657; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 657: + label = 658; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 658: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream9) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 659; break; } else { label = 2841; break; } //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 659: + label = 2840; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 660: + label = 661; break; //@line 145 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 661: + label = 662; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 662: + __ZN6StringC1EPKc($2603, ((4544)|0)); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2602, $2603, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 663; break; } else { label = 707; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 663: + var $6032 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2602, ((4288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 664; break; } else { label = 708; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 664: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2602) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 665; break; } else { label = 707; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 665: + __ZN6StringD1Ev($2603); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6032) { label = 666; break; } else { label = 726; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 666: + $1945=$std_stringstream10; + $1946=24; + var $6036=$1945; + var $6037=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6038=(($6037+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6039=$6038; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1944=$6039; + var $6040=$1944; + var $6041=$6040; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1943=$6041; + var $6042=$1943; + var $6043=$6042; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6043)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $6044=$6040; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6044)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $6045=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6045)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6046=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6047=(($6046+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6048=$6047; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6048)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6049=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6050=(($6049+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6051=$6050; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6051)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6052=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6053=(($6036+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6054=$6053; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1913=$6052; + $1914=((109796)|0); + $1915=$6054; + var $6055=$1913; + var $6056=$1914; + var $6057=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6058=(($6056+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6059=$1915; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1910=$6057; + $1911=$6058; + $1912=$6059; + var $6060=$1910; + var $6061=$1911; + var $6062=HEAP32[(($6061)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6063=$6060; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6063)>>2)]=$6062; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6064=(($6061+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6065=HEAP32[(($6064)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6066=$6060; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6067=HEAP32[(($6066)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6068=((($6067)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6069=$6068; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6070=HEAP32[(($6069)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6071=$6060; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6072=(($6071+$6070)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6073=$6072; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6073)>>2)]=$6065; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6074=(($6060+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6074)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6075=$6060; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6076=HEAP32[(($6075)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6077=((($6076)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6078=$6077; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6079=HEAP32[(($6078)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6080=$6060; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6081=(($6080+$6079)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6082=$6081; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6083=$1912; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1908=$6082; + $1909=$6083; + var $6084=$1908; + var $6085=$6084; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6086=$1909; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6087=$6086; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($6085, $6087) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 667; break; } else { label = 683; break; } + case 667: + var $6088=(($6084+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6088)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $6089=(($6084+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6089)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $6090=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6091=(($6090+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6092=$6091; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6093=(($6056+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1906=$6092; + $1907=$6093; + var $6094=$1906; + var $6095=$1907; + var $6096=HEAP32[(($6095)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6097=$6094; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6097)>>2)]=$6096; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6098=(($6095+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6099=HEAP32[(($6098)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6100=$6094; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6101=HEAP32[(($6100)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6102=((($6101)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6103=$6102; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6104=HEAP32[(($6103)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6105=$6094; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6106=(($6105+$6104)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6107=$6106; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6107)>>2)]=$6099; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6108=HEAP32[(($6056)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6109=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6109)>>2)]=$6108; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6110=(($6056+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6111=HEAP32[(($6110)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6112=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6113=HEAP32[(($6112)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6114=((($6113)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6115=$6114; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6116=HEAP32[(($6115)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6117=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6118=(($6117+$6116)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6119=$6118; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6119)>>2)]=$6111; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6120=(($6056+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6121=HEAP32[(($6120)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6122=$6055; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6123=(($6122+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6124=$6123; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6124)>>2)]=$6121; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6125=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6125)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6126=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6127=(($6126+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6128=$6127; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6128)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6129=$6036; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6130=(($6129+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6131=$6130; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6131)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6132=(($6036+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6133=$1946; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1941=$6132; + $1942=$6133; + var $6134=$1941; + var $6135=$1942; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1936=$6134; + $1937=$6135; + var $6136=$1936; + var $6137=$6136; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($6137) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 668; break; } else { label = 684; break; } + case 668: + var $6138=$6136; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6138)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6139=(($6136+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1935=$6139; + var $6140=$1935; + $1934=$6140; + var $6141=$1934; + var $6142=$6141; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6143=(($6141)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1933=$6143; + var $6144=$1933; + $1932=$6144; + var $6145=$1932; + var $6146=$6145; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1931=$6146; + var $6147=$1931; + var $6148=$6147; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1930=$6148; + var $6149=$1930; + var $6150=(($6147)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1929=$6141; + var $6151=$1929; + var $6152=(($6151)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1928=$6152; + var $6153=$1928; + var $6154=$6153; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1927=$6154; + var $6155=$1927; + var $6156=(($6155)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6157=(($6156)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6158=$6157; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6159=(($6158)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i162=$6159; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i163=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 669; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 669: + var $6161=$__i_i_i_i_i_i_i163; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6162=(($6161)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6162) { label = 670; break; } else { label = 671; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 670: + var $6164=$__i_i_i_i_i_i_i163; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6165=$__a_i_i_i_i_i_i162; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6166=(($6165+($6164<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6166)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6167=$__i_i_i_i_i_i_i163; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6168=((($6167)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i163=$6168; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 669; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 671: + var $6169=(($6136+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6169)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6170=(($6136+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6171=$1937; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6170)>>2)]=$6171; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1926=$1940; + var $6172=$1926; + $1925=$6172; + var $6173=$1925; + var $6174=$6173; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6175=(($6173)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1924=$6175; + var $6176=$1924; + $1923=$6176; + var $6177=$1923; + var $6178=$6177; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1922=$6178; + var $6179=$1922; + var $6180=$6179; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1921=$6180; + var $6181=$1921; + var $6182=(($6179)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1920=$6173; + var $6183=$1920; + var $6184=(($6183)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1919=$6184; + var $6185=$1919; + var $6186=$6185; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1918=$6186; + var $6187=$1918; + var $6188=(($6187)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6189=(($6188)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6190=$6189; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6191=(($6190)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i160=$6191; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i161=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 672; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 672: + var $6193=$__i_i_i_i2_i_i_i161; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6194=(($6193)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6194) { label = 673; break; } else { label = 674; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 673: + var $6196=$__i_i_i_i2_i_i_i161; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6197=$__a_i_i_i1_i_i_i160; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6198=(($6197+($6196<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6198)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6199=$__i_i_i_i2_i_i_i161; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6200=((($6199)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i161=$6200; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 672; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 674: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($6136, $1940) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 675; break; } else { label = 677; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 675: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1940) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 690; break; } else { label = 676; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 676: + var $6203$0 = ___cxa_find_matching_catch(-1, -1); $6203$1 = tempRet0; + var $6204=$6203$0; + $1938=$6204; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6205=$6203$1; + $1939=$6205; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 679; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 677: + var $6207$0 = ___cxa_find_matching_catch(-1, -1); $6207$1 = tempRet0; + var $6208=$6207$0; + $1938=$6208; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6209=$6207$1; + $1939=$6209; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1940) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 678; break; } else { label = 682; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 678: + label = 679; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 679: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($6139) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 680; break; } else { label = 682; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 680: + var $6213=$6136; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($6213) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 681; break; } else { label = 682; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 681: + var $6215=$1938; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6216=$1939; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6217$0=$6215; + var $6217$1=0; + var $6218$0=$6217$0; + var $6218$1=$6216; + var $eh_lpad_body_i168$1 = $6218$1;var $eh_lpad_body_i168$0 = $6218$0;label = 685; break; + case 682: + var $6220$0 = ___cxa_find_matching_catch(-1, -1,0); $6220$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 683: + var $6222$0 = ___cxa_find_matching_catch(-1, -1); $6222$1 = tempRet0; + var $6223=$6222$0; + $1947=$6223; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6224=$6222$1; + $1948=$6224; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 687; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 684: + var $6226$0 = ___cxa_find_matching_catch(-1, -1); $6226$1 = tempRet0; + var $eh_lpad_body_i168$1 = $6226$1;var $eh_lpad_body_i168$0 = $6226$0;label = 685; break; + case 685: + var $eh_lpad_body_i168$0; + var $eh_lpad_body_i168$1; + var $6227=$eh_lpad_body_i168$0; + $1947=$6227; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6228=$eh_lpad_body_i168$1; + $1948=$6228; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6229=$6036; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($6229, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 686; break; } else { label = 689; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 686: + label = 687; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 687: + var $6232=$6036; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6233=(($6232+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6234=$6233; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($6234) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 688; break; } else { label = 689; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 688: + var $6236=$1947; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6237=$1948; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6238$0=$6236; + var $6238$1=0; + var $6239$0=$6238$0; + var $6239$1=$6237; + ___resumeException($6239$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 689: + var $6241$0 = ___cxa_find_matching_catch(-1, -1,0); $6241$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 690: + var $6242=$std_stringstream10; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6243=(($6242+8)|0); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6244=$6243; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6245 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6244, ((3256)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 691; break; } else { label = 712; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 691: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2605, ((4544)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 692; break; } else { label = 712; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 692: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2604, $2605, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 693; break; } else { label = 713; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 693: + var $6249 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($6245, $2604) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 694; break; } else { label = 714; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 694: + var $6251 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6249, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 695; break; } else { label = 714; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 695: + var $6253 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6251, ((4288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 696; break; } else { label = 714; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 696: + var $6255 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6253, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 697; break; } else { label = 714; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 697: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2604) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 698; break; } else { label = 713; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 698: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2605) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 699; break; } else { label = 712; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 699: + var $6259=___cxa_allocate_exception(8); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2607=1; + var $6260=$6259; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1905=$std_stringstream10; + var $6261=$1905; + var $6262=(($6261+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2606, $6262) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 700; break; } else { label = 718; break; } + case 700: + label = 701; break; + case 701: + $1904=$2606; + var $6264=$1904; + $1903=$6264; + var $6265=$1903; + $1902=$6265; + var $6266=$1902; + $1901=$6266; + var $6267=$1901; + var $6268=(($6267)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1900=$6268; + var $6269=$1900; + var $6270=$6269; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1899=$6270; + var $6271=$1899; + var $6272=(($6271)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6273=(($6272)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6274=$6273; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6275=(($6274)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6276=$6275; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6277=HEAP8[($6276)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6278=(($6277)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6279=$6278 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6280=(($6279)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($6280) { label = 702; break; } else { label = 703; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 702: + $1893=$6266; + var $6282=$1893; + var $6283=(($6282)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1892=$6283; + var $6284=$1892; + var $6285=$6284; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1891=$6285; + var $6286=$1891; + var $6287=(($6286)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6288=(($6287)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6289=$6288; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6290=(($6289+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6291=HEAP32[(($6290)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6305 = $6291;label = 704; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 703: + $1898=$6266; + var $6293=$1898; + var $6294=(($6293)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1897=$6294; + var $6295=$1897; + var $6296=$6295; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1896=$6296; + var $6297=$1896; + var $6298=(($6297)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6299=(($6298)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6300=$6299; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6301=(($6300+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6302=(($6301)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1895=$6302; + var $6303=$1895; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1894=$6303; + var $6304=$1894; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $6305 = $6304;label = 704; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 704: + var $6305; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1890=$6305; + var $6306=$1890; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($6260, $6306) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 705; break; } else { label = 719; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 705: + $2607=0; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($6259, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 719; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2606) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 706; break; } else { label = 718; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 706: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream10); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 726; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 707: + var $6311$0 = ___cxa_find_matching_catch(-1, -1); $6311$1 = tempRet0; + var $6312=$6311$0; + $2542=$6312; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6313=$6311$1; + $2543=$6313; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 710; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 708: + var $6315$0 = ___cxa_find_matching_catch(-1, -1); $6315$1 = tempRet0; + var $6316=$6315$0; + $2542=$6316; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6317=$6315$1; + $2543=$6317; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2602) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 709; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 709: + label = 710; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 710: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2603) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 711; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 711: + label = 2840; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 712: + var $6322$0 = ___cxa_find_matching_catch(-1, -1); $6322$1 = tempRet0; + var $6323=$6322$0; + $2542=$6323; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6324=$6322$1; + $2543=$6324; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 724; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 713: + var $6326$0 = ___cxa_find_matching_catch(-1, -1); $6326$1 = tempRet0; + var $6327=$6326$0; + $2542=$6327; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6328=$6326$1; + $2543=$6328; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 716; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 714: + var $6330$0 = ___cxa_find_matching_catch(-1, -1); $6330$1 = tempRet0; + var $6331=$6330$0; + $2542=$6331; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6332=$6330$1; + $2543=$6332; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2604) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 715; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 715: + label = 716; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 716: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2605) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 717; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 717: + label = 724; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 718: + var $6337$0 = ___cxa_find_matching_catch(-1, -1); $6337$1 = tempRet0; + var $6338=$6337$0; + $2542=$6338; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6339=$6337$1; + $2543=$6339; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 721; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 719: + var $6341$0 = ___cxa_find_matching_catch(-1, -1); $6341$1 = tempRet0; + var $6342=$6341$0; + $2542=$6342; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6343=$6341$1; + $2543=$6343; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2606) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 720; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 720: + label = 721; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 721: + var $6346=$2607; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6346) { label = 722; break; } else { label = 723; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 722: + ___cxa_free_exception($6259); //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 723; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 723: + label = 724; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 724: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream10) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 725; break; } else { label = 2841; break; } //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 725: + label = 2840; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 726: + label = 727; break; //@line 146 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 727: + label = 728; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 728: + __ZN6StringC1EPKc($2609, ((2744)|0)); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2608, $2609, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 729; break; } else { label = 773; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 729: + var $6355 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2608, ((4288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 730; break; } else { label = 774; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 730: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2608) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 731; break; } else { label = 773; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 731: + __ZN6StringD1Ev($2609); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6355) { label = 732; break; } else { label = 792; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 732: + $1886=$std_stringstream11; + $1887=24; + var $6359=$1886; + var $6360=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6361=(($6360+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6362=$6361; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1885=$6362; + var $6363=$1885; + var $6364=$6363; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1884=$6364; + var $6365=$1884; + var $6366=$6365; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6366)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $6367=$6363; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6367)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $6368=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6368)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6369=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6370=(($6369+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6371=$6370; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6371)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6372=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6373=(($6372+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6374=$6373; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6374)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6375=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6376=(($6359+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6377=$6376; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1854=$6375; + $1855=((109796)|0); + $1856=$6377; + var $6378=$1854; + var $6379=$1855; + var $6380=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6381=(($6379+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6382=$1856; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1851=$6380; + $1852=$6381; + $1853=$6382; + var $6383=$1851; + var $6384=$1852; + var $6385=HEAP32[(($6384)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6386=$6383; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6386)>>2)]=$6385; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6387=(($6384+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6388=HEAP32[(($6387)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6389=$6383; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6390=HEAP32[(($6389)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6391=((($6390)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6392=$6391; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6393=HEAP32[(($6392)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6394=$6383; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6395=(($6394+$6393)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6396=$6395; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6396)>>2)]=$6388; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6397=(($6383+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6397)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6398=$6383; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6399=HEAP32[(($6398)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6400=((($6399)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6401=$6400; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6402=HEAP32[(($6401)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6403=$6383; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6404=(($6403+$6402)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6405=$6404; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6406=$1853; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1849=$6405; + $1850=$6406; + var $6407=$1849; + var $6408=$6407; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6409=$1850; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6410=$6409; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($6408, $6410) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 733; break; } else { label = 749; break; } + case 733: + var $6411=(($6407+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6411)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $6412=(($6407+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6412)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $6413=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6414=(($6413+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6415=$6414; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6416=(($6379+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1847=$6415; + $1848=$6416; + var $6417=$1847; + var $6418=$1848; + var $6419=HEAP32[(($6418)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6420=$6417; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6420)>>2)]=$6419; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6421=(($6418+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6422=HEAP32[(($6421)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6423=$6417; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6424=HEAP32[(($6423)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6425=((($6424)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6426=$6425; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6427=HEAP32[(($6426)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6428=$6417; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6429=(($6428+$6427)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6430=$6429; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6430)>>2)]=$6422; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6431=HEAP32[(($6379)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6432=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6432)>>2)]=$6431; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6433=(($6379+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6434=HEAP32[(($6433)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6435=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6436=HEAP32[(($6435)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6437=((($6436)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6438=$6437; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6439=HEAP32[(($6438)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6440=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6441=(($6440+$6439)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6442=$6441; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6442)>>2)]=$6434; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6443=(($6379+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6444=HEAP32[(($6443)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6445=$6378; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6446=(($6445+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6447=$6446; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6447)>>2)]=$6444; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6448=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6448)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6449=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6450=(($6449+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6451=$6450; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6451)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6452=$6359; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6453=(($6452+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6454=$6453; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6454)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6455=(($6359+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6456=$1887; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1882=$6455; + $1883=$6456; + var $6457=$1882; + var $6458=$1883; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1877=$6457; + $1878=$6458; + var $6459=$1877; + var $6460=$6459; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($6460) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 734; break; } else { label = 750; break; } + case 734: + var $6461=$6459; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6461)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6462=(($6459+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1876=$6462; + var $6463=$1876; + $1875=$6463; + var $6464=$1875; + var $6465=$6464; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6466=(($6464)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1874=$6466; + var $6467=$1874; + $1873=$6467; + var $6468=$1873; + var $6469=$6468; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1872=$6469; + var $6470=$1872; + var $6471=$6470; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1871=$6471; + var $6472=$1871; + var $6473=(($6470)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1870=$6464; + var $6474=$1870; + var $6475=(($6474)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1869=$6475; + var $6476=$1869; + var $6477=$6476; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1868=$6477; + var $6478=$1868; + var $6479=(($6478)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6480=(($6479)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6481=$6480; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6482=(($6481)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i175=$6482; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i176=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 735; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 735: + var $6484=$__i_i_i_i_i_i_i176; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6485=(($6484)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6485) { label = 736; break; } else { label = 737; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 736: + var $6487=$__i_i_i_i_i_i_i176; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6488=$__a_i_i_i_i_i_i175; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6489=(($6488+($6487<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6489)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6490=$__i_i_i_i_i_i_i176; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6491=((($6490)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i176=$6491; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 735; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 737: + var $6492=(($6459+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6492)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6493=(($6459+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6494=$1878; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6493)>>2)]=$6494; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1867=$1881; + var $6495=$1867; + $1866=$6495; + var $6496=$1866; + var $6497=$6496; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6498=(($6496)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1865=$6498; + var $6499=$1865; + $1864=$6499; + var $6500=$1864; + var $6501=$6500; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1863=$6501; + var $6502=$1863; + var $6503=$6502; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1862=$6503; + var $6504=$1862; + var $6505=(($6502)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1861=$6496; + var $6506=$1861; + var $6507=(($6506)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1860=$6507; + var $6508=$1860; + var $6509=$6508; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1859=$6509; + var $6510=$1859; + var $6511=(($6510)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6512=(($6511)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6513=$6512; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6514=(($6513)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i173=$6514; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i174=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 738; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 738: + var $6516=$__i_i_i_i2_i_i_i174; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6517=(($6516)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6517) { label = 739; break; } else { label = 740; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 739: + var $6519=$__i_i_i_i2_i_i_i174; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6520=$__a_i_i_i1_i_i_i173; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6521=(($6520+($6519<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6521)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6522=$__i_i_i_i2_i_i_i174; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6523=((($6522)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i174=$6523; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 738; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 740: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($6459, $1881) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 741; break; } else { label = 743; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 741: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1881) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 756; break; } else { label = 742; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 742: + var $6526$0 = ___cxa_find_matching_catch(-1, -1); $6526$1 = tempRet0; + var $6527=$6526$0; + $1879=$6527; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6528=$6526$1; + $1880=$6528; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 745; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 743: + var $6530$0 = ___cxa_find_matching_catch(-1, -1); $6530$1 = tempRet0; + var $6531=$6530$0; + $1879=$6531; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6532=$6530$1; + $1880=$6532; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1881) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 744; break; } else { label = 748; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 744: + label = 745; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 745: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($6462) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 746; break; } else { label = 748; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 746: + var $6536=$6459; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($6536) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 747; break; } else { label = 748; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 747: + var $6538=$1879; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6539=$1880; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6540$0=$6538; + var $6540$1=0; + var $6541$0=$6540$0; + var $6541$1=$6539; + var $eh_lpad_body_i181$1 = $6541$1;var $eh_lpad_body_i181$0 = $6541$0;label = 751; break; + case 748: + var $6543$0 = ___cxa_find_matching_catch(-1, -1,0); $6543$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 749: + var $6545$0 = ___cxa_find_matching_catch(-1, -1); $6545$1 = tempRet0; + var $6546=$6545$0; + $1888=$6546; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6547=$6545$1; + $1889=$6547; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 753; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 750: + var $6549$0 = ___cxa_find_matching_catch(-1, -1); $6549$1 = tempRet0; + var $eh_lpad_body_i181$1 = $6549$1;var $eh_lpad_body_i181$0 = $6549$0;label = 751; break; + case 751: + var $eh_lpad_body_i181$0; + var $eh_lpad_body_i181$1; + var $6550=$eh_lpad_body_i181$0; + $1888=$6550; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6551=$eh_lpad_body_i181$1; + $1889=$6551; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6552=$6359; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($6552, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 752; break; } else { label = 755; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 752: + label = 753; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 753: + var $6555=$6359; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6556=(($6555+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6557=$6556; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($6557) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 754; break; } else { label = 755; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 754: + var $6559=$1888; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6560=$1889; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6561$0=$6559; + var $6561$1=0; + var $6562$0=$6561$0; + var $6562$1=$6560; + ___resumeException($6562$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 755: + var $6564$0 = ___cxa_find_matching_catch(-1, -1,0); $6564$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 756: + var $6565=$std_stringstream11; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6566=(($6565+8)|0); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6567=$6566; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6568 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6567, ((2328)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 757; break; } else { label = 778; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 757: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2611, ((2744)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 758; break; } else { label = 778; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 758: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2610, $2611, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 759; break; } else { label = 779; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 759: + var $6572 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($6568, $2610) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 760; break; } else { label = 780; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 760: + var $6574 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6572, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 761; break; } else { label = 780; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 761: + var $6576 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6574, ((4288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 762; break; } else { label = 780; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 762: + var $6578 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6576, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 763; break; } else { label = 780; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 763: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2610) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 764; break; } else { label = 779; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 764: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2611) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 765; break; } else { label = 778; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 765: + var $6582=___cxa_allocate_exception(8); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2613=1; + var $6583=$6582; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1846=$std_stringstream11; + var $6584=$1846; + var $6585=(($6584+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2612, $6585) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 766; break; } else { label = 784; break; } + case 766: + label = 767; break; + case 767: + $1845=$2612; + var $6587=$1845; + $1844=$6587; + var $6588=$1844; + $1843=$6588; + var $6589=$1843; + $1842=$6589; + var $6590=$1842; + var $6591=(($6590)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1841=$6591; + var $6592=$1841; + var $6593=$6592; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1840=$6593; + var $6594=$1840; + var $6595=(($6594)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6596=(($6595)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6597=$6596; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6598=(($6597)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6599=$6598; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6600=HEAP8[($6599)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6601=(($6600)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6602=$6601 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6603=(($6602)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($6603) { label = 768; break; } else { label = 769; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 768: + $1834=$6589; + var $6605=$1834; + var $6606=(($6605)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1833=$6606; + var $6607=$1833; + var $6608=$6607; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1832=$6608; + var $6609=$1832; + var $6610=(($6609)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6611=(($6610)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6612=$6611; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6613=(($6612+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6614=HEAP32[(($6613)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6628 = $6614;label = 770; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 769: + $1839=$6589; + var $6616=$1839; + var $6617=(($6616)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1838=$6617; + var $6618=$1838; + var $6619=$6618; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1837=$6619; + var $6620=$1837; + var $6621=(($6620)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6622=(($6621)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6623=$6622; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6624=(($6623+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6625=(($6624)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1836=$6625; + var $6626=$1836; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1835=$6626; + var $6627=$1835; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $6628 = $6627;label = 770; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 770: + var $6628; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1831=$6628; + var $6629=$1831; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($6583, $6629) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 771; break; } else { label = 785; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 771: + $2613=0; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($6582, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 785; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2612) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 772; break; } else { label = 784; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 772: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream11); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 792; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 773: + var $6634$0 = ___cxa_find_matching_catch(-1, -1); $6634$1 = tempRet0; + var $6635=$6634$0; + $2542=$6635; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6636=$6634$1; + $2543=$6636; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 776; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 774: + var $6638$0 = ___cxa_find_matching_catch(-1, -1); $6638$1 = tempRet0; + var $6639=$6638$0; + $2542=$6639; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6640=$6638$1; + $2543=$6640; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2608) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 775; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 775: + label = 776; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 776: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2609) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 777; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 777: + label = 2840; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 778: + var $6645$0 = ___cxa_find_matching_catch(-1, -1); $6645$1 = tempRet0; + var $6646=$6645$0; + $2542=$6646; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6647=$6645$1; + $2543=$6647; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 790; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 779: + var $6649$0 = ___cxa_find_matching_catch(-1, -1); $6649$1 = tempRet0; + var $6650=$6649$0; + $2542=$6650; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6651=$6649$1; + $2543=$6651; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 782; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 780: + var $6653$0 = ___cxa_find_matching_catch(-1, -1); $6653$1 = tempRet0; + var $6654=$6653$0; + $2542=$6654; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6655=$6653$1; + $2543=$6655; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2610) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 781; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 781: + label = 782; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 782: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2611) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 783; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 783: + label = 790; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 784: + var $6660$0 = ___cxa_find_matching_catch(-1, -1); $6660$1 = tempRet0; + var $6661=$6660$0; + $2542=$6661; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6662=$6660$1; + $2543=$6662; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 787; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 785: + var $6664$0 = ___cxa_find_matching_catch(-1, -1); $6664$1 = tempRet0; + var $6665=$6664$0; + $2542=$6665; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6666=$6664$1; + $2543=$6666; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2612) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 786; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 786: + label = 787; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 787: + var $6669=$2613; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6669) { label = 788; break; } else { label = 789; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 788: + ___cxa_free_exception($6582); //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 789; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 789: + label = 790; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 790: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream11) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 791; break; } else { label = 2841; break; } //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 791: + label = 2840; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 792: + label = 793; break; //@line 147 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 793: + label = 794; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 794: + __ZN6StringC1EPKc($2615, ((1992)|0)); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2614, $2615, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 795; break; } else { label = 839; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 795: + var $6678 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2614, ((1664)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 796; break; } else { label = 840; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 796: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2614) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 797; break; } else { label = 839; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 797: + __ZN6StringD1Ev($2615); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6678) { label = 798; break; } else { label = 858; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 798: + $1827=$std_stringstream12; + $1828=24; + var $6682=$1827; + var $6683=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6684=(($6683+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6685=$6684; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1826=$6685; + var $6686=$1826; + var $6687=$6686; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1825=$6687; + var $6688=$1825; + var $6689=$6688; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6689)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $6690=$6686; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6690)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $6691=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6691)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6692=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6693=(($6692+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6694=$6693; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6694)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6695=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6696=(($6695+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6697=$6696; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6697)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6698=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6699=(($6682+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6700=$6699; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1795=$6698; + $1796=((109796)|0); + $1797=$6700; + var $6701=$1795; + var $6702=$1796; + var $6703=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6704=(($6702+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6705=$1797; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1792=$6703; + $1793=$6704; + $1794=$6705; + var $6706=$1792; + var $6707=$1793; + var $6708=HEAP32[(($6707)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6709=$6706; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6709)>>2)]=$6708; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6710=(($6707+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6711=HEAP32[(($6710)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6712=$6706; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6713=HEAP32[(($6712)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6714=((($6713)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6715=$6714; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6716=HEAP32[(($6715)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6717=$6706; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6718=(($6717+$6716)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6719=$6718; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6719)>>2)]=$6711; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6720=(($6706+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6720)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $6721=$6706; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6722=HEAP32[(($6721)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6723=((($6722)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6724=$6723; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6725=HEAP32[(($6724)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6726=$6706; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6727=(($6726+$6725)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6728=$6727; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $6729=$1794; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1790=$6728; + $1791=$6729; + var $6730=$1790; + var $6731=$6730; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6732=$1791; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $6733=$6732; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($6731, $6733) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 799; break; } else { label = 815; break; } + case 799: + var $6734=(($6730+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6734)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $6735=(($6730+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($6735)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $6736=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6737=(($6736+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6738=$6737; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6739=(($6702+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1788=$6738; + $1789=$6739; + var $6740=$1788; + var $6741=$1789; + var $6742=HEAP32[(($6741)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6743=$6740; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6743)>>2)]=$6742; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6744=(($6741+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6745=HEAP32[(($6744)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6746=$6740; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6747=HEAP32[(($6746)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6748=((($6747)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6749=$6748; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6750=HEAP32[(($6749)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6751=$6740; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6752=(($6751+$6750)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6753=$6752; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6753)>>2)]=$6745; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $6754=HEAP32[(($6702)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6755=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6755)>>2)]=$6754; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6756=(($6702+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6757=HEAP32[(($6756)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6758=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6759=HEAP32[(($6758)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6760=((($6759)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6761=$6760; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6762=HEAP32[(($6761)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6763=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6764=(($6763+$6762)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6765=$6764; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6765)>>2)]=$6757; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6766=(($6702+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6767=HEAP32[(($6766)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6768=$6701; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6769=(($6768+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6770=$6769; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6770)>>2)]=$6767; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $6771=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6771)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6772=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6773=(($6772+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6774=$6773; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6774)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6775=$6682; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6776=(($6775+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6777=$6776; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6777)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6778=(($6682+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6779=$1828; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1823=$6778; + $1824=$6779; + var $6780=$1823; + var $6781=$1824; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1818=$6780; + $1819=$6781; + var $6782=$1818; + var $6783=$6782; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($6783) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 800; break; } else { label = 816; break; } + case 800: + var $6784=$6782; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6784)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6785=(($6782+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1817=$6785; + var $6786=$1817; + $1816=$6786; + var $6787=$1816; + var $6788=$6787; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6789=(($6787)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1815=$6789; + var $6790=$1815; + $1814=$6790; + var $6791=$1814; + var $6792=$6791; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1813=$6792; + var $6793=$1813; + var $6794=$6793; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1812=$6794; + var $6795=$1812; + var $6796=(($6793)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1811=$6787; + var $6797=$1811; + var $6798=(($6797)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1810=$6798; + var $6799=$1810; + var $6800=$6799; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1809=$6800; + var $6801=$1809; + var $6802=(($6801)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6803=(($6802)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6804=$6803; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6805=(($6804)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i188=$6805; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i189=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 801; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 801: + var $6807=$__i_i_i_i_i_i_i189; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6808=(($6807)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6808) { label = 802; break; } else { label = 803; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 802: + var $6810=$__i_i_i_i_i_i_i189; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6811=$__a_i_i_i_i_i_i188; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6812=(($6811+($6810<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6812)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6813=$__i_i_i_i_i_i_i189; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6814=((($6813)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i189=$6814; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 801; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 803: + var $6815=(($6782+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6815)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6816=(($6782+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $6817=$1819; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($6816)>>2)]=$6817; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1808=$1822; + var $6818=$1808; + $1807=$6818; + var $6819=$1807; + var $6820=$6819; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $6821=(($6819)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1806=$6821; + var $6822=$1806; + $1805=$6822; + var $6823=$1805; + var $6824=$6823; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1804=$6824; + var $6825=$1804; + var $6826=$6825; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1803=$6826; + var $6827=$1803; + var $6828=(($6825)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1802=$6819; + var $6829=$1802; + var $6830=(($6829)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1801=$6830; + var $6831=$1801; + var $6832=$6831; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1800=$6832; + var $6833=$1800; + var $6834=(($6833)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $6835=(($6834)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6836=$6835; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $6837=(($6836)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i186=$6837; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i187=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 804; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 804: + var $6839=$__i_i_i_i2_i_i_i187; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6840=(($6839)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($6840) { label = 805; break; } else { label = 806; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 805: + var $6842=$__i_i_i_i2_i_i_i187; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6843=$__a_i_i_i1_i_i_i186; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6844=(($6843+($6842<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($6844)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $6845=$__i_i_i_i2_i_i_i187; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $6846=((($6845)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i187=$6846; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 804; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 806: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($6782, $1822) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 807; break; } else { label = 809; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 807: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1822) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 822; break; } else { label = 808; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 808: + var $6849$0 = ___cxa_find_matching_catch(-1, -1); $6849$1 = tempRet0; + var $6850=$6849$0; + $1820=$6850; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6851=$6849$1; + $1821=$6851; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 811; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 809: + var $6853$0 = ___cxa_find_matching_catch(-1, -1); $6853$1 = tempRet0; + var $6854=$6853$0; + $1820=$6854; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $6855=$6853$1; + $1821=$6855; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1822) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 810; break; } else { label = 814; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 810: + label = 811; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 811: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($6785) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 812; break; } else { label = 814; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 812: + var $6859=$6782; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($6859) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 813; break; } else { label = 814; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 813: + var $6861=$1820; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6862=$1821; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $6863$0=$6861; + var $6863$1=0; + var $6864$0=$6863$0; + var $6864$1=$6862; + var $eh_lpad_body_i194$1 = $6864$1;var $eh_lpad_body_i194$0 = $6864$0;label = 817; break; + case 814: + var $6866$0 = ___cxa_find_matching_catch(-1, -1,0); $6866$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 815: + var $6868$0 = ___cxa_find_matching_catch(-1, -1); $6868$1 = tempRet0; + var $6869=$6868$0; + $1829=$6869; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6870=$6868$1; + $1830=$6870; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 819; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 816: + var $6872$0 = ___cxa_find_matching_catch(-1, -1); $6872$1 = tempRet0; + var $eh_lpad_body_i194$1 = $6872$1;var $eh_lpad_body_i194$0 = $6872$0;label = 817; break; + case 817: + var $eh_lpad_body_i194$0; + var $eh_lpad_body_i194$1; + var $6873=$eh_lpad_body_i194$0; + $1829=$6873; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6874=$eh_lpad_body_i194$1; + $1830=$6874; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $6875=$6682; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($6875, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 818; break; } else { label = 821; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 818: + label = 819; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 819: + var $6878=$6682; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6879=(($6878+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6880=$6879; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($6880) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 820; break; } else { label = 821; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 820: + var $6882=$1829; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6883=$1830; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $6884$0=$6882; + var $6884$1=0; + var $6885$0=$6884$0; + var $6885$1=$6883; + ___resumeException($6885$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 821: + var $6887$0 = ___cxa_find_matching_catch(-1, -1,0); $6887$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 822: + var $6888=$std_stringstream12; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6889=(($6888+8)|0); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6890=$6889; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6891 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6890, ((1224)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 823; break; } else { label = 844; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 823: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2617, ((1992)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 824; break; } else { label = 844; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 824: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2616, $2617, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 825; break; } else { label = 845; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 825: + var $6895 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($6891, $2616) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 826; break; } else { label = 846; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 826: + var $6897 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6895, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 827; break; } else { label = 846; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 827: + var $6899 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6897, ((1664)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 828; break; } else { label = 846; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 828: + var $6901 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($6899, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 829; break; } else { label = 846; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 829: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2616) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 830; break; } else { label = 845; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 830: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2617) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 831; break; } else { label = 844; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 831: + var $6905=___cxa_allocate_exception(8); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2619=1; + var $6906=$6905; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1787=$std_stringstream12; + var $6907=$1787; + var $6908=(($6907+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2618, $6908) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 832; break; } else { label = 850; break; } + case 832: + label = 833; break; + case 833: + $1786=$2618; + var $6910=$1786; + $1785=$6910; + var $6911=$1785; + $1784=$6911; + var $6912=$1784; + $1783=$6912; + var $6913=$1783; + var $6914=(($6913)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1782=$6914; + var $6915=$1782; + var $6916=$6915; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1781=$6916; + var $6917=$1781; + var $6918=(($6917)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6919=(($6918)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6920=$6919; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6921=(($6920)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6922=$6921; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6923=HEAP8[($6922)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6924=(($6923)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6925=$6924 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $6926=(($6925)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($6926) { label = 834; break; } else { label = 835; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 834: + $1775=$6912; + var $6928=$1775; + var $6929=(($6928)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1774=$6929; + var $6930=$1774; + var $6931=$6930; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1773=$6931; + var $6932=$1773; + var $6933=(($6932)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6934=(($6933)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6935=$6934; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6936=(($6935+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6937=HEAP32[(($6936)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $6951 = $6937;label = 836; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 835: + $1780=$6912; + var $6939=$1780; + var $6940=(($6939)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1779=$6940; + var $6941=$1779; + var $6942=$6941; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1778=$6942; + var $6943=$1778; + var $6944=(($6943)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $6945=(($6944)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6946=$6945; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6947=(($6946+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $6948=(($6947)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1777=$6948; + var $6949=$1777; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1776=$6949; + var $6950=$1776; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $6951 = $6950;label = 836; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 836: + var $6951; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1772=$6951; + var $6952=$1772; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($6906, $6952) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 837; break; } else { label = 851; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 837: + $2619=0; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($6905, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 851; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2618) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 838; break; } else { label = 850; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 838: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream12); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 858; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 839: + var $6957$0 = ___cxa_find_matching_catch(-1, -1); $6957$1 = tempRet0; + var $6958=$6957$0; + $2542=$6958; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6959=$6957$1; + $2543=$6959; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 842; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 840: + var $6961$0 = ___cxa_find_matching_catch(-1, -1); $6961$1 = tempRet0; + var $6962=$6961$0; + $2542=$6962; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6963=$6961$1; + $2543=$6963; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2614) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 841; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 841: + label = 842; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 842: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2615) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 843; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 843: + label = 2840; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 844: + var $6968$0 = ___cxa_find_matching_catch(-1, -1); $6968$1 = tempRet0; + var $6969=$6968$0; + $2542=$6969; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6970=$6968$1; + $2543=$6970; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 856; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 845: + var $6972$0 = ___cxa_find_matching_catch(-1, -1); $6972$1 = tempRet0; + var $6973=$6972$0; + $2542=$6973; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6974=$6972$1; + $2543=$6974; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 848; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 846: + var $6976$0 = ___cxa_find_matching_catch(-1, -1); $6976$1 = tempRet0; + var $6977=$6976$0; + $2542=$6977; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6978=$6976$1; + $2543=$6978; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2616) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 847; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 847: + label = 848; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 848: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2617) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 849; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 849: + label = 856; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 850: + var $6983$0 = ___cxa_find_matching_catch(-1, -1); $6983$1 = tempRet0; + var $6984=$6983$0; + $2542=$6984; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6985=$6983$1; + $2543=$6985; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 853; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 851: + var $6987$0 = ___cxa_find_matching_catch(-1, -1); $6987$1 = tempRet0; + var $6988=$6987$0; + $2542=$6988; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $6989=$6987$1; + $2543=$6989; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2618) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 852; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 852: + label = 853; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 853: + var $6992=$2619; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($6992) { label = 854; break; } else { label = 855; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 854: + ___cxa_free_exception($6905); //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 855; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 855: + label = 856; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 856: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream12) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 857; break; } else { label = 2841; break; } //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 857: + label = 2840; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 858: + label = 859; break; //@line 148 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 859: + label = 860; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 860: + __ZN6StringC1EPKc($2621, ((912)|0)); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2620, $2621, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 861; break; } else { label = 905; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 861: + var $7001 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2620, ((1664)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 862; break; } else { label = 906; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 862: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2620) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 863; break; } else { label = 905; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 863: + __ZN6StringD1Ev($2621); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7001) { label = 864; break; } else { label = 924; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 864: + $1768=$std_stringstream13; + $1769=24; + var $7005=$1768; + var $7006=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7007=(($7006+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7008=$7007; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1767=$7008; + var $7009=$1767; + var $7010=$7009; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1766=$7010; + var $7011=$1766; + var $7012=$7011; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7012)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $7013=$7009; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7013)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $7014=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7014)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7015=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7016=(($7015+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7017=$7016; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7017)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7018=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7019=(($7018+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7020=$7019; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7020)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7021=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7022=(($7005+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7023=$7022; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1736=$7021; + $1737=((109796)|0); + $1738=$7023; + var $7024=$1736; + var $7025=$1737; + var $7026=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7027=(($7025+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7028=$1738; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1733=$7026; + $1734=$7027; + $1735=$7028; + var $7029=$1733; + var $7030=$1734; + var $7031=HEAP32[(($7030)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7032=$7029; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7032)>>2)]=$7031; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7033=(($7030+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7034=HEAP32[(($7033)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7035=$7029; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7036=HEAP32[(($7035)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7037=((($7036)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7038=$7037; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7039=HEAP32[(($7038)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7040=$7029; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7041=(($7040+$7039)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7042=$7041; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7042)>>2)]=$7034; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7043=(($7029+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7043)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7044=$7029; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7045=HEAP32[(($7044)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7046=((($7045)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7047=$7046; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7048=HEAP32[(($7047)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7049=$7029; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7050=(($7049+$7048)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7051=$7050; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7052=$1735; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1731=$7051; + $1732=$7052; + var $7053=$1731; + var $7054=$7053; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7055=$1732; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7056=$7055; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($7054, $7056) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 865; break; } else { label = 881; break; } + case 865: + var $7057=(($7053+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7057)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $7058=(($7053+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7058)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $7059=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7060=(($7059+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7061=$7060; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7062=(($7025+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1729=$7061; + $1730=$7062; + var $7063=$1729; + var $7064=$1730; + var $7065=HEAP32[(($7064)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7066=$7063; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7066)>>2)]=$7065; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7067=(($7064+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7068=HEAP32[(($7067)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7069=$7063; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7070=HEAP32[(($7069)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7071=((($7070)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7072=$7071; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7073=HEAP32[(($7072)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7074=$7063; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7075=(($7074+$7073)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7076=$7075; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7076)>>2)]=$7068; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7077=HEAP32[(($7025)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7078=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7078)>>2)]=$7077; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7079=(($7025+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7080=HEAP32[(($7079)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7081=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7082=HEAP32[(($7081)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7083=((($7082)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7084=$7083; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7085=HEAP32[(($7084)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7086=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7087=(($7086+$7085)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7088=$7087; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7088)>>2)]=$7080; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7089=(($7025+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7090=HEAP32[(($7089)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7091=$7024; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7092=(($7091+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7093=$7092; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7093)>>2)]=$7090; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7094=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7094)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7095=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7096=(($7095+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7097=$7096; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7097)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7098=$7005; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7099=(($7098+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7100=$7099; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7100)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7101=(($7005+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7102=$1769; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1764=$7101; + $1765=$7102; + var $7103=$1764; + var $7104=$1765; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1759=$7103; + $1760=$7104; + var $7105=$1759; + var $7106=$7105; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($7106) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 866; break; } else { label = 882; break; } + case 866: + var $7107=$7105; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7107)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7108=(($7105+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1758=$7108; + var $7109=$1758; + $1757=$7109; + var $7110=$1757; + var $7111=$7110; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7112=(($7110)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1756=$7112; + var $7113=$1756; + $1755=$7113; + var $7114=$1755; + var $7115=$7114; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1754=$7115; + var $7116=$1754; + var $7117=$7116; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1753=$7117; + var $7118=$1753; + var $7119=(($7116)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1752=$7110; + var $7120=$1752; + var $7121=(($7120)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1751=$7121; + var $7122=$1751; + var $7123=$7122; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1750=$7123; + var $7124=$1750; + var $7125=(($7124)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7126=(($7125)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7127=$7126; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7128=(($7127)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i201=$7128; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i202=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 867; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 867: + var $7130=$__i_i_i_i_i_i_i202; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7131=(($7130)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7131) { label = 868; break; } else { label = 869; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 868: + var $7133=$__i_i_i_i_i_i_i202; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7134=$__a_i_i_i_i_i_i201; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7135=(($7134+($7133<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7135)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7136=$__i_i_i_i_i_i_i202; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7137=((($7136)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i202=$7137; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 867; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 869: + var $7138=(($7105+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7138)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7139=(($7105+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7140=$1760; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7139)>>2)]=$7140; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1749=$1763; + var $7141=$1749; + $1748=$7141; + var $7142=$1748; + var $7143=$7142; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7144=(($7142)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1747=$7144; + var $7145=$1747; + $1746=$7145; + var $7146=$1746; + var $7147=$7146; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1745=$7147; + var $7148=$1745; + var $7149=$7148; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1744=$7149; + var $7150=$1744; + var $7151=(($7148)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1743=$7142; + var $7152=$1743; + var $7153=(($7152)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1742=$7153; + var $7154=$1742; + var $7155=$7154; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1741=$7155; + var $7156=$1741; + var $7157=(($7156)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7158=(($7157)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7159=$7158; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7160=(($7159)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i199=$7160; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i200=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 870; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 870: + var $7162=$__i_i_i_i2_i_i_i200; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7163=(($7162)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7163) { label = 871; break; } else { label = 872; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 871: + var $7165=$__i_i_i_i2_i_i_i200; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7166=$__a_i_i_i1_i_i_i199; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7167=(($7166+($7165<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7167)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7168=$__i_i_i_i2_i_i_i200; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7169=((($7168)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i200=$7169; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 870; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 872: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($7105, $1763) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 873; break; } else { label = 875; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 873: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1763) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 888; break; } else { label = 874; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 874: + var $7172$0 = ___cxa_find_matching_catch(-1, -1); $7172$1 = tempRet0; + var $7173=$7172$0; + $1761=$7173; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7174=$7172$1; + $1762=$7174; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 877; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 875: + var $7176$0 = ___cxa_find_matching_catch(-1, -1); $7176$1 = tempRet0; + var $7177=$7176$0; + $1761=$7177; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7178=$7176$1; + $1762=$7178; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1763) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 876; break; } else { label = 880; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 876: + label = 877; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 877: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($7108) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 878; break; } else { label = 880; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 878: + var $7182=$7105; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($7182) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 879; break; } else { label = 880; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 879: + var $7184=$1761; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7185=$1762; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7186$0=$7184; + var $7186$1=0; + var $7187$0=$7186$0; + var $7187$1=$7185; + var $eh_lpad_body_i207$1 = $7187$1;var $eh_lpad_body_i207$0 = $7187$0;label = 883; break; + case 880: + var $7189$0 = ___cxa_find_matching_catch(-1, -1,0); $7189$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 881: + var $7191$0 = ___cxa_find_matching_catch(-1, -1); $7191$1 = tempRet0; + var $7192=$7191$0; + $1770=$7192; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7193=$7191$1; + $1771=$7193; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 885; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 882: + var $7195$0 = ___cxa_find_matching_catch(-1, -1); $7195$1 = tempRet0; + var $eh_lpad_body_i207$1 = $7195$1;var $eh_lpad_body_i207$0 = $7195$0;label = 883; break; + case 883: + var $eh_lpad_body_i207$0; + var $eh_lpad_body_i207$1; + var $7196=$eh_lpad_body_i207$0; + $1770=$7196; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7197=$eh_lpad_body_i207$1; + $1771=$7197; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7198=$7005; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($7198, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 884; break; } else { label = 887; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 884: + label = 885; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 885: + var $7201=$7005; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7202=(($7201+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7203=$7202; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($7203) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 886; break; } else { label = 887; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 886: + var $7205=$1770; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7206=$1771; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7207$0=$7205; + var $7207$1=0; + var $7208$0=$7207$0; + var $7208$1=$7206; + ___resumeException($7208$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 887: + var $7210$0 = ___cxa_find_matching_catch(-1, -1,0); $7210$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 888: + var $7211=$std_stringstream13; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7212=(($7211+8)|0); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7213=$7212; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7214 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7213, ((456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 889; break; } else { label = 910; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 889: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2623, ((912)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 890; break; } else { label = 910; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 890: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2622, $2623, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 891; break; } else { label = 911; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 891: + var $7218 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($7214, $2622) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 892; break; } else { label = 912; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 892: + var $7220 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7218, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 893; break; } else { label = 912; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 893: + var $7222 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7220, ((1664)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 894; break; } else { label = 912; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 894: + var $7224 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7222, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 895; break; } else { label = 912; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 895: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2622) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 896; break; } else { label = 911; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 896: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2623) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 897; break; } else { label = 910; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 897: + var $7228=___cxa_allocate_exception(8); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2625=1; + var $7229=$7228; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1728=$std_stringstream13; + var $7230=$1728; + var $7231=(($7230+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2624, $7231) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 898; break; } else { label = 916; break; } + case 898: + label = 899; break; + case 899: + $1727=$2624; + var $7233=$1727; + $1726=$7233; + var $7234=$1726; + $1725=$7234; + var $7235=$1725; + $1724=$7235; + var $7236=$1724; + var $7237=(($7236)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1723=$7237; + var $7238=$1723; + var $7239=$7238; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1722=$7239; + var $7240=$1722; + var $7241=(($7240)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7242=(($7241)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7243=$7242; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7244=(($7243)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7245=$7244; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7246=HEAP8[($7245)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7247=(($7246)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7248=$7247 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7249=(($7248)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($7249) { label = 900; break; } else { label = 901; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 900: + $1716=$7235; + var $7251=$1716; + var $7252=(($7251)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1715=$7252; + var $7253=$1715; + var $7254=$7253; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1714=$7254; + var $7255=$1714; + var $7256=(($7255)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7257=(($7256)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7258=$7257; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7259=(($7258+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7260=HEAP32[(($7259)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7274 = $7260;label = 902; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 901: + $1721=$7235; + var $7262=$1721; + var $7263=(($7262)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1720=$7263; + var $7264=$1720; + var $7265=$7264; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1719=$7265; + var $7266=$1719; + var $7267=(($7266)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7268=(($7267)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7269=$7268; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7270=(($7269+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7271=(($7270)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1718=$7271; + var $7272=$1718; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1717=$7272; + var $7273=$1717; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $7274 = $7273;label = 902; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 902: + var $7274; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1713=$7274; + var $7275=$1713; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($7229, $7275) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 903; break; } else { label = 917; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 903: + $2625=0; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($7228, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 917; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2624) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 904; break; } else { label = 916; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 904: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream13); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 924; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 905: + var $7280$0 = ___cxa_find_matching_catch(-1, -1); $7280$1 = tempRet0; + var $7281=$7280$0; + $2542=$7281; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7282=$7280$1; + $2543=$7282; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 908; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 906: + var $7284$0 = ___cxa_find_matching_catch(-1, -1); $7284$1 = tempRet0; + var $7285=$7284$0; + $2542=$7285; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7286=$7284$1; + $2543=$7286; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2620) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 907; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 907: + label = 908; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 908: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2621) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 909; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 909: + label = 2840; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 910: + var $7291$0 = ___cxa_find_matching_catch(-1, -1); $7291$1 = tempRet0; + var $7292=$7291$0; + $2542=$7292; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7293=$7291$1; + $2543=$7293; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 922; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 911: + var $7295$0 = ___cxa_find_matching_catch(-1, -1); $7295$1 = tempRet0; + var $7296=$7295$0; + $2542=$7296; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7297=$7295$1; + $2543=$7297; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 914; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 912: + var $7299$0 = ___cxa_find_matching_catch(-1, -1); $7299$1 = tempRet0; + var $7300=$7299$0; + $2542=$7300; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7301=$7299$1; + $2543=$7301; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2622) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 913; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 913: + label = 914; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 914: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2623) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 915; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 915: + label = 922; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 916: + var $7306$0 = ___cxa_find_matching_catch(-1, -1); $7306$1 = tempRet0; + var $7307=$7306$0; + $2542=$7307; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7308=$7306$1; + $2543=$7308; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 919; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 917: + var $7310$0 = ___cxa_find_matching_catch(-1, -1); $7310$1 = tempRet0; + var $7311=$7310$0; + $2542=$7311; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7312=$7310$1; + $2543=$7312; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2624) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 918; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 918: + label = 919; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 919: + var $7315=$2625; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7315) { label = 920; break; } else { label = 921; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 920: + ___cxa_free_exception($7228); //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 921; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 921: + label = 922; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 922: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream13) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 923; break; } else { label = 2841; break; } //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 923: + label = 2840; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 924: + label = 925; break; //@line 149 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 925: + label = 926; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 926: + __ZN6StringC1EPKc($2627, ((1992)|0)); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2626, $2627, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 927; break; } else { label = 971; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 927: + var $7324 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2626, ((101424)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 928; break; } else { label = 972; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 928: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2626) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 929; break; } else { label = 971; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 929: + __ZN6StringD1Ev($2627); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7324) { label = 930; break; } else { label = 990; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 930: + $1709=$std_stringstream14; + $1710=24; + var $7328=$1709; + var $7329=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7330=(($7329+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7331=$7330; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1708=$7331; + var $7332=$1708; + var $7333=$7332; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1707=$7333; + var $7334=$1707; + var $7335=$7334; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7335)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $7336=$7332; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7336)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $7337=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7337)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7338=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7339=(($7338+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7340=$7339; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7340)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7341=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7342=(($7341+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7343=$7342; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7343)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7344=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7345=(($7328+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7346=$7345; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1677=$7344; + $1678=((109796)|0); + $1679=$7346; + var $7347=$1677; + var $7348=$1678; + var $7349=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7350=(($7348+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7351=$1679; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1674=$7349; + $1675=$7350; + $1676=$7351; + var $7352=$1674; + var $7353=$1675; + var $7354=HEAP32[(($7353)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7355=$7352; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7355)>>2)]=$7354; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7356=(($7353+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7357=HEAP32[(($7356)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7358=$7352; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7359=HEAP32[(($7358)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7360=((($7359)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7361=$7360; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7362=HEAP32[(($7361)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7363=$7352; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7364=(($7363+$7362)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7365=$7364; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7365)>>2)]=$7357; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7366=(($7352+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7366)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7367=$7352; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7368=HEAP32[(($7367)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7369=((($7368)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7370=$7369; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7371=HEAP32[(($7370)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7372=$7352; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7373=(($7372+$7371)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7374=$7373; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7375=$1676; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1672=$7374; + $1673=$7375; + var $7376=$1672; + var $7377=$7376; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7378=$1673; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7379=$7378; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($7377, $7379) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 931; break; } else { label = 947; break; } + case 931: + var $7380=(($7376+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7380)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $7381=(($7376+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7381)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $7382=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7383=(($7382+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7384=$7383; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7385=(($7348+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1670=$7384; + $1671=$7385; + var $7386=$1670; + var $7387=$1671; + var $7388=HEAP32[(($7387)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7389=$7386; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7389)>>2)]=$7388; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7390=(($7387+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7391=HEAP32[(($7390)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7392=$7386; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7393=HEAP32[(($7392)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7394=((($7393)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7395=$7394; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7396=HEAP32[(($7395)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7397=$7386; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7398=(($7397+$7396)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7399=$7398; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7399)>>2)]=$7391; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7400=HEAP32[(($7348)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7401=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7401)>>2)]=$7400; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7402=(($7348+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7403=HEAP32[(($7402)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7404=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7405=HEAP32[(($7404)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7406=((($7405)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7407=$7406; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7408=HEAP32[(($7407)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7409=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7410=(($7409+$7408)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7411=$7410; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7411)>>2)]=$7403; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7412=(($7348+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7413=HEAP32[(($7412)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7414=$7347; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7415=(($7414+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7416=$7415; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7416)>>2)]=$7413; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7417=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7417)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7418=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7419=(($7418+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7420=$7419; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7420)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7421=$7328; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7422=(($7421+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7423=$7422; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7423)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7424=(($7328+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7425=$1710; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1705=$7424; + $1706=$7425; + var $7426=$1705; + var $7427=$1706; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1700=$7426; + $1701=$7427; + var $7428=$1700; + var $7429=$7428; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($7429) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 932; break; } else { label = 948; break; } + case 932: + var $7430=$7428; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7430)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7431=(($7428+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1699=$7431; + var $7432=$1699; + $1698=$7432; + var $7433=$1698; + var $7434=$7433; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7435=(($7433)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1697=$7435; + var $7436=$1697; + $1696=$7436; + var $7437=$1696; + var $7438=$7437; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1695=$7438; + var $7439=$1695; + var $7440=$7439; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1694=$7440; + var $7441=$1694; + var $7442=(($7439)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1693=$7433; + var $7443=$1693; + var $7444=(($7443)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1692=$7444; + var $7445=$1692; + var $7446=$7445; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1691=$7446; + var $7447=$1691; + var $7448=(($7447)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7449=(($7448)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7450=$7449; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7451=(($7450)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i214=$7451; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i215=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 933; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 933: + var $7453=$__i_i_i_i_i_i_i215; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7454=(($7453)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7454) { label = 934; break; } else { label = 935; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 934: + var $7456=$__i_i_i_i_i_i_i215; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7457=$__a_i_i_i_i_i_i214; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7458=(($7457+($7456<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7458)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7459=$__i_i_i_i_i_i_i215; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7460=((($7459)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i215=$7460; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 933; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 935: + var $7461=(($7428+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7461)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7462=(($7428+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7463=$1701; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7462)>>2)]=$7463; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1690=$1704; + var $7464=$1690; + $1689=$7464; + var $7465=$1689; + var $7466=$7465; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7467=(($7465)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1688=$7467; + var $7468=$1688; + $1687=$7468; + var $7469=$1687; + var $7470=$7469; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1686=$7470; + var $7471=$1686; + var $7472=$7471; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1685=$7472; + var $7473=$1685; + var $7474=(($7471)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1684=$7465; + var $7475=$1684; + var $7476=(($7475)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1683=$7476; + var $7477=$1683; + var $7478=$7477; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1682=$7478; + var $7479=$1682; + var $7480=(($7479)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7481=(($7480)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7482=$7481; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7483=(($7482)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i212=$7483; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i213=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 936; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 936: + var $7485=$__i_i_i_i2_i_i_i213; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7486=(($7485)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7486) { label = 937; break; } else { label = 938; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 937: + var $7488=$__i_i_i_i2_i_i_i213; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7489=$__a_i_i_i1_i_i_i212; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7490=(($7489+($7488<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7490)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7491=$__i_i_i_i2_i_i_i213; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7492=((($7491)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i213=$7492; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 936; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 938: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($7428, $1704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 939; break; } else { label = 941; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 939: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 954; break; } else { label = 940; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 940: + var $7495$0 = ___cxa_find_matching_catch(-1, -1); $7495$1 = tempRet0; + var $7496=$7495$0; + $1702=$7496; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7497=$7495$1; + $1703=$7497; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 943; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 941: + var $7499$0 = ___cxa_find_matching_catch(-1, -1); $7499$1 = tempRet0; + var $7500=$7499$0; + $1702=$7500; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7501=$7499$1; + $1703=$7501; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 942; break; } else { label = 946; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 942: + label = 943; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 943: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($7431) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 944; break; } else { label = 946; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 944: + var $7505=$7428; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($7505) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 945; break; } else { label = 946; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 945: + var $7507=$1702; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7508=$1703; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7509$0=$7507; + var $7509$1=0; + var $7510$0=$7509$0; + var $7510$1=$7508; + var $eh_lpad_body_i220$1 = $7510$1;var $eh_lpad_body_i220$0 = $7510$0;label = 949; break; + case 946: + var $7512$0 = ___cxa_find_matching_catch(-1, -1,0); $7512$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 947: + var $7514$0 = ___cxa_find_matching_catch(-1, -1); $7514$1 = tempRet0; + var $7515=$7514$0; + $1711=$7515; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7516=$7514$1; + $1712=$7516; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 951; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 948: + var $7518$0 = ___cxa_find_matching_catch(-1, -1); $7518$1 = tempRet0; + var $eh_lpad_body_i220$1 = $7518$1;var $eh_lpad_body_i220$0 = $7518$0;label = 949; break; + case 949: + var $eh_lpad_body_i220$0; + var $eh_lpad_body_i220$1; + var $7519=$eh_lpad_body_i220$0; + $1711=$7519; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7520=$eh_lpad_body_i220$1; + $1712=$7520; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7521=$7328; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($7521, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 950; break; } else { label = 953; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 950: + label = 951; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 951: + var $7524=$7328; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7525=(($7524+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7526=$7525; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($7526) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 952; break; } else { label = 953; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 952: + var $7528=$1711; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7529=$1712; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7530$0=$7528; + var $7530$1=0; + var $7531$0=$7530$0; + var $7531$1=$7529; + ___resumeException($7531$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 953: + var $7533$0 = ___cxa_find_matching_catch(-1, -1,0); $7533$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 954: + var $7534=$std_stringstream14; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7535=(($7534+8)|0); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7536=$7535; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7537 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7536, ((101040)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 955; break; } else { label = 976; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 955: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2629, ((1992)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 956; break; } else { label = 976; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 956: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2628, $2629, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 957; break; } else { label = 977; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 957: + var $7541 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($7537, $2628) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 958; break; } else { label = 978; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 958: + var $7543 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7541, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 959; break; } else { label = 978; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 959: + var $7545 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7543, ((101424)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 960; break; } else { label = 978; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 960: + var $7547 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7545, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 961; break; } else { label = 978; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 961: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2628) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 962; break; } else { label = 977; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 962: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2629) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 963; break; } else { label = 976; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 963: + var $7551=___cxa_allocate_exception(8); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2631=1; + var $7552=$7551; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1669=$std_stringstream14; + var $7553=$1669; + var $7554=(($7553+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2630, $7554) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 964; break; } else { label = 982; break; } + case 964: + label = 965; break; + case 965: + $1668=$2630; + var $7556=$1668; + $1667=$7556; + var $7557=$1667; + $1666=$7557; + var $7558=$1666; + $1665=$7558; + var $7559=$1665; + var $7560=(($7559)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1664=$7560; + var $7561=$1664; + var $7562=$7561; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1663=$7562; + var $7563=$1663; + var $7564=(($7563)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7565=(($7564)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7566=$7565; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7567=(($7566)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7568=$7567; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7569=HEAP8[($7568)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7570=(($7569)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7571=$7570 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7572=(($7571)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($7572) { label = 966; break; } else { label = 967; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 966: + $1657=$7558; + var $7574=$1657; + var $7575=(($7574)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1656=$7575; + var $7576=$1656; + var $7577=$7576; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1655=$7577; + var $7578=$1655; + var $7579=(($7578)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7580=(($7579)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7581=$7580; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7582=(($7581+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7583=HEAP32[(($7582)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7597 = $7583;label = 968; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 967: + $1662=$7558; + var $7585=$1662; + var $7586=(($7585)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1661=$7586; + var $7587=$1661; + var $7588=$7587; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1660=$7588; + var $7589=$1660; + var $7590=(($7589)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7591=(($7590)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7592=$7591; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7593=(($7592+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7594=(($7593)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1659=$7594; + var $7595=$1659; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1658=$7595; + var $7596=$1658; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $7597 = $7596;label = 968; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 968: + var $7597; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1654=$7597; + var $7598=$1654; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($7552, $7598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 969; break; } else { label = 983; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 969: + $2631=0; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($7551, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 983; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2630) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 970; break; } else { label = 982; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 970: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream14); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 990; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 971: + var $7603$0 = ___cxa_find_matching_catch(-1, -1); $7603$1 = tempRet0; + var $7604=$7603$0; + $2542=$7604; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7605=$7603$1; + $2543=$7605; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 974; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 972: + var $7607$0 = ___cxa_find_matching_catch(-1, -1); $7607$1 = tempRet0; + var $7608=$7607$0; + $2542=$7608; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7609=$7607$1; + $2543=$7609; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2626) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 973; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 973: + label = 974; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 974: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2627) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 975; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 975: + label = 2840; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 976: + var $7614$0 = ___cxa_find_matching_catch(-1, -1); $7614$1 = tempRet0; + var $7615=$7614$0; + $2542=$7615; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7616=$7614$1; + $2543=$7616; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 988; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 977: + var $7618$0 = ___cxa_find_matching_catch(-1, -1); $7618$1 = tempRet0; + var $7619=$7618$0; + $2542=$7619; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7620=$7618$1; + $2543=$7620; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 980; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 978: + var $7622$0 = ___cxa_find_matching_catch(-1, -1); $7622$1 = tempRet0; + var $7623=$7622$0; + $2542=$7623; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7624=$7622$1; + $2543=$7624; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2628) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 979; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 979: + label = 980; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 980: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2629) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 981; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 981: + label = 988; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 982: + var $7629$0 = ___cxa_find_matching_catch(-1, -1); $7629$1 = tempRet0; + var $7630=$7629$0; + $2542=$7630; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7631=$7629$1; + $2543=$7631; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 985; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 983: + var $7633$0 = ___cxa_find_matching_catch(-1, -1); $7633$1 = tempRet0; + var $7634=$7633$0; + $2542=$7634; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7635=$7633$1; + $2543=$7635; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2630) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 984; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 984: + label = 985; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 985: + var $7638=$2631; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7638) { label = 986; break; } else { label = 987; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 986: + ___cxa_free_exception($7551); //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 987; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 987: + label = 988; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 988: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream14) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 989; break; } else { label = 2841; break; } //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 989: + label = 2840; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 990: + label = 991; break; //@line 150 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 991: + label = 992; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 992: + __ZN6StringC1EPKc($2633, ((912)|0)); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2632, $2633, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 993; break; } else { label = 1037; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 993: + var $7647 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2632, ((101424)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 994; break; } else { label = 1038; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 994: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2632) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 995; break; } else { label = 1037; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 995: + __ZN6StringD1Ev($2633); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7647) { label = 996; break; } else { label = 1056; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 996: + $1650=$std_stringstream15; + $1651=24; + var $7651=$1650; + var $7652=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7653=(($7652+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7654=$7653; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1649=$7654; + var $7655=$1649; + var $7656=$7655; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1648=$7656; + var $7657=$1648; + var $7658=$7657; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7658)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $7659=$7655; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7659)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $7660=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7660)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7661=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7662=(($7661+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7663=$7662; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7663)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7664=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7665=(($7664+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7666=$7665; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7666)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7667=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7668=(($7651+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7669=$7668; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1618=$7667; + $1619=((109796)|0); + $1620=$7669; + var $7670=$1618; + var $7671=$1619; + var $7672=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7673=(($7671+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7674=$1620; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1615=$7672; + $1616=$7673; + $1617=$7674; + var $7675=$1615; + var $7676=$1616; + var $7677=HEAP32[(($7676)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7678=$7675; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7678)>>2)]=$7677; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7679=(($7676+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7680=HEAP32[(($7679)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7681=$7675; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7682=HEAP32[(($7681)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7683=((($7682)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7684=$7683; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7685=HEAP32[(($7684)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7686=$7675; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7687=(($7686+$7685)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7688=$7687; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7688)>>2)]=$7680; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7689=(($7675+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7689)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $7690=$7675; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7691=HEAP32[(($7690)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7692=((($7691)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7693=$7692; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7694=HEAP32[(($7693)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7695=$7675; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7696=(($7695+$7694)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7697=$7696; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $7698=$1617; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1613=$7697; + $1614=$7698; + var $7699=$1613; + var $7700=$7699; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7701=$1614; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $7702=$7701; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($7700, $7702) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 997; break; } else { label = 1013; break; } + case 997: + var $7703=(($7699+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7703)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $7704=(($7699+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7704)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $7705=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7706=(($7705+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7707=$7706; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7708=(($7671+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1611=$7707; + $1612=$7708; + var $7709=$1611; + var $7710=$1612; + var $7711=HEAP32[(($7710)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7712=$7709; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7712)>>2)]=$7711; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7713=(($7710+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7714=HEAP32[(($7713)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7715=$7709; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7716=HEAP32[(($7715)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7717=((($7716)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7718=$7717; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7719=HEAP32[(($7718)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7720=$7709; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7721=(($7720+$7719)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7722=$7721; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7722)>>2)]=$7714; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $7723=HEAP32[(($7671)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7724=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7724)>>2)]=$7723; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7725=(($7671+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7726=HEAP32[(($7725)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7727=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7728=HEAP32[(($7727)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7729=((($7728)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7730=$7729; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7731=HEAP32[(($7730)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7732=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7733=(($7732+$7731)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7734=$7733; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7734)>>2)]=$7726; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7735=(($7671+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7736=HEAP32[(($7735)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7737=$7670; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7738=(($7737+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7739=$7738; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7739)>>2)]=$7736; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7740=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7740)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7741=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7742=(($7741+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7743=$7742; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7743)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7744=$7651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7745=(($7744+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7746=$7745; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7746)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7747=(($7651+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7748=$1651; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1646=$7747; + $1647=$7748; + var $7749=$1646; + var $7750=$1647; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1641=$7749; + $1642=$7750; + var $7751=$1641; + var $7752=$7751; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($7752) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 998; break; } else { label = 1014; break; } + case 998: + var $7753=$7751; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7753)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7754=(($7751+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1640=$7754; + var $7755=$1640; + $1639=$7755; + var $7756=$1639; + var $7757=$7756; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7758=(($7756)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1638=$7758; + var $7759=$1638; + $1637=$7759; + var $7760=$1637; + var $7761=$7760; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1636=$7761; + var $7762=$1636; + var $7763=$7762; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1635=$7763; + var $7764=$1635; + var $7765=(($7762)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1634=$7756; + var $7766=$1634; + var $7767=(($7766)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1633=$7767; + var $7768=$1633; + var $7769=$7768; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1632=$7769; + var $7770=$1632; + var $7771=(($7770)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7772=(($7771)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7773=$7772; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7774=(($7773)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i227=$7774; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i228=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 999; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 999: + var $7776=$__i_i_i_i_i_i_i228; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7777=(($7776)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7777) { label = 1000; break; } else { label = 1001; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1000: + var $7779=$__i_i_i_i_i_i_i228; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7780=$__a_i_i_i_i_i_i227; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7781=(($7780+($7779<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7781)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7782=$__i_i_i_i_i_i_i228; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7783=((($7782)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i228=$7783; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 999; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1001: + var $7784=(($7751+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7784)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7785=(($7751+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $7786=$1642; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7785)>>2)]=$7786; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1631=$1645; + var $7787=$1631; + $1630=$7787; + var $7788=$1630; + var $7789=$7788; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $7790=(($7788)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1629=$7790; + var $7791=$1629; + $1628=$7791; + var $7792=$1628; + var $7793=$7792; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1627=$7793; + var $7794=$1627; + var $7795=$7794; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1626=$7795; + var $7796=$1626; + var $7797=(($7794)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1625=$7788; + var $7798=$1625; + var $7799=(($7798)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1624=$7799; + var $7800=$1624; + var $7801=$7800; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1623=$7801; + var $7802=$1623; + var $7803=(($7802)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $7804=(($7803)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7805=$7804; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $7806=(($7805)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i225=$7806; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i226=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1002; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1002: + var $7808=$__i_i_i_i2_i_i_i226; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7809=(($7808)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($7809) { label = 1003; break; } else { label = 1004; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1003: + var $7811=$__i_i_i_i2_i_i_i226; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7812=$__a_i_i_i1_i_i_i225; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7813=(($7812+($7811<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($7813)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $7814=$__i_i_i_i2_i_i_i226; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $7815=((($7814)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i226=$7815; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1002; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1004: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($7751, $1645) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1005; break; } else { label = 1007; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1005: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1645) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1020; break; } else { label = 1006; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1006: + var $7818$0 = ___cxa_find_matching_catch(-1, -1); $7818$1 = tempRet0; + var $7819=$7818$0; + $1643=$7819; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7820=$7818$1; + $1644=$7820; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1009; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1007: + var $7822$0 = ___cxa_find_matching_catch(-1, -1); $7822$1 = tempRet0; + var $7823=$7822$0; + $1643=$7823; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $7824=$7822$1; + $1644=$7824; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1645) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1008; break; } else { label = 1012; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1008: + label = 1009; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1009: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($7754) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1010; break; } else { label = 1012; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1010: + var $7828=$7751; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($7828) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1011; break; } else { label = 1012; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1011: + var $7830=$1643; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7831=$1644; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $7832$0=$7830; + var $7832$1=0; + var $7833$0=$7832$0; + var $7833$1=$7831; + var $eh_lpad_body_i233$1 = $7833$1;var $eh_lpad_body_i233$0 = $7833$0;label = 1015; break; + case 1012: + var $7835$0 = ___cxa_find_matching_catch(-1, -1,0); $7835$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1013: + var $7837$0 = ___cxa_find_matching_catch(-1, -1); $7837$1 = tempRet0; + var $7838=$7837$0; + $1652=$7838; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7839=$7837$1; + $1653=$7839; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1017; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1014: + var $7841$0 = ___cxa_find_matching_catch(-1, -1); $7841$1 = tempRet0; + var $eh_lpad_body_i233$1 = $7841$1;var $eh_lpad_body_i233$0 = $7841$0;label = 1015; break; + case 1015: + var $eh_lpad_body_i233$0; + var $eh_lpad_body_i233$1; + var $7842=$eh_lpad_body_i233$0; + $1652=$7842; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7843=$eh_lpad_body_i233$1; + $1653=$7843; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7844=$7651; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($7844, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1016; break; } else { label = 1019; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1016: + label = 1017; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1017: + var $7847=$7651; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7848=(($7847+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7849=$7848; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($7849) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1018; break; } else { label = 1019; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1018: + var $7851=$1652; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7852=$1653; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $7853$0=$7851; + var $7853$1=0; + var $7854$0=$7853$0; + var $7854$1=$7852; + ___resumeException($7854$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1019: + var $7856$0 = ___cxa_find_matching_catch(-1, -1,0); $7856$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1020: + var $7857=$std_stringstream15; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7858=(($7857+8)|0); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7859=$7858; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7860 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7859, ((99976)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1021; break; } else { label = 1042; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1021: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2635, ((912)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1022; break; } else { label = 1042; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1022: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2634, $2635, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1023; break; } else { label = 1043; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1023: + var $7864 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($7860, $2634) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1024; break; } else { label = 1044; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1024: + var $7866 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7864, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1025; break; } else { label = 1044; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1025: + var $7868 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7866, ((101424)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1026; break; } else { label = 1044; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1026: + var $7870 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($7868, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1027; break; } else { label = 1044; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1027: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2634) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1028; break; } else { label = 1043; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1028: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2635) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1029; break; } else { label = 1042; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1029: + var $7874=___cxa_allocate_exception(8); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2637=1; + var $7875=$7874; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1610=$std_stringstream15; + var $7876=$1610; + var $7877=(($7876+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2636, $7877) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1030; break; } else { label = 1048; break; } + case 1030: + label = 1031; break; + case 1031: + $1609=$2636; + var $7879=$1609; + $1608=$7879; + var $7880=$1608; + $1607=$7880; + var $7881=$1607; + $1606=$7881; + var $7882=$1606; + var $7883=(($7882)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1605=$7883; + var $7884=$1605; + var $7885=$7884; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1604=$7885; + var $7886=$1604; + var $7887=(($7886)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7888=(($7887)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7889=$7888; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7890=(($7889)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7891=$7890; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7892=HEAP8[($7891)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7893=(($7892)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7894=$7893 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $7895=(($7894)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($7895) { label = 1032; break; } else { label = 1033; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1032: + $1598=$7881; + var $7897=$1598; + var $7898=(($7897)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1597=$7898; + var $7899=$1597; + var $7900=$7899; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1596=$7900; + var $7901=$1596; + var $7902=(($7901)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7903=(($7902)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7904=$7903; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7905=(($7904+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7906=HEAP32[(($7905)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $7920 = $7906;label = 1034; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1033: + $1603=$7881; + var $7908=$1603; + var $7909=(($7908)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1602=$7909; + var $7910=$1602; + var $7911=$7910; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1601=$7911; + var $7912=$1601; + var $7913=(($7912)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $7914=(($7913)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7915=$7914; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7916=(($7915+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $7917=(($7916)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1600=$7917; + var $7918=$1600; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1599=$7918; + var $7919=$1599; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $7920 = $7919;label = 1034; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1034: + var $7920; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1595=$7920; + var $7921=$1595; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($7875, $7921) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1035; break; } else { label = 1049; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1035: + $2637=0; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($7874, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1049; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2636) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1036; break; } else { label = 1048; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1036: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream15); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1056; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1037: + var $7926$0 = ___cxa_find_matching_catch(-1, -1); $7926$1 = tempRet0; + var $7927=$7926$0; + $2542=$7927; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7928=$7926$1; + $2543=$7928; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1040; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1038: + var $7930$0 = ___cxa_find_matching_catch(-1, -1); $7930$1 = tempRet0; + var $7931=$7930$0; + $2542=$7931; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7932=$7930$1; + $2543=$7932; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2632) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1039; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1039: + label = 1040; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1040: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2633) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1041; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1041: + label = 2840; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1042: + var $7937$0 = ___cxa_find_matching_catch(-1, -1); $7937$1 = tempRet0; + var $7938=$7937$0; + $2542=$7938; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7939=$7937$1; + $2543=$7939; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1054; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1043: + var $7941$0 = ___cxa_find_matching_catch(-1, -1); $7941$1 = tempRet0; + var $7942=$7941$0; + $2542=$7942; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7943=$7941$1; + $2543=$7943; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1046; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1044: + var $7945$0 = ___cxa_find_matching_catch(-1, -1); $7945$1 = tempRet0; + var $7946=$7945$0; + $2542=$7946; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7947=$7945$1; + $2543=$7947; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2634) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1045; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1045: + label = 1046; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1046: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2635) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1047; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1047: + label = 1054; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1048: + var $7952$0 = ___cxa_find_matching_catch(-1, -1); $7952$1 = tempRet0; + var $7953=$7952$0; + $2542=$7953; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7954=$7952$1; + $2543=$7954; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1051; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1049: + var $7956$0 = ___cxa_find_matching_catch(-1, -1); $7956$1 = tempRet0; + var $7957=$7956$0; + $2542=$7957; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $7958=$7956$1; + $2543=$7958; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2636) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1050; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1050: + label = 1051; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1051: + var $7961=$2637; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7961) { label = 1052; break; } else { label = 1053; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1052: + ___cxa_free_exception($7874); //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1053; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1053: + label = 1054; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1054: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream15) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1055; break; } else { label = 2841; break; } //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1055: + label = 2840; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1056: + label = 1057; break; //@line 151 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1057: + label = 1058; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1058: + __ZN6StringC1EPKc($2639, ((99448)|0)); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2638, $2639, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1059; break; } else { label = 1103; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1059: + var $7970 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2638, ((99072)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1060; break; } else { label = 1104; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1060: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2638) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1061; break; } else { label = 1103; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1061: + __ZN6StringD1Ev($2639); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($7970) { label = 1062; break; } else { label = 1122; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1062: + $1591=$std_stringstream16; + $1592=24; + var $7974=$1591; + var $7975=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7976=(($7975+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7977=$7976; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1590=$7977; + var $7978=$1590; + var $7979=$7978; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1589=$7979; + var $7980=$1589; + var $7981=$7980; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($7981)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $7982=$7978; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7982)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $7983=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7983)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7984=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7985=(($7984+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7986=$7985; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7986)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7987=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7988=(($7987+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7989=$7988; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($7989)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7990=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7991=(($7974+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $7992=$7991; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1559=$7990; + $1560=((109796)|0); + $1561=$7992; + var $7993=$1559; + var $7994=$1560; + var $7995=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7996=(($7994+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $7997=$1561; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1556=$7995; + $1557=$7996; + $1558=$7997; + var $7998=$1556; + var $7999=$1557; + var $8000=HEAP32[(($7999)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8001=$7998; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8001)>>2)]=$8000; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8002=(($7999+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8003=HEAP32[(($8002)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8004=$7998; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8005=HEAP32[(($8004)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8006=((($8005)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8007=$8006; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8008=HEAP32[(($8007)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8009=$7998; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8010=(($8009+$8008)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8011=$8010; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8011)>>2)]=$8003; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8012=(($7998+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8012)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8013=$7998; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8014=HEAP32[(($8013)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8015=((($8014)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8016=$8015; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8017=HEAP32[(($8016)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8018=$7998; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8019=(($8018+$8017)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8020=$8019; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8021=$1558; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1554=$8020; + $1555=$8021; + var $8022=$1554; + var $8023=$8022; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8024=$1555; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8025=$8024; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($8023, $8025) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1063; break; } else { label = 1079; break; } + case 1063: + var $8026=(($8022+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8026)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $8027=(($8022+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8027)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $8028=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8029=(($8028+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8030=$8029; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8031=(($7994+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1552=$8030; + $1553=$8031; + var $8032=$1552; + var $8033=$1553; + var $8034=HEAP32[(($8033)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8035=$8032; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8035)>>2)]=$8034; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8036=(($8033+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8037=HEAP32[(($8036)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8038=$8032; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8039=HEAP32[(($8038)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8040=((($8039)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8041=$8040; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8042=HEAP32[(($8041)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8043=$8032; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8044=(($8043+$8042)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8045=$8044; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8045)>>2)]=$8037; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8046=HEAP32[(($7994)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8047=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8047)>>2)]=$8046; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8048=(($7994+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8049=HEAP32[(($8048)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8050=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8051=HEAP32[(($8050)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8052=((($8051)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8053=$8052; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8054=HEAP32[(($8053)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8055=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8056=(($8055+$8054)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8057=$8056; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8057)>>2)]=$8049; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8058=(($7994+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8059=HEAP32[(($8058)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8060=$7993; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8061=(($8060+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8062=$8061; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8062)>>2)]=$8059; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8063=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8063)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8064=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8065=(($8064+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8066=$8065; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8066)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8067=$7974; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8068=(($8067+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8069=$8068; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8069)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8070=(($7974+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8071=$1592; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1587=$8070; + $1588=$8071; + var $8072=$1587; + var $8073=$1588; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1582=$8072; + $1583=$8073; + var $8074=$1582; + var $8075=$8074; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($8075) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1064; break; } else { label = 1080; break; } + case 1064: + var $8076=$8074; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8076)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8077=(($8074+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1581=$8077; + var $8078=$1581; + $1580=$8078; + var $8079=$1580; + var $8080=$8079; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8081=(($8079)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1579=$8081; + var $8082=$1579; + $1578=$8082; + var $8083=$1578; + var $8084=$8083; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1577=$8084; + var $8085=$1577; + var $8086=$8085; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1576=$8086; + var $8087=$1576; + var $8088=(($8085)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1575=$8079; + var $8089=$1575; + var $8090=(($8089)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1574=$8090; + var $8091=$1574; + var $8092=$8091; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1573=$8092; + var $8093=$1573; + var $8094=(($8093)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8095=(($8094)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8096=$8095; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8097=(($8096)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i240=$8097; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i241=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1065; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1065: + var $8099=$__i_i_i_i_i_i_i241; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8100=(($8099)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8100) { label = 1066; break; } else { label = 1067; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1066: + var $8102=$__i_i_i_i_i_i_i241; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8103=$__a_i_i_i_i_i_i240; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8104=(($8103+($8102<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8104)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8105=$__i_i_i_i_i_i_i241; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8106=((($8105)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i241=$8106; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1065; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1067: + var $8107=(($8074+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8107)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8108=(($8074+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8109=$1583; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8108)>>2)]=$8109; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1572=$1586; + var $8110=$1572; + $1571=$8110; + var $8111=$1571; + var $8112=$8111; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8113=(($8111)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1570=$8113; + var $8114=$1570; + $1569=$8114; + var $8115=$1569; + var $8116=$8115; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1568=$8116; + var $8117=$1568; + var $8118=$8117; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1567=$8118; + var $8119=$1567; + var $8120=(($8117)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1566=$8111; + var $8121=$1566; + var $8122=(($8121)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1565=$8122; + var $8123=$1565; + var $8124=$8123; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1564=$8124; + var $8125=$1564; + var $8126=(($8125)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8127=(($8126)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8128=$8127; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8129=(($8128)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i238=$8129; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i239=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1068; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1068: + var $8131=$__i_i_i_i2_i_i_i239; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8132=(($8131)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8132) { label = 1069; break; } else { label = 1070; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1069: + var $8134=$__i_i_i_i2_i_i_i239; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8135=$__a_i_i_i1_i_i_i238; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8136=(($8135+($8134<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8136)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8137=$__i_i_i_i2_i_i_i239; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8138=((($8137)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i239=$8138; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1068; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1070: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($8074, $1586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1071; break; } else { label = 1073; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1071: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1086; break; } else { label = 1072; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1072: + var $8141$0 = ___cxa_find_matching_catch(-1, -1); $8141$1 = tempRet0; + var $8142=$8141$0; + $1584=$8142; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8143=$8141$1; + $1585=$8143; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1075; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1073: + var $8145$0 = ___cxa_find_matching_catch(-1, -1); $8145$1 = tempRet0; + var $8146=$8145$0; + $1584=$8146; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8147=$8145$1; + $1585=$8147; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1586) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1074; break; } else { label = 1078; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1074: + label = 1075; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1075: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($8077) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1076; break; } else { label = 1078; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1076: + var $8151=$8074; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($8151) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1077; break; } else { label = 1078; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1077: + var $8153=$1584; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8154=$1585; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8155$0=$8153; + var $8155$1=0; + var $8156$0=$8155$0; + var $8156$1=$8154; + var $eh_lpad_body_i246$1 = $8156$1;var $eh_lpad_body_i246$0 = $8156$0;label = 1081; break; + case 1078: + var $8158$0 = ___cxa_find_matching_catch(-1, -1,0); $8158$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1079: + var $8160$0 = ___cxa_find_matching_catch(-1, -1); $8160$1 = tempRet0; + var $8161=$8160$0; + $1593=$8161; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8162=$8160$1; + $1594=$8162; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1083; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1080: + var $8164$0 = ___cxa_find_matching_catch(-1, -1); $8164$1 = tempRet0; + var $eh_lpad_body_i246$1 = $8164$1;var $eh_lpad_body_i246$0 = $8164$0;label = 1081; break; + case 1081: + var $eh_lpad_body_i246$0; + var $eh_lpad_body_i246$1; + var $8165=$eh_lpad_body_i246$0; + $1593=$8165; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8166=$eh_lpad_body_i246$1; + $1594=$8166; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8167=$7974; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($8167, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1082; break; } else { label = 1085; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1082: + label = 1083; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1083: + var $8170=$7974; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8171=(($8170+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8172=$8171; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($8172) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1084; break; } else { label = 1085; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1084: + var $8174=$1593; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8175=$1594; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8176$0=$8174; + var $8176$1=0; + var $8177$0=$8176$0; + var $8177$1=$8175; + ___resumeException($8177$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1085: + var $8179$0 = ___cxa_find_matching_catch(-1, -1,0); $8179$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1086: + var $8180=$std_stringstream16; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8181=(($8180+8)|0); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8182=$8181; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8183 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8182, ((98664)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1087; break; } else { label = 1108; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1087: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2641, ((99448)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1088; break; } else { label = 1108; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1088: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2640, $2641, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1089; break; } else { label = 1109; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1089: + var $8187 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($8183, $2640) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1090; break; } else { label = 1110; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1090: + var $8189 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8187, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1091; break; } else { label = 1110; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1091: + var $8191 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8189, ((99072)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1092; break; } else { label = 1110; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1092: + var $8193 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8191, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1093; break; } else { label = 1110; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1093: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2640) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1094; break; } else { label = 1109; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1094: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2641) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1095; break; } else { label = 1108; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1095: + var $8197=___cxa_allocate_exception(8); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2643=1; + var $8198=$8197; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1551=$std_stringstream16; + var $8199=$1551; + var $8200=(($8199+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2642, $8200) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1096; break; } else { label = 1114; break; } + case 1096: + label = 1097; break; + case 1097: + $1550=$2642; + var $8202=$1550; + $1549=$8202; + var $8203=$1549; + $1548=$8203; + var $8204=$1548; + $1547=$8204; + var $8205=$1547; + var $8206=(($8205)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1546=$8206; + var $8207=$1546; + var $8208=$8207; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1545=$8208; + var $8209=$1545; + var $8210=(($8209)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8211=(($8210)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8212=$8211; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8213=(($8212)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8214=$8213; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8215=HEAP8[($8214)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8216=(($8215)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8217=$8216 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8218=(($8217)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($8218) { label = 1098; break; } else { label = 1099; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1098: + $1539=$8204; + var $8220=$1539; + var $8221=(($8220)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1538=$8221; + var $8222=$1538; + var $8223=$8222; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1537=$8223; + var $8224=$1537; + var $8225=(($8224)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8226=(($8225)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8227=$8226; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8228=(($8227+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8229=HEAP32[(($8228)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8243 = $8229;label = 1100; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1099: + $1544=$8204; + var $8231=$1544; + var $8232=(($8231)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1543=$8232; + var $8233=$1543; + var $8234=$8233; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1542=$8234; + var $8235=$1542; + var $8236=(($8235)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8237=(($8236)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8238=$8237; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8239=(($8238+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8240=(($8239)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1541=$8240; + var $8241=$1541; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1540=$8241; + var $8242=$1540; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $8243 = $8242;label = 1100; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1100: + var $8243; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1536=$8243; + var $8244=$1536; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($8198, $8244) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1101; break; } else { label = 1115; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1101: + $2643=0; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($8197, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1115; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1102; break; } else { label = 1114; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1102: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream16); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1122; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1103: + var $8249$0 = ___cxa_find_matching_catch(-1, -1); $8249$1 = tempRet0; + var $8250=$8249$0; + $2542=$8250; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8251=$8249$1; + $2543=$8251; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1106; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1104: + var $8253$0 = ___cxa_find_matching_catch(-1, -1); $8253$1 = tempRet0; + var $8254=$8253$0; + $2542=$8254; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8255=$8253$1; + $2543=$8255; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2638) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1105; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1105: + label = 1106; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1106: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2639) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1107; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1107: + label = 2840; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1108: + var $8260$0 = ___cxa_find_matching_catch(-1, -1); $8260$1 = tempRet0; + var $8261=$8260$0; + $2542=$8261; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8262=$8260$1; + $2543=$8262; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1120; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1109: + var $8264$0 = ___cxa_find_matching_catch(-1, -1); $8264$1 = tempRet0; + var $8265=$8264$0; + $2542=$8265; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8266=$8264$1; + $2543=$8266; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1112; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1110: + var $8268$0 = ___cxa_find_matching_catch(-1, -1); $8268$1 = tempRet0; + var $8269=$8268$0; + $2542=$8269; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8270=$8268$1; + $2543=$8270; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2640) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1111; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1111: + label = 1112; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1112: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2641) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1113; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1113: + label = 1120; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1114: + var $8275$0 = ___cxa_find_matching_catch(-1, -1); $8275$1 = tempRet0; + var $8276=$8275$0; + $2542=$8276; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8277=$8275$1; + $2543=$8277; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1117; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1115: + var $8279$0 = ___cxa_find_matching_catch(-1, -1); $8279$1 = tempRet0; + var $8280=$8279$0; + $2542=$8280; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8281=$8279$1; + $2543=$8281; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1116; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1116: + label = 1117; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1117: + var $8284=$2643; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8284) { label = 1118; break; } else { label = 1119; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1118: + ___cxa_free_exception($8197); //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1119; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1119: + label = 1120; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1120: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream16) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1121; break; } else { label = 2841; break; } //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1121: + label = 2840; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1122: + label = 1123; break; //@line 153 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1123: + label = 1124; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1124: + __ZN6StringC1EPKc($2645, ((99448)|0)); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2644, $2645, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1125; break; } else { label = 1169; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1125: + var $8293 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2644, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1126; break; } else { label = 1170; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1126: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2644) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1127; break; } else { label = 1169; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1127: + __ZN6StringD1Ev($2645); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8293) { label = 1128; break; } else { label = 1188; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1128: + $1532=$std_stringstream17; + $1533=24; + var $8297=$1532; + var $8298=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8299=(($8298+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8300=$8299; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1531=$8300; + var $8301=$1531; + var $8302=$8301; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1530=$8302; + var $8303=$1530; + var $8304=$8303; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8304)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $8305=$8301; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8305)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $8306=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8306)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8307=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8308=(($8307+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8309=$8308; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8309)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8310=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8311=(($8310+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8312=$8311; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8312)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8313=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8314=(($8297+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8315=$8314; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1500=$8313; + $1501=((109796)|0); + $1502=$8315; + var $8316=$1500; + var $8317=$1501; + var $8318=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8319=(($8317+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8320=$1502; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1497=$8318; + $1498=$8319; + $1499=$8320; + var $8321=$1497; + var $8322=$1498; + var $8323=HEAP32[(($8322)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8324=$8321; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8324)>>2)]=$8323; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8325=(($8322+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8326=HEAP32[(($8325)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8327=$8321; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8328=HEAP32[(($8327)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8329=((($8328)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8330=$8329; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8331=HEAP32[(($8330)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8332=$8321; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8333=(($8332+$8331)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8334=$8333; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8334)>>2)]=$8326; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8335=(($8321+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8335)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8336=$8321; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8337=HEAP32[(($8336)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8338=((($8337)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8339=$8338; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8340=HEAP32[(($8339)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8341=$8321; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8342=(($8341+$8340)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8343=$8342; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8344=$1499; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1495=$8343; + $1496=$8344; + var $8345=$1495; + var $8346=$8345; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8347=$1496; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8348=$8347; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($8346, $8348) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1129; break; } else { label = 1145; break; } + case 1129: + var $8349=(($8345+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8349)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $8350=(($8345+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8350)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $8351=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8352=(($8351+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8353=$8352; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8354=(($8317+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1493=$8353; + $1494=$8354; + var $8355=$1493; + var $8356=$1494; + var $8357=HEAP32[(($8356)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8358=$8355; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8358)>>2)]=$8357; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8359=(($8356+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8360=HEAP32[(($8359)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8361=$8355; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8362=HEAP32[(($8361)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8363=((($8362)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8364=$8363; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8365=HEAP32[(($8364)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8366=$8355; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8367=(($8366+$8365)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8368=$8367; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8368)>>2)]=$8360; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8369=HEAP32[(($8317)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8370=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8370)>>2)]=$8369; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8371=(($8317+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8372=HEAP32[(($8371)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8373=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8374=HEAP32[(($8373)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8375=((($8374)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8376=$8375; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8377=HEAP32[(($8376)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8378=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8379=(($8378+$8377)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8380=$8379; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8380)>>2)]=$8372; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8381=(($8317+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8382=HEAP32[(($8381)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8383=$8316; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8384=(($8383+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8385=$8384; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8385)>>2)]=$8382; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8386=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8386)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8387=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8388=(($8387+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8389=$8388; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8389)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8390=$8297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8391=(($8390+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8392=$8391; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8392)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8393=(($8297+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8394=$1533; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1528=$8393; + $1529=$8394; + var $8395=$1528; + var $8396=$1529; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1523=$8395; + $1524=$8396; + var $8397=$1523; + var $8398=$8397; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($8398) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1130; break; } else { label = 1146; break; } + case 1130: + var $8399=$8397; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8399)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8400=(($8397+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1522=$8400; + var $8401=$1522; + $1521=$8401; + var $8402=$1521; + var $8403=$8402; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8404=(($8402)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1520=$8404; + var $8405=$1520; + $1519=$8405; + var $8406=$1519; + var $8407=$8406; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1518=$8407; + var $8408=$1518; + var $8409=$8408; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1517=$8409; + var $8410=$1517; + var $8411=(($8408)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1516=$8402; + var $8412=$1516; + var $8413=(($8412)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1515=$8413; + var $8414=$1515; + var $8415=$8414; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1514=$8415; + var $8416=$1514; + var $8417=(($8416)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8418=(($8417)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8419=$8418; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8420=(($8419)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i253=$8420; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i254=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1131; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1131: + var $8422=$__i_i_i_i_i_i_i254; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8423=(($8422)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8423) { label = 1132; break; } else { label = 1133; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1132: + var $8425=$__i_i_i_i_i_i_i254; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8426=$__a_i_i_i_i_i_i253; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8427=(($8426+($8425<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8427)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8428=$__i_i_i_i_i_i_i254; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8429=((($8428)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i254=$8429; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1131; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1133: + var $8430=(($8397+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8430)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8431=(($8397+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8432=$1524; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8431)>>2)]=$8432; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1513=$1527; + var $8433=$1513; + $1512=$8433; + var $8434=$1512; + var $8435=$8434; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8436=(($8434)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1511=$8436; + var $8437=$1511; + $1510=$8437; + var $8438=$1510; + var $8439=$8438; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1509=$8439; + var $8440=$1509; + var $8441=$8440; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1508=$8441; + var $8442=$1508; + var $8443=(($8440)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1507=$8434; + var $8444=$1507; + var $8445=(($8444)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1506=$8445; + var $8446=$1506; + var $8447=$8446; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1505=$8447; + var $8448=$1505; + var $8449=(($8448)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8450=(($8449)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8451=$8450; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8452=(($8451)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i251=$8452; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i252=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1134; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1134: + var $8454=$__i_i_i_i2_i_i_i252; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8455=(($8454)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8455) { label = 1135; break; } else { label = 1136; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1135: + var $8457=$__i_i_i_i2_i_i_i252; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8458=$__a_i_i_i1_i_i_i251; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8459=(($8458+($8457<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8459)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8460=$__i_i_i_i2_i_i_i252; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8461=((($8460)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i252=$8461; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1134; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1136: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($8397, $1527) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1137; break; } else { label = 1139; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1137: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1527) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1152; break; } else { label = 1138; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1138: + var $8464$0 = ___cxa_find_matching_catch(-1, -1); $8464$1 = tempRet0; + var $8465=$8464$0; + $1525=$8465; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8466=$8464$1; + $1526=$8466; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1141; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1139: + var $8468$0 = ___cxa_find_matching_catch(-1, -1); $8468$1 = tempRet0; + var $8469=$8468$0; + $1525=$8469; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8470=$8468$1; + $1526=$8470; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1527) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1140; break; } else { label = 1144; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1140: + label = 1141; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1141: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($8400) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1142; break; } else { label = 1144; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1142: + var $8474=$8397; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($8474) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1143; break; } else { label = 1144; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1143: + var $8476=$1525; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8477=$1526; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8478$0=$8476; + var $8478$1=0; + var $8479$0=$8478$0; + var $8479$1=$8477; + var $eh_lpad_body_i259$1 = $8479$1;var $eh_lpad_body_i259$0 = $8479$0;label = 1147; break; + case 1144: + var $8481$0 = ___cxa_find_matching_catch(-1, -1,0); $8481$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1145: + var $8483$0 = ___cxa_find_matching_catch(-1, -1); $8483$1 = tempRet0; + var $8484=$8483$0; + $1534=$8484; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8485=$8483$1; + $1535=$8485; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1149; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1146: + var $8487$0 = ___cxa_find_matching_catch(-1, -1); $8487$1 = tempRet0; + var $eh_lpad_body_i259$1 = $8487$1;var $eh_lpad_body_i259$0 = $8487$0;label = 1147; break; + case 1147: + var $eh_lpad_body_i259$0; + var $eh_lpad_body_i259$1; + var $8488=$eh_lpad_body_i259$0; + $1534=$8488; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8489=$eh_lpad_body_i259$1; + $1535=$8489; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8490=$8297; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($8490, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1148; break; } else { label = 1151; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1148: + label = 1149; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1149: + var $8493=$8297; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8494=(($8493+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8495=$8494; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($8495) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1150; break; } else { label = 1151; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1150: + var $8497=$1534; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8498=$1535; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8499$0=$8497; + var $8499$1=0; + var $8500$0=$8499$0; + var $8500$1=$8498; + ___resumeException($8500$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1151: + var $8502$0 = ___cxa_find_matching_catch(-1, -1,0); $8502$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1152: + var $8503=$std_stringstream17; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8504=(($8503+8)|0); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8505=$8504; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8506 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8505, ((98272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1153; break; } else { label = 1174; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1153: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2647, ((99448)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1154; break; } else { label = 1174; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1154: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2646, $2647, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1155; break; } else { label = 1175; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1155: + var $8510 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($8506, $2646) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1156; break; } else { label = 1176; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1156: + var $8512 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8510, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1157; break; } else { label = 1176; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1157: + var $8514 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8512, ((14584)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1158; break; } else { label = 1176; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1158: + var $8516 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8514, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1159; break; } else { label = 1176; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1159: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2646) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1160; break; } else { label = 1175; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1160: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2647) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1161; break; } else { label = 1174; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1161: + var $8520=___cxa_allocate_exception(8); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2649=1; + var $8521=$8520; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1492=$std_stringstream17; + var $8522=$1492; + var $8523=(($8522+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2648, $8523) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1162; break; } else { label = 1180; break; } + case 1162: + label = 1163; break; + case 1163: + $1491=$2648; + var $8525=$1491; + $1490=$8525; + var $8526=$1490; + $1489=$8526; + var $8527=$1489; + $1488=$8527; + var $8528=$1488; + var $8529=(($8528)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1487=$8529; + var $8530=$1487; + var $8531=$8530; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1486=$8531; + var $8532=$1486; + var $8533=(($8532)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8534=(($8533)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8535=$8534; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8536=(($8535)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8537=$8536; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8538=HEAP8[($8537)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8539=(($8538)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8540=$8539 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8541=(($8540)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($8541) { label = 1164; break; } else { label = 1165; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1164: + $1480=$8527; + var $8543=$1480; + var $8544=(($8543)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1479=$8544; + var $8545=$1479; + var $8546=$8545; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1478=$8546; + var $8547=$1478; + var $8548=(($8547)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8549=(($8548)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8550=$8549; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8551=(($8550+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8552=HEAP32[(($8551)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8566 = $8552;label = 1166; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1165: + $1485=$8527; + var $8554=$1485; + var $8555=(($8554)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1484=$8555; + var $8556=$1484; + var $8557=$8556; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1483=$8557; + var $8558=$1483; + var $8559=(($8558)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8560=(($8559)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8561=$8560; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8562=(($8561+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8563=(($8562)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1482=$8563; + var $8564=$1482; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1481=$8564; + var $8565=$1481; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $8566 = $8565;label = 1166; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1166: + var $8566; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1477=$8566; + var $8567=$1477; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($8521, $8567) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1167; break; } else { label = 1181; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1167: + $2649=0; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($8520, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1181; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2648) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1168; break; } else { label = 1180; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1168: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream17); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1188; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1169: + var $8572$0 = ___cxa_find_matching_catch(-1, -1); $8572$1 = tempRet0; + var $8573=$8572$0; + $2542=$8573; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8574=$8572$1; + $2543=$8574; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1172; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1170: + var $8576$0 = ___cxa_find_matching_catch(-1, -1); $8576$1 = tempRet0; + var $8577=$8576$0; + $2542=$8577; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8578=$8576$1; + $2543=$8578; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2644) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1171; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1171: + label = 1172; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1172: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2645) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1173; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1173: + label = 2840; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1174: + var $8583$0 = ___cxa_find_matching_catch(-1, -1); $8583$1 = tempRet0; + var $8584=$8583$0; + $2542=$8584; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8585=$8583$1; + $2543=$8585; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1186; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1175: + var $8587$0 = ___cxa_find_matching_catch(-1, -1); $8587$1 = tempRet0; + var $8588=$8587$0; + $2542=$8588; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8589=$8587$1; + $2543=$8589; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1178; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1176: + var $8591$0 = ___cxa_find_matching_catch(-1, -1); $8591$1 = tempRet0; + var $8592=$8591$0; + $2542=$8592; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8593=$8591$1; + $2543=$8593; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2646) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1177; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1177: + label = 1178; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1178: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2647) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1179; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1179: + label = 1186; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1180: + var $8598$0 = ___cxa_find_matching_catch(-1, -1); $8598$1 = tempRet0; + var $8599=$8598$0; + $2542=$8599; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8600=$8598$1; + $2543=$8600; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1183; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1181: + var $8602$0 = ___cxa_find_matching_catch(-1, -1); $8602$1 = tempRet0; + var $8603=$8602$0; + $2542=$8603; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8604=$8602$1; + $2543=$8604; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2648) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1182; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1182: + label = 1183; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1183: + var $8607=$2649; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8607) { label = 1184; break; } else { label = 1185; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1184: + ___cxa_free_exception($8520); //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1185; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1185: + label = 1186; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1186: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream17) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1187; break; } else { label = 2841; break; } //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1187: + label = 2840; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1188: + label = 1189; break; //@line 154 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1189: + label = 1190; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1190: + __ZN6StringC1EPKc($2651, ((97952)|0)); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2650, $2651, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1191; break; } else { label = 1235; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1191: + var $8616 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2650, ((97624)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1192; break; } else { label = 1236; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1192: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2650) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1193; break; } else { label = 1235; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1193: + __ZN6StringD1Ev($2651); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8616) { label = 1194; break; } else { label = 1254; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1194: + $1473=$std_stringstream18; + $1474=24; + var $8620=$1473; + var $8621=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8622=(($8621+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8623=$8622; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1472=$8623; + var $8624=$1472; + var $8625=$8624; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1471=$8625; + var $8626=$1471; + var $8627=$8626; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8627)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $8628=$8624; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8628)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $8629=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8629)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8630=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8631=(($8630+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8632=$8631; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8632)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8633=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8634=(($8633+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8635=$8634; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8635)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8636=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8637=(($8620+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8638=$8637; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1441=$8636; + $1442=((109796)|0); + $1443=$8638; + var $8639=$1441; + var $8640=$1442; + var $8641=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8642=(($8640+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8643=$1443; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1438=$8641; + $1439=$8642; + $1440=$8643; + var $8644=$1438; + var $8645=$1439; + var $8646=HEAP32[(($8645)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8647=$8644; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8647)>>2)]=$8646; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8648=(($8645+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8649=HEAP32[(($8648)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8650=$8644; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8651=HEAP32[(($8650)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8652=((($8651)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8653=$8652; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8654=HEAP32[(($8653)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8655=$8644; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8656=(($8655+$8654)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8657=$8656; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8657)>>2)]=$8649; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8658=(($8644+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8658)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8659=$8644; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8660=HEAP32[(($8659)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8661=((($8660)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8662=$8661; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8663=HEAP32[(($8662)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8664=$8644; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8665=(($8664+$8663)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8666=$8665; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8667=$1440; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1436=$8666; + $1437=$8667; + var $8668=$1436; + var $8669=$8668; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8670=$1437; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8671=$8670; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($8669, $8671) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1195; break; } else { label = 1211; break; } + case 1195: + var $8672=(($8668+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8672)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $8673=(($8668+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8673)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $8674=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8675=(($8674+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8676=$8675; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8677=(($8640+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1434=$8676; + $1435=$8677; + var $8678=$1434; + var $8679=$1435; + var $8680=HEAP32[(($8679)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8681=$8678; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8681)>>2)]=$8680; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8682=(($8679+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8683=HEAP32[(($8682)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8684=$8678; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8685=HEAP32[(($8684)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8686=((($8685)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8687=$8686; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8688=HEAP32[(($8687)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8689=$8678; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8690=(($8689+$8688)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8691=$8690; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8691)>>2)]=$8683; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $8692=HEAP32[(($8640)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8693=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8693)>>2)]=$8692; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8694=(($8640+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8695=HEAP32[(($8694)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8696=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8697=HEAP32[(($8696)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8698=((($8697)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8699=$8698; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8700=HEAP32[(($8699)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8701=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8702=(($8701+$8700)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8703=$8702; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8703)>>2)]=$8695; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8704=(($8640+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8705=HEAP32[(($8704)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8706=$8639; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8707=(($8706+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8708=$8707; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8708)>>2)]=$8705; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8709=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8709)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8710=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8711=(($8710+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8712=$8711; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8712)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8713=$8620; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8714=(($8713+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8715=$8714; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8715)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8716=(($8620+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8717=$1474; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1469=$8716; + $1470=$8717; + var $8718=$1469; + var $8719=$1470; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1464=$8718; + $1465=$8719; + var $8720=$1464; + var $8721=$8720; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($8721) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1196; break; } else { label = 1212; break; } + case 1196: + var $8722=$8720; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8722)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8723=(($8720+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1463=$8723; + var $8724=$1463; + $1462=$8724; + var $8725=$1462; + var $8726=$8725; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8727=(($8725)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1461=$8727; + var $8728=$1461; + $1460=$8728; + var $8729=$1460; + var $8730=$8729; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1459=$8730; + var $8731=$1459; + var $8732=$8731; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1458=$8732; + var $8733=$1458; + var $8734=(($8731)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1457=$8725; + var $8735=$1457; + var $8736=(($8735)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1456=$8736; + var $8737=$1456; + var $8738=$8737; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1455=$8738; + var $8739=$1455; + var $8740=(($8739)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8741=(($8740)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8742=$8741; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8743=(($8742)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i266=$8743; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i267=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1197; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1197: + var $8745=$__i_i_i_i_i_i_i267; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8746=(($8745)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8746) { label = 1198; break; } else { label = 1199; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1198: + var $8748=$__i_i_i_i_i_i_i267; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8749=$__a_i_i_i_i_i_i266; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8750=(($8749+($8748<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8750)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8751=$__i_i_i_i_i_i_i267; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8752=((($8751)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i267=$8752; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1197; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1199: + var $8753=(($8720+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8753)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8754=(($8720+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $8755=$1465; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8754)>>2)]=$8755; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1454=$1468; + var $8756=$1454; + $1453=$8756; + var $8757=$1453; + var $8758=$8757; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $8759=(($8757)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1452=$8759; + var $8760=$1452; + $1451=$8760; + var $8761=$1451; + var $8762=$8761; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1450=$8762; + var $8763=$1450; + var $8764=$8763; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1449=$8764; + var $8765=$1449; + var $8766=(($8763)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1448=$8757; + var $8767=$1448; + var $8768=(($8767)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1447=$8768; + var $8769=$1447; + var $8770=$8769; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1446=$8770; + var $8771=$1446; + var $8772=(($8771)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $8773=(($8772)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8774=$8773; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $8775=(($8774)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i264=$8775; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i265=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1200; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1200: + var $8777=$__i_i_i_i2_i_i_i265; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8778=(($8777)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($8778) { label = 1201; break; } else { label = 1202; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1201: + var $8780=$__i_i_i_i2_i_i_i265; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8781=$__a_i_i_i1_i_i_i264; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8782=(($8781+($8780<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($8782)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $8783=$__i_i_i_i2_i_i_i265; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $8784=((($8783)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i265=$8784; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1200; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1202: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($8720, $1468) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1203; break; } else { label = 1205; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1203: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1468) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1218; break; } else { label = 1204; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1204: + var $8787$0 = ___cxa_find_matching_catch(-1, -1); $8787$1 = tempRet0; + var $8788=$8787$0; + $1466=$8788; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8789=$8787$1; + $1467=$8789; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1207; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1205: + var $8791$0 = ___cxa_find_matching_catch(-1, -1); $8791$1 = tempRet0; + var $8792=$8791$0; + $1466=$8792; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $8793=$8791$1; + $1467=$8793; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1468) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1206; break; } else { label = 1210; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1206: + label = 1207; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1207: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($8723) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1208; break; } else { label = 1210; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1208: + var $8797=$8720; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($8797) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1209; break; } else { label = 1210; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1209: + var $8799=$1466; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8800=$1467; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $8801$0=$8799; + var $8801$1=0; + var $8802$0=$8801$0; + var $8802$1=$8800; + var $eh_lpad_body_i272$1 = $8802$1;var $eh_lpad_body_i272$0 = $8802$0;label = 1213; break; + case 1210: + var $8804$0 = ___cxa_find_matching_catch(-1, -1,0); $8804$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1211: + var $8806$0 = ___cxa_find_matching_catch(-1, -1); $8806$1 = tempRet0; + var $8807=$8806$0; + $1475=$8807; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8808=$8806$1; + $1476=$8808; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1215; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1212: + var $8810$0 = ___cxa_find_matching_catch(-1, -1); $8810$1 = tempRet0; + var $eh_lpad_body_i272$1 = $8810$1;var $eh_lpad_body_i272$0 = $8810$0;label = 1213; break; + case 1213: + var $eh_lpad_body_i272$0; + var $eh_lpad_body_i272$1; + var $8811=$eh_lpad_body_i272$0; + $1475=$8811; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8812=$eh_lpad_body_i272$1; + $1476=$8812; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8813=$8620; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($8813, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1214; break; } else { label = 1217; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1214: + label = 1215; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1215: + var $8816=$8620; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8817=(($8816+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8818=$8817; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($8818) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1216; break; } else { label = 1217; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1216: + var $8820=$1475; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8821=$1476; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $8822$0=$8820; + var $8822$1=0; + var $8823$0=$8822$0; + var $8823$1=$8821; + ___resumeException($8823$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1217: + var $8825$0 = ___cxa_find_matching_catch(-1, -1,0); $8825$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1218: + var $8826=$std_stringstream18; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8827=(($8826+8)|0); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8828=$8827; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8829 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8828, ((97272)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1219; break; } else { label = 1240; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1219: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2653, ((97952)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1220; break; } else { label = 1240; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1220: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2652, $2653, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1221; break; } else { label = 1241; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1221: + var $8833 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($8829, $2652) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1222; break; } else { label = 1242; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1222: + var $8835 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8833, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1223; break; } else { label = 1242; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1223: + var $8837 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8835, ((97624)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1224; break; } else { label = 1242; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1224: + var $8839 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($8837, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1225; break; } else { label = 1242; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1225: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2652) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1226; break; } else { label = 1241; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1226: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2653) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1227; break; } else { label = 1240; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1227: + var $8843=___cxa_allocate_exception(8); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2655=1; + var $8844=$8843; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1433=$std_stringstream18; + var $8845=$1433; + var $8846=(($8845+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2654, $8846) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1228; break; } else { label = 1246; break; } + case 1228: + label = 1229; break; + case 1229: + $1432=$2654; + var $8848=$1432; + $1431=$8848; + var $8849=$1431; + $1430=$8849; + var $8850=$1430; + $1429=$8850; + var $8851=$1429; + var $8852=(($8851)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1428=$8852; + var $8853=$1428; + var $8854=$8853; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1427=$8854; + var $8855=$1427; + var $8856=(($8855)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8857=(($8856)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8858=$8857; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8859=(($8858)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8860=$8859; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8861=HEAP8[($8860)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8862=(($8861)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8863=$8862 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $8864=(($8863)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($8864) { label = 1230; break; } else { label = 1231; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1230: + $1421=$8850; + var $8866=$1421; + var $8867=(($8866)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1420=$8867; + var $8868=$1420; + var $8869=$8868; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1419=$8869; + var $8870=$1419; + var $8871=(($8870)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8872=(($8871)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8873=$8872; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8874=(($8873+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8875=HEAP32[(($8874)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $8889 = $8875;label = 1232; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1231: + $1426=$8850; + var $8877=$1426; + var $8878=(($8877)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1425=$8878; + var $8879=$1425; + var $8880=$8879; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1424=$8880; + var $8881=$1424; + var $8882=(($8881)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $8883=(($8882)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8884=$8883; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8885=(($8884+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $8886=(($8885)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1423=$8886; + var $8887=$1423; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1422=$8887; + var $8888=$1422; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $8889 = $8888;label = 1232; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1232: + var $8889; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1418=$8889; + var $8890=$1418; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($8844, $8890) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1233; break; } else { label = 1247; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1233: + $2655=0; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($8843, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1247; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2654) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1234; break; } else { label = 1246; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1234: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream18); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1254; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1235: + var $8895$0 = ___cxa_find_matching_catch(-1, -1); $8895$1 = tempRet0; + var $8896=$8895$0; + $2542=$8896; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8897=$8895$1; + $2543=$8897; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1238; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1236: + var $8899$0 = ___cxa_find_matching_catch(-1, -1); $8899$1 = tempRet0; + var $8900=$8899$0; + $2542=$8900; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8901=$8899$1; + $2543=$8901; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2650) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1237; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1237: + label = 1238; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1238: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2651) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1239; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1239: + label = 2840; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1240: + var $8906$0 = ___cxa_find_matching_catch(-1, -1); $8906$1 = tempRet0; + var $8907=$8906$0; + $2542=$8907; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8908=$8906$1; + $2543=$8908; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1252; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1241: + var $8910$0 = ___cxa_find_matching_catch(-1, -1); $8910$1 = tempRet0; + var $8911=$8910$0; + $2542=$8911; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8912=$8910$1; + $2543=$8912; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1244; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1242: + var $8914$0 = ___cxa_find_matching_catch(-1, -1); $8914$1 = tempRet0; + var $8915=$8914$0; + $2542=$8915; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8916=$8914$1; + $2543=$8916; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2652) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1243; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1243: + label = 1244; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1244: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2653) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1245; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1245: + label = 1252; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1246: + var $8921$0 = ___cxa_find_matching_catch(-1, -1); $8921$1 = tempRet0; + var $8922=$8921$0; + $2542=$8922; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8923=$8921$1; + $2543=$8923; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1249; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1247: + var $8925$0 = ___cxa_find_matching_catch(-1, -1); $8925$1 = tempRet0; + var $8926=$8925$0; + $2542=$8926; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $8927=$8925$1; + $2543=$8927; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2654) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1248; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1248: + label = 1249; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1249: + var $8930=$2655; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8930) { label = 1250; break; } else { label = 1251; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1250: + ___cxa_free_exception($8843); //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1251; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1251: + label = 1252; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1252: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream18) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1253; break; } else { label = 2841; break; } //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1253: + label = 2840; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1254: + label = 1255; break; //@line 155 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1255: + label = 1256; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1256: + __ZN6StringC1EPKc($2657, ((97952)|0)); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2656, $2657, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1257; break; } else { label = 1301; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1257: + var $8939 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2656, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1258; break; } else { label = 1302; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1258: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2656) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1259; break; } else { label = 1301; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1259: + __ZN6StringD1Ev($2657); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($8939) { label = 1260; break; } else { label = 1320; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1260: + $1414=$std_stringstream19; + $1415=24; + var $8943=$1414; + var $8944=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8945=(($8944+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8946=$8945; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1413=$8946; + var $8947=$1413; + var $8948=$8947; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1412=$8948; + var $8949=$1412; + var $8950=$8949; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8950)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $8951=$8947; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8951)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $8952=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8952)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8953=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8954=(($8953+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8955=$8954; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8955)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8956=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8957=(($8956+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8958=$8957; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8958)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8959=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8960=(($8943+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $8961=$8960; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1382=$8959; + $1383=((109796)|0); + $1384=$8961; + var $8962=$1382; + var $8963=$1383; + var $8964=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8965=(($8963+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8966=$1384; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1379=$8964; + $1380=$8965; + $1381=$8966; + var $8967=$1379; + var $8968=$1380; + var $8969=HEAP32[(($8968)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8970=$8967; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8970)>>2)]=$8969; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8971=(($8968+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8972=HEAP32[(($8971)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8973=$8967; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8974=HEAP32[(($8973)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8975=((($8974)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8976=$8975; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8977=HEAP32[(($8976)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8978=$8967; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8979=(($8978+$8977)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8980=$8979; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8980)>>2)]=$8972; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8981=(($8967+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($8981)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $8982=$8967; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8983=HEAP32[(($8982)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8984=((($8983)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8985=$8984; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8986=HEAP32[(($8985)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8987=$8967; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8988=(($8987+$8986)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8989=$8988; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $8990=$1381; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1377=$8989; + $1378=$8990; + var $8991=$1377; + var $8992=$8991; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8993=$1378; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $8994=$8993; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($8992, $8994) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1261; break; } else { label = 1277; break; } + case 1261: + var $8995=(($8991+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8995)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $8996=(($8991+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($8996)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $8997=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8998=(($8997+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $8999=$8998; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9000=(($8963+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1375=$8999; + $1376=$9000; + var $9001=$1375; + var $9002=$1376; + var $9003=HEAP32[(($9002)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9004=$9001; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9004)>>2)]=$9003; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9005=(($9002+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9006=HEAP32[(($9005)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9007=$9001; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9008=HEAP32[(($9007)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9009=((($9008)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9010=$9009; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9011=HEAP32[(($9010)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9012=$9001; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9013=(($9012+$9011)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9014=$9013; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9014)>>2)]=$9006; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9015=HEAP32[(($8963)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9016=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9016)>>2)]=$9015; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9017=(($8963+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9018=HEAP32[(($9017)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9019=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9020=HEAP32[(($9019)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9021=((($9020)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9022=$9021; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9023=HEAP32[(($9022)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9024=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9025=(($9024+$9023)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9026=$9025; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9026)>>2)]=$9018; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9027=(($8963+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9028=HEAP32[(($9027)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9029=$8962; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9030=(($9029+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9031=$9030; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9031)>>2)]=$9028; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9032=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9032)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9033=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9034=(($9033+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9035=$9034; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9035)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9036=$8943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9037=(($9036+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9038=$9037; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9038)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9039=(($8943+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9040=$1415; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1410=$9039; + $1411=$9040; + var $9041=$1410; + var $9042=$1411; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1405=$9041; + $1406=$9042; + var $9043=$1405; + var $9044=$9043; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($9044) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1262; break; } else { label = 1278; break; } + case 1262: + var $9045=$9043; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9045)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9046=(($9043+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1404=$9046; + var $9047=$1404; + $1403=$9047; + var $9048=$1403; + var $9049=$9048; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9050=(($9048)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1402=$9050; + var $9051=$1402; + $1401=$9051; + var $9052=$1401; + var $9053=$9052; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1400=$9053; + var $9054=$1400; + var $9055=$9054; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1399=$9055; + var $9056=$1399; + var $9057=(($9054)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1398=$9048; + var $9058=$1398; + var $9059=(($9058)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1397=$9059; + var $9060=$1397; + var $9061=$9060; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1396=$9061; + var $9062=$1396; + var $9063=(($9062)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9064=(($9063)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9065=$9064; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9066=(($9065)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i279=$9066; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i280=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1263; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1263: + var $9068=$__i_i_i_i_i_i_i280; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9069=(($9068)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9069) { label = 1264; break; } else { label = 1265; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1264: + var $9071=$__i_i_i_i_i_i_i280; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9072=$__a_i_i_i_i_i_i279; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9073=(($9072+($9071<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9073)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9074=$__i_i_i_i_i_i_i280; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9075=((($9074)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i280=$9075; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1263; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1265: + var $9076=(($9043+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9076)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9077=(($9043+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9078=$1406; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9077)>>2)]=$9078; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1395=$1409; + var $9079=$1395; + $1394=$9079; + var $9080=$1394; + var $9081=$9080; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9082=(($9080)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1393=$9082; + var $9083=$1393; + $1392=$9083; + var $9084=$1392; + var $9085=$9084; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1391=$9085; + var $9086=$1391; + var $9087=$9086; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1390=$9087; + var $9088=$1390; + var $9089=(($9086)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1389=$9080; + var $9090=$1389; + var $9091=(($9090)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1388=$9091; + var $9092=$1388; + var $9093=$9092; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1387=$9093; + var $9094=$1387; + var $9095=(($9094)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9096=(($9095)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9097=$9096; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9098=(($9097)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i277=$9098; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i278=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1266; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1266: + var $9100=$__i_i_i_i2_i_i_i278; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9101=(($9100)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9101) { label = 1267; break; } else { label = 1268; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1267: + var $9103=$__i_i_i_i2_i_i_i278; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9104=$__a_i_i_i1_i_i_i277; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9105=(($9104+($9103<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9105)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9106=$__i_i_i_i2_i_i_i278; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9107=((($9106)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i278=$9107; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1266; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1268: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($9043, $1409) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1269; break; } else { label = 1271; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1269: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1409) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1284; break; } else { label = 1270; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1270: + var $9110$0 = ___cxa_find_matching_catch(-1, -1); $9110$1 = tempRet0; + var $9111=$9110$0; + $1407=$9111; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9112=$9110$1; + $1408=$9112; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1273; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1271: + var $9114$0 = ___cxa_find_matching_catch(-1, -1); $9114$1 = tempRet0; + var $9115=$9114$0; + $1407=$9115; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9116=$9114$1; + $1408=$9116; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1409) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1272; break; } else { label = 1276; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1272: + label = 1273; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1273: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($9046) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1274; break; } else { label = 1276; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1274: + var $9120=$9043; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($9120) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1275; break; } else { label = 1276; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1275: + var $9122=$1407; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9123=$1408; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9124$0=$9122; + var $9124$1=0; + var $9125$0=$9124$0; + var $9125$1=$9123; + var $eh_lpad_body_i285$1 = $9125$1;var $eh_lpad_body_i285$0 = $9125$0;label = 1279; break; + case 1276: + var $9127$0 = ___cxa_find_matching_catch(-1, -1,0); $9127$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1277: + var $9129$0 = ___cxa_find_matching_catch(-1, -1); $9129$1 = tempRet0; + var $9130=$9129$0; + $1416=$9130; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9131=$9129$1; + $1417=$9131; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1281; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1278: + var $9133$0 = ___cxa_find_matching_catch(-1, -1); $9133$1 = tempRet0; + var $eh_lpad_body_i285$1 = $9133$1;var $eh_lpad_body_i285$0 = $9133$0;label = 1279; break; + case 1279: + var $eh_lpad_body_i285$0; + var $eh_lpad_body_i285$1; + var $9134=$eh_lpad_body_i285$0; + $1416=$9134; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9135=$eh_lpad_body_i285$1; + $1417=$9135; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9136=$8943; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($9136, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1280; break; } else { label = 1283; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1280: + label = 1281; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1281: + var $9139=$8943; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9140=(($9139+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9141=$9140; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($9141) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1282; break; } else { label = 1283; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1282: + var $9143=$1416; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9144=$1417; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9145$0=$9143; + var $9145$1=0; + var $9146$0=$9145$0; + var $9146$1=$9144; + ___resumeException($9146$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1283: + var $9148$0 = ___cxa_find_matching_catch(-1, -1,0); $9148$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1284: + var $9149=$std_stringstream19; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9150=(($9149+8)|0); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9151=$9150; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9152 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9151, ((96848)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1285; break; } else { label = 1306; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1285: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2659, ((97952)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1286; break; } else { label = 1306; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1286: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2658, $2659, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1287; break; } else { label = 1307; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1287: + var $9156 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($9152, $2658) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1288; break; } else { label = 1308; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1288: + var $9158 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9156, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1289; break; } else { label = 1308; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1289: + var $9160 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9158, ((13320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1290; break; } else { label = 1308; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1290: + var $9162 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9160, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1291; break; } else { label = 1308; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1291: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2658) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1292; break; } else { label = 1307; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1292: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2659) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1293; break; } else { label = 1306; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1293: + var $9166=___cxa_allocate_exception(8); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2661=1; + var $9167=$9166; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1374=$std_stringstream19; + var $9168=$1374; + var $9169=(($9168+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2660, $9169) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1294; break; } else { label = 1312; break; } + case 1294: + label = 1295; break; + case 1295: + $1373=$2660; + var $9171=$1373; + $1372=$9171; + var $9172=$1372; + $1371=$9172; + var $9173=$1371; + $1370=$9173; + var $9174=$1370; + var $9175=(($9174)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1369=$9175; + var $9176=$1369; + var $9177=$9176; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1368=$9177; + var $9178=$1368; + var $9179=(($9178)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9180=(($9179)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9181=$9180; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9182=(($9181)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9183=$9182; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9184=HEAP8[($9183)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9185=(($9184)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9186=$9185 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9187=(($9186)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($9187) { label = 1296; break; } else { label = 1297; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1296: + $1362=$9173; + var $9189=$1362; + var $9190=(($9189)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1361=$9190; + var $9191=$1361; + var $9192=$9191; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1360=$9192; + var $9193=$1360; + var $9194=(($9193)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9195=(($9194)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9196=$9195; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9197=(($9196+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9198=HEAP32[(($9197)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9212 = $9198;label = 1298; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1297: + $1367=$9173; + var $9200=$1367; + var $9201=(($9200)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1366=$9201; + var $9202=$1366; + var $9203=$9202; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1365=$9203; + var $9204=$1365; + var $9205=(($9204)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9206=(($9205)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9207=$9206; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9208=(($9207+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9209=(($9208)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1364=$9209; + var $9210=$1364; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1363=$9210; + var $9211=$1363; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $9212 = $9211;label = 1298; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1298: + var $9212; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1359=$9212; + var $9213=$1359; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($9167, $9213) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1299; break; } else { label = 1313; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1299: + $2661=0; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($9166, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1313; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2660) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1300; break; } else { label = 1312; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1300: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream19); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1320; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1301: + var $9218$0 = ___cxa_find_matching_catch(-1, -1); $9218$1 = tempRet0; + var $9219=$9218$0; + $2542=$9219; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9220=$9218$1; + $2543=$9220; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1304; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1302: + var $9222$0 = ___cxa_find_matching_catch(-1, -1); $9222$1 = tempRet0; + var $9223=$9222$0; + $2542=$9223; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9224=$9222$1; + $2543=$9224; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2656) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1303; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1303: + label = 1304; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1304: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2657) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1305; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1305: + label = 2840; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1306: + var $9229$0 = ___cxa_find_matching_catch(-1, -1); $9229$1 = tempRet0; + var $9230=$9229$0; + $2542=$9230; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9231=$9229$1; + $2543=$9231; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1318; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1307: + var $9233$0 = ___cxa_find_matching_catch(-1, -1); $9233$1 = tempRet0; + var $9234=$9233$0; + $2542=$9234; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9235=$9233$1; + $2543=$9235; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1310; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1308: + var $9237$0 = ___cxa_find_matching_catch(-1, -1); $9237$1 = tempRet0; + var $9238=$9237$0; + $2542=$9238; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9239=$9237$1; + $2543=$9239; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2658) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1309; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1309: + label = 1310; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1310: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2659) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1311; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1311: + label = 1318; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1312: + var $9244$0 = ___cxa_find_matching_catch(-1, -1); $9244$1 = tempRet0; + var $9245=$9244$0; + $2542=$9245; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9246=$9244$1; + $2543=$9246; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1315; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1313: + var $9248$0 = ___cxa_find_matching_catch(-1, -1); $9248$1 = tempRet0; + var $9249=$9248$0; + $2542=$9249; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9250=$9248$1; + $2543=$9250; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2660) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1314; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1314: + label = 1315; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1315: + var $9253=$2661; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9253) { label = 1316; break; } else { label = 1317; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1316: + ___cxa_free_exception($9166); //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1317; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1317: + label = 1318; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1318: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream19) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1319; break; } else { label = 2841; break; } //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1319: + label = 2840; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1320: + label = 1321; break; //@line 156 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1321: + label = 1322; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1322: + __ZN6StringC1EPKc($2663, ((96568)|0)); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2662, $2663, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1323; break; } else { label = 1367; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1323: + var $9262 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2662, ((95840)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1324; break; } else { label = 1368; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1324: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2662) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1325; break; } else { label = 1367; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1325: + __ZN6StringD1Ev($2663); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9262) { label = 1326; break; } else { label = 1386; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1326: + $1355=$std_stringstream20; + $1356=24; + var $9266=$1355; + var $9267=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9268=(($9267+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9269=$9268; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1354=$9269; + var $9270=$1354; + var $9271=$9270; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1353=$9271; + var $9272=$1353; + var $9273=$9272; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9273)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $9274=$9270; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9274)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $9275=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9275)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9276=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9277=(($9276+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9278=$9277; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9278)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9279=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9280=(($9279+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9281=$9280; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9281)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9282=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9283=(($9266+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9284=$9283; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1323=$9282; + $1324=((109796)|0); + $1325=$9284; + var $9285=$1323; + var $9286=$1324; + var $9287=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9288=(($9286+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9289=$1325; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1320=$9287; + $1321=$9288; + $1322=$9289; + var $9290=$1320; + var $9291=$1321; + var $9292=HEAP32[(($9291)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9293=$9290; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9293)>>2)]=$9292; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9294=(($9291+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9295=HEAP32[(($9294)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9296=$9290; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9297=HEAP32[(($9296)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9298=((($9297)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9299=$9298; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9300=HEAP32[(($9299)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9301=$9290; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9302=(($9301+$9300)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9303=$9302; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9303)>>2)]=$9295; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9304=(($9290+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9304)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9305=$9290; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9306=HEAP32[(($9305)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9307=((($9306)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9308=$9307; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9309=HEAP32[(($9308)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9310=$9290; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9311=(($9310+$9309)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9312=$9311; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9313=$1322; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1318=$9312; + $1319=$9313; + var $9314=$1318; + var $9315=$9314; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9316=$1319; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9317=$9316; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($9315, $9317) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1327; break; } else { label = 1343; break; } + case 1327: + var $9318=(($9314+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9318)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $9319=(($9314+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9319)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $9320=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9321=(($9320+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9322=$9321; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9323=(($9286+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1316=$9322; + $1317=$9323; + var $9324=$1316; + var $9325=$1317; + var $9326=HEAP32[(($9325)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9327=$9324; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9327)>>2)]=$9326; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9328=(($9325+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9329=HEAP32[(($9328)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9330=$9324; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9331=HEAP32[(($9330)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9332=((($9331)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9333=$9332; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9334=HEAP32[(($9333)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9335=$9324; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9336=(($9335+$9334)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9337=$9336; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9337)>>2)]=$9329; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9338=HEAP32[(($9286)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9339=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9339)>>2)]=$9338; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9340=(($9286+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9341=HEAP32[(($9340)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9342=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9343=HEAP32[(($9342)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9344=((($9343)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9345=$9344; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9346=HEAP32[(($9345)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9347=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9348=(($9347+$9346)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9349=$9348; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9349)>>2)]=$9341; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9350=(($9286+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9351=HEAP32[(($9350)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9352=$9285; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9353=(($9352+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9354=$9353; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9354)>>2)]=$9351; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9355=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9355)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9356=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9357=(($9356+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9358=$9357; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9358)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9359=$9266; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9360=(($9359+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9361=$9360; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9361)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9362=(($9266+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9363=$1356; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1351=$9362; + $1352=$9363; + var $9364=$1351; + var $9365=$1352; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1346=$9364; + $1347=$9365; + var $9366=$1346; + var $9367=$9366; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($9367) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1328; break; } else { label = 1344; break; } + case 1328: + var $9368=$9366; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9368)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9369=(($9366+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1345=$9369; + var $9370=$1345; + $1344=$9370; + var $9371=$1344; + var $9372=$9371; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9373=(($9371)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1343=$9373; + var $9374=$1343; + $1342=$9374; + var $9375=$1342; + var $9376=$9375; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1341=$9376; + var $9377=$1341; + var $9378=$9377; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1340=$9378; + var $9379=$1340; + var $9380=(($9377)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1339=$9371; + var $9381=$1339; + var $9382=(($9381)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1338=$9382; + var $9383=$1338; + var $9384=$9383; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1337=$9384; + var $9385=$1337; + var $9386=(($9385)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9387=(($9386)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9388=$9387; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9389=(($9388)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i292=$9389; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i293=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1329; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1329: + var $9391=$__i_i_i_i_i_i_i293; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9392=(($9391)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9392) { label = 1330; break; } else { label = 1331; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1330: + var $9394=$__i_i_i_i_i_i_i293; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9395=$__a_i_i_i_i_i_i292; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9396=(($9395+($9394<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9396)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9397=$__i_i_i_i_i_i_i293; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9398=((($9397)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i293=$9398; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1329; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1331: + var $9399=(($9366+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9399)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9400=(($9366+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9401=$1347; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9400)>>2)]=$9401; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1336=$1350; + var $9402=$1336; + $1335=$9402; + var $9403=$1335; + var $9404=$9403; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9405=(($9403)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1334=$9405; + var $9406=$1334; + $1333=$9406; + var $9407=$1333; + var $9408=$9407; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1332=$9408; + var $9409=$1332; + var $9410=$9409; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1331=$9410; + var $9411=$1331; + var $9412=(($9409)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1330=$9403; + var $9413=$1330; + var $9414=(($9413)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1329=$9414; + var $9415=$1329; + var $9416=$9415; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1328=$9416; + var $9417=$1328; + var $9418=(($9417)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9419=(($9418)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9420=$9419; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9421=(($9420)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i290=$9421; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i291=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1332; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1332: + var $9423=$__i_i_i_i2_i_i_i291; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9424=(($9423)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9424) { label = 1333; break; } else { label = 1334; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1333: + var $9426=$__i_i_i_i2_i_i_i291; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9427=$__a_i_i_i1_i_i_i290; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9428=(($9427+($9426<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9428)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9429=$__i_i_i_i2_i_i_i291; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9430=((($9429)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i291=$9430; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1332; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1334: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($9366, $1350) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1335; break; } else { label = 1337; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1335: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1350) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1350; break; } else { label = 1336; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1336: + var $9433$0 = ___cxa_find_matching_catch(-1, -1); $9433$1 = tempRet0; + var $9434=$9433$0; + $1348=$9434; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9435=$9433$1; + $1349=$9435; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1339; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1337: + var $9437$0 = ___cxa_find_matching_catch(-1, -1); $9437$1 = tempRet0; + var $9438=$9437$0; + $1348=$9438; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9439=$9437$1; + $1349=$9439; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1350) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1338; break; } else { label = 1342; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1338: + label = 1339; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1339: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($9369) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1340; break; } else { label = 1342; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1340: + var $9443=$9366; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($9443) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1341; break; } else { label = 1342; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1341: + var $9445=$1348; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9446=$1349; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9447$0=$9445; + var $9447$1=0; + var $9448$0=$9447$0; + var $9448$1=$9446; + var $eh_lpad_body_i298$1 = $9448$1;var $eh_lpad_body_i298$0 = $9448$0;label = 1345; break; + case 1342: + var $9450$0 = ___cxa_find_matching_catch(-1, -1,0); $9450$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1343: + var $9452$0 = ___cxa_find_matching_catch(-1, -1); $9452$1 = tempRet0; + var $9453=$9452$0; + $1357=$9453; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9454=$9452$1; + $1358=$9454; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1347; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1344: + var $9456$0 = ___cxa_find_matching_catch(-1, -1); $9456$1 = tempRet0; + var $eh_lpad_body_i298$1 = $9456$1;var $eh_lpad_body_i298$0 = $9456$0;label = 1345; break; + case 1345: + var $eh_lpad_body_i298$0; + var $eh_lpad_body_i298$1; + var $9457=$eh_lpad_body_i298$0; + $1357=$9457; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9458=$eh_lpad_body_i298$1; + $1358=$9458; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9459=$9266; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($9459, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1346; break; } else { label = 1349; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1346: + label = 1347; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1347: + var $9462=$9266; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9463=(($9462+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9464=$9463; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($9464) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1348; break; } else { label = 1349; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1348: + var $9466=$1357; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9467=$1358; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9468$0=$9466; + var $9468$1=0; + var $9469$0=$9468$0; + var $9469$1=$9467; + ___resumeException($9469$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1349: + var $9471$0 = ___cxa_find_matching_catch(-1, -1,0); $9471$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1350: + var $9472=$std_stringstream20; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9473=(($9472+8)|0); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9474=$9473; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9475 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9474, ((95248)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1351; break; } else { label = 1372; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1351: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2665, ((96568)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1352; break; } else { label = 1372; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1352: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2664, $2665, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1353; break; } else { label = 1373; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1353: + var $9479 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($9475, $2664) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1354; break; } else { label = 1374; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1354: + var $9481 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9479, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1355; break; } else { label = 1374; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1355: + var $9483 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9481, ((95840)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1356; break; } else { label = 1374; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1356: + var $9485 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9483, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1357; break; } else { label = 1374; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1357: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2664) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1358; break; } else { label = 1373; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1358: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2665) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1359; break; } else { label = 1372; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1359: + var $9489=___cxa_allocate_exception(8); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2667=1; + var $9490=$9489; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1315=$std_stringstream20; + var $9491=$1315; + var $9492=(($9491+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2666, $9492) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1360; break; } else { label = 1378; break; } + case 1360: + label = 1361; break; + case 1361: + $1314=$2666; + var $9494=$1314; + $1313=$9494; + var $9495=$1313; + $1312=$9495; + var $9496=$1312; + $1311=$9496; + var $9497=$1311; + var $9498=(($9497)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1310=$9498; + var $9499=$1310; + var $9500=$9499; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1309=$9500; + var $9501=$1309; + var $9502=(($9501)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9503=(($9502)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9504=$9503; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9505=(($9504)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9506=$9505; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9507=HEAP8[($9506)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9508=(($9507)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9509=$9508 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9510=(($9509)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($9510) { label = 1362; break; } else { label = 1363; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1362: + $1303=$9496; + var $9512=$1303; + var $9513=(($9512)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1302=$9513; + var $9514=$1302; + var $9515=$9514; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1301=$9515; + var $9516=$1301; + var $9517=(($9516)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9518=(($9517)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9519=$9518; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9520=(($9519+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9521=HEAP32[(($9520)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9535 = $9521;label = 1364; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1363: + $1308=$9496; + var $9523=$1308; + var $9524=(($9523)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1307=$9524; + var $9525=$1307; + var $9526=$9525; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1306=$9526; + var $9527=$1306; + var $9528=(($9527)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9529=(($9528)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9530=$9529; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9531=(($9530+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9532=(($9531)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1305=$9532; + var $9533=$1305; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1304=$9533; + var $9534=$1304; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $9535 = $9534;label = 1364; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1364: + var $9535; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1300=$9535; + var $9536=$1300; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($9490, $9536) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1365; break; } else { label = 1379; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1365: + $2667=0; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($9489, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1379; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2666) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1366; break; } else { label = 1378; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1366: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream20); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1386; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1367: + var $9541$0 = ___cxa_find_matching_catch(-1, -1); $9541$1 = tempRet0; + var $9542=$9541$0; + $2542=$9542; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9543=$9541$1; + $2543=$9543; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1370; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1368: + var $9545$0 = ___cxa_find_matching_catch(-1, -1); $9545$1 = tempRet0; + var $9546=$9545$0; + $2542=$9546; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9547=$9545$1; + $2543=$9547; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2662) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1369; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1369: + label = 1370; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1370: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2663) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1371; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1371: + label = 2840; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1372: + var $9552$0 = ___cxa_find_matching_catch(-1, -1); $9552$1 = tempRet0; + var $9553=$9552$0; + $2542=$9553; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9554=$9552$1; + $2543=$9554; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1384; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1373: + var $9556$0 = ___cxa_find_matching_catch(-1, -1); $9556$1 = tempRet0; + var $9557=$9556$0; + $2542=$9557; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9558=$9556$1; + $2543=$9558; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1376; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1374: + var $9560$0 = ___cxa_find_matching_catch(-1, -1); $9560$1 = tempRet0; + var $9561=$9560$0; + $2542=$9561; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9562=$9560$1; + $2543=$9562; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2664) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1375; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1375: + label = 1376; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1376: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2665) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1377; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1377: + label = 1384; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1378: + var $9567$0 = ___cxa_find_matching_catch(-1, -1); $9567$1 = tempRet0; + var $9568=$9567$0; + $2542=$9568; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9569=$9567$1; + $2543=$9569; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1381; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1379: + var $9571$0 = ___cxa_find_matching_catch(-1, -1); $9571$1 = tempRet0; + var $9572=$9571$0; + $2542=$9572; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9573=$9571$1; + $2543=$9573; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2666) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1380; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1380: + label = 1381; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1381: + var $9576=$2667; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9576) { label = 1382; break; } else { label = 1383; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1382: + ___cxa_free_exception($9489); //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1383; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1383: + label = 1384; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1384: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream20) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1385; break; } else { label = 2841; break; } //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1385: + label = 2840; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1386: + label = 1387; break; //@line 158 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1387: + label = 1388; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1388: + __ZN6StringC1EPKc($2669, ((96568)|0)); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2668, $2669, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1389; break; } else { label = 1433; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1389: + var $9585 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2668, ((94840)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1390; break; } else { label = 1434; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1390: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2668) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1391; break; } else { label = 1433; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1391: + __ZN6StringD1Ev($2669); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9585) { label = 1392; break; } else { label = 1452; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1392: + $1296=$std_stringstream21; + $1297=24; + var $9589=$1296; + var $9590=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9591=(($9590+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9592=$9591; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1295=$9592; + var $9593=$1295; + var $9594=$9593; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1294=$9594; + var $9595=$1294; + var $9596=$9595; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9596)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $9597=$9593; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9597)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $9598=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9598)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9599=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9600=(($9599+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9601=$9600; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9601)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9602=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9603=(($9602+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9604=$9603; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9604)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9605=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9606=(($9589+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9607=$9606; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1264=$9605; + $1265=((109796)|0); + $1266=$9607; + var $9608=$1264; + var $9609=$1265; + var $9610=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9611=(($9609+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9612=$1266; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1261=$9610; + $1262=$9611; + $1263=$9612; + var $9613=$1261; + var $9614=$1262; + var $9615=HEAP32[(($9614)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9616=$9613; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9616)>>2)]=$9615; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9617=(($9614+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9618=HEAP32[(($9617)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9619=$9613; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9620=HEAP32[(($9619)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9621=((($9620)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9622=$9621; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9623=HEAP32[(($9622)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9624=$9613; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9625=(($9624+$9623)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9626=$9625; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9626)>>2)]=$9618; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9627=(($9613+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9627)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9628=$9613; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9629=HEAP32[(($9628)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9630=((($9629)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9631=$9630; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9632=HEAP32[(($9631)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9633=$9613; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9634=(($9633+$9632)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9635=$9634; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9636=$1263; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1259=$9635; + $1260=$9636; + var $9637=$1259; + var $9638=$9637; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9639=$1260; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9640=$9639; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($9638, $9640) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1393; break; } else { label = 1409; break; } + case 1393: + var $9641=(($9637+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9641)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $9642=(($9637+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9642)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $9643=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9644=(($9643+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9645=$9644; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9646=(($9609+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1257=$9645; + $1258=$9646; + var $9647=$1257; + var $9648=$1258; + var $9649=HEAP32[(($9648)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9650=$9647; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9650)>>2)]=$9649; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9651=(($9648+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9652=HEAP32[(($9651)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9653=$9647; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9654=HEAP32[(($9653)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9655=((($9654)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9656=$9655; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9657=HEAP32[(($9656)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9658=$9647; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9659=(($9658+$9657)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9660=$9659; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9660)>>2)]=$9652; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9661=HEAP32[(($9609)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9662=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9662)>>2)]=$9661; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9663=(($9609+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9664=HEAP32[(($9663)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9665=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9666=HEAP32[(($9665)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9667=((($9666)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9668=$9667; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9669=HEAP32[(($9668)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9670=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9671=(($9670+$9669)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9672=$9671; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9672)>>2)]=$9664; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9673=(($9609+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9674=HEAP32[(($9673)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9675=$9608; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9676=(($9675+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9677=$9676; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9677)>>2)]=$9674; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9678=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9678)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9679=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9680=(($9679+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9681=$9680; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9681)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9682=$9589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9683=(($9682+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9684=$9683; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9684)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9685=(($9589+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9686=$1297; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1292=$9685; + $1293=$9686; + var $9687=$1292; + var $9688=$1293; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1287=$9687; + $1288=$9688; + var $9689=$1287; + var $9690=$9689; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($9690) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1394; break; } else { label = 1410; break; } + case 1394: + var $9691=$9689; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9691)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9692=(($9689+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1286=$9692; + var $9693=$1286; + $1285=$9693; + var $9694=$1285; + var $9695=$9694; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9696=(($9694)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1284=$9696; + var $9697=$1284; + $1283=$9697; + var $9698=$1283; + var $9699=$9698; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1282=$9699; + var $9700=$1282; + var $9701=$9700; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1281=$9701; + var $9702=$1281; + var $9703=(($9700)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1280=$9694; + var $9704=$1280; + var $9705=(($9704)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1279=$9705; + var $9706=$1279; + var $9707=$9706; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1278=$9707; + var $9708=$1278; + var $9709=(($9708)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9710=(($9709)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9711=$9710; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9712=(($9711)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i305=$9712; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i306=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1395; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1395: + var $9714=$__i_i_i_i_i_i_i306; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9715=(($9714)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9715) { label = 1396; break; } else { label = 1397; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1396: + var $9717=$__i_i_i_i_i_i_i306; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9718=$__a_i_i_i_i_i_i305; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9719=(($9718+($9717<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9719)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9720=$__i_i_i_i_i_i_i306; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9721=((($9720)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i306=$9721; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1395; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1397: + var $9722=(($9689+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9722)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9723=(($9689+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $9724=$1288; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9723)>>2)]=$9724; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1277=$1291; + var $9725=$1277; + $1276=$9725; + var $9726=$1276; + var $9727=$9726; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $9728=(($9726)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1275=$9728; + var $9729=$1275; + $1274=$9729; + var $9730=$1274; + var $9731=$9730; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1273=$9731; + var $9732=$1273; + var $9733=$9732; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1272=$9733; + var $9734=$1272; + var $9735=(($9732)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1271=$9726; + var $9736=$1271; + var $9737=(($9736)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1270=$9737; + var $9738=$1270; + var $9739=$9738; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1269=$9739; + var $9740=$1269; + var $9741=(($9740)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $9742=(($9741)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9743=$9742; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $9744=(($9743)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i303=$9744; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i304=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1398; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1398: + var $9746=$__i_i_i_i2_i_i_i304; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9747=(($9746)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($9747) { label = 1399; break; } else { label = 1400; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1399: + var $9749=$__i_i_i_i2_i_i_i304; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9750=$__a_i_i_i1_i_i_i303; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9751=(($9750+($9749<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($9751)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $9752=$__i_i_i_i2_i_i_i304; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $9753=((($9752)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i304=$9753; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1398; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1400: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($9689, $1291) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1401; break; } else { label = 1403; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1401: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1291) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1416; break; } else { label = 1402; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1402: + var $9756$0 = ___cxa_find_matching_catch(-1, -1); $9756$1 = tempRet0; + var $9757=$9756$0; + $1289=$9757; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9758=$9756$1; + $1290=$9758; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1405; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1403: + var $9760$0 = ___cxa_find_matching_catch(-1, -1); $9760$1 = tempRet0; + var $9761=$9760$0; + $1289=$9761; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $9762=$9760$1; + $1290=$9762; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1291) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1404; break; } else { label = 1408; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1404: + label = 1405; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1405: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($9692) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1406; break; } else { label = 1408; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1406: + var $9766=$9689; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($9766) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1407; break; } else { label = 1408; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1407: + var $9768=$1289; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9769=$1290; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $9770$0=$9768; + var $9770$1=0; + var $9771$0=$9770$0; + var $9771$1=$9769; + var $eh_lpad_body_i311$1 = $9771$1;var $eh_lpad_body_i311$0 = $9771$0;label = 1411; break; + case 1408: + var $9773$0 = ___cxa_find_matching_catch(-1, -1,0); $9773$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1409: + var $9775$0 = ___cxa_find_matching_catch(-1, -1); $9775$1 = tempRet0; + var $9776=$9775$0; + $1298=$9776; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9777=$9775$1; + $1299=$9777; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1413; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1410: + var $9779$0 = ___cxa_find_matching_catch(-1, -1); $9779$1 = tempRet0; + var $eh_lpad_body_i311$1 = $9779$1;var $eh_lpad_body_i311$0 = $9779$0;label = 1411; break; + case 1411: + var $eh_lpad_body_i311$0; + var $eh_lpad_body_i311$1; + var $9780=$eh_lpad_body_i311$0; + $1298=$9780; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9781=$eh_lpad_body_i311$1; + $1299=$9781; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9782=$9589; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($9782, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1412; break; } else { label = 1415; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1412: + label = 1413; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1413: + var $9785=$9589; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9786=(($9785+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9787=$9786; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($9787) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1414; break; } else { label = 1415; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1414: + var $9789=$1298; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9790=$1299; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $9791$0=$9789; + var $9791$1=0; + var $9792$0=$9791$0; + var $9792$1=$9790; + ___resumeException($9792$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1415: + var $9794$0 = ___cxa_find_matching_catch(-1, -1,0); $9794$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1416: + var $9795=$std_stringstream21; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9796=(($9795+8)|0); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9797=$9796; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9798 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9797, ((94536)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1417; break; } else { label = 1438; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1417: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2671, ((96568)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1418; break; } else { label = 1438; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1418: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2670, $2671, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1419; break; } else { label = 1439; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1419: + var $9802 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($9798, $2670) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1420; break; } else { label = 1440; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1420: + var $9804 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9802, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1421; break; } else { label = 1440; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1421: + var $9806 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9804, ((94840)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1422; break; } else { label = 1440; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1422: + var $9808 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($9806, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1423; break; } else { label = 1440; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1423: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2670) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1424; break; } else { label = 1439; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1424: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2671) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1425; break; } else { label = 1438; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1425: + var $9812=___cxa_allocate_exception(8); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2673=1; + var $9813=$9812; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1256=$std_stringstream21; + var $9814=$1256; + var $9815=(($9814+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2672, $9815) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1426; break; } else { label = 1444; break; } + case 1426: + label = 1427; break; + case 1427: + $1255=$2672; + var $9817=$1255; + $1254=$9817; + var $9818=$1254; + $1253=$9818; + var $9819=$1253; + $1252=$9819; + var $9820=$1252; + var $9821=(($9820)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1251=$9821; + var $9822=$1251; + var $9823=$9822; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1250=$9823; + var $9824=$1250; + var $9825=(($9824)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9826=(($9825)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9827=$9826; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9828=(($9827)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9829=$9828; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9830=HEAP8[($9829)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9831=(($9830)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9832=$9831 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $9833=(($9832)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($9833) { label = 1428; break; } else { label = 1429; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1428: + $1244=$9819; + var $9835=$1244; + var $9836=(($9835)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1243=$9836; + var $9837=$1243; + var $9838=$9837; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1242=$9838; + var $9839=$1242; + var $9840=(($9839)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9841=(($9840)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9842=$9841; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9843=(($9842+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9844=HEAP32[(($9843)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $9858 = $9844;label = 1430; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1429: + $1249=$9819; + var $9846=$1249; + var $9847=(($9846)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1248=$9847; + var $9848=$1248; + var $9849=$9848; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1247=$9849; + var $9850=$1247; + var $9851=(($9850)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $9852=(($9851)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9853=$9852; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9854=(($9853+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $9855=(($9854)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1246=$9855; + var $9856=$1246; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1245=$9856; + var $9857=$1245; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $9858 = $9857;label = 1430; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1430: + var $9858; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1241=$9858; + var $9859=$1241; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($9813, $9859) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1431; break; } else { label = 1445; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1431: + $2673=0; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($9812, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1445; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2672) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1432; break; } else { label = 1444; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1432: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream21); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1452; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1433: + var $9864$0 = ___cxa_find_matching_catch(-1, -1); $9864$1 = tempRet0; + var $9865=$9864$0; + $2542=$9865; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9866=$9864$1; + $2543=$9866; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1436; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1434: + var $9868$0 = ___cxa_find_matching_catch(-1, -1); $9868$1 = tempRet0; + var $9869=$9868$0; + $2542=$9869; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9870=$9868$1; + $2543=$9870; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2668) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1435; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1435: + label = 1436; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1436: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2669) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1437; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1437: + label = 2840; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1438: + var $9875$0 = ___cxa_find_matching_catch(-1, -1); $9875$1 = tempRet0; + var $9876=$9875$0; + $2542=$9876; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9877=$9875$1; + $2543=$9877; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1450; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1439: + var $9879$0 = ___cxa_find_matching_catch(-1, -1); $9879$1 = tempRet0; + var $9880=$9879$0; + $2542=$9880; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9881=$9879$1; + $2543=$9881; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1442; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1440: + var $9883$0 = ___cxa_find_matching_catch(-1, -1); $9883$1 = tempRet0; + var $9884=$9883$0; + $2542=$9884; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9885=$9883$1; + $2543=$9885; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2670) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1441; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1441: + label = 1442; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1442: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2671) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1443; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1443: + label = 1450; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1444: + var $9890$0 = ___cxa_find_matching_catch(-1, -1); $9890$1 = tempRet0; + var $9891=$9890$0; + $2542=$9891; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9892=$9890$1; + $2543=$9892; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1447; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1445: + var $9894$0 = ___cxa_find_matching_catch(-1, -1); $9894$1 = tempRet0; + var $9895=$9894$0; + $2542=$9895; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $9896=$9894$1; + $2543=$9896; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2672) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1446; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1446: + label = 1447; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1447: + var $9899=$2673; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9899) { label = 1448; break; } else { label = 1449; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1448: + ___cxa_free_exception($9812); //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1449; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1449: + label = 1450; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1450: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream21) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1451; break; } else { label = 2841; break; } //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1451: + label = 2840; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1452: + label = 1453; break; //@line 159 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1453: + label = 1454; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1454: + __ZN6StringC1EPKc($2675, ((94168)|0)); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2674, $2675, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1455; break; } else { label = 1499; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1455: + var $9908 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2674, ((93872)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1456; break; } else { label = 1500; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1456: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2674) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1457; break; } else { label = 1499; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1457: + __ZN6StringD1Ev($2675); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($9908) { label = 1458; break; } else { label = 1518; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1458: + $1237=$std_stringstream22; + $1238=24; + var $9912=$1237; + var $9913=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9914=(($9913+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9915=$9914; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1236=$9915; + var $9916=$1236; + var $9917=$9916; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1235=$9917; + var $9918=$1235; + var $9919=$9918; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9919)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $9920=$9916; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9920)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $9921=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9921)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9922=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9923=(($9922+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9924=$9923; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9924)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9925=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9926=(($9925+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9927=$9926; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9927)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9928=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9929=(($9912+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $9930=$9929; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1205=$9928; + $1206=((109796)|0); + $1207=$9930; + var $9931=$1205; + var $9932=$1206; + var $9933=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9934=(($9932+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9935=$1207; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1202=$9933; + $1203=$9934; + $1204=$9935; + var $9936=$1202; + var $9937=$1203; + var $9938=HEAP32[(($9937)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9939=$9936; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9939)>>2)]=$9938; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9940=(($9937+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9941=HEAP32[(($9940)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9942=$9936; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9943=HEAP32[(($9942)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9944=((($9943)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9945=$9944; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9946=HEAP32[(($9945)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9947=$9936; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9948=(($9947+$9946)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9949=$9948; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9949)>>2)]=$9941; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9950=(($9936+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9950)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $9951=$9936; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9952=HEAP32[(($9951)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9953=((($9952)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9954=$9953; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9955=HEAP32[(($9954)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9956=$9936; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9957=(($9956+$9955)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9958=$9957; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $9959=$1204; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1200=$9958; + $1201=$9959; + var $9960=$1200; + var $9961=$9960; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9962=$1201; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $9963=$9962; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($9961, $9963) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1459; break; } else { label = 1475; break; } + case 1459: + var $9964=(($9960+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9964)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $9965=(($9960+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($9965)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $9966=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9967=(($9966+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9968=$9967; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9969=(($9932+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1198=$9968; + $1199=$9969; + var $9970=$1198; + var $9971=$1199; + var $9972=HEAP32[(($9971)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9973=$9970; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9973)>>2)]=$9972; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9974=(($9971+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9975=HEAP32[(($9974)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9976=$9970; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9977=HEAP32[(($9976)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9978=((($9977)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9979=$9978; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9980=HEAP32[(($9979)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9981=$9970; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9982=(($9981+$9980)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9983=$9982; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9983)>>2)]=$9975; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $9984=HEAP32[(($9932)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9985=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9985)>>2)]=$9984; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9986=(($9932+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9987=HEAP32[(($9986)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9988=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9989=HEAP32[(($9988)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9990=((($9989)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9991=$9990; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9992=HEAP32[(($9991)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9993=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9994=(($9993+$9992)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9995=$9994; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($9995)>>2)]=$9987; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9996=(($9932+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9997=HEAP32[(($9996)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9998=$9931; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $9999=(($9998+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10000=$9999; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10000)>>2)]=$9997; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10001=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10001)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10002=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10003=(($10002+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10004=$10003; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10004)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10005=$9912; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10006=(($10005+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10007=$10006; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10007)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10008=(($9912+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10009=$1238; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1233=$10008; + $1234=$10009; + var $10010=$1233; + var $10011=$1234; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1228=$10010; + $1229=$10011; + var $10012=$1228; + var $10013=$10012; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($10013) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1460; break; } else { label = 1476; break; } + case 1460: + var $10014=$10012; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10014)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10015=(($10012+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1227=$10015; + var $10016=$1227; + $1226=$10016; + var $10017=$1226; + var $10018=$10017; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10019=(($10017)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1225=$10019; + var $10020=$1225; + $1224=$10020; + var $10021=$1224; + var $10022=$10021; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1223=$10022; + var $10023=$1223; + var $10024=$10023; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1222=$10024; + var $10025=$1222; + var $10026=(($10023)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1221=$10017; + var $10027=$1221; + var $10028=(($10027)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1220=$10028; + var $10029=$1220; + var $10030=$10029; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1219=$10030; + var $10031=$1219; + var $10032=(($10031)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10033=(($10032)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10034=$10033; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10035=(($10034)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i318=$10035; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i319=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1461; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1461: + var $10037=$__i_i_i_i_i_i_i319; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10038=(($10037)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10038) { label = 1462; break; } else { label = 1463; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1462: + var $10040=$__i_i_i_i_i_i_i319; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10041=$__a_i_i_i_i_i_i318; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10042=(($10041+($10040<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10042)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10043=$__i_i_i_i_i_i_i319; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10044=((($10043)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i319=$10044; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1461; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1463: + var $10045=(($10012+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10045)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10046=(($10012+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10047=$1229; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10046)>>2)]=$10047; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1218=$1232; + var $10048=$1218; + $1217=$10048; + var $10049=$1217; + var $10050=$10049; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10051=(($10049)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1216=$10051; + var $10052=$1216; + $1215=$10052; + var $10053=$1215; + var $10054=$10053; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1214=$10054; + var $10055=$1214; + var $10056=$10055; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1213=$10056; + var $10057=$1213; + var $10058=(($10055)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1212=$10049; + var $10059=$1212; + var $10060=(($10059)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1211=$10060; + var $10061=$1211; + var $10062=$10061; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1210=$10062; + var $10063=$1210; + var $10064=(($10063)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10065=(($10064)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10066=$10065; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10067=(($10066)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i316=$10067; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i317=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1464; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1464: + var $10069=$__i_i_i_i2_i_i_i317; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10070=(($10069)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10070) { label = 1465; break; } else { label = 1466; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1465: + var $10072=$__i_i_i_i2_i_i_i317; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10073=$__a_i_i_i1_i_i_i316; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10074=(($10073+($10072<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10074)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10075=$__i_i_i_i2_i_i_i317; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10076=((($10075)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i317=$10076; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1464; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1466: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($10012, $1232) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1467; break; } else { label = 1469; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1467: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1232) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1482; break; } else { label = 1468; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1468: + var $10079$0 = ___cxa_find_matching_catch(-1, -1); $10079$1 = tempRet0; + var $10080=$10079$0; + $1230=$10080; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10081=$10079$1; + $1231=$10081; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1471; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1469: + var $10083$0 = ___cxa_find_matching_catch(-1, -1); $10083$1 = tempRet0; + var $10084=$10083$0; + $1230=$10084; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10085=$10083$1; + $1231=$10085; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1232) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1470; break; } else { label = 1474; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1470: + label = 1471; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1471: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($10015) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1472; break; } else { label = 1474; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1472: + var $10089=$10012; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($10089) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1473; break; } else { label = 1474; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1473: + var $10091=$1230; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10092=$1231; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10093$0=$10091; + var $10093$1=0; + var $10094$0=$10093$0; + var $10094$1=$10092; + var $eh_lpad_body_i324$1 = $10094$1;var $eh_lpad_body_i324$0 = $10094$0;label = 1477; break; + case 1474: + var $10096$0 = ___cxa_find_matching_catch(-1, -1,0); $10096$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1475: + var $10098$0 = ___cxa_find_matching_catch(-1, -1); $10098$1 = tempRet0; + var $10099=$10098$0; + $1239=$10099; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10100=$10098$1; + $1240=$10100; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1479; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1476: + var $10102$0 = ___cxa_find_matching_catch(-1, -1); $10102$1 = tempRet0; + var $eh_lpad_body_i324$1 = $10102$1;var $eh_lpad_body_i324$0 = $10102$0;label = 1477; break; + case 1477: + var $eh_lpad_body_i324$0; + var $eh_lpad_body_i324$1; + var $10103=$eh_lpad_body_i324$0; + $1239=$10103; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10104=$eh_lpad_body_i324$1; + $1240=$10104; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10105=$9912; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($10105, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1478; break; } else { label = 1481; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1478: + label = 1479; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1479: + var $10108=$9912; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10109=(($10108+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10110=$10109; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($10110) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1480; break; } else { label = 1481; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1480: + var $10112=$1239; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10113=$1240; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10114$0=$10112; + var $10114$1=0; + var $10115$0=$10114$0; + var $10115$1=$10113; + ___resumeException($10115$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1481: + var $10117$0 = ___cxa_find_matching_catch(-1, -1,0); $10117$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1482: + var $10118=$std_stringstream22; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10119=(($10118+8)|0); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10120=$10119; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10121 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10120, ((93576)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1483; break; } else { label = 1504; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1483: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2677, ((94168)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1484; break; } else { label = 1504; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1484: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2676, $2677, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1485; break; } else { label = 1505; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1485: + var $10125 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($10121, $2676) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1486; break; } else { label = 1506; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1486: + var $10127 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10125, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1487; break; } else { label = 1506; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1487: + var $10129 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10127, ((93872)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1488; break; } else { label = 1506; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1488: + var $10131 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10129, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1489; break; } else { label = 1506; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1489: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2676) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1490; break; } else { label = 1505; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1490: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2677) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1491; break; } else { label = 1504; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1491: + var $10135=___cxa_allocate_exception(8); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2679=1; + var $10136=$10135; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1197=$std_stringstream22; + var $10137=$1197; + var $10138=(($10137+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2678, $10138) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1492; break; } else { label = 1510; break; } + case 1492: + label = 1493; break; + case 1493: + $1196=$2678; + var $10140=$1196; + $1195=$10140; + var $10141=$1195; + $1194=$10141; + var $10142=$1194; + $1193=$10142; + var $10143=$1193; + var $10144=(($10143)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1192=$10144; + var $10145=$1192; + var $10146=$10145; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1191=$10146; + var $10147=$1191; + var $10148=(($10147)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10149=(($10148)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10150=$10149; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10151=(($10150)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10152=$10151; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10153=HEAP8[($10152)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10154=(($10153)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10155=$10154 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10156=(($10155)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($10156) { label = 1494; break; } else { label = 1495; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1494: + $1185=$10142; + var $10158=$1185; + var $10159=(($10158)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1184=$10159; + var $10160=$1184; + var $10161=$10160; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1183=$10161; + var $10162=$1183; + var $10163=(($10162)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10164=(($10163)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10165=$10164; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10166=(($10165+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10167=HEAP32[(($10166)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10181 = $10167;label = 1496; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1495: + $1190=$10142; + var $10169=$1190; + var $10170=(($10169)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1189=$10170; + var $10171=$1189; + var $10172=$10171; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1188=$10172; + var $10173=$1188; + var $10174=(($10173)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10175=(($10174)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10176=$10175; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10177=(($10176+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10178=(($10177)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1187=$10178; + var $10179=$1187; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1186=$10179; + var $10180=$1186; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $10181 = $10180;label = 1496; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1496: + var $10181; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1182=$10181; + var $10182=$1182; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($10136, $10182) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1497; break; } else { label = 1511; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1497: + $2679=0; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($10135, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1511; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2678) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1498; break; } else { label = 1510; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1498: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream22); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1518; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1499: + var $10187$0 = ___cxa_find_matching_catch(-1, -1); $10187$1 = tempRet0; + var $10188=$10187$0; + $2542=$10188; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10189=$10187$1; + $2543=$10189; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1502; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1500: + var $10191$0 = ___cxa_find_matching_catch(-1, -1); $10191$1 = tempRet0; + var $10192=$10191$0; + $2542=$10192; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10193=$10191$1; + $2543=$10193; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2674) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1501; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1501: + label = 1502; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1502: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2675) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1503; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1503: + label = 2840; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1504: + var $10198$0 = ___cxa_find_matching_catch(-1, -1); $10198$1 = tempRet0; + var $10199=$10198$0; + $2542=$10199; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10200=$10198$1; + $2543=$10200; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1516; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1505: + var $10202$0 = ___cxa_find_matching_catch(-1, -1); $10202$1 = tempRet0; + var $10203=$10202$0; + $2542=$10203; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10204=$10202$1; + $2543=$10204; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1508; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1506: + var $10206$0 = ___cxa_find_matching_catch(-1, -1); $10206$1 = tempRet0; + var $10207=$10206$0; + $2542=$10207; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10208=$10206$1; + $2543=$10208; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2676) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1507; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1507: + label = 1508; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1508: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2677) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1509; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1509: + label = 1516; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1510: + var $10213$0 = ___cxa_find_matching_catch(-1, -1); $10213$1 = tempRet0; + var $10214=$10213$0; + $2542=$10214; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10215=$10213$1; + $2543=$10215; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1513; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1511: + var $10217$0 = ___cxa_find_matching_catch(-1, -1); $10217$1 = tempRet0; + var $10218=$10217$0; + $2542=$10218; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10219=$10217$1; + $2543=$10219; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2678) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1512; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1512: + label = 1513; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1513: + var $10222=$2679; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10222) { label = 1514; break; } else { label = 1515; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1514: + ___cxa_free_exception($10135); //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1515; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1515: + label = 1516; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1516: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream22) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1517; break; } else { label = 2841; break; } //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1517: + label = 2840; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1518: + label = 1519; break; //@line 160 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1519: + label = 1520; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1520: + __ZN6StringC1EPKc($2681, ((94168)|0)); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2680, $2681, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1521; break; } else { label = 1565; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1521: + var $10231 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2680, ((93368)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1522; break; } else { label = 1566; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1522: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2680) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1523; break; } else { label = 1565; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1523: + __ZN6StringD1Ev($2681); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10231) { label = 1524; break; } else { label = 1584; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1524: + $1178=$std_stringstream23; + $1179=24; + var $10235=$1178; + var $10236=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10237=(($10236+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10238=$10237; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1177=$10238; + var $10239=$1177; + var $10240=$10239; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1176=$10240; + var $10241=$1176; + var $10242=$10241; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10242)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $10243=$10239; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10243)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $10244=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10244)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10245=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10246=(($10245+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10247=$10246; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10247)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10248=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10249=(($10248+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10250=$10249; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10250)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10251=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10252=(($10235+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10253=$10252; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1146=$10251; + $1147=((109796)|0); + $1148=$10253; + var $10254=$1146; + var $10255=$1147; + var $10256=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10257=(($10255+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10258=$1148; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1143=$10256; + $1144=$10257; + $1145=$10258; + var $10259=$1143; + var $10260=$1144; + var $10261=HEAP32[(($10260)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10262=$10259; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10262)>>2)]=$10261; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10263=(($10260+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10264=HEAP32[(($10263)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10265=$10259; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10266=HEAP32[(($10265)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10267=((($10266)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10268=$10267; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10269=HEAP32[(($10268)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10270=$10259; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10271=(($10270+$10269)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10272=$10271; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10272)>>2)]=$10264; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10273=(($10259+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10273)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10274=$10259; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10275=HEAP32[(($10274)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10276=((($10275)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10277=$10276; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10278=HEAP32[(($10277)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10279=$10259; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10280=(($10279+$10278)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10281=$10280; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10282=$1145; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1141=$10281; + $1142=$10282; + var $10283=$1141; + var $10284=$10283; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10285=$1142; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10286=$10285; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($10284, $10286) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1525; break; } else { label = 1541; break; } + case 1525: + var $10287=(($10283+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10287)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $10288=(($10283+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10288)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $10289=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10290=(($10289+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10291=$10290; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10292=(($10255+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1139=$10291; + $1140=$10292; + var $10293=$1139; + var $10294=$1140; + var $10295=HEAP32[(($10294)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10296=$10293; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10296)>>2)]=$10295; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10297=(($10294+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10298=HEAP32[(($10297)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10299=$10293; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10300=HEAP32[(($10299)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10301=((($10300)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10302=$10301; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10303=HEAP32[(($10302)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10304=$10293; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10305=(($10304+$10303)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10306=$10305; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10306)>>2)]=$10298; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10307=HEAP32[(($10255)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10308=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10308)>>2)]=$10307; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10309=(($10255+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10310=HEAP32[(($10309)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10311=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10312=HEAP32[(($10311)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10313=((($10312)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10314=$10313; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10315=HEAP32[(($10314)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10316=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10317=(($10316+$10315)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10318=$10317; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10318)>>2)]=$10310; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10319=(($10255+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10320=HEAP32[(($10319)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10321=$10254; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10322=(($10321+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10323=$10322; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10323)>>2)]=$10320; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10324=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10324)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10325=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10326=(($10325+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10327=$10326; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10327)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10328=$10235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10329=(($10328+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10330=$10329; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10330)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10331=(($10235+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10332=$1179; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1174=$10331; + $1175=$10332; + var $10333=$1174; + var $10334=$1175; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1169=$10333; + $1170=$10334; + var $10335=$1169; + var $10336=$10335; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($10336) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1526; break; } else { label = 1542; break; } + case 1526: + var $10337=$10335; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10337)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10338=(($10335+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1168=$10338; + var $10339=$1168; + $1167=$10339; + var $10340=$1167; + var $10341=$10340; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10342=(($10340)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1166=$10342; + var $10343=$1166; + $1165=$10343; + var $10344=$1165; + var $10345=$10344; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1164=$10345; + var $10346=$1164; + var $10347=$10346; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1163=$10347; + var $10348=$1163; + var $10349=(($10346)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1162=$10340; + var $10350=$1162; + var $10351=(($10350)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1161=$10351; + var $10352=$1161; + var $10353=$10352; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1160=$10353; + var $10354=$1160; + var $10355=(($10354)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10356=(($10355)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10357=$10356; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10358=(($10357)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i331=$10358; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i332=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1527; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1527: + var $10360=$__i_i_i_i_i_i_i332; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10361=(($10360)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10361) { label = 1528; break; } else { label = 1529; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1528: + var $10363=$__i_i_i_i_i_i_i332; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10364=$__a_i_i_i_i_i_i331; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10365=(($10364+($10363<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10365)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10366=$__i_i_i_i_i_i_i332; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10367=((($10366)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i332=$10367; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1527; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1529: + var $10368=(($10335+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10368)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10369=(($10335+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10370=$1170; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10369)>>2)]=$10370; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1159=$1173; + var $10371=$1159; + $1158=$10371; + var $10372=$1158; + var $10373=$10372; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10374=(($10372)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1157=$10374; + var $10375=$1157; + $1156=$10375; + var $10376=$1156; + var $10377=$10376; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1155=$10377; + var $10378=$1155; + var $10379=$10378; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1154=$10379; + var $10380=$1154; + var $10381=(($10378)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1153=$10372; + var $10382=$1153; + var $10383=(($10382)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1152=$10383; + var $10384=$1152; + var $10385=$10384; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1151=$10385; + var $10386=$1151; + var $10387=(($10386)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10388=(($10387)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10389=$10388; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10390=(($10389)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i329=$10390; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i330=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1530; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1530: + var $10392=$__i_i_i_i2_i_i_i330; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10393=(($10392)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10393) { label = 1531; break; } else { label = 1532; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1531: + var $10395=$__i_i_i_i2_i_i_i330; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10396=$__a_i_i_i1_i_i_i329; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10397=(($10396+($10395<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10397)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10398=$__i_i_i_i2_i_i_i330; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10399=((($10398)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i330=$10399; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1530; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1532: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($10335, $1173) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1533; break; } else { label = 1535; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1533: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1173) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1548; break; } else { label = 1534; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1534: + var $10402$0 = ___cxa_find_matching_catch(-1, -1); $10402$1 = tempRet0; + var $10403=$10402$0; + $1171=$10403; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10404=$10402$1; + $1172=$10404; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1537; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1535: + var $10406$0 = ___cxa_find_matching_catch(-1, -1); $10406$1 = tempRet0; + var $10407=$10406$0; + $1171=$10407; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10408=$10406$1; + $1172=$10408; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1173) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1536; break; } else { label = 1540; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1536: + label = 1537; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1537: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($10338) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1538; break; } else { label = 1540; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1538: + var $10412=$10335; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($10412) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1539; break; } else { label = 1540; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1539: + var $10414=$1171; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10415=$1172; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10416$0=$10414; + var $10416$1=0; + var $10417$0=$10416$0; + var $10417$1=$10415; + var $eh_lpad_body_i337$1 = $10417$1;var $eh_lpad_body_i337$0 = $10417$0;label = 1543; break; + case 1540: + var $10419$0 = ___cxa_find_matching_catch(-1, -1,0); $10419$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1541: + var $10421$0 = ___cxa_find_matching_catch(-1, -1); $10421$1 = tempRet0; + var $10422=$10421$0; + $1180=$10422; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10423=$10421$1; + $1181=$10423; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1545; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1542: + var $10425$0 = ___cxa_find_matching_catch(-1, -1); $10425$1 = tempRet0; + var $eh_lpad_body_i337$1 = $10425$1;var $eh_lpad_body_i337$0 = $10425$0;label = 1543; break; + case 1543: + var $eh_lpad_body_i337$0; + var $eh_lpad_body_i337$1; + var $10426=$eh_lpad_body_i337$0; + $1180=$10426; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10427=$eh_lpad_body_i337$1; + $1181=$10427; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10428=$10235; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($10428, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1544; break; } else { label = 1547; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1544: + label = 1545; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1545: + var $10431=$10235; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10432=(($10431+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10433=$10432; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($10433) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1546; break; } else { label = 1547; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1546: + var $10435=$1180; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10436=$1181; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10437$0=$10435; + var $10437$1=0; + var $10438$0=$10437$0; + var $10438$1=$10436; + ___resumeException($10438$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1547: + var $10440$0 = ___cxa_find_matching_catch(-1, -1,0); $10440$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1548: + var $10441=$std_stringstream23; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10442=(($10441+8)|0); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10443=$10442; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10444 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10443, ((92800)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1549; break; } else { label = 1570; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1549: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2683, ((94168)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1550; break; } else { label = 1570; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1550: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2682, $2683, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1551; break; } else { label = 1571; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1551: + var $10448 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($10444, $2682) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1552; break; } else { label = 1572; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1552: + var $10450 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10448, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1553; break; } else { label = 1572; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1553: + var $10452 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10450, ((93368)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1554; break; } else { label = 1572; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1554: + var $10454 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10452, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1555; break; } else { label = 1572; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1555: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2682) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1556; break; } else { label = 1571; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1556: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2683) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1557; break; } else { label = 1570; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1557: + var $10458=___cxa_allocate_exception(8); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2685=1; + var $10459=$10458; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1138=$std_stringstream23; + var $10460=$1138; + var $10461=(($10460+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2684, $10461) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1558; break; } else { label = 1576; break; } + case 1558: + label = 1559; break; + case 1559: + $1137=$2684; + var $10463=$1137; + $1136=$10463; + var $10464=$1136; + $1135=$10464; + var $10465=$1135; + $1134=$10465; + var $10466=$1134; + var $10467=(($10466)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1133=$10467; + var $10468=$1133; + var $10469=$10468; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1132=$10469; + var $10470=$1132; + var $10471=(($10470)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10472=(($10471)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10473=$10472; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10474=(($10473)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10475=$10474; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10476=HEAP8[($10475)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10477=(($10476)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10478=$10477 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10479=(($10478)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($10479) { label = 1560; break; } else { label = 1561; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1560: + $1126=$10465; + var $10481=$1126; + var $10482=(($10481)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1125=$10482; + var $10483=$1125; + var $10484=$10483; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1124=$10484; + var $10485=$1124; + var $10486=(($10485)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10487=(($10486)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10488=$10487; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10489=(($10488+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10490=HEAP32[(($10489)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10504 = $10490;label = 1562; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1561: + $1131=$10465; + var $10492=$1131; + var $10493=(($10492)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1130=$10493; + var $10494=$1130; + var $10495=$10494; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1129=$10495; + var $10496=$1129; + var $10497=(($10496)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10498=(($10497)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10499=$10498; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10500=(($10499+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10501=(($10500)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1128=$10501; + var $10502=$1128; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1127=$10502; + var $10503=$1127; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $10504 = $10503;label = 1562; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1562: + var $10504; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1123=$10504; + var $10505=$1123; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($10459, $10505) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1563; break; } else { label = 1577; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1563: + $2685=0; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($10458, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1577; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2684) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1564; break; } else { label = 1576; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1564: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream23); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1584; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1565: + var $10510$0 = ___cxa_find_matching_catch(-1, -1); $10510$1 = tempRet0; + var $10511=$10510$0; + $2542=$10511; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10512=$10510$1; + $2543=$10512; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1568; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1566: + var $10514$0 = ___cxa_find_matching_catch(-1, -1); $10514$1 = tempRet0; + var $10515=$10514$0; + $2542=$10515; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10516=$10514$1; + $2543=$10516; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2680) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1567; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1567: + label = 1568; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1568: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2681) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1569; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1569: + label = 2840; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1570: + var $10521$0 = ___cxa_find_matching_catch(-1, -1); $10521$1 = tempRet0; + var $10522=$10521$0; + $2542=$10522; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10523=$10521$1; + $2543=$10523; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1582; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1571: + var $10525$0 = ___cxa_find_matching_catch(-1, -1); $10525$1 = tempRet0; + var $10526=$10525$0; + $2542=$10526; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10527=$10525$1; + $2543=$10527; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1574; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1572: + var $10529$0 = ___cxa_find_matching_catch(-1, -1); $10529$1 = tempRet0; + var $10530=$10529$0; + $2542=$10530; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10531=$10529$1; + $2543=$10531; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2682) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1573; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1573: + label = 1574; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1574: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2683) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1575; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1575: + label = 1582; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1576: + var $10536$0 = ___cxa_find_matching_catch(-1, -1); $10536$1 = tempRet0; + var $10537=$10536$0; + $2542=$10537; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10538=$10536$1; + $2543=$10538; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1579; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1577: + var $10540$0 = ___cxa_find_matching_catch(-1, -1); $10540$1 = tempRet0; + var $10541=$10540$0; + $2542=$10541; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10542=$10540$1; + $2543=$10542; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2684) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1578; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1578: + label = 1579; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1579: + var $10545=$2685; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10545) { label = 1580; break; } else { label = 1581; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1580: + ___cxa_free_exception($10458); //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1581; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1581: + label = 1582; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1582: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream23) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1583; break; } else { label = 2841; break; } //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1583: + label = 2840; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1584: + label = 1585; break; //@line 161 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1585: + label = 1586; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1586: + __ZN6StringC1EPKc($2687, ((92576)|0)); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2686, $2687, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1587; break; } else { label = 1631; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1587: + var $10554 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2686, ((91784)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1588; break; } else { label = 1632; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1588: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2686) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1589; break; } else { label = 1631; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1589: + __ZN6StringD1Ev($2687); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10554) { label = 1590; break; } else { label = 1650; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1590: + $1119=$std_stringstream24; + $1120=24; + var $10558=$1119; + var $10559=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10560=(($10559+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10561=$10560; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1118=$10561; + var $10562=$1118; + var $10563=$10562; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1117=$10563; + var $10564=$1117; + var $10565=$10564; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10565)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $10566=$10562; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10566)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $10567=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10567)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10568=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10569=(($10568+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10570=$10569; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10570)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10571=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10572=(($10571+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10573=$10572; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10573)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10574=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10575=(($10558+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10576=$10575; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1087=$10574; + $1088=((109796)|0); + $1089=$10576; + var $10577=$1087; + var $10578=$1088; + var $10579=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10580=(($10578+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10581=$1089; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1084=$10579; + $1085=$10580; + $1086=$10581; + var $10582=$1084; + var $10583=$1085; + var $10584=HEAP32[(($10583)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10585=$10582; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10585)>>2)]=$10584; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10586=(($10583+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10587=HEAP32[(($10586)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10588=$10582; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10589=HEAP32[(($10588)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10590=((($10589)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10591=$10590; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10592=HEAP32[(($10591)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10593=$10582; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10594=(($10593+$10592)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10595=$10594; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10595)>>2)]=$10587; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10596=(($10582+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10596)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10597=$10582; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10598=HEAP32[(($10597)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10599=((($10598)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10600=$10599; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10601=HEAP32[(($10600)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10602=$10582; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10603=(($10602+$10601)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10604=$10603; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10605=$1086; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1082=$10604; + $1083=$10605; + var $10606=$1082; + var $10607=$10606; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10608=$1083; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10609=$10608; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($10607, $10609) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1591; break; } else { label = 1607; break; } + case 1591: + var $10610=(($10606+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10610)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $10611=(($10606+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10611)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $10612=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10613=(($10612+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10614=$10613; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10615=(($10578+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1080=$10614; + $1081=$10615; + var $10616=$1080; + var $10617=$1081; + var $10618=HEAP32[(($10617)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10619=$10616; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10619)>>2)]=$10618; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10620=(($10617+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10621=HEAP32[(($10620)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10622=$10616; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10623=HEAP32[(($10622)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10624=((($10623)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10625=$10624; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10626=HEAP32[(($10625)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10627=$10616; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10628=(($10627+$10626)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10629=$10628; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10629)>>2)]=$10621; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10630=HEAP32[(($10578)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10631=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10631)>>2)]=$10630; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10632=(($10578+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10633=HEAP32[(($10632)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10634=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10635=HEAP32[(($10634)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10636=((($10635)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10637=$10636; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10638=HEAP32[(($10637)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10639=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10640=(($10639+$10638)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10641=$10640; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10641)>>2)]=$10633; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10642=(($10578+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10643=HEAP32[(($10642)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10644=$10577; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10645=(($10644+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10646=$10645; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10646)>>2)]=$10643; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10647=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10647)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10648=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10649=(($10648+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10650=$10649; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10650)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10651=$10558; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10652=(($10651+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10653=$10652; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10653)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10654=(($10558+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10655=$1120; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1115=$10654; + $1116=$10655; + var $10656=$1115; + var $10657=$1116; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1110=$10656; + $1111=$10657; + var $10658=$1110; + var $10659=$10658; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($10659) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1592; break; } else { label = 1608; break; } + case 1592: + var $10660=$10658; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10660)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10661=(($10658+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1109=$10661; + var $10662=$1109; + $1108=$10662; + var $10663=$1108; + var $10664=$10663; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10665=(($10663)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1107=$10665; + var $10666=$1107; + $1106=$10666; + var $10667=$1106; + var $10668=$10667; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1105=$10668; + var $10669=$1105; + var $10670=$10669; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1104=$10670; + var $10671=$1104; + var $10672=(($10669)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1103=$10663; + var $10673=$1103; + var $10674=(($10673)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1102=$10674; + var $10675=$1102; + var $10676=$10675; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1101=$10676; + var $10677=$1101; + var $10678=(($10677)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10679=(($10678)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10680=$10679; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10681=(($10680)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i344=$10681; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i345=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1593; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1593: + var $10683=$__i_i_i_i_i_i_i345; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10684=(($10683)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10684) { label = 1594; break; } else { label = 1595; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1594: + var $10686=$__i_i_i_i_i_i_i345; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10687=$__a_i_i_i_i_i_i344; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10688=(($10687+($10686<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10688)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10689=$__i_i_i_i_i_i_i345; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10690=((($10689)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i345=$10690; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1593; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1595: + var $10691=(($10658+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10691)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10692=(($10658+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10693=$1111; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10692)>>2)]=$10693; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1100=$1114; + var $10694=$1100; + $1099=$10694; + var $10695=$1099; + var $10696=$10695; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10697=(($10695)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1098=$10697; + var $10698=$1098; + $1097=$10698; + var $10699=$1097; + var $10700=$10699; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1096=$10700; + var $10701=$1096; + var $10702=$10701; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1095=$10702; + var $10703=$1095; + var $10704=(($10701)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1094=$10695; + var $10705=$1094; + var $10706=(($10705)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1093=$10706; + var $10707=$1093; + var $10708=$10707; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1092=$10708; + var $10709=$1092; + var $10710=(($10709)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $10711=(($10710)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10712=$10711; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $10713=(($10712)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i342=$10713; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i343=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1596; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1596: + var $10715=$__i_i_i_i2_i_i_i343; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10716=(($10715)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($10716) { label = 1597; break; } else { label = 1598; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1597: + var $10718=$__i_i_i_i2_i_i_i343; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10719=$__a_i_i_i1_i_i_i342; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10720=(($10719+($10718<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($10720)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $10721=$__i_i_i_i2_i_i_i343; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $10722=((($10721)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i343=$10722; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1596; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1598: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($10658, $1114) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1599; break; } else { label = 1601; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1599: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1114) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1614; break; } else { label = 1600; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1600: + var $10725$0 = ___cxa_find_matching_catch(-1, -1); $10725$1 = tempRet0; + var $10726=$10725$0; + $1112=$10726; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10727=$10725$1; + $1113=$10727; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1603; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1601: + var $10729$0 = ___cxa_find_matching_catch(-1, -1); $10729$1 = tempRet0; + var $10730=$10729$0; + $1112=$10730; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $10731=$10729$1; + $1113=$10731; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1114) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1602; break; } else { label = 1606; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1602: + label = 1603; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1603: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($10661) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1604; break; } else { label = 1606; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1604: + var $10735=$10658; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($10735) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1605; break; } else { label = 1606; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1605: + var $10737=$1112; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10738=$1113; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $10739$0=$10737; + var $10739$1=0; + var $10740$0=$10739$0; + var $10740$1=$10738; + var $eh_lpad_body_i350$1 = $10740$1;var $eh_lpad_body_i350$0 = $10740$0;label = 1609; break; + case 1606: + var $10742$0 = ___cxa_find_matching_catch(-1, -1,0); $10742$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1607: + var $10744$0 = ___cxa_find_matching_catch(-1, -1); $10744$1 = tempRet0; + var $10745=$10744$0; + $1121=$10745; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10746=$10744$1; + $1122=$10746; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1611; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1608: + var $10748$0 = ___cxa_find_matching_catch(-1, -1); $10748$1 = tempRet0; + var $eh_lpad_body_i350$1 = $10748$1;var $eh_lpad_body_i350$0 = $10748$0;label = 1609; break; + case 1609: + var $eh_lpad_body_i350$0; + var $eh_lpad_body_i350$1; + var $10749=$eh_lpad_body_i350$0; + $1121=$10749; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10750=$eh_lpad_body_i350$1; + $1122=$10750; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10751=$10558; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($10751, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1610; break; } else { label = 1613; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1610: + label = 1611; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1611: + var $10754=$10558; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10755=(($10754+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10756=$10755; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($10756) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1612; break; } else { label = 1613; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1612: + var $10758=$1121; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10759=$1122; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $10760$0=$10758; + var $10760$1=0; + var $10761$0=$10760$0; + var $10761$1=$10759; + ___resumeException($10761$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1613: + var $10763$0 = ___cxa_find_matching_catch(-1, -1,0); $10763$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1614: + var $10764=$std_stringstream24; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10765=(($10764+8)|0); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10766=$10765; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10767 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10766, ((91320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1615; break; } else { label = 1636; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1615: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2689, ((92576)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1616; break; } else { label = 1636; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1616: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2688, $2689, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1617; break; } else { label = 1637; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1617: + var $10771 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($10767, $2688) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1618; break; } else { label = 1638; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1618: + var $10773 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10771, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1619; break; } else { label = 1638; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1619: + var $10775 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10773, ((91784)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1620; break; } else { label = 1638; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1620: + var $10777 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($10775, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1621; break; } else { label = 1638; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1621: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2688) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1622; break; } else { label = 1637; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1622: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2689) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1623; break; } else { label = 1636; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1623: + var $10781=___cxa_allocate_exception(8); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2691=1; + var $10782=$10781; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1079=$std_stringstream24; + var $10783=$1079; + var $10784=(($10783+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2690, $10784) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1624; break; } else { label = 1642; break; } + case 1624: + label = 1625; break; + case 1625: + $1078=$2690; + var $10786=$1078; + $1077=$10786; + var $10787=$1077; + $1076=$10787; + var $10788=$1076; + $1075=$10788; + var $10789=$1075; + var $10790=(($10789)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1074=$10790; + var $10791=$1074; + var $10792=$10791; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1073=$10792; + var $10793=$1073; + var $10794=(($10793)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10795=(($10794)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10796=$10795; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10797=(($10796)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10798=$10797; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10799=HEAP8[($10798)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10800=(($10799)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10801=$10800 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $10802=(($10801)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($10802) { label = 1626; break; } else { label = 1627; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1626: + $1067=$10788; + var $10804=$1067; + var $10805=(($10804)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1066=$10805; + var $10806=$1066; + var $10807=$10806; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1065=$10807; + var $10808=$1065; + var $10809=(($10808)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10810=(($10809)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10811=$10810; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10812=(($10811+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10813=HEAP32[(($10812)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $10827 = $10813;label = 1628; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1627: + $1072=$10788; + var $10815=$1072; + var $10816=(($10815)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1071=$10816; + var $10817=$1071; + var $10818=$10817; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1070=$10818; + var $10819=$1070; + var $10820=(($10819)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $10821=(($10820)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10822=$10821; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10823=(($10822+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $10824=(($10823)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1069=$10824; + var $10825=$1069; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1068=$10825; + var $10826=$1068; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $10827 = $10826;label = 1628; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1628: + var $10827; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1064=$10827; + var $10828=$1064; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($10782, $10828) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1629; break; } else { label = 1643; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1629: + $2691=0; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($10781, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1643; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2690) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1630; break; } else { label = 1642; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1630: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream24); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1650; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1631: + var $10833$0 = ___cxa_find_matching_catch(-1, -1); $10833$1 = tempRet0; + var $10834=$10833$0; + $2542=$10834; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10835=$10833$1; + $2543=$10835; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1634; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1632: + var $10837$0 = ___cxa_find_matching_catch(-1, -1); $10837$1 = tempRet0; + var $10838=$10837$0; + $2542=$10838; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10839=$10837$1; + $2543=$10839; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2686) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1633; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1633: + label = 1634; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1634: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2687) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1635; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1635: + label = 2840; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1636: + var $10844$0 = ___cxa_find_matching_catch(-1, -1); $10844$1 = tempRet0; + var $10845=$10844$0; + $2542=$10845; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10846=$10844$1; + $2543=$10846; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1648; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1637: + var $10848$0 = ___cxa_find_matching_catch(-1, -1); $10848$1 = tempRet0; + var $10849=$10848$0; + $2542=$10849; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10850=$10848$1; + $2543=$10850; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1640; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1638: + var $10852$0 = ___cxa_find_matching_catch(-1, -1); $10852$1 = tempRet0; + var $10853=$10852$0; + $2542=$10853; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10854=$10852$1; + $2543=$10854; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2688) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1639; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1639: + label = 1640; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1640: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2689) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1641; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1641: + label = 1648; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1642: + var $10859$0 = ___cxa_find_matching_catch(-1, -1); $10859$1 = tempRet0; + var $10860=$10859$0; + $2542=$10860; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10861=$10859$1; + $2543=$10861; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1645; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1643: + var $10863$0 = ___cxa_find_matching_catch(-1, -1); $10863$1 = tempRet0; + var $10864=$10863$0; + $2542=$10864; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $10865=$10863$1; + $2543=$10865; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2690) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1644; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1644: + label = 1645; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1645: + var $10868=$2691; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10868) { label = 1646; break; } else { label = 1647; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1646: + ___cxa_free_exception($10781); //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1647; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1647: + label = 1648; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1648: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream24) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1649; break; } else { label = 2841; break; } //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1649: + label = 2840; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1650: + label = 1651; break; //@line 163 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1651: + label = 1652; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1652: + __ZN6StringC1EPKc($2693, ((92576)|0)); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2692, $2693, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1653; break; } else { label = 1697; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1653: + var $10877 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2692, ((91072)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1654; break; } else { label = 1698; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1654: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2692) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1655; break; } else { label = 1697; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1655: + __ZN6StringD1Ev($2693); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($10877) { label = 1656; break; } else { label = 1716; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1656: + $1060=$std_stringstream25; + $1061=24; + var $10881=$1060; + var $10882=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10883=(($10882+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10884=$10883; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1059=$10884; + var $10885=$1059; + var $10886=$10885; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $1058=$10886; + var $10887=$1058; + var $10888=$10887; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10888)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $10889=$10885; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10889)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $10890=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10890)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10891=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10892=(($10891+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10893=$10892; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10893)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10894=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10895=(($10894+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10896=$10895; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10896)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10897=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10898=(($10881+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10899=$10898; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1028=$10897; + $1029=((109796)|0); + $1030=$10899; + var $10900=$1028; + var $10901=$1029; + var $10902=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10903=(($10901+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10904=$1030; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1025=$10902; + $1026=$10903; + $1027=$10904; + var $10905=$1025; + var $10906=$1026; + var $10907=HEAP32[(($10906)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10908=$10905; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10908)>>2)]=$10907; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10909=(($10906+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10910=HEAP32[(($10909)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10911=$10905; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10912=HEAP32[(($10911)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10913=((($10912)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10914=$10913; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10915=HEAP32[(($10914)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10916=$10905; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10917=(($10916+$10915)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10918=$10917; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10918)>>2)]=$10910; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10919=(($10905+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10919)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $10920=$10905; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10921=HEAP32[(($10920)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10922=((($10921)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10923=$10922; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10924=HEAP32[(($10923)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10925=$10905; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10926=(($10925+$10924)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10927=$10926; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $10928=$1027; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $1023=$10927; + $1024=$10928; + var $10929=$1023; + var $10930=$10929; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10931=$1024; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $10932=$10931; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($10930, $10932) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1657; break; } else { label = 1673; break; } + case 1657: + var $10933=(($10929+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10933)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $10934=(($10929+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($10934)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $10935=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10936=(($10935+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10937=$10936; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10938=(($10901+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $1021=$10937; + $1022=$10938; + var $10939=$1021; + var $10940=$1022; + var $10941=HEAP32[(($10940)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10942=$10939; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10942)>>2)]=$10941; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10943=(($10940+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10944=HEAP32[(($10943)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10945=$10939; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10946=HEAP32[(($10945)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10947=((($10946)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10948=$10947; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10949=HEAP32[(($10948)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10950=$10939; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10951=(($10950+$10949)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10952=$10951; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10952)>>2)]=$10944; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $10953=HEAP32[(($10901)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10954=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10954)>>2)]=$10953; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10955=(($10901+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10956=HEAP32[(($10955)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10957=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10958=HEAP32[(($10957)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10959=((($10958)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10960=$10959; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10961=HEAP32[(($10960)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10962=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10963=(($10962+$10961)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10964=$10963; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10964)>>2)]=$10956; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10965=(($10901+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10966=HEAP32[(($10965)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10967=$10900; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10968=(($10967+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10969=$10968; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10969)>>2)]=$10966; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $10970=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10970)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10971=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10972=(($10971+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10973=$10972; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10973)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10974=$10881; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10975=(($10974+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10976=$10975; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10976)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10977=(($10881+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $10978=$1061; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1056=$10977; + $1057=$10978; + var $10979=$1056; + var $10980=$1057; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $1051=$10979; + $1052=$10980; + var $10981=$1051; + var $10982=$10981; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($10982) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1658; break; } else { label = 1674; break; } + case 1658: + var $10983=$10981; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($10983)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $10984=(($10981+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1050=$10984; + var $10985=$1050; + $1049=$10985; + var $10986=$1049; + var $10987=$10986; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $10988=(($10986)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1048=$10988; + var $10989=$1048; + $1047=$10989; + var $10990=$1047; + var $10991=$10990; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1046=$10991; + var $10992=$1046; + var $10993=$10992; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1045=$10993; + var $10994=$1045; + var $10995=(($10992)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1044=$10986; + var $10996=$1044; + var $10997=(($10996)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1043=$10997; + var $10998=$1043; + var $10999=$10998; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1042=$10999; + var $11000=$1042; + var $11001=(($11000)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11002=(($11001)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11003=$11002; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11004=(($11003)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i357=$11004; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i358=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1659; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1659: + var $11006=$__i_i_i_i_i_i_i358; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11007=(($11006)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11007) { label = 1660; break; } else { label = 1661; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1660: + var $11009=$__i_i_i_i_i_i_i358; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11010=$__a_i_i_i_i_i_i357; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11011=(($11010+($11009<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11011)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11012=$__i_i_i_i_i_i_i358; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11013=((($11012)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i358=$11013; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1659; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1661: + var $11014=(($10981+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11014)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11015=(($10981+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11016=$1052; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11015)>>2)]=$11016; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $1041=$1055; + var $11017=$1041; + $1040=$11017; + var $11018=$1040; + var $11019=$11018; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11020=(($11018)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $1039=$11020; + var $11021=$1039; + $1038=$11021; + var $11022=$1038; + var $11023=$11022; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $1037=$11023; + var $11024=$1037; + var $11025=$11024; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1036=$11025; + var $11026=$1036; + var $11027=(($11024)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $1035=$11018; + var $11028=$1035; + var $11029=(($11028)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $1034=$11029; + var $11030=$1034; + var $11031=$11030; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $1033=$11031; + var $11032=$1033; + var $11033=(($11032)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11034=(($11033)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11035=$11034; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11036=(($11035)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i355=$11036; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i356=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1662; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1662: + var $11038=$__i_i_i_i2_i_i_i356; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11039=(($11038)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11039) { label = 1663; break; } else { label = 1664; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1663: + var $11041=$__i_i_i_i2_i_i_i356; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11042=$__a_i_i_i1_i_i_i355; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11043=(($11042+($11041<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11043)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11044=$__i_i_i_i2_i_i_i356; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11045=((($11044)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i356=$11045; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1662; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1664: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($10981, $1055) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1665; break; } else { label = 1667; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1665: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1055) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1680; break; } else { label = 1666; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1666: + var $11048$0 = ___cxa_find_matching_catch(-1, -1); $11048$1 = tempRet0; + var $11049=$11048$0; + $1053=$11049; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11050=$11048$1; + $1054=$11050; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1669; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1667: + var $11052$0 = ___cxa_find_matching_catch(-1, -1); $11052$1 = tempRet0; + var $11053=$11052$0; + $1053=$11053; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11054=$11052$1; + $1054=$11054; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($1055) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1668; break; } else { label = 1672; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1668: + label = 1669; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1669: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($10984) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1670; break; } else { label = 1672; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1670: + var $11058=$10981; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($11058) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1671; break; } else { label = 1672; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1671: + var $11060=$1053; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11061=$1054; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11062$0=$11060; + var $11062$1=0; + var $11063$0=$11062$0; + var $11063$1=$11061; + var $eh_lpad_body_i363$1 = $11063$1;var $eh_lpad_body_i363$0 = $11063$0;label = 1675; break; + case 1672: + var $11065$0 = ___cxa_find_matching_catch(-1, -1,0); $11065$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1673: + var $11067$0 = ___cxa_find_matching_catch(-1, -1); $11067$1 = tempRet0; + var $11068=$11067$0; + $1062=$11068; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11069=$11067$1; + $1063=$11069; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1677; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1674: + var $11071$0 = ___cxa_find_matching_catch(-1, -1); $11071$1 = tempRet0; + var $eh_lpad_body_i363$1 = $11071$1;var $eh_lpad_body_i363$0 = $11071$0;label = 1675; break; + case 1675: + var $eh_lpad_body_i363$0; + var $eh_lpad_body_i363$1; + var $11072=$eh_lpad_body_i363$0; + $1062=$11072; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11073=$eh_lpad_body_i363$1; + $1063=$11073; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11074=$10881; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($11074, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1676; break; } else { label = 1679; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1676: + label = 1677; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1677: + var $11077=$10881; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11078=(($11077+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11079=$11078; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($11079) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1678; break; } else { label = 1679; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1678: + var $11081=$1062; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11082=$1063; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11083$0=$11081; + var $11083$1=0; + var $11084$0=$11083$0; + var $11084$1=$11082; + ___resumeException($11084$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1679: + var $11086$0 = ___cxa_find_matching_catch(-1, -1,0); $11086$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1680: + var $11087=$std_stringstream25; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11088=(($11087+8)|0); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11089=$11088; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11090 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11089, ((90728)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1681; break; } else { label = 1702; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1681: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2695, ((92576)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1682; break; } else { label = 1702; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1682: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2694, $2695, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1683; break; } else { label = 1703; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1683: + var $11094 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($11090, $2694) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1684; break; } else { label = 1704; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1684: + var $11096 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11094, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1685; break; } else { label = 1704; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1685: + var $11098 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11096, ((91072)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1686; break; } else { label = 1704; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1686: + var $11100 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11098, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1687; break; } else { label = 1704; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1687: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2694) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1688; break; } else { label = 1703; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1688: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2695) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1689; break; } else { label = 1702; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1689: + var $11104=___cxa_allocate_exception(8); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2697=1; + var $11105=$11104; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $1020=$std_stringstream25; + var $11106=$1020; + var $11107=(($11106+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2696, $11107) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1690; break; } else { label = 1708; break; } + case 1690: + label = 1691; break; + case 1691: + $1019=$2696; + var $11109=$1019; + $1018=$11109; + var $11110=$1018; + $1017=$11110; + var $11111=$1017; + $1016=$11111; + var $11112=$1016; + var $11113=(($11112)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $1015=$11113; + var $11114=$1015; + var $11115=$11114; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1014=$11115; + var $11116=$1014; + var $11117=(($11116)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11118=(($11117)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11119=$11118; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11120=(($11119)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11121=$11120; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11122=HEAP8[($11121)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11123=(($11122)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11124=$11123 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11125=(($11124)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($11125) { label = 1692; break; } else { label = 1693; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1692: + $1008=$11111; + var $11127=$1008; + var $11128=(($11127)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $1007=$11128; + var $11129=$1007; + var $11130=$11129; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1006=$11130; + var $11131=$1006; + var $11132=(($11131)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11133=(($11132)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11134=$11133; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11135=(($11134+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11136=HEAP32[(($11135)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11150 = $11136;label = 1694; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1693: + $1013=$11111; + var $11138=$1013; + var $11139=(($11138)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1012=$11139; + var $11140=$1012; + var $11141=$11140; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $1011=$11141; + var $11142=$1011; + var $11143=(($11142)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11144=(($11143)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11145=$11144; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11146=(($11145+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11147=(($11146)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $1010=$11147; + var $11148=$1010; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $1009=$11148; + var $11149=$1009; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $11150 = $11149;label = 1694; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1694: + var $11150; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $1005=$11150; + var $11151=$1005; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($11105, $11151) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1695; break; } else { label = 1709; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1695: + $2697=0; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($11104, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1709; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2696) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1696; break; } else { label = 1708; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1696: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream25); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1716; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1697: + var $11156$0 = ___cxa_find_matching_catch(-1, -1); $11156$1 = tempRet0; + var $11157=$11156$0; + $2542=$11157; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11158=$11156$1; + $2543=$11158; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1700; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1698: + var $11160$0 = ___cxa_find_matching_catch(-1, -1); $11160$1 = tempRet0; + var $11161=$11160$0; + $2542=$11161; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11162=$11160$1; + $2543=$11162; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2692) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1699; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1699: + label = 1700; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1700: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2693) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1701; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1701: + label = 2840; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1702: + var $11167$0 = ___cxa_find_matching_catch(-1, -1); $11167$1 = tempRet0; + var $11168=$11167$0; + $2542=$11168; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11169=$11167$1; + $2543=$11169; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1714; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1703: + var $11171$0 = ___cxa_find_matching_catch(-1, -1); $11171$1 = tempRet0; + var $11172=$11171$0; + $2542=$11172; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11173=$11171$1; + $2543=$11173; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1706; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1704: + var $11175$0 = ___cxa_find_matching_catch(-1, -1); $11175$1 = tempRet0; + var $11176=$11175$0; + $2542=$11176; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11177=$11175$1; + $2543=$11177; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2694) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1705; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1705: + label = 1706; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1706: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2695) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1707; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1707: + label = 1714; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1708: + var $11182$0 = ___cxa_find_matching_catch(-1, -1); $11182$1 = tempRet0; + var $11183=$11182$0; + $2542=$11183; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11184=$11182$1; + $2543=$11184; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1711; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1709: + var $11186$0 = ___cxa_find_matching_catch(-1, -1); $11186$1 = tempRet0; + var $11187=$11186$0; + $2542=$11187; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11188=$11186$1; + $2543=$11188; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2696) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1710; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1710: + label = 1711; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1711: + var $11191=$2697; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11191) { label = 1712; break; } else { label = 1713; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1712: + ___cxa_free_exception($11104); //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1713; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1713: + label = 1714; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1714: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream25) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1715; break; } else { label = 2841; break; } //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1715: + label = 2840; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1716: + label = 1717; break; //@line 164 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1717: + label = 1718; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1718: + __ZN6StringC1EPKc($2699, ((90472)|0)); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2698, $2699, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1719; break; } else { label = 1763; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1719: + var $11200 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2698, ((90160)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1720; break; } else { label = 1764; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1720: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2698) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1721; break; } else { label = 1763; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1721: + __ZN6StringD1Ev($2699); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11200) { label = 1722; break; } else { label = 1782; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1722: + $1001=$std_stringstream26; + $1002=24; + var $11204=$1001; + var $11205=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11206=(($11205+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11207=$11206; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $1000=$11207; + var $11208=$1000; + var $11209=$11208; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $999=$11209; + var $11210=$999; + var $11211=$11210; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11211)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $11212=$11208; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11212)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $11213=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11213)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11214=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11215=(($11214+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11216=$11215; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11216)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11217=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11218=(($11217+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11219=$11218; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11219)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11220=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11221=(($11204+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11222=$11221; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $969=$11220; + $970=((109796)|0); + $971=$11222; + var $11223=$969; + var $11224=$970; + var $11225=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11226=(($11224+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11227=$971; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $966=$11225; + $967=$11226; + $968=$11227; + var $11228=$966; + var $11229=$967; + var $11230=HEAP32[(($11229)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11231=$11228; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11231)>>2)]=$11230; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11232=(($11229+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11233=HEAP32[(($11232)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11234=$11228; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11235=HEAP32[(($11234)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11236=((($11235)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11237=$11236; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11238=HEAP32[(($11237)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11239=$11228; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11240=(($11239+$11238)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11241=$11240; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11241)>>2)]=$11233; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11242=(($11228+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11242)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11243=$11228; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11244=HEAP32[(($11243)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11245=((($11244)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11246=$11245; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11247=HEAP32[(($11246)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11248=$11228; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11249=(($11248+$11247)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11250=$11249; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11251=$968; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $964=$11250; + $965=$11251; + var $11252=$964; + var $11253=$11252; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11254=$965; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11255=$11254; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($11253, $11255) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1723; break; } else { label = 1739; break; } + case 1723: + var $11256=(($11252+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11256)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $11257=(($11252+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11257)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $11258=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11259=(($11258+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11260=$11259; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11261=(($11224+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $962=$11260; + $963=$11261; + var $11262=$962; + var $11263=$963; + var $11264=HEAP32[(($11263)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11265=$11262; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11265)>>2)]=$11264; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11266=(($11263+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11267=HEAP32[(($11266)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11268=$11262; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11269=HEAP32[(($11268)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11270=((($11269)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11271=$11270; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11272=HEAP32[(($11271)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11273=$11262; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11274=(($11273+$11272)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11275=$11274; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11275)>>2)]=$11267; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11276=HEAP32[(($11224)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11277=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11277)>>2)]=$11276; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11278=(($11224+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11279=HEAP32[(($11278)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11280=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11281=HEAP32[(($11280)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11282=((($11281)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11283=$11282; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11284=HEAP32[(($11283)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11285=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11286=(($11285+$11284)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11287=$11286; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11287)>>2)]=$11279; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11288=(($11224+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11289=HEAP32[(($11288)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11290=$11223; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11291=(($11290+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11292=$11291; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11292)>>2)]=$11289; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11293=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11293)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11294=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11295=(($11294+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11296=$11295; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11296)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11297=$11204; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11298=(($11297+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11299=$11298; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11299)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11300=(($11204+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11301=$1002; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $997=$11300; + $998=$11301; + var $11302=$997; + var $11303=$998; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $992=$11302; + $993=$11303; + var $11304=$992; + var $11305=$11304; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($11305) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1724; break; } else { label = 1740; break; } + case 1724: + var $11306=$11304; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11306)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11307=(($11304+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $991=$11307; + var $11308=$991; + $990=$11308; + var $11309=$990; + var $11310=$11309; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11311=(($11309)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $989=$11311; + var $11312=$989; + $988=$11312; + var $11313=$988; + var $11314=$11313; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $987=$11314; + var $11315=$987; + var $11316=$11315; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $986=$11316; + var $11317=$986; + var $11318=(($11315)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $985=$11309; + var $11319=$985; + var $11320=(($11319)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $984=$11320; + var $11321=$984; + var $11322=$11321; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $983=$11322; + var $11323=$983; + var $11324=(($11323)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11325=(($11324)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11326=$11325; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11327=(($11326)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i370=$11327; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i371=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1725; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1725: + var $11329=$__i_i_i_i_i_i_i371; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11330=(($11329)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11330) { label = 1726; break; } else { label = 1727; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1726: + var $11332=$__i_i_i_i_i_i_i371; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11333=$__a_i_i_i_i_i_i370; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11334=(($11333+($11332<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11334)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11335=$__i_i_i_i_i_i_i371; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11336=((($11335)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i371=$11336; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1725; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1727: + var $11337=(($11304+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11337)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11338=(($11304+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11339=$993; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11338)>>2)]=$11339; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $982=$996; + var $11340=$982; + $981=$11340; + var $11341=$981; + var $11342=$11341; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11343=(($11341)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $980=$11343; + var $11344=$980; + $979=$11344; + var $11345=$979; + var $11346=$11345; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $978=$11346; + var $11347=$978; + var $11348=$11347; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $977=$11348; + var $11349=$977; + var $11350=(($11347)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $976=$11341; + var $11351=$976; + var $11352=(($11351)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $975=$11352; + var $11353=$975; + var $11354=$11353; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $974=$11354; + var $11355=$974; + var $11356=(($11355)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11357=(($11356)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11358=$11357; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11359=(($11358)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i368=$11359; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i369=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1728; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1728: + var $11361=$__i_i_i_i2_i_i_i369; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11362=(($11361)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11362) { label = 1729; break; } else { label = 1730; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1729: + var $11364=$__i_i_i_i2_i_i_i369; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11365=$__a_i_i_i1_i_i_i368; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11366=(($11365+($11364<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11366)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11367=$__i_i_i_i2_i_i_i369; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11368=((($11367)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i369=$11368; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1728; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1730: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($11304, $996) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1731; break; } else { label = 1733; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1731: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($996) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1746; break; } else { label = 1732; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1732: + var $11371$0 = ___cxa_find_matching_catch(-1, -1); $11371$1 = tempRet0; + var $11372=$11371$0; + $994=$11372; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11373=$11371$1; + $995=$11373; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1735; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1733: + var $11375$0 = ___cxa_find_matching_catch(-1, -1); $11375$1 = tempRet0; + var $11376=$11375$0; + $994=$11376; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11377=$11375$1; + $995=$11377; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($996) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1734; break; } else { label = 1738; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1734: + label = 1735; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1735: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($11307) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1736; break; } else { label = 1738; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1736: + var $11381=$11304; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($11381) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1737; break; } else { label = 1738; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1737: + var $11383=$994; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11384=$995; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11385$0=$11383; + var $11385$1=0; + var $11386$0=$11385$0; + var $11386$1=$11384; + var $eh_lpad_body_i376$1 = $11386$1;var $eh_lpad_body_i376$0 = $11386$0;label = 1741; break; + case 1738: + var $11388$0 = ___cxa_find_matching_catch(-1, -1,0); $11388$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1739: + var $11390$0 = ___cxa_find_matching_catch(-1, -1); $11390$1 = tempRet0; + var $11391=$11390$0; + $1003=$11391; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11392=$11390$1; + $1004=$11392; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1743; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1740: + var $11394$0 = ___cxa_find_matching_catch(-1, -1); $11394$1 = tempRet0; + var $eh_lpad_body_i376$1 = $11394$1;var $eh_lpad_body_i376$0 = $11394$0;label = 1741; break; + case 1741: + var $eh_lpad_body_i376$0; + var $eh_lpad_body_i376$1; + var $11395=$eh_lpad_body_i376$0; + $1003=$11395; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11396=$eh_lpad_body_i376$1; + $1004=$11396; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11397=$11204; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($11397, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1742; break; } else { label = 1745; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1742: + label = 1743; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1743: + var $11400=$11204; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11401=(($11400+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11402=$11401; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($11402) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1744; break; } else { label = 1745; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1744: + var $11404=$1003; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11405=$1004; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11406$0=$11404; + var $11406$1=0; + var $11407$0=$11406$0; + var $11407$1=$11405; + ___resumeException($11407$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1745: + var $11409$0 = ___cxa_find_matching_catch(-1, -1,0); $11409$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1746: + var $11410=$std_stringstream26; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11411=(($11410+8)|0); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11412=$11411; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11413 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11412, ((89792)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1747; break; } else { label = 1768; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1747: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2701, ((90472)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1748; break; } else { label = 1768; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1748: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2700, $2701, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1749; break; } else { label = 1769; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1749: + var $11417 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($11413, $2700) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1750; break; } else { label = 1770; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1750: + var $11419 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11417, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1751; break; } else { label = 1770; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1751: + var $11421 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11419, ((90160)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1752; break; } else { label = 1770; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1752: + var $11423 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11421, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1753; break; } else { label = 1770; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1753: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2700) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1754; break; } else { label = 1769; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1754: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2701) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1755; break; } else { label = 1768; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1755: + var $11427=___cxa_allocate_exception(8); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2703=1; + var $11428=$11427; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $961=$std_stringstream26; + var $11429=$961; + var $11430=(($11429+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2702, $11430) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1756; break; } else { label = 1774; break; } + case 1756: + label = 1757; break; + case 1757: + $960=$2702; + var $11432=$960; + $959=$11432; + var $11433=$959; + $958=$11433; + var $11434=$958; + $957=$11434; + var $11435=$957; + var $11436=(($11435)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $956=$11436; + var $11437=$956; + var $11438=$11437; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $955=$11438; + var $11439=$955; + var $11440=(($11439)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11441=(($11440)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11442=$11441; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11443=(($11442)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11444=$11443; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11445=HEAP8[($11444)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11446=(($11445)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11447=$11446 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11448=(($11447)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($11448) { label = 1758; break; } else { label = 1759; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1758: + $949=$11434; + var $11450=$949; + var $11451=(($11450)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $948=$11451; + var $11452=$948; + var $11453=$11452; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $947=$11453; + var $11454=$947; + var $11455=(($11454)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11456=(($11455)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11457=$11456; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11458=(($11457+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11459=HEAP32[(($11458)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11473 = $11459;label = 1760; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1759: + $954=$11434; + var $11461=$954; + var $11462=(($11461)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $953=$11462; + var $11463=$953; + var $11464=$11463; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $952=$11464; + var $11465=$952; + var $11466=(($11465)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11467=(($11466)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11468=$11467; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11469=(($11468+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11470=(($11469)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $951=$11470; + var $11471=$951; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $950=$11471; + var $11472=$950; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $11473 = $11472;label = 1760; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1760: + var $11473; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $946=$11473; + var $11474=$946; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($11428, $11474) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1761; break; } else { label = 1775; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1761: + $2703=0; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($11427, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1775; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2702) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1762; break; } else { label = 1774; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1762: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream26); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1782; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1763: + var $11479$0 = ___cxa_find_matching_catch(-1, -1); $11479$1 = tempRet0; + var $11480=$11479$0; + $2542=$11480; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11481=$11479$1; + $2543=$11481; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1766; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1764: + var $11483$0 = ___cxa_find_matching_catch(-1, -1); $11483$1 = tempRet0; + var $11484=$11483$0; + $2542=$11484; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11485=$11483$1; + $2543=$11485; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2698) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1765; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1765: + label = 1766; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1766: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2699) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1767; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1767: + label = 2840; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1768: + var $11490$0 = ___cxa_find_matching_catch(-1, -1); $11490$1 = tempRet0; + var $11491=$11490$0; + $2542=$11491; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11492=$11490$1; + $2543=$11492; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1780; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1769: + var $11494$0 = ___cxa_find_matching_catch(-1, -1); $11494$1 = tempRet0; + var $11495=$11494$0; + $2542=$11495; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11496=$11494$1; + $2543=$11496; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1772; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1770: + var $11498$0 = ___cxa_find_matching_catch(-1, -1); $11498$1 = tempRet0; + var $11499=$11498$0; + $2542=$11499; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11500=$11498$1; + $2543=$11500; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2700) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1771; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1771: + label = 1772; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1772: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2701) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1773; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1773: + label = 1780; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1774: + var $11505$0 = ___cxa_find_matching_catch(-1, -1); $11505$1 = tempRet0; + var $11506=$11505$0; + $2542=$11506; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11507=$11505$1; + $2543=$11507; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1777; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1775: + var $11509$0 = ___cxa_find_matching_catch(-1, -1); $11509$1 = tempRet0; + var $11510=$11509$0; + $2542=$11510; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11511=$11509$1; + $2543=$11511; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2702) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1776; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1776: + label = 1777; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1777: + var $11514=$2703; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11514) { label = 1778; break; } else { label = 1779; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1778: + ___cxa_free_exception($11427); //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1779; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1779: + label = 1780; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1780: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream26) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1781; break; } else { label = 2841; break; } //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1781: + label = 2840; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1782: + label = 1783; break; //@line 165 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1783: + label = 1784; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1784: + __ZN6StringC1EPKc($2705, ((90472)|0)); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2704, $2705, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1785; break; } else { label = 1829; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1785: + var $11523 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2704, ((89536)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1786; break; } else { label = 1830; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1786: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1787; break; } else { label = 1829; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1787: + __ZN6StringD1Ev($2705); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11523) { label = 1788; break; } else { label = 1848; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1788: + $942=$std_stringstream27; + $943=24; + var $11527=$942; + var $11528=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11529=(($11528+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11530=$11529; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $941=$11530; + var $11531=$941; + var $11532=$11531; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $940=$11532; + var $11533=$940; + var $11534=$11533; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11534)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $11535=$11531; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11535)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $11536=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11536)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11537=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11538=(($11537+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11539=$11538; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11539)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11540=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11541=(($11540+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11542=$11541; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11542)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11543=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11544=(($11527+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11545=$11544; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $910=$11543; + $911=((109796)|0); + $912=$11545; + var $11546=$910; + var $11547=$911; + var $11548=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11549=(($11547+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11550=$912; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $907=$11548; + $908=$11549; + $909=$11550; + var $11551=$907; + var $11552=$908; + var $11553=HEAP32[(($11552)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11554=$11551; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11554)>>2)]=$11553; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11555=(($11552+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11556=HEAP32[(($11555)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11557=$11551; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11558=HEAP32[(($11557)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11559=((($11558)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11560=$11559; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11561=HEAP32[(($11560)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11562=$11551; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11563=(($11562+$11561)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11564=$11563; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11564)>>2)]=$11556; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11565=(($11551+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11565)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11566=$11551; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11567=HEAP32[(($11566)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11568=((($11567)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11569=$11568; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11570=HEAP32[(($11569)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11571=$11551; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11572=(($11571+$11570)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11573=$11572; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11574=$909; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $905=$11573; + $906=$11574; + var $11575=$905; + var $11576=$11575; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11577=$906; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11578=$11577; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($11576, $11578) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1789; break; } else { label = 1805; break; } + case 1789: + var $11579=(($11575+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11579)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $11580=(($11575+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11580)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $11581=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11582=(($11581+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11583=$11582; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11584=(($11547+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $903=$11583; + $904=$11584; + var $11585=$903; + var $11586=$904; + var $11587=HEAP32[(($11586)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11588=$11585; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11588)>>2)]=$11587; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11589=(($11586+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11590=HEAP32[(($11589)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11591=$11585; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11592=HEAP32[(($11591)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11593=((($11592)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11594=$11593; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11595=HEAP32[(($11594)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11596=$11585; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11597=(($11596+$11595)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11598=$11597; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11598)>>2)]=$11590; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11599=HEAP32[(($11547)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11600=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11600)>>2)]=$11599; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11601=(($11547+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11602=HEAP32[(($11601)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11603=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11604=HEAP32[(($11603)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11605=((($11604)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11606=$11605; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11607=HEAP32[(($11606)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11608=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11609=(($11608+$11607)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11610=$11609; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11610)>>2)]=$11602; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11611=(($11547+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11612=HEAP32[(($11611)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11613=$11546; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11614=(($11613+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11615=$11614; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11615)>>2)]=$11612; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11616=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11616)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11617=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11618=(($11617+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11619=$11618; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11619)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11620=$11527; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11621=(($11620+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11622=$11621; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11622)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11623=(($11527+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11624=$943; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $938=$11623; + $939=$11624; + var $11625=$938; + var $11626=$939; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $933=$11625; + $934=$11626; + var $11627=$933; + var $11628=$11627; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($11628) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1790; break; } else { label = 1806; break; } + case 1790: + var $11629=$11627; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11629)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11630=(($11627+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $932=$11630; + var $11631=$932; + $931=$11631; + var $11632=$931; + var $11633=$11632; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11634=(($11632)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $930=$11634; + var $11635=$930; + $929=$11635; + var $11636=$929; + var $11637=$11636; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $928=$11637; + var $11638=$928; + var $11639=$11638; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $927=$11639; + var $11640=$927; + var $11641=(($11638)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $926=$11632; + var $11642=$926; + var $11643=(($11642)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $925=$11643; + var $11644=$925; + var $11645=$11644; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $924=$11645; + var $11646=$924; + var $11647=(($11646)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11648=(($11647)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11649=$11648; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11650=(($11649)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i383=$11650; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i384=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1791; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1791: + var $11652=$__i_i_i_i_i_i_i384; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11653=(($11652)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11653) { label = 1792; break; } else { label = 1793; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1792: + var $11655=$__i_i_i_i_i_i_i384; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11656=$__a_i_i_i_i_i_i383; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11657=(($11656+($11655<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11657)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11658=$__i_i_i_i_i_i_i384; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11659=((($11658)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i384=$11659; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1791; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1793: + var $11660=(($11627+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11660)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11661=(($11627+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11662=$934; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11661)>>2)]=$11662; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $923=$937; + var $11663=$923; + $922=$11663; + var $11664=$922; + var $11665=$11664; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11666=(($11664)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $921=$11666; + var $11667=$921; + $920=$11667; + var $11668=$920; + var $11669=$11668; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $919=$11669; + var $11670=$919; + var $11671=$11670; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $918=$11671; + var $11672=$918; + var $11673=(($11670)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $917=$11664; + var $11674=$917; + var $11675=(($11674)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $916=$11675; + var $11676=$916; + var $11677=$11676; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $915=$11677; + var $11678=$915; + var $11679=(($11678)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11680=(($11679)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11681=$11680; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11682=(($11681)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i381=$11682; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i382=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1794; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1794: + var $11684=$__i_i_i_i2_i_i_i382; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11685=(($11684)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11685) { label = 1795; break; } else { label = 1796; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1795: + var $11687=$__i_i_i_i2_i_i_i382; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11688=$__a_i_i_i1_i_i_i381; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11689=(($11688+($11687<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11689)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11690=$__i_i_i_i2_i_i_i382; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11691=((($11690)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i382=$11691; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1794; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1796: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($11627, $937) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1797; break; } else { label = 1799; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1797: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($937) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1812; break; } else { label = 1798; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1798: + var $11694$0 = ___cxa_find_matching_catch(-1, -1); $11694$1 = tempRet0; + var $11695=$11694$0; + $935=$11695; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11696=$11694$1; + $936=$11696; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1801; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1799: + var $11698$0 = ___cxa_find_matching_catch(-1, -1); $11698$1 = tempRet0; + var $11699=$11698$0; + $935=$11699; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $11700=$11698$1; + $936=$11700; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($937) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1800; break; } else { label = 1804; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1800: + label = 1801; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1801: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($11630) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1802; break; } else { label = 1804; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1802: + var $11704=$11627; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($11704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1803; break; } else { label = 1804; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1803: + var $11706=$935; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11707=$936; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $11708$0=$11706; + var $11708$1=0; + var $11709$0=$11708$0; + var $11709$1=$11707; + var $eh_lpad_body_i389$1 = $11709$1;var $eh_lpad_body_i389$0 = $11709$0;label = 1807; break; + case 1804: + var $11711$0 = ___cxa_find_matching_catch(-1, -1,0); $11711$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1805: + var $11713$0 = ___cxa_find_matching_catch(-1, -1); $11713$1 = tempRet0; + var $11714=$11713$0; + $944=$11714; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11715=$11713$1; + $945=$11715; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1809; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1806: + var $11717$0 = ___cxa_find_matching_catch(-1, -1); $11717$1 = tempRet0; + var $eh_lpad_body_i389$1 = $11717$1;var $eh_lpad_body_i389$0 = $11717$0;label = 1807; break; + case 1807: + var $eh_lpad_body_i389$0; + var $eh_lpad_body_i389$1; + var $11718=$eh_lpad_body_i389$0; + $944=$11718; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11719=$eh_lpad_body_i389$1; + $945=$11719; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11720=$11527; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($11720, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1808; break; } else { label = 1811; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1808: + label = 1809; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1809: + var $11723=$11527; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11724=(($11723+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11725=$11724; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($11725) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1810; break; } else { label = 1811; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1810: + var $11727=$944; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11728=$945; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $11729$0=$11727; + var $11729$1=0; + var $11730$0=$11729$0; + var $11730$1=$11728; + ___resumeException($11730$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1811: + var $11732$0 = ___cxa_find_matching_catch(-1, -1,0); $11732$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1812: + var $11733=$std_stringstream27; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11734=(($11733+8)|0); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11735=$11734; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11736 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11735, ((89232)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1813; break; } else { label = 1834; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1813: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2707, ((90472)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1814; break; } else { label = 1834; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1814: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2706, $2707, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1815; break; } else { label = 1835; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1815: + var $11740 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($11736, $2706) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1816; break; } else { label = 1836; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1816: + var $11742 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11740, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1817; break; } else { label = 1836; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1817: + var $11744 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11742, ((89536)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1818; break; } else { label = 1836; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1818: + var $11746 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($11744, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1819; break; } else { label = 1836; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1819: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2706) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1820; break; } else { label = 1835; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1820: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2707) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1821; break; } else { label = 1834; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1821: + var $11750=___cxa_allocate_exception(8); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2709=1; + var $11751=$11750; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $902=$std_stringstream27; + var $11752=$902; + var $11753=(($11752+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2708, $11753) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1822; break; } else { label = 1840; break; } + case 1822: + label = 1823; break; + case 1823: + $901=$2708; + var $11755=$901; + $900=$11755; + var $11756=$900; + $899=$11756; + var $11757=$899; + $898=$11757; + var $11758=$898; + var $11759=(($11758)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $897=$11759; + var $11760=$897; + var $11761=$11760; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $896=$11761; + var $11762=$896; + var $11763=(($11762)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11764=(($11763)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11765=$11764; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11766=(($11765)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11767=$11766; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11768=HEAP8[($11767)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11769=(($11768)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11770=$11769 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $11771=(($11770)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($11771) { label = 1824; break; } else { label = 1825; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1824: + $890=$11757; + var $11773=$890; + var $11774=(($11773)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $889=$11774; + var $11775=$889; + var $11776=$11775; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $888=$11776; + var $11777=$888; + var $11778=(($11777)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11779=(($11778)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11780=$11779; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11781=(($11780+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11782=HEAP32[(($11781)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $11796 = $11782;label = 1826; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1825: + $895=$11757; + var $11784=$895; + var $11785=(($11784)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $894=$11785; + var $11786=$894; + var $11787=$11786; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $893=$11787; + var $11788=$893; + var $11789=(($11788)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $11790=(($11789)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11791=$11790; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11792=(($11791+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $11793=(($11792)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $892=$11793; + var $11794=$892; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $891=$11794; + var $11795=$891; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $11796 = $11795;label = 1826; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1826: + var $11796; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $887=$11796; + var $11797=$887; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($11751, $11797) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1827; break; } else { label = 1841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1827: + $2709=0; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($11750, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2708) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1828; break; } else { label = 1840; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1828: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream27); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1848; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1829: + var $11802$0 = ___cxa_find_matching_catch(-1, -1); $11802$1 = tempRet0; + var $11803=$11802$0; + $2542=$11803; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11804=$11802$1; + $2543=$11804; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1832; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1830: + var $11806$0 = ___cxa_find_matching_catch(-1, -1); $11806$1 = tempRet0; + var $11807=$11806$0; + $2542=$11807; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11808=$11806$1; + $2543=$11808; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1831; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1831: + label = 1832; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1832: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2705) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1833; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1833: + label = 2840; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1834: + var $11813$0 = ___cxa_find_matching_catch(-1, -1); $11813$1 = tempRet0; + var $11814=$11813$0; + $2542=$11814; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11815=$11813$1; + $2543=$11815; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1846; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1835: + var $11817$0 = ___cxa_find_matching_catch(-1, -1); $11817$1 = tempRet0; + var $11818=$11817$0; + $2542=$11818; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11819=$11817$1; + $2543=$11819; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1838; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1836: + var $11821$0 = ___cxa_find_matching_catch(-1, -1); $11821$1 = tempRet0; + var $11822=$11821$0; + $2542=$11822; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11823=$11821$1; + $2543=$11823; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2706) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1837; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1837: + label = 1838; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1838: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2707) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1839; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1839: + label = 1846; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1840: + var $11828$0 = ___cxa_find_matching_catch(-1, -1); $11828$1 = tempRet0; + var $11829=$11828$0; + $2542=$11829; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11830=$11828$1; + $2543=$11830; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1843; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1841: + var $11832$0 = ___cxa_find_matching_catch(-1, -1); $11832$1 = tempRet0; + var $11833=$11832$0; + $2542=$11833; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $11834=$11832$1; + $2543=$11834; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2708) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1842; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1842: + label = 1843; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1843: + var $11837=$2709; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11837) { label = 1844; break; } else { label = 1845; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1844: + ___cxa_free_exception($11750); //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1845; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1845: + label = 1846; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1846: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream27) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1847; break; } else { label = 2841; break; } //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1847: + label = 2840; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1848: + label = 1849; break; //@line 166 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1849: + label = 1850; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1850: + __ZN6StringC1EPKc($2711, ((88960)|0)); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2710, $2711, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1851; break; } else { label = 1895; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1851: + var $11846 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2710, ((88176)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1852; break; } else { label = 1896; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1852: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2710) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1853; break; } else { label = 1895; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1853: + __ZN6StringD1Ev($2711); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($11846) { label = 1854; break; } else { label = 1914; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1854: + $883=$std_stringstream28; + $884=24; + var $11850=$883; + var $11851=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11852=(($11851+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11853=$11852; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $882=$11853; + var $11854=$882; + var $11855=$11854; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $881=$11855; + var $11856=$881; + var $11857=$11856; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11857)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $11858=$11854; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11858)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $11859=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11859)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11860=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11861=(($11860+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11862=$11861; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11862)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11863=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11864=(($11863+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11865=$11864; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11865)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11866=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11867=(($11850+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11868=$11867; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $851=$11866; + $852=((109796)|0); + $853=$11868; + var $11869=$851; + var $11870=$852; + var $11871=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11872=(($11870+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11873=$853; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $848=$11871; + $849=$11872; + $850=$11873; + var $11874=$848; + var $11875=$849; + var $11876=HEAP32[(($11875)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11877=$11874; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11877)>>2)]=$11876; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11878=(($11875+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11879=HEAP32[(($11878)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11880=$11874; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11881=HEAP32[(($11880)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11882=((($11881)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11883=$11882; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11884=HEAP32[(($11883)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11885=$11874; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11886=(($11885+$11884)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11887=$11886; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11887)>>2)]=$11879; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11888=(($11874+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11888)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $11889=$11874; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11890=HEAP32[(($11889)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11891=((($11890)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11892=$11891; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11893=HEAP32[(($11892)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11894=$11874; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11895=(($11894+$11893)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11896=$11895; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $11897=$850; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $846=$11896; + $847=$11897; + var $11898=$846; + var $11899=$11898; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11900=$847; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $11901=$11900; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($11899, $11901) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1855; break; } else { label = 1871; break; } + case 1855: + var $11902=(($11898+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11902)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $11903=(($11898+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($11903)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $11904=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11905=(($11904+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11906=$11905; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11907=(($11870+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $844=$11906; + $845=$11907; + var $11908=$844; + var $11909=$845; + var $11910=HEAP32[(($11909)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11911=$11908; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11911)>>2)]=$11910; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11912=(($11909+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11913=HEAP32[(($11912)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11914=$11908; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11915=HEAP32[(($11914)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11916=((($11915)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11917=$11916; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11918=HEAP32[(($11917)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11919=$11908; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11920=(($11919+$11918)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11921=$11920; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11921)>>2)]=$11913; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $11922=HEAP32[(($11870)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11923=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11923)>>2)]=$11922; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11924=(($11870+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11925=HEAP32[(($11924)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11926=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11927=HEAP32[(($11926)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11928=((($11927)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11929=$11928; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11930=HEAP32[(($11929)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11931=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11932=(($11931+$11930)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11933=$11932; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11933)>>2)]=$11925; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11934=(($11870+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11935=HEAP32[(($11934)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11936=$11869; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11937=(($11936+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11938=$11937; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11938)>>2)]=$11935; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $11939=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11939)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11940=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11941=(($11940+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11942=$11941; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11942)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11943=$11850; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11944=(($11943+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11945=$11944; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11945)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11946=(($11850+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $11947=$884; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $879=$11946; + $880=$11947; + var $11948=$879; + var $11949=$880; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $874=$11948; + $875=$11949; + var $11950=$874; + var $11951=$11950; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($11951) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1856; break; } else { label = 1872; break; } + case 1856: + var $11952=$11950; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11952)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11953=(($11950+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $873=$11953; + var $11954=$873; + $872=$11954; + var $11955=$872; + var $11956=$11955; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11957=(($11955)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $871=$11957; + var $11958=$871; + $870=$11958; + var $11959=$870; + var $11960=$11959; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $869=$11960; + var $11961=$869; + var $11962=$11961; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $868=$11962; + var $11963=$868; + var $11964=(($11961)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $867=$11955; + var $11965=$867; + var $11966=(($11965)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $866=$11966; + var $11967=$866; + var $11968=$11967; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $865=$11968; + var $11969=$865; + var $11970=(($11969)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $11971=(($11970)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11972=$11971; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $11973=(($11972)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i396=$11973; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i397=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1857; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1857: + var $11975=$__i_i_i_i_i_i_i397; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11976=(($11975)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($11976) { label = 1858; break; } else { label = 1859; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1858: + var $11978=$__i_i_i_i_i_i_i397; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11979=$__a_i_i_i_i_i_i396; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11980=(($11979+($11978<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($11980)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $11981=$__i_i_i_i_i_i_i397; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $11982=((($11981)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i397=$11982; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1857; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1859: + var $11983=(($11950+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11983)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11984=(($11950+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $11985=$875; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($11984)>>2)]=$11985; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $864=$878; + var $11986=$864; + $863=$11986; + var $11987=$863; + var $11988=$11987; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $11989=(($11987)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $862=$11989; + var $11990=$862; + $861=$11990; + var $11991=$861; + var $11992=$11991; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $860=$11992; + var $11993=$860; + var $11994=$11993; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $859=$11994; + var $11995=$859; + var $11996=(($11993)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $858=$11987; + var $11997=$858; + var $11998=(($11997)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $857=$11998; + var $11999=$857; + var $12000=$11999; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $856=$12000; + var $12001=$856; + var $12002=(($12001)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12003=(($12002)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12004=$12003; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12005=(($12004)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i394=$12005; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i395=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1860; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1860: + var $12007=$__i_i_i_i2_i_i_i395; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12008=(($12007)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12008) { label = 1861; break; } else { label = 1862; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1861: + var $12010=$__i_i_i_i2_i_i_i395; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12011=$__a_i_i_i1_i_i_i394; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12012=(($12011+($12010<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12012)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12013=$__i_i_i_i2_i_i_i395; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12014=((($12013)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i395=$12014; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1860; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1862: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($11950, $878) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1863; break; } else { label = 1865; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1863: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($878) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1878; break; } else { label = 1864; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1864: + var $12017$0 = ___cxa_find_matching_catch(-1, -1); $12017$1 = tempRet0; + var $12018=$12017$0; + $876=$12018; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12019=$12017$1; + $877=$12019; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1867; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1865: + var $12021$0 = ___cxa_find_matching_catch(-1, -1); $12021$1 = tempRet0; + var $12022=$12021$0; + $876=$12022; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12023=$12021$1; + $877=$12023; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($878) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1866; break; } else { label = 1870; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1866: + label = 1867; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1867: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($11953) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1868; break; } else { label = 1870; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1868: + var $12027=$11950; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($12027) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1869; break; } else { label = 1870; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1869: + var $12029=$876; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12030=$877; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12031$0=$12029; + var $12031$1=0; + var $12032$0=$12031$0; + var $12032$1=$12030; + var $eh_lpad_body_i402$1 = $12032$1;var $eh_lpad_body_i402$0 = $12032$0;label = 1873; break; + case 1870: + var $12034$0 = ___cxa_find_matching_catch(-1, -1,0); $12034$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1871: + var $12036$0 = ___cxa_find_matching_catch(-1, -1); $12036$1 = tempRet0; + var $12037=$12036$0; + $885=$12037; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12038=$12036$1; + $886=$12038; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1875; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1872: + var $12040$0 = ___cxa_find_matching_catch(-1, -1); $12040$1 = tempRet0; + var $eh_lpad_body_i402$1 = $12040$1;var $eh_lpad_body_i402$0 = $12040$0;label = 1873; break; + case 1873: + var $eh_lpad_body_i402$0; + var $eh_lpad_body_i402$1; + var $12041=$eh_lpad_body_i402$0; + $885=$12041; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12042=$eh_lpad_body_i402$1; + $886=$12042; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12043=$11850; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($12043, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1874; break; } else { label = 1877; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1874: + label = 1875; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1875: + var $12046=$11850; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12047=(($12046+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12048=$12047; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($12048) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1876; break; } else { label = 1877; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1876: + var $12050=$885; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12051=$886; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12052$0=$12050; + var $12052$1=0; + var $12053$0=$12052$0; + var $12053$1=$12051; + ___resumeException($12053$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1877: + var $12055$0 = ___cxa_find_matching_catch(-1, -1,0); $12055$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1878: + var $12056=$std_stringstream28; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12057=(($12056+8)|0); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12058=$12057; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12059 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12058, ((87560)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1879; break; } else { label = 1900; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1879: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2713, ((88960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1880; break; } else { label = 1900; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1880: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2712, $2713, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1881; break; } else { label = 1901; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1881: + var $12063 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($12059, $2712) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1882; break; } else { label = 1902; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1882: + var $12065 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12063, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1883; break; } else { label = 1902; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1883: + var $12067 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12065, ((88176)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1884; break; } else { label = 1902; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1884: + var $12069 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12067, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1885; break; } else { label = 1902; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1885: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2712) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1886; break; } else { label = 1901; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1886: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2713) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1887; break; } else { label = 1900; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1887: + var $12073=___cxa_allocate_exception(8); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2715=1; + var $12074=$12073; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $843=$std_stringstream28; + var $12075=$843; + var $12076=(($12075+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2714, $12076) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1888; break; } else { label = 1906; break; } + case 1888: + label = 1889; break; + case 1889: + $842=$2714; + var $12078=$842; + $841=$12078; + var $12079=$841; + $840=$12079; + var $12080=$840; + $839=$12080; + var $12081=$839; + var $12082=(($12081)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $838=$12082; + var $12083=$838; + var $12084=$12083; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $837=$12084; + var $12085=$837; + var $12086=(($12085)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12087=(($12086)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12088=$12087; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12089=(($12088)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12090=$12089; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12091=HEAP8[($12090)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12092=(($12091)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12093=$12092 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12094=(($12093)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($12094) { label = 1890; break; } else { label = 1891; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1890: + $831=$12080; + var $12096=$831; + var $12097=(($12096)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $830=$12097; + var $12098=$830; + var $12099=$12098; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $829=$12099; + var $12100=$829; + var $12101=(($12100)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12102=(($12101)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12103=$12102; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12104=(($12103+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12105=HEAP32[(($12104)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12119 = $12105;label = 1892; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1891: + $836=$12080; + var $12107=$836; + var $12108=(($12107)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $835=$12108; + var $12109=$835; + var $12110=$12109; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $834=$12110; + var $12111=$834; + var $12112=(($12111)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12113=(($12112)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12114=$12113; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12115=(($12114+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12116=(($12115)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $833=$12116; + var $12117=$833; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $832=$12117; + var $12118=$832; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $12119 = $12118;label = 1892; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1892: + var $12119; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $828=$12119; + var $12120=$828; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($12074, $12120) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1893; break; } else { label = 1907; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1893: + $2715=0; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($12073, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1907; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2714) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1894; break; } else { label = 1906; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1894: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream28); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1914; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1895: + var $12125$0 = ___cxa_find_matching_catch(-1, -1); $12125$1 = tempRet0; + var $12126=$12125$0; + $2542=$12126; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12127=$12125$1; + $2543=$12127; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1898; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1896: + var $12129$0 = ___cxa_find_matching_catch(-1, -1); $12129$1 = tempRet0; + var $12130=$12129$0; + $2542=$12130; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12131=$12129$1; + $2543=$12131; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2710) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1897; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1897: + label = 1898; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1898: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2711) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1899; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1899: + label = 2840; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1900: + var $12136$0 = ___cxa_find_matching_catch(-1, -1); $12136$1 = tempRet0; + var $12137=$12136$0; + $2542=$12137; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12138=$12136$1; + $2543=$12138; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1912; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1901: + var $12140$0 = ___cxa_find_matching_catch(-1, -1); $12140$1 = tempRet0; + var $12141=$12140$0; + $2542=$12141; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12142=$12140$1; + $2543=$12142; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1904; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1902: + var $12144$0 = ___cxa_find_matching_catch(-1, -1); $12144$1 = tempRet0; + var $12145=$12144$0; + $2542=$12145; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12146=$12144$1; + $2543=$12146; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2712) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1903; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1903: + label = 1904; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1904: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2713) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1905; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1905: + label = 1912; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1906: + var $12151$0 = ___cxa_find_matching_catch(-1, -1); $12151$1 = tempRet0; + var $12152=$12151$0; + $2542=$12152; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12153=$12151$1; + $2543=$12153; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1909; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1907: + var $12155$0 = ___cxa_find_matching_catch(-1, -1); $12155$1 = tempRet0; + var $12156=$12155$0; + $2542=$12156; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12157=$12155$1; + $2543=$12157; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2714) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1908; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1908: + label = 1909; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1909: + var $12160=$2715; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12160) { label = 1910; break; } else { label = 1911; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1910: + ___cxa_free_exception($12073); //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1911; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1911: + label = 1912; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1912: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream28) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1913; break; } else { label = 2841; break; } //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1913: + label = 2840; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1914: + label = 1915; break; //@line 168 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1915: + label = 1916; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1916: + __ZN6StringC1EPKc($2717, ((88960)|0)); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2716, $2717, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1917; break; } else { label = 1961; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1917: + var $12169 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2716, ((87208)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1918; break; } else { label = 1962; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1918: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2716) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1919; break; } else { label = 1961; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1919: + __ZN6StringD1Ev($2717); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12169) { label = 1920; break; } else { label = 1980; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1920: + $824=$std_stringstream29; + $825=24; + var $12173=$824; + var $12174=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12175=(($12174+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12176=$12175; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $823=$12176; + var $12177=$823; + var $12178=$12177; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $822=$12178; + var $12179=$822; + var $12180=$12179; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12180)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $12181=$12177; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12181)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $12182=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12182)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12183=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12184=(($12183+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12185=$12184; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12185)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12186=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12187=(($12186+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12188=$12187; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12188)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12189=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12190=(($12173+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12191=$12190; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $792=$12189; + $793=((109796)|0); + $794=$12191; + var $12192=$792; + var $12193=$793; + var $12194=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12195=(($12193+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12196=$794; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $789=$12194; + $790=$12195; + $791=$12196; + var $12197=$789; + var $12198=$790; + var $12199=HEAP32[(($12198)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12200=$12197; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12200)>>2)]=$12199; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12201=(($12198+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12202=HEAP32[(($12201)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12203=$12197; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12204=HEAP32[(($12203)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12205=((($12204)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12206=$12205; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12207=HEAP32[(($12206)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12208=$12197; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12209=(($12208+$12207)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12210=$12209; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12210)>>2)]=$12202; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12211=(($12197+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12211)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12212=$12197; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12213=HEAP32[(($12212)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12214=((($12213)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12215=$12214; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12216=HEAP32[(($12215)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12217=$12197; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12218=(($12217+$12216)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12219=$12218; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12220=$791; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $787=$12219; + $788=$12220; + var $12221=$787; + var $12222=$12221; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12223=$788; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12224=$12223; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($12222, $12224) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1921; break; } else { label = 1937; break; } + case 1921: + var $12225=(($12221+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12225)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $12226=(($12221+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12226)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $12227=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12228=(($12227+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12229=$12228; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12230=(($12193+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $785=$12229; + $786=$12230; + var $12231=$785; + var $12232=$786; + var $12233=HEAP32[(($12232)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12234=$12231; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12234)>>2)]=$12233; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12235=(($12232+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12236=HEAP32[(($12235)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12237=$12231; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12238=HEAP32[(($12237)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12239=((($12238)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12240=$12239; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12241=HEAP32[(($12240)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12242=$12231; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12243=(($12242+$12241)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12244=$12243; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12244)>>2)]=$12236; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12245=HEAP32[(($12193)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12246=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12246)>>2)]=$12245; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12247=(($12193+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12248=HEAP32[(($12247)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12249=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12250=HEAP32[(($12249)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12251=((($12250)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12252=$12251; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12253=HEAP32[(($12252)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12254=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12255=(($12254+$12253)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12256=$12255; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12256)>>2)]=$12248; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12257=(($12193+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12258=HEAP32[(($12257)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12259=$12192; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12260=(($12259+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12261=$12260; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12261)>>2)]=$12258; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12262=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12262)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12263=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12264=(($12263+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12265=$12264; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12265)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12266=$12173; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12267=(($12266+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12268=$12267; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12268)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12269=(($12173+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12270=$825; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $820=$12269; + $821=$12270; + var $12271=$820; + var $12272=$821; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $815=$12271; + $816=$12272; + var $12273=$815; + var $12274=$12273; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($12274) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1922; break; } else { label = 1938; break; } + case 1922: + var $12275=$12273; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12275)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12276=(($12273+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $814=$12276; + var $12277=$814; + $813=$12277; + var $12278=$813; + var $12279=$12278; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12280=(($12278)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $812=$12280; + var $12281=$812; + $811=$12281; + var $12282=$811; + var $12283=$12282; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $810=$12283; + var $12284=$810; + var $12285=$12284; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $809=$12285; + var $12286=$809; + var $12287=(($12284)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $808=$12278; + var $12288=$808; + var $12289=(($12288)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $807=$12289; + var $12290=$807; + var $12291=$12290; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $806=$12291; + var $12292=$806; + var $12293=(($12292)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12294=(($12293)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12295=$12294; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12296=(($12295)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i409=$12296; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i410=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1923; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1923: + var $12298=$__i_i_i_i_i_i_i410; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12299=(($12298)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12299) { label = 1924; break; } else { label = 1925; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1924: + var $12301=$__i_i_i_i_i_i_i410; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12302=$__a_i_i_i_i_i_i409; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12303=(($12302+($12301<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12303)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12304=$__i_i_i_i_i_i_i410; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12305=((($12304)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i410=$12305; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1923; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1925: + var $12306=(($12273+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12306)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12307=(($12273+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12308=$816; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12307)>>2)]=$12308; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $805=$819; + var $12309=$805; + $804=$12309; + var $12310=$804; + var $12311=$12310; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12312=(($12310)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $803=$12312; + var $12313=$803; + $802=$12313; + var $12314=$802; + var $12315=$12314; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $801=$12315; + var $12316=$801; + var $12317=$12316; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $800=$12317; + var $12318=$800; + var $12319=(($12316)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $799=$12310; + var $12320=$799; + var $12321=(($12320)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $798=$12321; + var $12322=$798; + var $12323=$12322; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $797=$12323; + var $12324=$797; + var $12325=(($12324)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12326=(($12325)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12327=$12326; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12328=(($12327)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i407=$12328; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i408=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1926; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1926: + var $12330=$__i_i_i_i2_i_i_i408; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12331=(($12330)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12331) { label = 1927; break; } else { label = 1928; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1927: + var $12333=$__i_i_i_i2_i_i_i408; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12334=$__a_i_i_i1_i_i_i407; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12335=(($12334+($12333<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12335)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12336=$__i_i_i_i2_i_i_i408; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12337=((($12336)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i408=$12337; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1926; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1928: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($12273, $819) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1929; break; } else { label = 1931; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1929: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($819) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1944; break; } else { label = 1930; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1930: + var $12340$0 = ___cxa_find_matching_catch(-1, -1); $12340$1 = tempRet0; + var $12341=$12340$0; + $817=$12341; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12342=$12340$1; + $818=$12342; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1933; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1931: + var $12344$0 = ___cxa_find_matching_catch(-1, -1); $12344$1 = tempRet0; + var $12345=$12344$0; + $817=$12345; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12346=$12344$1; + $818=$12346; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($819) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1932; break; } else { label = 1936; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1932: + label = 1933; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1933: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($12276) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1934; break; } else { label = 1936; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1934: + var $12350=$12273; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($12350) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1935; break; } else { label = 1936; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 1935: + var $12352=$817; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12353=$818; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12354$0=$12352; + var $12354$1=0; + var $12355$0=$12354$0; + var $12355$1=$12353; + var $eh_lpad_body_i415$1 = $12355$1;var $eh_lpad_body_i415$0 = $12355$0;label = 1939; break; + case 1936: + var $12357$0 = ___cxa_find_matching_catch(-1, -1,0); $12357$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1937: + var $12359$0 = ___cxa_find_matching_catch(-1, -1); $12359$1 = tempRet0; + var $12360=$12359$0; + $826=$12360; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12361=$12359$1; + $827=$12361; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 1941; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 1938: + var $12363$0 = ___cxa_find_matching_catch(-1, -1); $12363$1 = tempRet0; + var $eh_lpad_body_i415$1 = $12363$1;var $eh_lpad_body_i415$0 = $12363$0;label = 1939; break; + case 1939: + var $eh_lpad_body_i415$0; + var $eh_lpad_body_i415$1; + var $12364=$eh_lpad_body_i415$0; + $826=$12364; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12365=$eh_lpad_body_i415$1; + $827=$12365; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12366=$12173; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($12366, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1940; break; } else { label = 1943; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1940: + label = 1941; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1941: + var $12369=$12173; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12370=(($12369+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12371=$12370; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($12371) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1942; break; } else { label = 1943; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1942: + var $12373=$826; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12374=$827; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12375$0=$12373; + var $12375$1=0; + var $12376$0=$12375$0; + var $12376$1=$12374; + ___resumeException($12376$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1943: + var $12378$0 = ___cxa_find_matching_catch(-1, -1,0); $12378$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 1944: + var $12379=$std_stringstream29; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12380=(($12379+8)|0); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12381=$12380; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12382 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12381, ((86936)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1945; break; } else { label = 1966; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1945: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2719, ((88960)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1946; break; } else { label = 1966; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1946: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2718, $2719, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1947; break; } else { label = 1967; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1947: + var $12386 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($12382, $2718) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1948; break; } else { label = 1968; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1948: + var $12388 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12386, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1949; break; } else { label = 1968; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1949: + var $12390 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12388, ((87208)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1950; break; } else { label = 1968; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1950: + var $12392 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12390, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1951; break; } else { label = 1968; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1951: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2718) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1952; break; } else { label = 1967; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1952: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2719) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1953; break; } else { label = 1966; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1953: + var $12396=___cxa_allocate_exception(8); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2721=1; + var $12397=$12396; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $784=$std_stringstream29; + var $12398=$784; + var $12399=(($12398+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2720, $12399) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1954; break; } else { label = 1972; break; } + case 1954: + label = 1955; break; + case 1955: + $783=$2720; + var $12401=$783; + $782=$12401; + var $12402=$782; + $781=$12402; + var $12403=$781; + $780=$12403; + var $12404=$780; + var $12405=(($12404)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $779=$12405; + var $12406=$779; + var $12407=$12406; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $778=$12407; + var $12408=$778; + var $12409=(($12408)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12410=(($12409)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12411=$12410; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12412=(($12411)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12413=$12412; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12414=HEAP8[($12413)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12415=(($12414)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12416=$12415 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12417=(($12416)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($12417) { label = 1956; break; } else { label = 1957; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1956: + $772=$12403; + var $12419=$772; + var $12420=(($12419)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $771=$12420; + var $12421=$771; + var $12422=$12421; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $770=$12422; + var $12423=$770; + var $12424=(($12423)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12425=(($12424)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12426=$12425; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12427=(($12426+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12428=HEAP32[(($12427)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12442 = $12428;label = 1958; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1957: + $777=$12403; + var $12430=$777; + var $12431=(($12430)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $776=$12431; + var $12432=$776; + var $12433=$12432; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $775=$12433; + var $12434=$775; + var $12435=(($12434)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12436=(($12435)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12437=$12436; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12438=(($12437+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12439=(($12438)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $774=$12439; + var $12440=$774; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $773=$12440; + var $12441=$773; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $12442 = $12441;label = 1958; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 1958: + var $12442; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $769=$12442; + var $12443=$769; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($12397, $12443) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1959; break; } else { label = 1973; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1959: + $2721=0; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($12396, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 1973; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2720) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1960; break; } else { label = 1972; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1960: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream29); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1980; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1961: + var $12448$0 = ___cxa_find_matching_catch(-1, -1); $12448$1 = tempRet0; + var $12449=$12448$0; + $2542=$12449; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12450=$12448$1; + $2543=$12450; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1964; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1962: + var $12452$0 = ___cxa_find_matching_catch(-1, -1); $12452$1 = tempRet0; + var $12453=$12452$0; + $2542=$12453; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12454=$12452$1; + $2543=$12454; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2716) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1963; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1963: + label = 1964; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1964: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2717) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1965; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1965: + label = 2840; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1966: + var $12459$0 = ___cxa_find_matching_catch(-1, -1); $12459$1 = tempRet0; + var $12460=$12459$0; + $2542=$12460; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12461=$12459$1; + $2543=$12461; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1978; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1967: + var $12463$0 = ___cxa_find_matching_catch(-1, -1); $12463$1 = tempRet0; + var $12464=$12463$0; + $2542=$12464; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12465=$12463$1; + $2543=$12465; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1970; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1968: + var $12467$0 = ___cxa_find_matching_catch(-1, -1); $12467$1 = tempRet0; + var $12468=$12467$0; + $2542=$12468; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12469=$12467$1; + $2543=$12469; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2718) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1969; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1969: + label = 1970; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1970: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2719) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1971; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1971: + label = 1978; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1972: + var $12474$0 = ___cxa_find_matching_catch(-1, -1); $12474$1 = tempRet0; + var $12475=$12474$0; + $2542=$12475; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12476=$12474$1; + $2543=$12476; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1975; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1973: + var $12478$0 = ___cxa_find_matching_catch(-1, -1); $12478$1 = tempRet0; + var $12479=$12478$0; + $2542=$12479; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12480=$12478$1; + $2543=$12480; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2720) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1974; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1974: + label = 1975; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1975: + var $12483=$2721; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12483) { label = 1976; break; } else { label = 1977; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1976: + ___cxa_free_exception($12396); //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 1977; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1977: + label = 1978; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1978: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream29) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1979; break; } else { label = 2841; break; } //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1979: + label = 2840; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1980: + label = 1981; break; //@line 169 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1981: + label = 1982; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1982: + __ZN6StringC1EPKc($2723, ((86608)|0)); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2722, $2723, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1983; break; } else { label = 2027; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1983: + var $12492 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2722, ((86608)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1984; break; } else { label = 2028; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1984: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2722) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1985; break; } else { label = 2027; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1985: + __ZN6StringD1Ev($2723); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12492) { label = 1986; break; } else { label = 2046; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 1986: + $765=$std_stringstream30; + $766=24; + var $12496=$765; + var $12497=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12498=(($12497+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12499=$12498; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $764=$12499; + var $12500=$764; + var $12501=$12500; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $763=$12501; + var $12502=$763; + var $12503=$12502; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12503)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $12504=$12500; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12504)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $12505=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12505)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12506=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12507=(($12506+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12508=$12507; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12508)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12509=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12510=(($12509+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12511=$12510; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12511)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12512=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12513=(($12496+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12514=$12513; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $733=$12512; + $734=((109796)|0); + $735=$12514; + var $12515=$733; + var $12516=$734; + var $12517=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12518=(($12516+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12519=$735; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $730=$12517; + $731=$12518; + $732=$12519; + var $12520=$730; + var $12521=$731; + var $12522=HEAP32[(($12521)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12523=$12520; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12523)>>2)]=$12522; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12524=(($12521+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12525=HEAP32[(($12524)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12526=$12520; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12527=HEAP32[(($12526)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12528=((($12527)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12529=$12528; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12530=HEAP32[(($12529)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12531=$12520; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12532=(($12531+$12530)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12533=$12532; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12533)>>2)]=$12525; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12534=(($12520+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12534)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12535=$12520; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12536=HEAP32[(($12535)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12537=((($12536)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12538=$12537; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12539=HEAP32[(($12538)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12540=$12520; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12541=(($12540+$12539)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12542=$12541; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12543=$732; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $728=$12542; + $729=$12543; + var $12544=$728; + var $12545=$12544; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12546=$729; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12547=$12546; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($12545, $12547) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1987; break; } else { label = 2003; break; } + case 1987: + var $12548=(($12544+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12548)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $12549=(($12544+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12549)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $12550=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12551=(($12550+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12552=$12551; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12553=(($12516+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $726=$12552; + $727=$12553; + var $12554=$726; + var $12555=$727; + var $12556=HEAP32[(($12555)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12557=$12554; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12557)>>2)]=$12556; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12558=(($12555+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12559=HEAP32[(($12558)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12560=$12554; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12561=HEAP32[(($12560)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12562=((($12561)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12563=$12562; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12564=HEAP32[(($12563)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12565=$12554; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12566=(($12565+$12564)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12567=$12566; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12567)>>2)]=$12559; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12568=HEAP32[(($12516)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12569=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12569)>>2)]=$12568; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12570=(($12516+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12571=HEAP32[(($12570)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12572=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12573=HEAP32[(($12572)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12574=((($12573)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12575=$12574; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12576=HEAP32[(($12575)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12577=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12578=(($12577+$12576)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12579=$12578; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12579)>>2)]=$12571; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12580=(($12516+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12581=HEAP32[(($12580)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12582=$12515; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12583=(($12582+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12584=$12583; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12584)>>2)]=$12581; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12585=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12585)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12586=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12587=(($12586+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12588=$12587; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12588)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12589=$12496; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12590=(($12589+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12591=$12590; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12591)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12592=(($12496+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12593=$766; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $761=$12592; + $762=$12593; + var $12594=$761; + var $12595=$762; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $756=$12594; + $757=$12595; + var $12596=$756; + var $12597=$12596; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($12597) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1988; break; } else { label = 2004; break; } + case 1988: + var $12598=$12596; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12598)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12599=(($12596+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $755=$12599; + var $12600=$755; + $754=$12600; + var $12601=$754; + var $12602=$12601; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12603=(($12601)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $753=$12603; + var $12604=$753; + $752=$12604; + var $12605=$752; + var $12606=$12605; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $751=$12606; + var $12607=$751; + var $12608=$12607; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $750=$12608; + var $12609=$750; + var $12610=(($12607)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $749=$12601; + var $12611=$749; + var $12612=(($12611)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $748=$12612; + var $12613=$748; + var $12614=$12613; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $747=$12614; + var $12615=$747; + var $12616=(($12615)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12617=(($12616)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12618=$12617; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12619=(($12618)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i422=$12619; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i423=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1989; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1989: + var $12621=$__i_i_i_i_i_i_i423; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12622=(($12621)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12622) { label = 1990; break; } else { label = 1991; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1990: + var $12624=$__i_i_i_i_i_i_i423; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12625=$__a_i_i_i_i_i_i422; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12626=(($12625+($12624<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12626)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12627=$__i_i_i_i_i_i_i423; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12628=((($12627)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i423=$12628; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1989; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1991: + var $12629=(($12596+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12629)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12630=(($12596+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12631=$757; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12630)>>2)]=$12631; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $746=$760; + var $12632=$746; + $745=$12632; + var $12633=$745; + var $12634=$12633; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12635=(($12633)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $744=$12635; + var $12636=$744; + $743=$12636; + var $12637=$743; + var $12638=$12637; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $742=$12638; + var $12639=$742; + var $12640=$12639; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $741=$12640; + var $12641=$741; + var $12642=(($12639)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $740=$12633; + var $12643=$740; + var $12644=(($12643)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $739=$12644; + var $12645=$739; + var $12646=$12645; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $738=$12646; + var $12647=$738; + var $12648=(($12647)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12649=(($12648)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12650=$12649; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12651=(($12650)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i420=$12651; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i421=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1992; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1992: + var $12653=$__i_i_i_i2_i_i_i421; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12654=(($12653)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12654) { label = 1993; break; } else { label = 1994; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1993: + var $12656=$__i_i_i_i2_i_i_i421; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12657=$__a_i_i_i1_i_i_i420; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12658=(($12657+($12656<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12658)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12659=$__i_i_i_i2_i_i_i421; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12660=((($12659)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i421=$12660; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 1992; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 1994: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($12596, $760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1995; break; } else { label = 1997; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1995: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2010; break; } else { label = 1996; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1996: + var $12663$0 = ___cxa_find_matching_catch(-1, -1); $12663$1 = tempRet0; + var $12664=$12663$0; + $758=$12664; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12665=$12663$1; + $759=$12665; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 1999; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1997: + var $12667$0 = ___cxa_find_matching_catch(-1, -1); $12667$1 = tempRet0; + var $12668=$12667$0; + $758=$12668; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12669=$12667$1; + $759=$12669; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 1998; break; } else { label = 2002; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1998: + label = 1999; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 1999: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($12599) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2000; break; } else { label = 2002; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2000: + var $12673=$12596; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($12673) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2001; break; } else { label = 2002; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2001: + var $12675=$758; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12676=$759; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12677$0=$12675; + var $12677$1=0; + var $12678$0=$12677$0; + var $12678$1=$12676; + var $eh_lpad_body_i428$1 = $12678$1;var $eh_lpad_body_i428$0 = $12678$0;label = 2005; break; + case 2002: + var $12680$0 = ___cxa_find_matching_catch(-1, -1,0); $12680$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2003: + var $12682$0 = ___cxa_find_matching_catch(-1, -1); $12682$1 = tempRet0; + var $12683=$12682$0; + $767=$12683; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12684=$12682$1; + $768=$12684; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2007; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2004: + var $12686$0 = ___cxa_find_matching_catch(-1, -1); $12686$1 = tempRet0; + var $eh_lpad_body_i428$1 = $12686$1;var $eh_lpad_body_i428$0 = $12686$0;label = 2005; break; + case 2005: + var $eh_lpad_body_i428$0; + var $eh_lpad_body_i428$1; + var $12687=$eh_lpad_body_i428$0; + $767=$12687; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12688=$eh_lpad_body_i428$1; + $768=$12688; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12689=$12496; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($12689, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2006; break; } else { label = 2009; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2006: + label = 2007; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2007: + var $12692=$12496; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12693=(($12692+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12694=$12693; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($12694) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2008; break; } else { label = 2009; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2008: + var $12696=$767; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12697=$768; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $12698$0=$12696; + var $12698$1=0; + var $12699$0=$12698$0; + var $12699$1=$12697; + ___resumeException($12699$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2009: + var $12701$0 = ___cxa_find_matching_catch(-1, -1,0); $12701$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2010: + var $12702=$std_stringstream30; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12703=(($12702+8)|0); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12704=$12703; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12705 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12704, ((86168)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2011; break; } else { label = 2032; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2011: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2725, ((86608)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2012; break; } else { label = 2032; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2012: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2724, $2725, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2013; break; } else { label = 2033; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2013: + var $12709 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($12705, $2724) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2014; break; } else { label = 2034; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2014: + var $12711 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12709, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2015; break; } else { label = 2034; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2015: + var $12713 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12711, ((86608)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2016; break; } else { label = 2034; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2016: + var $12715 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($12713, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2017; break; } else { label = 2034; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2017: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2724) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2018; break; } else { label = 2033; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2018: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2725) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2019; break; } else { label = 2032; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2019: + var $12719=___cxa_allocate_exception(8); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2727=1; + var $12720=$12719; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $725=$std_stringstream30; + var $12721=$725; + var $12722=(($12721+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2726, $12722) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2020; break; } else { label = 2038; break; } + case 2020: + label = 2021; break; + case 2021: + $724=$2726; + var $12724=$724; + $723=$12724; + var $12725=$723; + $722=$12725; + var $12726=$722; + $721=$12726; + var $12727=$721; + var $12728=(($12727)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $720=$12728; + var $12729=$720; + var $12730=$12729; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $719=$12730; + var $12731=$719; + var $12732=(($12731)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12733=(($12732)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12734=$12733; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12735=(($12734)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12736=$12735; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12737=HEAP8[($12736)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12738=(($12737)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12739=$12738 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $12740=(($12739)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($12740) { label = 2022; break; } else { label = 2023; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2022: + $713=$12726; + var $12742=$713; + var $12743=(($12742)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $712=$12743; + var $12744=$712; + var $12745=$12744; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $711=$12745; + var $12746=$711; + var $12747=(($12746)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12748=(($12747)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12749=$12748; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12750=(($12749+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12751=HEAP32[(($12750)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $12765 = $12751;label = 2024; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2023: + $718=$12726; + var $12753=$718; + var $12754=(($12753)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $717=$12754; + var $12755=$717; + var $12756=$12755; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $716=$12756; + var $12757=$716; + var $12758=(($12757)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $12759=(($12758)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12760=$12759; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12761=(($12760+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $12762=(($12761)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $715=$12762; + var $12763=$715; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $714=$12763; + var $12764=$714; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $12765 = $12764;label = 2024; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2024: + var $12765; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $710=$12765; + var $12766=$710; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($12720, $12766) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2025; break; } else { label = 2039; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2025: + $2727=0; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($12719, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2039; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2726) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2026; break; } else { label = 2038; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2026: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream30); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2046; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2027: + var $12771$0 = ___cxa_find_matching_catch(-1, -1); $12771$1 = tempRet0; + var $12772=$12771$0; + $2542=$12772; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12773=$12771$1; + $2543=$12773; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2030; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2028: + var $12775$0 = ___cxa_find_matching_catch(-1, -1); $12775$1 = tempRet0; + var $12776=$12775$0; + $2542=$12776; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12777=$12775$1; + $2543=$12777; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2722) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2029; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2029: + label = 2030; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2030: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2723) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2031; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2031: + label = 2840; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2032: + var $12782$0 = ___cxa_find_matching_catch(-1, -1); $12782$1 = tempRet0; + var $12783=$12782$0; + $2542=$12783; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12784=$12782$1; + $2543=$12784; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2044; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2033: + var $12786$0 = ___cxa_find_matching_catch(-1, -1); $12786$1 = tempRet0; + var $12787=$12786$0; + $2542=$12787; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12788=$12786$1; + $2543=$12788; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2036; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2034: + var $12790$0 = ___cxa_find_matching_catch(-1, -1); $12790$1 = tempRet0; + var $12791=$12790$0; + $2542=$12791; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12792=$12790$1; + $2543=$12792; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2724) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2035; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2035: + label = 2036; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2036: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2725) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2037; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2037: + label = 2044; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2038: + var $12797$0 = ___cxa_find_matching_catch(-1, -1); $12797$1 = tempRet0; + var $12798=$12797$0; + $2542=$12798; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12799=$12797$1; + $2543=$12799; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2041; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2039: + var $12801$0 = ___cxa_find_matching_catch(-1, -1); $12801$1 = tempRet0; + var $12802=$12801$0; + $2542=$12802; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $12803=$12801$1; + $2543=$12803; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2726) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2040; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2040: + label = 2041; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2041: + var $12806=$2727; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12806) { label = 2042; break; } else { label = 2043; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2042: + ___cxa_free_exception($12719); //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2043; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2043: + label = 2044; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2044: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream30) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2045; break; } else { label = 2841; break; } //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2045: + label = 2840; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2046: + label = 2047; break; //@line 171 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2047: + label = 2048; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2048: + __ZN6StringC1EPKc($2729, ((86056)|0)); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2728, $2729, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2049; break; } else { label = 2093; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2049: + var $12815 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2728, ((85832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2050; break; } else { label = 2094; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2050: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2728) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2051; break; } else { label = 2093; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2051: + __ZN6StringD1Ev($2729); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($12815) { label = 2052; break; } else { label = 2112; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2052: + $706=$std_stringstream31; + $707=24; + var $12819=$706; + var $12820=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12821=(($12820+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12822=$12821; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $705=$12822; + var $12823=$705; + var $12824=$12823; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $704=$12824; + var $12825=$704; + var $12826=$12825; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12826)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $12827=$12823; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12827)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $12828=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12828)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12829=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12830=(($12829+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12831=$12830; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12831)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12832=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12833=(($12832+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12834=$12833; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12834)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12835=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12836=(($12819+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12837=$12836; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $674=$12835; + $675=((109796)|0); + $676=$12837; + var $12838=$674; + var $12839=$675; + var $12840=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12841=(($12839+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12842=$676; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $671=$12840; + $672=$12841; + $673=$12842; + var $12843=$671; + var $12844=$672; + var $12845=HEAP32[(($12844)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12846=$12843; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12846)>>2)]=$12845; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12847=(($12844+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12848=HEAP32[(($12847)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12849=$12843; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12850=HEAP32[(($12849)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12851=((($12850)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12852=$12851; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12853=HEAP32[(($12852)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12854=$12843; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12855=(($12854+$12853)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12856=$12855; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12856)>>2)]=$12848; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12857=(($12843+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12857)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $12858=$12843; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12859=HEAP32[(($12858)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12860=((($12859)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12861=$12860; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12862=HEAP32[(($12861)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12863=$12843; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12864=(($12863+$12862)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12865=$12864; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $12866=$673; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $669=$12865; + $670=$12866; + var $12867=$669; + var $12868=$12867; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12869=$670; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $12870=$12869; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($12868, $12870) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2053; break; } else { label = 2069; break; } + case 2053: + var $12871=(($12867+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12871)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $12872=(($12867+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($12872)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $12873=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12874=(($12873+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12875=$12874; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12876=(($12839+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $667=$12875; + $668=$12876; + var $12877=$667; + var $12878=$668; + var $12879=HEAP32[(($12878)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12880=$12877; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12880)>>2)]=$12879; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12881=(($12878+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12882=HEAP32[(($12881)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12883=$12877; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12884=HEAP32[(($12883)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12885=((($12884)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12886=$12885; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12887=HEAP32[(($12886)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12888=$12877; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12889=(($12888+$12887)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12890=$12889; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12890)>>2)]=$12882; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $12891=HEAP32[(($12839)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12892=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12892)>>2)]=$12891; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12893=(($12839+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12894=HEAP32[(($12893)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12895=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12896=HEAP32[(($12895)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12897=((($12896)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12898=$12897; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12899=HEAP32[(($12898)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12900=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12901=(($12900+$12899)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12902=$12901; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12902)>>2)]=$12894; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12903=(($12839+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12904=HEAP32[(($12903)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12905=$12838; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12906=(($12905+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12907=$12906; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12907)>>2)]=$12904; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $12908=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12908)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12909=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12910=(($12909+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12911=$12910; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12911)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12912=$12819; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12913=(($12912+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12914=$12913; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12914)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12915=(($12819+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $12916=$707; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $702=$12915; + $703=$12916; + var $12917=$702; + var $12918=$703; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $697=$12917; + $698=$12918; + var $12919=$697; + var $12920=$12919; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($12920) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2054; break; } else { label = 2070; break; } + case 2054: + var $12921=$12919; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12921)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12922=(($12919+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $696=$12922; + var $12923=$696; + $695=$12923; + var $12924=$695; + var $12925=$12924; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12926=(($12924)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $694=$12926; + var $12927=$694; + $693=$12927; + var $12928=$693; + var $12929=$12928; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $692=$12929; + var $12930=$692; + var $12931=$12930; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $691=$12931; + var $12932=$691; + var $12933=(($12930)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $690=$12924; + var $12934=$690; + var $12935=(($12934)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $689=$12935; + var $12936=$689; + var $12937=$12936; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $688=$12937; + var $12938=$688; + var $12939=(($12938)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12940=(($12939)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12941=$12940; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12942=(($12941)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i435=$12942; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i436=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2055; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2055: + var $12944=$__i_i_i_i_i_i_i436; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12945=(($12944)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12945) { label = 2056; break; } else { label = 2057; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2056: + var $12947=$__i_i_i_i_i_i_i436; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12948=$__a_i_i_i_i_i_i435; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12949=(($12948+($12947<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12949)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12950=$__i_i_i_i_i_i_i436; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12951=((($12950)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i436=$12951; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2055; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2057: + var $12952=(($12919+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12952)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12953=(($12919+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $12954=$698; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($12953)>>2)]=$12954; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $687=$701; + var $12955=$687; + $686=$12955; + var $12956=$686; + var $12957=$12956; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $12958=(($12956)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $685=$12958; + var $12959=$685; + $684=$12959; + var $12960=$684; + var $12961=$12960; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $683=$12961; + var $12962=$683; + var $12963=$12962; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $682=$12963; + var $12964=$682; + var $12965=(($12962)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $681=$12956; + var $12966=$681; + var $12967=(($12966)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $680=$12967; + var $12968=$680; + var $12969=$12968; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $679=$12969; + var $12970=$679; + var $12971=(($12970)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $12972=(($12971)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12973=$12972; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $12974=(($12973)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i433=$12974; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i434=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2058; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2058: + var $12976=$__i_i_i_i2_i_i_i434; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12977=(($12976)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($12977) { label = 2059; break; } else { label = 2060; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2059: + var $12979=$__i_i_i_i2_i_i_i434; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12980=$__a_i_i_i1_i_i_i433; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12981=(($12980+($12979<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($12981)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $12982=$__i_i_i_i2_i_i_i434; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $12983=((($12982)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i434=$12983; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2058; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2060: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($12919, $701) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2061; break; } else { label = 2063; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2061: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($701) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2076; break; } else { label = 2062; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2062: + var $12986$0 = ___cxa_find_matching_catch(-1, -1); $12986$1 = tempRet0; + var $12987=$12986$0; + $699=$12987; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12988=$12986$1; + $700=$12988; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2065; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2063: + var $12990$0 = ___cxa_find_matching_catch(-1, -1); $12990$1 = tempRet0; + var $12991=$12990$0; + $699=$12991; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $12992=$12990$1; + $700=$12992; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($701) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2064; break; } else { label = 2068; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2064: + label = 2065; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2065: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($12922) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2066; break; } else { label = 2068; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2066: + var $12996=$12919; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($12996) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2067; break; } else { label = 2068; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2067: + var $12998=$699; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $12999=$700; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13000$0=$12998; + var $13000$1=0; + var $13001$0=$13000$0; + var $13001$1=$12999; + var $eh_lpad_body_i441$1 = $13001$1;var $eh_lpad_body_i441$0 = $13001$0;label = 2071; break; + case 2068: + var $13003$0 = ___cxa_find_matching_catch(-1, -1,0); $13003$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2069: + var $13005$0 = ___cxa_find_matching_catch(-1, -1); $13005$1 = tempRet0; + var $13006=$13005$0; + $708=$13006; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13007=$13005$1; + $709=$13007; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2073; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2070: + var $13009$0 = ___cxa_find_matching_catch(-1, -1); $13009$1 = tempRet0; + var $eh_lpad_body_i441$1 = $13009$1;var $eh_lpad_body_i441$0 = $13009$0;label = 2071; break; + case 2071: + var $eh_lpad_body_i441$0; + var $eh_lpad_body_i441$1; + var $13010=$eh_lpad_body_i441$0; + $708=$13010; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13011=$eh_lpad_body_i441$1; + $709=$13011; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13012=$12819; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($13012, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2072; break; } else { label = 2075; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2072: + label = 2073; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2073: + var $13015=$12819; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13016=(($13015+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13017=$13016; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($13017) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2074; break; } else { label = 2075; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2074: + var $13019=$708; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13020=$709; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13021$0=$13019; + var $13021$1=0; + var $13022$0=$13021$0; + var $13022$1=$13020; + ___resumeException($13022$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2075: + var $13024$0 = ___cxa_find_matching_catch(-1, -1,0); $13024$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2076: + var $13025=$std_stringstream31; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13026=(($13025+8)|0); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13027=$13026; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13028 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13027, ((85424)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2077; break; } else { label = 2098; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2077: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2731, ((86056)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2078; break; } else { label = 2098; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2078: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2730, $2731, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2079; break; } else { label = 2099; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2079: + var $13032 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($13028, $2730) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2080; break; } else { label = 2100; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2080: + var $13034 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13032, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2081; break; } else { label = 2100; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2081: + var $13036 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13034, ((85832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2082; break; } else { label = 2100; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2082: + var $13038 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13036, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2083; break; } else { label = 2100; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2083: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2730) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2084; break; } else { label = 2099; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2084: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2731) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2085; break; } else { label = 2098; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2085: + var $13042=___cxa_allocate_exception(8); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2733=1; + var $13043=$13042; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $666=$std_stringstream31; + var $13044=$666; + var $13045=(($13044+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2732, $13045) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2086; break; } else { label = 2104; break; } + case 2086: + label = 2087; break; + case 2087: + $665=$2732; + var $13047=$665; + $664=$13047; + var $13048=$664; + $663=$13048; + var $13049=$663; + $662=$13049; + var $13050=$662; + var $13051=(($13050)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $661=$13051; + var $13052=$661; + var $13053=$13052; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $660=$13053; + var $13054=$660; + var $13055=(($13054)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13056=(($13055)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13057=$13056; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13058=(($13057)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13059=$13058; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13060=HEAP8[($13059)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13061=(($13060)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13062=$13061 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13063=(($13062)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($13063) { label = 2088; break; } else { label = 2089; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2088: + $654=$13049; + var $13065=$654; + var $13066=(($13065)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $653=$13066; + var $13067=$653; + var $13068=$13067; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $652=$13068; + var $13069=$652; + var $13070=(($13069)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13071=(($13070)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13072=$13071; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13073=(($13072+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13074=HEAP32[(($13073)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13088 = $13074;label = 2090; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2089: + $659=$13049; + var $13076=$659; + var $13077=(($13076)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $658=$13077; + var $13078=$658; + var $13079=$13078; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $657=$13079; + var $13080=$657; + var $13081=(($13080)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13082=(($13081)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13083=$13082; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13084=(($13083+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13085=(($13084)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $656=$13085; + var $13086=$656; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $655=$13086; + var $13087=$655; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $13088 = $13087;label = 2090; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2090: + var $13088; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $651=$13088; + var $13089=$651; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($13043, $13089) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2091; break; } else { label = 2105; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2091: + $2733=0; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($13042, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2105; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2732) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2092; break; } else { label = 2104; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2092: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream31); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2112; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2093: + var $13094$0 = ___cxa_find_matching_catch(-1, -1); $13094$1 = tempRet0; + var $13095=$13094$0; + $2542=$13095; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13096=$13094$1; + $2543=$13096; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2096; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2094: + var $13098$0 = ___cxa_find_matching_catch(-1, -1); $13098$1 = tempRet0; + var $13099=$13098$0; + $2542=$13099; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13100=$13098$1; + $2543=$13100; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2728) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2095; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2095: + label = 2096; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2096: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2729) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2097; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2097: + label = 2840; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2098: + var $13105$0 = ___cxa_find_matching_catch(-1, -1); $13105$1 = tempRet0; + var $13106=$13105$0; + $2542=$13106; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13107=$13105$1; + $2543=$13107; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2110; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2099: + var $13109$0 = ___cxa_find_matching_catch(-1, -1); $13109$1 = tempRet0; + var $13110=$13109$0; + $2542=$13110; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13111=$13109$1; + $2543=$13111; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2102; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2100: + var $13113$0 = ___cxa_find_matching_catch(-1, -1); $13113$1 = tempRet0; + var $13114=$13113$0; + $2542=$13114; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13115=$13113$1; + $2543=$13115; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2730) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2101; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2101: + label = 2102; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2102: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2731) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2103; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2103: + label = 2110; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2104: + var $13120$0 = ___cxa_find_matching_catch(-1, -1); $13120$1 = tempRet0; + var $13121=$13120$0; + $2542=$13121; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13122=$13120$1; + $2543=$13122; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2107; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2105: + var $13124$0 = ___cxa_find_matching_catch(-1, -1); $13124$1 = tempRet0; + var $13125=$13124$0; + $2542=$13125; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13126=$13124$1; + $2543=$13126; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2732) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2106; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2106: + label = 2107; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2107: + var $13129=$2733; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13129) { label = 2108; break; } else { label = 2109; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2108: + ___cxa_free_exception($13042); //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2109; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2109: + label = 2110; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2110: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream31) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2111; break; } else { label = 2841; break; } //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2111: + label = 2840; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2112: + label = 2113; break; //@line 172 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2113: + label = 2114; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2114: + __ZN6StringC1EPKc($2735, ((85832)|0)); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2734, $2735, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2115; break; } else { label = 2159; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2115: + var $13138 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2734, ((86056)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2116; break; } else { label = 2160; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2116: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2734) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2117; break; } else { label = 2159; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2117: + __ZN6StringD1Ev($2735); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13138) { label = 2118; break; } else { label = 2178; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2118: + $647=$std_stringstream32; + $648=24; + var $13142=$647; + var $13143=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13144=(($13143+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13145=$13144; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $646=$13145; + var $13146=$646; + var $13147=$13146; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $645=$13147; + var $13148=$645; + var $13149=$13148; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13149)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $13150=$13146; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13150)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $13151=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13151)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13152=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13153=(($13152+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13154=$13153; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13154)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13155=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13156=(($13155+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13157=$13156; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13157)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13158=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13159=(($13142+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13160=$13159; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $615=$13158; + $616=((109796)|0); + $617=$13160; + var $13161=$615; + var $13162=$616; + var $13163=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13164=(($13162+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13165=$617; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $612=$13163; + $613=$13164; + $614=$13165; + var $13166=$612; + var $13167=$613; + var $13168=HEAP32[(($13167)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13169=$13166; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13169)>>2)]=$13168; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13170=(($13167+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13171=HEAP32[(($13170)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13172=$13166; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13173=HEAP32[(($13172)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13174=((($13173)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13175=$13174; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13176=HEAP32[(($13175)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13177=$13166; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13178=(($13177+$13176)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13179=$13178; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13179)>>2)]=$13171; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13180=(($13166+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13180)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13181=$13166; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13182=HEAP32[(($13181)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13183=((($13182)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13184=$13183; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13185=HEAP32[(($13184)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13186=$13166; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13187=(($13186+$13185)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13188=$13187; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13189=$614; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $610=$13188; + $611=$13189; + var $13190=$610; + var $13191=$13190; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13192=$611; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13193=$13192; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($13191, $13193) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2119; break; } else { label = 2135; break; } + case 2119: + var $13194=(($13190+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13194)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $13195=(($13190+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13195)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $13196=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13197=(($13196+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13198=$13197; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13199=(($13162+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $608=$13198; + $609=$13199; + var $13200=$608; + var $13201=$609; + var $13202=HEAP32[(($13201)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13203=$13200; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13203)>>2)]=$13202; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13204=(($13201+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13205=HEAP32[(($13204)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13206=$13200; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13207=HEAP32[(($13206)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13208=((($13207)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13209=$13208; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13210=HEAP32[(($13209)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13211=$13200; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13212=(($13211+$13210)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13213=$13212; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13213)>>2)]=$13205; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13214=HEAP32[(($13162)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13215=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13215)>>2)]=$13214; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13216=(($13162+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13217=HEAP32[(($13216)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13218=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13219=HEAP32[(($13218)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13220=((($13219)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13221=$13220; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13222=HEAP32[(($13221)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13223=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13224=(($13223+$13222)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13225=$13224; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13225)>>2)]=$13217; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13226=(($13162+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13227=HEAP32[(($13226)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13228=$13161; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13229=(($13228+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13230=$13229; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13230)>>2)]=$13227; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13231=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13231)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13232=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13233=(($13232+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13234=$13233; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13234)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13235=$13142; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13236=(($13235+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13237=$13236; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13237)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13238=(($13142+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13239=$648; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $643=$13238; + $644=$13239; + var $13240=$643; + var $13241=$644; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $638=$13240; + $639=$13241; + var $13242=$638; + var $13243=$13242; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($13243) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2120; break; } else { label = 2136; break; } + case 2120: + var $13244=$13242; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13244)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13245=(($13242+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $637=$13245; + var $13246=$637; + $636=$13246; + var $13247=$636; + var $13248=$13247; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13249=(($13247)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $635=$13249; + var $13250=$635; + $634=$13250; + var $13251=$634; + var $13252=$13251; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $633=$13252; + var $13253=$633; + var $13254=$13253; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $632=$13254; + var $13255=$632; + var $13256=(($13253)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $631=$13247; + var $13257=$631; + var $13258=(($13257)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $630=$13258; + var $13259=$630; + var $13260=$13259; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $629=$13260; + var $13261=$629; + var $13262=(($13261)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13263=(($13262)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13264=$13263; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13265=(($13264)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i448=$13265; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i449=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2121; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2121: + var $13267=$__i_i_i_i_i_i_i449; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13268=(($13267)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13268) { label = 2122; break; } else { label = 2123; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2122: + var $13270=$__i_i_i_i_i_i_i449; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13271=$__a_i_i_i_i_i_i448; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13272=(($13271+($13270<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13272)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13273=$__i_i_i_i_i_i_i449; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13274=((($13273)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i449=$13274; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2121; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2123: + var $13275=(($13242+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13275)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13276=(($13242+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13277=$639; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13276)>>2)]=$13277; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $628=$642; + var $13278=$628; + $627=$13278; + var $13279=$627; + var $13280=$13279; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13281=(($13279)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $626=$13281; + var $13282=$626; + $625=$13282; + var $13283=$625; + var $13284=$13283; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $624=$13284; + var $13285=$624; + var $13286=$13285; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $623=$13286; + var $13287=$623; + var $13288=(($13285)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $622=$13279; + var $13289=$622; + var $13290=(($13289)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $621=$13290; + var $13291=$621; + var $13292=$13291; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $620=$13292; + var $13293=$620; + var $13294=(($13293)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13295=(($13294)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13296=$13295; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13297=(($13296)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i446=$13297; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i447=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2124; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2124: + var $13299=$__i_i_i_i2_i_i_i447; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13300=(($13299)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13300) { label = 2125; break; } else { label = 2126; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2125: + var $13302=$__i_i_i_i2_i_i_i447; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13303=$__a_i_i_i1_i_i_i446; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13304=(($13303+($13302<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13304)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13305=$__i_i_i_i2_i_i_i447; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13306=((($13305)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i447=$13306; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2124; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2126: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($13242, $642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2127; break; } else { label = 2129; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2127: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2142; break; } else { label = 2128; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2128: + var $13309$0 = ___cxa_find_matching_catch(-1, -1); $13309$1 = tempRet0; + var $13310=$13309$0; + $640=$13310; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13311=$13309$1; + $641=$13311; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2131; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2129: + var $13313$0 = ___cxa_find_matching_catch(-1, -1); $13313$1 = tempRet0; + var $13314=$13313$0; + $640=$13314; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13315=$13313$1; + $641=$13315; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2130; break; } else { label = 2134; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2130: + label = 2131; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2131: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($13245) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2132; break; } else { label = 2134; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2132: + var $13319=$13242; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($13319) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2133; break; } else { label = 2134; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2133: + var $13321=$640; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13322=$641; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13323$0=$13321; + var $13323$1=0; + var $13324$0=$13323$0; + var $13324$1=$13322; + var $eh_lpad_body_i454$1 = $13324$1;var $eh_lpad_body_i454$0 = $13324$0;label = 2137; break; + case 2134: + var $13326$0 = ___cxa_find_matching_catch(-1, -1,0); $13326$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2135: + var $13328$0 = ___cxa_find_matching_catch(-1, -1); $13328$1 = tempRet0; + var $13329=$13328$0; + $649=$13329; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13330=$13328$1; + $650=$13330; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2139; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2136: + var $13332$0 = ___cxa_find_matching_catch(-1, -1); $13332$1 = tempRet0; + var $eh_lpad_body_i454$1 = $13332$1;var $eh_lpad_body_i454$0 = $13332$0;label = 2137; break; + case 2137: + var $eh_lpad_body_i454$0; + var $eh_lpad_body_i454$1; + var $13333=$eh_lpad_body_i454$0; + $649=$13333; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13334=$eh_lpad_body_i454$1; + $650=$13334; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13335=$13142; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($13335, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2138; break; } else { label = 2141; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2138: + label = 2139; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2139: + var $13338=$13142; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13339=(($13338+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13340=$13339; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($13340) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2140; break; } else { label = 2141; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2140: + var $13342=$649; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13343=$650; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13344$0=$13342; + var $13344$1=0; + var $13345$0=$13344$0; + var $13345$1=$13343; + ___resumeException($13345$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2141: + var $13347$0 = ___cxa_find_matching_catch(-1, -1,0); $13347$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2142: + var $13348=$std_stringstream32; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13349=(($13348+8)|0); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13350=$13349; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13351 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13350, ((85064)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2143; break; } else { label = 2164; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2143: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2737, ((85832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2144; break; } else { label = 2164; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2144: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2736, $2737, 92) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2145; break; } else { label = 2165; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2145: + var $13355 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($13351, $2736) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2146; break; } else { label = 2166; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2146: + var $13357 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13355, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2147; break; } else { label = 2166; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2147: + var $13359 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13357, ((86056)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2148; break; } else { label = 2166; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2148: + var $13361 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13359, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2149; break; } else { label = 2166; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2149: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2736) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2150; break; } else { label = 2165; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2150: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2737) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2151; break; } else { label = 2164; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2151: + var $13365=___cxa_allocate_exception(8); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2739=1; + var $13366=$13365; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $607=$std_stringstream32; + var $13367=$607; + var $13368=(($13367+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2738, $13368) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2152; break; } else { label = 2170; break; } + case 2152: + label = 2153; break; + case 2153: + $606=$2738; + var $13370=$606; + $605=$13370; + var $13371=$605; + $604=$13371; + var $13372=$604; + $603=$13372; + var $13373=$603; + var $13374=(($13373)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $602=$13374; + var $13375=$602; + var $13376=$13375; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $601=$13376; + var $13377=$601; + var $13378=(($13377)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13379=(($13378)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13380=$13379; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13381=(($13380)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13382=$13381; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13383=HEAP8[($13382)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13384=(($13383)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13385=$13384 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13386=(($13385)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($13386) { label = 2154; break; } else { label = 2155; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2154: + $595=$13372; + var $13388=$595; + var $13389=(($13388)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $594=$13389; + var $13390=$594; + var $13391=$13390; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $593=$13391; + var $13392=$593; + var $13393=(($13392)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13394=(($13393)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13395=$13394; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13396=(($13395+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13397=HEAP32[(($13396)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13411 = $13397;label = 2156; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2155: + $600=$13372; + var $13399=$600; + var $13400=(($13399)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $599=$13400; + var $13401=$599; + var $13402=$13401; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $598=$13402; + var $13403=$598; + var $13404=(($13403)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13405=(($13404)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13406=$13405; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13407=(($13406+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13408=(($13407)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $597=$13408; + var $13409=$597; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $596=$13409; + var $13410=$596; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $13411 = $13410;label = 2156; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2156: + var $13411; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $592=$13411; + var $13412=$592; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($13366, $13412) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2157; break; } else { label = 2171; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2157: + $2739=0; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($13365, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2171; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2738) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2158; break; } else { label = 2170; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2158: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream32); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2178; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2159: + var $13417$0 = ___cxa_find_matching_catch(-1, -1); $13417$1 = tempRet0; + var $13418=$13417$0; + $2542=$13418; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13419=$13417$1; + $2543=$13419; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2162; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2160: + var $13421$0 = ___cxa_find_matching_catch(-1, -1); $13421$1 = tempRet0; + var $13422=$13421$0; + $2542=$13422; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13423=$13421$1; + $2543=$13423; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2734) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2161; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2161: + label = 2162; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2162: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2735) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2163; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2163: + label = 2840; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2164: + var $13428$0 = ___cxa_find_matching_catch(-1, -1); $13428$1 = tempRet0; + var $13429=$13428$0; + $2542=$13429; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13430=$13428$1; + $2543=$13430; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2176; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2165: + var $13432$0 = ___cxa_find_matching_catch(-1, -1); $13432$1 = tempRet0; + var $13433=$13432$0; + $2542=$13433; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13434=$13432$1; + $2543=$13434; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2168; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2166: + var $13436$0 = ___cxa_find_matching_catch(-1, -1); $13436$1 = tempRet0; + var $13437=$13436$0; + $2542=$13437; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13438=$13436$1; + $2543=$13438; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2736) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2167; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2167: + label = 2168; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2168: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2737) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2169; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2169: + label = 2176; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2170: + var $13443$0 = ___cxa_find_matching_catch(-1, -1); $13443$1 = tempRet0; + var $13444=$13443$0; + $2542=$13444; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13445=$13443$1; + $2543=$13445; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2173; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2171: + var $13447$0 = ___cxa_find_matching_catch(-1, -1); $13447$1 = tempRet0; + var $13448=$13447$0; + $2542=$13448; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13449=$13447$1; + $2543=$13449; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2738) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2172; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2172: + label = 2173; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2173: + var $13452=$2739; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13452) { label = 2174; break; } else { label = 2175; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2174: + ___cxa_free_exception($13365); //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2175; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2175: + label = 2176; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2176: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream32) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2177; break; } else { label = 2841; break; } //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2177: + label = 2840; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2178: + label = 2179; break; //@line 173 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2179: + label = 2180; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2180: + __ZN6StringC1EPKc($2741, ((84520)|0)); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2740, $2741, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2181; break; } else { label = 2225; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2181: + var $13461 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2740, ((84520)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2182; break; } else { label = 2226; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2182: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2740) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2183; break; } else { label = 2225; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2183: + __ZN6StringD1Ev($2741); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13461) { label = 2184; break; } else { label = 2244; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2184: + $588=$std_stringstream33; + $589=24; + var $13465=$588; + var $13466=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13467=(($13466+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13468=$13467; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $587=$13468; + var $13469=$587; + var $13470=$13469; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $586=$13470; + var $13471=$586; + var $13472=$13471; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13472)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $13473=$13469; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13473)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $13474=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13474)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13475=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13476=(($13475+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13477=$13476; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13477)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13478=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13479=(($13478+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13480=$13479; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13480)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13481=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13482=(($13465+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13483=$13482; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $556=$13481; + $557=((109796)|0); + $558=$13483; + var $13484=$556; + var $13485=$557; + var $13486=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13487=(($13485+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13488=$558; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $553=$13486; + $554=$13487; + $555=$13488; + var $13489=$553; + var $13490=$554; + var $13491=HEAP32[(($13490)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13492=$13489; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13492)>>2)]=$13491; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13493=(($13490+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13494=HEAP32[(($13493)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13495=$13489; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13496=HEAP32[(($13495)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13497=((($13496)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13498=$13497; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13499=HEAP32[(($13498)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13500=$13489; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13501=(($13500+$13499)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13502=$13501; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13502)>>2)]=$13494; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13503=(($13489+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13503)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13504=$13489; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13505=HEAP32[(($13504)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13506=((($13505)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13507=$13506; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13508=HEAP32[(($13507)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13509=$13489; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13510=(($13509+$13508)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13511=$13510; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13512=$555; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $551=$13511; + $552=$13512; + var $13513=$551; + var $13514=$13513; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13515=$552; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13516=$13515; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($13514, $13516) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2185; break; } else { label = 2201; break; } + case 2185: + var $13517=(($13513+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13517)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $13518=(($13513+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13518)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $13519=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13520=(($13519+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13521=$13520; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13522=(($13485+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $549=$13521; + $550=$13522; + var $13523=$549; + var $13524=$550; + var $13525=HEAP32[(($13524)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13526=$13523; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13526)>>2)]=$13525; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13527=(($13524+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13528=HEAP32[(($13527)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13529=$13523; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13530=HEAP32[(($13529)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13531=((($13530)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13532=$13531; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13533=HEAP32[(($13532)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13534=$13523; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13535=(($13534+$13533)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13536=$13535; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13536)>>2)]=$13528; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13537=HEAP32[(($13485)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13538=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13538)>>2)]=$13537; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13539=(($13485+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13540=HEAP32[(($13539)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13541=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13542=HEAP32[(($13541)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13543=((($13542)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13544=$13543; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13545=HEAP32[(($13544)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13546=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13547=(($13546+$13545)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13548=$13547; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13548)>>2)]=$13540; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13549=(($13485+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13550=HEAP32[(($13549)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13551=$13484; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13552=(($13551+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13553=$13552; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13553)>>2)]=$13550; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13554=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13554)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13555=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13556=(($13555+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13557=$13556; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13557)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13558=$13465; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13559=(($13558+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13560=$13559; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13560)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13561=(($13465+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13562=$589; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $584=$13561; + $585=$13562; + var $13563=$584; + var $13564=$585; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $579=$13563; + $580=$13564; + var $13565=$579; + var $13566=$13565; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($13566) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2186; break; } else { label = 2202; break; } + case 2186: + var $13567=$13565; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13567)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13568=(($13565+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $578=$13568; + var $13569=$578; + $577=$13569; + var $13570=$577; + var $13571=$13570; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13572=(($13570)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $576=$13572; + var $13573=$576; + $575=$13573; + var $13574=$575; + var $13575=$13574; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $574=$13575; + var $13576=$574; + var $13577=$13576; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $573=$13577; + var $13578=$573; + var $13579=(($13576)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $572=$13570; + var $13580=$572; + var $13581=(($13580)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $571=$13581; + var $13582=$571; + var $13583=$13582; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $570=$13583; + var $13584=$570; + var $13585=(($13584)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13586=(($13585)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13587=$13586; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13588=(($13587)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i461=$13588; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i462=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2187; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2187: + var $13590=$__i_i_i_i_i_i_i462; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13591=(($13590)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13591) { label = 2188; break; } else { label = 2189; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2188: + var $13593=$__i_i_i_i_i_i_i462; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13594=$__a_i_i_i_i_i_i461; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13595=(($13594+($13593<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13595)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13596=$__i_i_i_i_i_i_i462; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13597=((($13596)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i462=$13597; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2187; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2189: + var $13598=(($13565+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13598)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13599=(($13565+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13600=$580; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13599)>>2)]=$13600; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $569=$583; + var $13601=$569; + $568=$13601; + var $13602=$568; + var $13603=$13602; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13604=(($13602)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $567=$13604; + var $13605=$567; + $566=$13605; + var $13606=$566; + var $13607=$13606; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $565=$13607; + var $13608=$565; + var $13609=$13608; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $564=$13609; + var $13610=$564; + var $13611=(($13608)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $563=$13602; + var $13612=$563; + var $13613=(($13612)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $562=$13613; + var $13614=$562; + var $13615=$13614; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $561=$13615; + var $13616=$561; + var $13617=(($13616)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13618=(($13617)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13619=$13618; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13620=(($13619)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i459=$13620; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i460=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2190; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2190: + var $13622=$__i_i_i_i2_i_i_i460; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13623=(($13622)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13623) { label = 2191; break; } else { label = 2192; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2191: + var $13625=$__i_i_i_i2_i_i_i460; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13626=$__a_i_i_i1_i_i_i459; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13627=(($13626+($13625<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13627)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13628=$__i_i_i_i2_i_i_i460; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13629=((($13628)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i460=$13629; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2190; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2192: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($13565, $583) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2193; break; } else { label = 2195; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2193: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($583) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2208; break; } else { label = 2194; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2194: + var $13632$0 = ___cxa_find_matching_catch(-1, -1); $13632$1 = tempRet0; + var $13633=$13632$0; + $581=$13633; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13634=$13632$1; + $582=$13634; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2197; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2195: + var $13636$0 = ___cxa_find_matching_catch(-1, -1); $13636$1 = tempRet0; + var $13637=$13636$0; + $581=$13637; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13638=$13636$1; + $582=$13638; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($583) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2196; break; } else { label = 2200; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2196: + label = 2197; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2197: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($13568) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2198; break; } else { label = 2200; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2198: + var $13642=$13565; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($13642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2199; break; } else { label = 2200; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2199: + var $13644=$581; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13645=$582; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13646$0=$13644; + var $13646$1=0; + var $13647$0=$13646$0; + var $13647$1=$13645; + var $eh_lpad_body_i467$1 = $13647$1;var $eh_lpad_body_i467$0 = $13647$0;label = 2203; break; + case 2200: + var $13649$0 = ___cxa_find_matching_catch(-1, -1,0); $13649$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2201: + var $13651$0 = ___cxa_find_matching_catch(-1, -1); $13651$1 = tempRet0; + var $13652=$13651$0; + $590=$13652; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13653=$13651$1; + $591=$13653; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2205; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2202: + var $13655$0 = ___cxa_find_matching_catch(-1, -1); $13655$1 = tempRet0; + var $eh_lpad_body_i467$1 = $13655$1;var $eh_lpad_body_i467$0 = $13655$0;label = 2203; break; + case 2203: + var $eh_lpad_body_i467$0; + var $eh_lpad_body_i467$1; + var $13656=$eh_lpad_body_i467$0; + $590=$13656; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13657=$eh_lpad_body_i467$1; + $591=$13657; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13658=$13465; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($13658, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2204; break; } else { label = 2207; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2204: + label = 2205; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2205: + var $13661=$13465; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13662=(($13661+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13663=$13662; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($13663) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2206; break; } else { label = 2207; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2206: + var $13665=$590; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13666=$591; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13667$0=$13665; + var $13667$1=0; + var $13668$0=$13667$0; + var $13668$1=$13666; + ___resumeException($13668$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2207: + var $13670$0 = ___cxa_find_matching_catch(-1, -1,0); $13670$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2208: + var $13671=$std_stringstream33; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13672=(($13671+8)|0); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13673=$13672; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13674 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13673, ((84080)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2209; break; } else { label = 2230; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2209: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2743, ((84520)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2210; break; } else { label = 2230; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2210: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2742, $2743, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2211; break; } else { label = 2231; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2211: + var $13678 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($13674, $2742) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2212; break; } else { label = 2232; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2212: + var $13680 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13678, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2213; break; } else { label = 2232; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2213: + var $13682 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13680, ((84520)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2214; break; } else { label = 2232; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2214: + var $13684 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13682, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2215; break; } else { label = 2232; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2215: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2742) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2216; break; } else { label = 2231; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2216: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2743) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2217; break; } else { label = 2230; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2217: + var $13688=___cxa_allocate_exception(8); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2745=1; + var $13689=$13688; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $548=$std_stringstream33; + var $13690=$548; + var $13691=(($13690+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2744, $13691) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2218; break; } else { label = 2236; break; } + case 2218: + label = 2219; break; + case 2219: + $547=$2744; + var $13693=$547; + $546=$13693; + var $13694=$546; + $545=$13694; + var $13695=$545; + $544=$13695; + var $13696=$544; + var $13697=(($13696)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $543=$13697; + var $13698=$543; + var $13699=$13698; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $542=$13699; + var $13700=$542; + var $13701=(($13700)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13702=(($13701)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13703=$13702; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13704=(($13703)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13705=$13704; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13706=HEAP8[($13705)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13707=(($13706)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13708=$13707 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $13709=(($13708)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($13709) { label = 2220; break; } else { label = 2221; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2220: + $536=$13695; + var $13711=$536; + var $13712=(($13711)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $535=$13712; + var $13713=$535; + var $13714=$13713; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $534=$13714; + var $13715=$534; + var $13716=(($13715)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13717=(($13716)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13718=$13717; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13719=(($13718+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13720=HEAP32[(($13719)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $13734 = $13720;label = 2222; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2221: + $541=$13695; + var $13722=$541; + var $13723=(($13722)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $540=$13723; + var $13724=$540; + var $13725=$13724; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $539=$13725; + var $13726=$539; + var $13727=(($13726)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $13728=(($13727)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13729=$13728; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13730=(($13729+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $13731=(($13730)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $538=$13731; + var $13732=$538; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $537=$13732; + var $13733=$537; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $13734 = $13733;label = 2222; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2222: + var $13734; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $533=$13734; + var $13735=$533; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($13689, $13735) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2223; break; } else { label = 2237; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2223: + $2745=0; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($13688, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2237; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2744) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2224; break; } else { label = 2236; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2224: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream33); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2244; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2225: + var $13740$0 = ___cxa_find_matching_catch(-1, -1); $13740$1 = tempRet0; + var $13741=$13740$0; + $2542=$13741; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13742=$13740$1; + $2543=$13742; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2228; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2226: + var $13744$0 = ___cxa_find_matching_catch(-1, -1); $13744$1 = tempRet0; + var $13745=$13744$0; + $2542=$13745; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13746=$13744$1; + $2543=$13746; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2740) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2227; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2227: + label = 2228; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2228: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2741) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2229; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2229: + label = 2840; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2230: + var $13751$0 = ___cxa_find_matching_catch(-1, -1); $13751$1 = tempRet0; + var $13752=$13751$0; + $2542=$13752; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13753=$13751$1; + $2543=$13753; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2242; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2231: + var $13755$0 = ___cxa_find_matching_catch(-1, -1); $13755$1 = tempRet0; + var $13756=$13755$0; + $2542=$13756; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13757=$13755$1; + $2543=$13757; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2234; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2232: + var $13759$0 = ___cxa_find_matching_catch(-1, -1); $13759$1 = tempRet0; + var $13760=$13759$0; + $2542=$13760; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13761=$13759$1; + $2543=$13761; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2742) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2233; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2233: + label = 2234; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2234: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2743) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2235; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2235: + label = 2242; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2236: + var $13766$0 = ___cxa_find_matching_catch(-1, -1); $13766$1 = tempRet0; + var $13767=$13766$0; + $2542=$13767; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13768=$13766$1; + $2543=$13768; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2239; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2237: + var $13770$0 = ___cxa_find_matching_catch(-1, -1); $13770$1 = tempRet0; + var $13771=$13770$0; + $2542=$13771; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13772=$13770$1; + $2543=$13772; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2744) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2238; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2238: + label = 2239; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2239: + var $13775=$2745; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13775) { label = 2240; break; } else { label = 2241; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2240: + ___cxa_free_exception($13688); //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2241; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2241: + label = 2242; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2242: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream33) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2243; break; } else { label = 2841; break; } //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2243: + label = 2840; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2244: + label = 2245; break; //@line 175 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2245: + label = 2246; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2246: + __ZN6StringC1EPKc($2747, ((83768)|0)); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2746, $2747, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2247; break; } else { label = 2291; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2247: + var $13784 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2746, ((83768)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2248; break; } else { label = 2292; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2248: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2746) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2249; break; } else { label = 2291; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2249: + __ZN6StringD1Ev($2747); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($13784) { label = 2250; break; } else { label = 2310; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2250: + $529=$std_stringstream34; + $530=24; + var $13788=$529; + var $13789=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13790=(($13789+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13791=$13790; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $528=$13791; + var $13792=$528; + var $13793=$13792; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $527=$13793; + var $13794=$527; + var $13795=$13794; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13795)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $13796=$13792; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13796)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $13797=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13797)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13798=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13799=(($13798+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13800=$13799; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13800)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13801=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13802=(($13801+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13803=$13802; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13803)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13804=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13805=(($13788+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13806=$13805; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $497=$13804; + $498=((109796)|0); + $499=$13806; + var $13807=$497; + var $13808=$498; + var $13809=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13810=(($13808+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13811=$499; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $494=$13809; + $495=$13810; + $496=$13811; + var $13812=$494; + var $13813=$495; + var $13814=HEAP32[(($13813)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13815=$13812; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13815)>>2)]=$13814; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13816=(($13813+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13817=HEAP32[(($13816)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13818=$13812; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13819=HEAP32[(($13818)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13820=((($13819)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13821=$13820; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13822=HEAP32[(($13821)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13823=$13812; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13824=(($13823+$13822)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13825=$13824; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13825)>>2)]=$13817; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13826=(($13812+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13826)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $13827=$13812; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13828=HEAP32[(($13827)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13829=((($13828)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13830=$13829; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13831=HEAP32[(($13830)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13832=$13812; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13833=(($13832+$13831)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13834=$13833; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $13835=$496; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $492=$13834; + $493=$13835; + var $13836=$492; + var $13837=$13836; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13838=$493; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $13839=$13838; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($13837, $13839) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2251; break; } else { label = 2267; break; } + case 2251: + var $13840=(($13836+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13840)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $13841=(($13836+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($13841)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $13842=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13843=(($13842+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13844=$13843; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13845=(($13808+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $490=$13844; + $491=$13845; + var $13846=$490; + var $13847=$491; + var $13848=HEAP32[(($13847)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13849=$13846; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13849)>>2)]=$13848; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13850=(($13847+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13851=HEAP32[(($13850)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13852=$13846; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13853=HEAP32[(($13852)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13854=((($13853)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13855=$13854; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13856=HEAP32[(($13855)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13857=$13846; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13858=(($13857+$13856)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13859=$13858; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13859)>>2)]=$13851; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $13860=HEAP32[(($13808)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13861=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13861)>>2)]=$13860; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13862=(($13808+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13863=HEAP32[(($13862)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13864=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13865=HEAP32[(($13864)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13866=((($13865)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13867=$13866; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13868=HEAP32[(($13867)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13869=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13870=(($13869+$13868)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13871=$13870; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13871)>>2)]=$13863; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13872=(($13808+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13873=HEAP32[(($13872)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13874=$13807; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13875=(($13874+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13876=$13875; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13876)>>2)]=$13873; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $13877=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13877)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13878=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13879=(($13878+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13880=$13879; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13880)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13881=$13788; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13882=(($13881+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13883=$13882; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13883)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13884=(($13788+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13885=$530; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $525=$13884; + $526=$13885; + var $13886=$525; + var $13887=$526; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $520=$13886; + $521=$13887; + var $13888=$520; + var $13889=$13888; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($13889) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2252; break; } else { label = 2268; break; } + case 2252: + var $13890=$13888; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13890)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13891=(($13888+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $519=$13891; + var $13892=$519; + $518=$13892; + var $13893=$518; + var $13894=$13893; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13895=(($13893)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $517=$13895; + var $13896=$517; + $516=$13896; + var $13897=$516; + var $13898=$13897; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $515=$13898; + var $13899=$515; + var $13900=$13899; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $514=$13900; + var $13901=$514; + var $13902=(($13899)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $513=$13893; + var $13903=$513; + var $13904=(($13903)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $512=$13904; + var $13905=$512; + var $13906=$13905; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $511=$13906; + var $13907=$511; + var $13908=(($13907)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13909=(($13908)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13910=$13909; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13911=(($13910)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i474=$13911; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i475=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2253; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2253: + var $13913=$__i_i_i_i_i_i_i475; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13914=(($13913)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13914) { label = 2254; break; } else { label = 2255; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2254: + var $13916=$__i_i_i_i_i_i_i475; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13917=$__a_i_i_i_i_i_i474; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13918=(($13917+($13916<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13918)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13919=$__i_i_i_i_i_i_i475; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13920=((($13919)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i475=$13920; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2253; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2255: + var $13921=(($13888+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13921)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13922=(($13888+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $13923=$521; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($13922)>>2)]=$13923; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $510=$524; + var $13924=$510; + $509=$13924; + var $13925=$509; + var $13926=$13925; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $13927=(($13925)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $508=$13927; + var $13928=$508; + $507=$13928; + var $13929=$507; + var $13930=$13929; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $506=$13930; + var $13931=$506; + var $13932=$13931; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $505=$13932; + var $13933=$505; + var $13934=(($13931)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $504=$13925; + var $13935=$504; + var $13936=(($13935)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $503=$13936; + var $13937=$503; + var $13938=$13937; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $502=$13938; + var $13939=$502; + var $13940=(($13939)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $13941=(($13940)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13942=$13941; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $13943=(($13942)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i472=$13943; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i473=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2256; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2256: + var $13945=$__i_i_i_i2_i_i_i473; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13946=(($13945)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($13946) { label = 2257; break; } else { label = 2258; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2257: + var $13948=$__i_i_i_i2_i_i_i473; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13949=$__a_i_i_i1_i_i_i472; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13950=(($13949+($13948<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($13950)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $13951=$__i_i_i_i2_i_i_i473; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $13952=((($13951)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i473=$13952; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2256; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2258: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($13888, $524) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2259; break; } else { label = 2261; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2259: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($524) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2274; break; } else { label = 2260; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2260: + var $13955$0 = ___cxa_find_matching_catch(-1, -1); $13955$1 = tempRet0; + var $13956=$13955$0; + $522=$13956; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13957=$13955$1; + $523=$13957; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2263; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2261: + var $13959$0 = ___cxa_find_matching_catch(-1, -1); $13959$1 = tempRet0; + var $13960=$13959$0; + $522=$13960; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $13961=$13959$1; + $523=$13961; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($524) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2262; break; } else { label = 2266; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2262: + label = 2263; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2263: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($13891) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2264; break; } else { label = 2266; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2264: + var $13965=$13888; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($13965) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2265; break; } else { label = 2266; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2265: + var $13967=$522; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13968=$523; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $13969$0=$13967; + var $13969$1=0; + var $13970$0=$13969$0; + var $13970$1=$13968; + var $eh_lpad_body_i480$1 = $13970$1;var $eh_lpad_body_i480$0 = $13970$0;label = 2269; break; + case 2266: + var $13972$0 = ___cxa_find_matching_catch(-1, -1,0); $13972$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2267: + var $13974$0 = ___cxa_find_matching_catch(-1, -1); $13974$1 = tempRet0; + var $13975=$13974$0; + $531=$13975; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13976=$13974$1; + $532=$13976; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2271; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2268: + var $13978$0 = ___cxa_find_matching_catch(-1, -1); $13978$1 = tempRet0; + var $eh_lpad_body_i480$1 = $13978$1;var $eh_lpad_body_i480$0 = $13978$0;label = 2269; break; + case 2269: + var $eh_lpad_body_i480$0; + var $eh_lpad_body_i480$1; + var $13979=$eh_lpad_body_i480$0; + $531=$13979; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13980=$eh_lpad_body_i480$1; + $532=$13980; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $13981=$13788; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($13981, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2270; break; } else { label = 2273; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2270: + label = 2271; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2271: + var $13984=$13788; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13985=(($13984+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13986=$13985; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($13986) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2272; break; } else { label = 2273; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2272: + var $13988=$531; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13989=$532; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $13990$0=$13988; + var $13990$1=0; + var $13991$0=$13990$0; + var $13991$1=$13989; + ___resumeException($13991$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2273: + var $13993$0 = ___cxa_find_matching_catch(-1, -1,0); $13993$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2274: + var $13994=$std_stringstream34; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13995=(($13994+8)|0); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13996=$13995; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $13997 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($13996, ((83512)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2275; break; } else { label = 2296; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2275: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2749, ((83768)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2276; break; } else { label = 2296; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2276: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2748, $2749, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2277; break; } else { label = 2297; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2277: + var $14001 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($13997, $2748) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2278; break; } else { label = 2298; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2278: + var $14003 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14001, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2279; break; } else { label = 2298; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2279: + var $14005 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14003, ((83768)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2280; break; } else { label = 2298; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2280: + var $14007 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14005, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2281; break; } else { label = 2298; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2281: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2748) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2282; break; } else { label = 2297; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2282: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2749) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2283; break; } else { label = 2296; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2283: + var $14011=___cxa_allocate_exception(8); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2751=1; + var $14012=$14011; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $489=$std_stringstream34; + var $14013=$489; + var $14014=(($14013+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2750, $14014) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2284; break; } else { label = 2302; break; } + case 2284: + label = 2285; break; + case 2285: + $488=$2750; + var $14016=$488; + $487=$14016; + var $14017=$487; + $486=$14017; + var $14018=$486; + $485=$14018; + var $14019=$485; + var $14020=(($14019)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $484=$14020; + var $14021=$484; + var $14022=$14021; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $483=$14022; + var $14023=$483; + var $14024=(($14023)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14025=(($14024)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14026=$14025; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14027=(($14026)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14028=$14027; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14029=HEAP8[($14028)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14030=(($14029)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14031=$14030 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14032=(($14031)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($14032) { label = 2286; break; } else { label = 2287; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2286: + $477=$14018; + var $14034=$477; + var $14035=(($14034)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $476=$14035; + var $14036=$476; + var $14037=$14036; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $475=$14037; + var $14038=$475; + var $14039=(($14038)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14040=(($14039)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14041=$14040; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14042=(($14041+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14043=HEAP32[(($14042)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14057 = $14043;label = 2288; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2287: + $482=$14018; + var $14045=$482; + var $14046=(($14045)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $481=$14046; + var $14047=$481; + var $14048=$14047; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $480=$14048; + var $14049=$480; + var $14050=(($14049)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14051=(($14050)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14052=$14051; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14053=(($14052+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14054=(($14053)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $479=$14054; + var $14055=$479; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $478=$14055; + var $14056=$478; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $14057 = $14056;label = 2288; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2288: + var $14057; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $474=$14057; + var $14058=$474; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($14012, $14058) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2289; break; } else { label = 2303; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2289: + $2751=0; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($14011, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2303; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2750) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2290; break; } else { label = 2302; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2290: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream34); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2310; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2291: + var $14063$0 = ___cxa_find_matching_catch(-1, -1); $14063$1 = tempRet0; + var $14064=$14063$0; + $2542=$14064; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14065=$14063$1; + $2543=$14065; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2294; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2292: + var $14067$0 = ___cxa_find_matching_catch(-1, -1); $14067$1 = tempRet0; + var $14068=$14067$0; + $2542=$14068; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14069=$14067$1; + $2543=$14069; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2746) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2293; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2293: + label = 2294; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2294: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2747) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2295; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2295: + label = 2840; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2296: + var $14074$0 = ___cxa_find_matching_catch(-1, -1); $14074$1 = tempRet0; + var $14075=$14074$0; + $2542=$14075; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14076=$14074$1; + $2543=$14076; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2308; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2297: + var $14078$0 = ___cxa_find_matching_catch(-1, -1); $14078$1 = tempRet0; + var $14079=$14078$0; + $2542=$14079; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14080=$14078$1; + $2543=$14080; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2300; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2298: + var $14082$0 = ___cxa_find_matching_catch(-1, -1); $14082$1 = tempRet0; + var $14083=$14082$0; + $2542=$14083; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14084=$14082$1; + $2543=$14084; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2748) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2299; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2299: + label = 2300; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2300: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2749) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2301; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2301: + label = 2308; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2302: + var $14089$0 = ___cxa_find_matching_catch(-1, -1); $14089$1 = tempRet0; + var $14090=$14089$0; + $2542=$14090; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14091=$14089$1; + $2543=$14091; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2305; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2303: + var $14093$0 = ___cxa_find_matching_catch(-1, -1); $14093$1 = tempRet0; + var $14094=$14093$0; + $2542=$14094; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14095=$14093$1; + $2543=$14095; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2750) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2304; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2304: + label = 2305; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2305: + var $14098=$2751; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14098) { label = 2306; break; } else { label = 2307; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2306: + ___cxa_free_exception($14011); //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2307; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2307: + label = 2308; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2308: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream34) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2309; break; } else { label = 2841; break; } //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2309: + label = 2840; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2310: + label = 2311; break; //@line 176 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2311: + label = 2312; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2312: + __ZN6StringC1EPKc($2753, ((83288)|0)); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2752, $2753, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2313; break; } else { label = 2357; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2313: + var $14107 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2752, ((83288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2314; break; } else { label = 2358; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2314: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2752) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2315; break; } else { label = 2357; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2315: + __ZN6StringD1Ev($2753); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14107) { label = 2316; break; } else { label = 2376; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2316: + $470=$std_stringstream35; + $471=24; + var $14111=$470; + var $14112=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14113=(($14112+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14114=$14113; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $469=$14114; + var $14115=$469; + var $14116=$14115; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $468=$14116; + var $14117=$468; + var $14118=$14117; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14118)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $14119=$14115; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14119)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $14120=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14120)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14121=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14122=(($14121+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14123=$14122; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14123)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14124=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14125=(($14124+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14126=$14125; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14126)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14127=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14128=(($14111+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14129=$14128; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $438=$14127; + $439=((109796)|0); + $440=$14129; + var $14130=$438; + var $14131=$439; + var $14132=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14133=(($14131+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14134=$440; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $435=$14132; + $436=$14133; + $437=$14134; + var $14135=$435; + var $14136=$436; + var $14137=HEAP32[(($14136)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14138=$14135; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14138)>>2)]=$14137; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14139=(($14136+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14140=HEAP32[(($14139)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14141=$14135; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14142=HEAP32[(($14141)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14143=((($14142)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14144=$14143; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14145=HEAP32[(($14144)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14146=$14135; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14147=(($14146+$14145)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14148=$14147; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14148)>>2)]=$14140; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14149=(($14135+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14149)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14150=$14135; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14151=HEAP32[(($14150)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14152=((($14151)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14153=$14152; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14154=HEAP32[(($14153)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14155=$14135; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14156=(($14155+$14154)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14157=$14156; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14158=$437; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $433=$14157; + $434=$14158; + var $14159=$433; + var $14160=$14159; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14161=$434; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14162=$14161; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($14160, $14162) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2317; break; } else { label = 2333; break; } + case 2317: + var $14163=(($14159+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14163)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $14164=(($14159+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14164)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $14165=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14166=(($14165+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14167=$14166; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14168=(($14131+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $431=$14167; + $432=$14168; + var $14169=$431; + var $14170=$432; + var $14171=HEAP32[(($14170)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14172=$14169; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14172)>>2)]=$14171; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14173=(($14170+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14174=HEAP32[(($14173)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14175=$14169; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14176=HEAP32[(($14175)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14177=((($14176)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14178=$14177; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14179=HEAP32[(($14178)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14180=$14169; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14181=(($14180+$14179)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14182=$14181; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14182)>>2)]=$14174; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14183=HEAP32[(($14131)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14184=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14184)>>2)]=$14183; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14185=(($14131+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14186=HEAP32[(($14185)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14187=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14188=HEAP32[(($14187)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14189=((($14188)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14190=$14189; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14191=HEAP32[(($14190)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14192=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14193=(($14192+$14191)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14194=$14193; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14194)>>2)]=$14186; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14195=(($14131+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14196=HEAP32[(($14195)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14197=$14130; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14198=(($14197+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14199=$14198; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14199)>>2)]=$14196; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14200=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14200)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14201=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14202=(($14201+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14203=$14202; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14203)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14204=$14111; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14205=(($14204+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14206=$14205; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14206)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14207=(($14111+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14208=$471; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $466=$14207; + $467=$14208; + var $14209=$466; + var $14210=$467; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $461=$14209; + $462=$14210; + var $14211=$461; + var $14212=$14211; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($14212) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2318; break; } else { label = 2334; break; } + case 2318: + var $14213=$14211; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14213)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14214=(($14211+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $460=$14214; + var $14215=$460; + $459=$14215; + var $14216=$459; + var $14217=$14216; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14218=(($14216)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $458=$14218; + var $14219=$458; + $457=$14219; + var $14220=$457; + var $14221=$14220; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $456=$14221; + var $14222=$456; + var $14223=$14222; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $455=$14223; + var $14224=$455; + var $14225=(($14222)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $454=$14216; + var $14226=$454; + var $14227=(($14226)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $453=$14227; + var $14228=$453; + var $14229=$14228; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $452=$14229; + var $14230=$452; + var $14231=(($14230)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14232=(($14231)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14233=$14232; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14234=(($14233)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i487=$14234; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i488=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2319; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2319: + var $14236=$__i_i_i_i_i_i_i488; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14237=(($14236)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14237) { label = 2320; break; } else { label = 2321; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2320: + var $14239=$__i_i_i_i_i_i_i488; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14240=$__a_i_i_i_i_i_i487; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14241=(($14240+($14239<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14241)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14242=$__i_i_i_i_i_i_i488; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14243=((($14242)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i488=$14243; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2319; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2321: + var $14244=(($14211+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14244)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14245=(($14211+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14246=$462; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14245)>>2)]=$14246; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $451=$465; + var $14247=$451; + $450=$14247; + var $14248=$450; + var $14249=$14248; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14250=(($14248)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $449=$14250; + var $14251=$449; + $448=$14251; + var $14252=$448; + var $14253=$14252; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $447=$14253; + var $14254=$447; + var $14255=$14254; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $446=$14255; + var $14256=$446; + var $14257=(($14254)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $445=$14248; + var $14258=$445; + var $14259=(($14258)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $444=$14259; + var $14260=$444; + var $14261=$14260; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $443=$14261; + var $14262=$443; + var $14263=(($14262)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14264=(($14263)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14265=$14264; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14266=(($14265)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i485=$14266; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i486=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2322; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2322: + var $14268=$__i_i_i_i2_i_i_i486; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14269=(($14268)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14269) { label = 2323; break; } else { label = 2324; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2323: + var $14271=$__i_i_i_i2_i_i_i486; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14272=$__a_i_i_i1_i_i_i485; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14273=(($14272+($14271<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14273)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14274=$__i_i_i_i2_i_i_i486; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14275=((($14274)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i486=$14275; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2322; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2324: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($14211, $465) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2325; break; } else { label = 2327; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2325: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($465) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2340; break; } else { label = 2326; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2326: + var $14278$0 = ___cxa_find_matching_catch(-1, -1); $14278$1 = tempRet0; + var $14279=$14278$0; + $463=$14279; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14280=$14278$1; + $464=$14280; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2329; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2327: + var $14282$0 = ___cxa_find_matching_catch(-1, -1); $14282$1 = tempRet0; + var $14283=$14282$0; + $463=$14283; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14284=$14282$1; + $464=$14284; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($465) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2328; break; } else { label = 2332; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2328: + label = 2329; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2329: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($14214) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2330; break; } else { label = 2332; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2330: + var $14288=$14211; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($14288) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2331; break; } else { label = 2332; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2331: + var $14290=$463; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14291=$464; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14292$0=$14290; + var $14292$1=0; + var $14293$0=$14292$0; + var $14293$1=$14291; + var $eh_lpad_body_i493$1 = $14293$1;var $eh_lpad_body_i493$0 = $14293$0;label = 2335; break; + case 2332: + var $14295$0 = ___cxa_find_matching_catch(-1, -1,0); $14295$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2333: + var $14297$0 = ___cxa_find_matching_catch(-1, -1); $14297$1 = tempRet0; + var $14298=$14297$0; + $472=$14298; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14299=$14297$1; + $473=$14299; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2337; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2334: + var $14301$0 = ___cxa_find_matching_catch(-1, -1); $14301$1 = tempRet0; + var $eh_lpad_body_i493$1 = $14301$1;var $eh_lpad_body_i493$0 = $14301$0;label = 2335; break; + case 2335: + var $eh_lpad_body_i493$0; + var $eh_lpad_body_i493$1; + var $14302=$eh_lpad_body_i493$0; + $472=$14302; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14303=$eh_lpad_body_i493$1; + $473=$14303; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14304=$14111; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($14304, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2336; break; } else { label = 2339; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2336: + label = 2337; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2337: + var $14307=$14111; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14308=(($14307+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14309=$14308; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($14309) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2338; break; } else { label = 2339; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2338: + var $14311=$472; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14312=$473; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14313$0=$14311; + var $14313$1=0; + var $14314$0=$14313$0; + var $14314$1=$14312; + ___resumeException($14314$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2339: + var $14316$0 = ___cxa_find_matching_catch(-1, -1,0); $14316$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2340: + var $14317=$std_stringstream35; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14318=(($14317+8)|0); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14319=$14318; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14320 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14319, ((82976)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2341; break; } else { label = 2362; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2341: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2755, ((83288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2342; break; } else { label = 2362; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2342: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2754, $2755, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2343; break; } else { label = 2363; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2343: + var $14324 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($14320, $2754) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2344; break; } else { label = 2364; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2344: + var $14326 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14324, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2345; break; } else { label = 2364; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2345: + var $14328 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14326, ((83288)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2346; break; } else { label = 2364; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2346: + var $14330 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14328, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2347; break; } else { label = 2364; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2347: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2754) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2348; break; } else { label = 2363; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2348: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2755) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2349; break; } else { label = 2362; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2349: + var $14334=___cxa_allocate_exception(8); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2757=1; + var $14335=$14334; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $430=$std_stringstream35; + var $14336=$430; + var $14337=(($14336+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2756, $14337) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2350; break; } else { label = 2368; break; } + case 2350: + label = 2351; break; + case 2351: + $429=$2756; + var $14339=$429; + $428=$14339; + var $14340=$428; + $427=$14340; + var $14341=$427; + $426=$14341; + var $14342=$426; + var $14343=(($14342)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $425=$14343; + var $14344=$425; + var $14345=$14344; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $424=$14345; + var $14346=$424; + var $14347=(($14346)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14348=(($14347)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14349=$14348; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14350=(($14349)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14351=$14350; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14352=HEAP8[($14351)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14353=(($14352)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14354=$14353 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14355=(($14354)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($14355) { label = 2352; break; } else { label = 2353; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2352: + $418=$14341; + var $14357=$418; + var $14358=(($14357)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $417=$14358; + var $14359=$417; + var $14360=$14359; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $416=$14360; + var $14361=$416; + var $14362=(($14361)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14363=(($14362)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14364=$14363; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14365=(($14364+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14366=HEAP32[(($14365)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14380 = $14366;label = 2354; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2353: + $423=$14341; + var $14368=$423; + var $14369=(($14368)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $422=$14369; + var $14370=$422; + var $14371=$14370; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $421=$14371; + var $14372=$421; + var $14373=(($14372)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14374=(($14373)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14375=$14374; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14376=(($14375+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14377=(($14376)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $420=$14377; + var $14378=$420; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $419=$14378; + var $14379=$419; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $14380 = $14379;label = 2354; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2354: + var $14380; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $415=$14380; + var $14381=$415; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($14335, $14381) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2355; break; } else { label = 2369; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2355: + $2757=0; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($14334, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2369; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2756) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2356; break; } else { label = 2368; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2356: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream35); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2376; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2357: + var $14386$0 = ___cxa_find_matching_catch(-1, -1); $14386$1 = tempRet0; + var $14387=$14386$0; + $2542=$14387; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14388=$14386$1; + $2543=$14388; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2360; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2358: + var $14390$0 = ___cxa_find_matching_catch(-1, -1); $14390$1 = tempRet0; + var $14391=$14390$0; + $2542=$14391; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14392=$14390$1; + $2543=$14392; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2752) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2359; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2359: + label = 2360; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2360: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2753) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2361; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2361: + label = 2840; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2362: + var $14397$0 = ___cxa_find_matching_catch(-1, -1); $14397$1 = tempRet0; + var $14398=$14397$0; + $2542=$14398; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14399=$14397$1; + $2543=$14399; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2374; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2363: + var $14401$0 = ___cxa_find_matching_catch(-1, -1); $14401$1 = tempRet0; + var $14402=$14401$0; + $2542=$14402; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14403=$14401$1; + $2543=$14403; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2366; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2364: + var $14405$0 = ___cxa_find_matching_catch(-1, -1); $14405$1 = tempRet0; + var $14406=$14405$0; + $2542=$14406; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14407=$14405$1; + $2543=$14407; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2754) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2365; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2365: + label = 2366; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2366: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2755) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2367; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2367: + label = 2374; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2368: + var $14412$0 = ___cxa_find_matching_catch(-1, -1); $14412$1 = tempRet0; + var $14413=$14412$0; + $2542=$14413; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14414=$14412$1; + $2543=$14414; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2371; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2369: + var $14416$0 = ___cxa_find_matching_catch(-1, -1); $14416$1 = tempRet0; + var $14417=$14416$0; + $2542=$14417; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14418=$14416$1; + $2543=$14418; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2756) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2370; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2370: + label = 2371; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2371: + var $14421=$2757; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14421) { label = 2372; break; } else { label = 2373; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2372: + ___cxa_free_exception($14334); //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2373; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2373: + label = 2374; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2374: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream35) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2375; break; } else { label = 2841; break; } //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2375: + label = 2840; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2376: + label = 2377; break; //@line 177 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2377: + label = 2378; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2378: + __ZN6StringC1EPKc($2759, ((82720)|0)); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2758, $2759, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2379; break; } else { label = 2423; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2379: + var $14430 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2758, ((82720)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2380; break; } else { label = 2424; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2380: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2758) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2381; break; } else { label = 2423; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2381: + __ZN6StringD1Ev($2759); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14430) { label = 2382; break; } else { label = 2442; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2382: + $411=$std_stringstream36; + $412=24; + var $14434=$411; + var $14435=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14436=(($14435+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14437=$14436; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $410=$14437; + var $14438=$410; + var $14439=$14438; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $409=$14439; + var $14440=$409; + var $14441=$14440; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14441)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $14442=$14438; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14442)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $14443=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14443)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14444=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14445=(($14444+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14446=$14445; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14446)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14447=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14448=(($14447+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14449=$14448; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14449)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14450=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14451=(($14434+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14452=$14451; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $379=$14450; + $380=((109796)|0); + $381=$14452; + var $14453=$379; + var $14454=$380; + var $14455=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14456=(($14454+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14457=$381; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $376=$14455; + $377=$14456; + $378=$14457; + var $14458=$376; + var $14459=$377; + var $14460=HEAP32[(($14459)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14461=$14458; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14461)>>2)]=$14460; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14462=(($14459+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14463=HEAP32[(($14462)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14464=$14458; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14465=HEAP32[(($14464)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14466=((($14465)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14467=$14466; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14468=HEAP32[(($14467)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14469=$14458; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14470=(($14469+$14468)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14471=$14470; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14471)>>2)]=$14463; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14472=(($14458+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14472)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14473=$14458; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14474=HEAP32[(($14473)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14475=((($14474)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14476=$14475; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14477=HEAP32[(($14476)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14478=$14458; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14479=(($14478+$14477)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14480=$14479; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14481=$378; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $374=$14480; + $375=$14481; + var $14482=$374; + var $14483=$14482; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14484=$375; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14485=$14484; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($14483, $14485) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2383; break; } else { label = 2399; break; } + case 2383: + var $14486=(($14482+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14486)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $14487=(($14482+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14487)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $14488=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14489=(($14488+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14490=$14489; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14491=(($14454+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $372=$14490; + $373=$14491; + var $14492=$372; + var $14493=$373; + var $14494=HEAP32[(($14493)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14495=$14492; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14495)>>2)]=$14494; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14496=(($14493+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14497=HEAP32[(($14496)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14498=$14492; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14499=HEAP32[(($14498)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14500=((($14499)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14501=$14500; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14502=HEAP32[(($14501)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14503=$14492; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14504=(($14503+$14502)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14505=$14504; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14505)>>2)]=$14497; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14506=HEAP32[(($14454)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14507=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14507)>>2)]=$14506; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14508=(($14454+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14509=HEAP32[(($14508)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14510=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14511=HEAP32[(($14510)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14512=((($14511)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14513=$14512; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14514=HEAP32[(($14513)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14515=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14516=(($14515+$14514)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14517=$14516; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14517)>>2)]=$14509; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14518=(($14454+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14519=HEAP32[(($14518)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14520=$14453; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14521=(($14520+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14522=$14521; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14522)>>2)]=$14519; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14523=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14523)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14524=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14525=(($14524+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14526=$14525; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14526)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14527=$14434; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14528=(($14527+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14529=$14528; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14529)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14530=(($14434+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14531=$412; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $407=$14530; + $408=$14531; + var $14532=$407; + var $14533=$408; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $402=$14532; + $403=$14533; + var $14534=$402; + var $14535=$14534; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($14535) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2384; break; } else { label = 2400; break; } + case 2384: + var $14536=$14534; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14536)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14537=(($14534+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $401=$14537; + var $14538=$401; + $400=$14538; + var $14539=$400; + var $14540=$14539; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14541=(($14539)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $399=$14541; + var $14542=$399; + $398=$14542; + var $14543=$398; + var $14544=$14543; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $397=$14544; + var $14545=$397; + var $14546=$14545; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $396=$14546; + var $14547=$396; + var $14548=(($14545)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $395=$14539; + var $14549=$395; + var $14550=(($14549)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $394=$14550; + var $14551=$394; + var $14552=$14551; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $393=$14552; + var $14553=$393; + var $14554=(($14553)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14555=(($14554)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14556=$14555; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14557=(($14556)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i500=$14557; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i501=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2385; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2385: + var $14559=$__i_i_i_i_i_i_i501; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14560=(($14559)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14560) { label = 2386; break; } else { label = 2387; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2386: + var $14562=$__i_i_i_i_i_i_i501; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14563=$__a_i_i_i_i_i_i500; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14564=(($14563+($14562<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14564)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14565=$__i_i_i_i_i_i_i501; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14566=((($14565)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i501=$14566; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2385; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2387: + var $14567=(($14534+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14567)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14568=(($14534+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14569=$403; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14568)>>2)]=$14569; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $392=$406; + var $14570=$392; + $391=$14570; + var $14571=$391; + var $14572=$14571; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14573=(($14571)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $390=$14573; + var $14574=$390; + $389=$14574; + var $14575=$389; + var $14576=$14575; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $388=$14576; + var $14577=$388; + var $14578=$14577; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $387=$14578; + var $14579=$387; + var $14580=(($14577)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $386=$14571; + var $14581=$386; + var $14582=(($14581)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $385=$14582; + var $14583=$385; + var $14584=$14583; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $384=$14584; + var $14585=$384; + var $14586=(($14585)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14587=(($14586)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14588=$14587; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14589=(($14588)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i498=$14589; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i499=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2388; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2388: + var $14591=$__i_i_i_i2_i_i_i499; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14592=(($14591)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14592) { label = 2389; break; } else { label = 2390; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2389: + var $14594=$__i_i_i_i2_i_i_i499; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14595=$__a_i_i_i1_i_i_i498; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14596=(($14595+($14594<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14596)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14597=$__i_i_i_i2_i_i_i499; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14598=((($14597)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i499=$14598; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2388; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2390: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($14534, $406) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2391; break; } else { label = 2393; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2391: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($406) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2406; break; } else { label = 2392; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2392: + var $14601$0 = ___cxa_find_matching_catch(-1, -1); $14601$1 = tempRet0; + var $14602=$14601$0; + $404=$14602; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14603=$14601$1; + $405=$14603; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2395; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2393: + var $14605$0 = ___cxa_find_matching_catch(-1, -1); $14605$1 = tempRet0; + var $14606=$14605$0; + $404=$14606; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14607=$14605$1; + $405=$14607; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($406) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2394; break; } else { label = 2398; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2394: + label = 2395; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2395: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($14537) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2396; break; } else { label = 2398; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2396: + var $14611=$14534; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($14611) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2397; break; } else { label = 2398; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2397: + var $14613=$404; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14614=$405; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14615$0=$14613; + var $14615$1=0; + var $14616$0=$14615$0; + var $14616$1=$14614; + var $eh_lpad_body_i506$1 = $14616$1;var $eh_lpad_body_i506$0 = $14616$0;label = 2401; break; + case 2398: + var $14618$0 = ___cxa_find_matching_catch(-1, -1,0); $14618$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2399: + var $14620$0 = ___cxa_find_matching_catch(-1, -1); $14620$1 = tempRet0; + var $14621=$14620$0; + $413=$14621; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14622=$14620$1; + $414=$14622; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2403; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2400: + var $14624$0 = ___cxa_find_matching_catch(-1, -1); $14624$1 = tempRet0; + var $eh_lpad_body_i506$1 = $14624$1;var $eh_lpad_body_i506$0 = $14624$0;label = 2401; break; + case 2401: + var $eh_lpad_body_i506$0; + var $eh_lpad_body_i506$1; + var $14625=$eh_lpad_body_i506$0; + $413=$14625; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14626=$eh_lpad_body_i506$1; + $414=$14626; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14627=$14434; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($14627, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2402; break; } else { label = 2405; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2402: + label = 2403; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2403: + var $14630=$14434; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14631=(($14630+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14632=$14631; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($14632) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2404; break; } else { label = 2405; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2404: + var $14634=$413; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14635=$414; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14636$0=$14634; + var $14636$1=0; + var $14637$0=$14636$0; + var $14637$1=$14635; + ___resumeException($14637$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2405: + var $14639$0 = ___cxa_find_matching_catch(-1, -1,0); $14639$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2406: + var $14640=$std_stringstream36; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14641=(($14640+8)|0); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14642=$14641; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14643 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14642, ((82360)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2407; break; } else { label = 2428; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2407: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2761, ((82720)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2408; break; } else { label = 2428; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2408: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2760, $2761, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2409; break; } else { label = 2429; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2409: + var $14647 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($14643, $2760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2410; break; } else { label = 2430; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2410: + var $14649 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14647, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2411; break; } else { label = 2430; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2411: + var $14651 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14649, ((82720)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2412; break; } else { label = 2430; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2412: + var $14653 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14651, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2413; break; } else { label = 2430; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2413: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2414; break; } else { label = 2429; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2414: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2761) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2415; break; } else { label = 2428; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2415: + var $14657=___cxa_allocate_exception(8); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2763=1; + var $14658=$14657; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $371=$std_stringstream36; + var $14659=$371; + var $14660=(($14659+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2762, $14660) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2416; break; } else { label = 2434; break; } + case 2416: + label = 2417; break; + case 2417: + $370=$2762; + var $14662=$370; + $369=$14662; + var $14663=$369; + $368=$14663; + var $14664=$368; + $367=$14664; + var $14665=$367; + var $14666=(($14665)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $366=$14666; + var $14667=$366; + var $14668=$14667; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $365=$14668; + var $14669=$365; + var $14670=(($14669)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14671=(($14670)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14672=$14671; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14673=(($14672)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14674=$14673; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14675=HEAP8[($14674)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14676=(($14675)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14677=$14676 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14678=(($14677)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($14678) { label = 2418; break; } else { label = 2419; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2418: + $359=$14664; + var $14680=$359; + var $14681=(($14680)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $358=$14681; + var $14682=$358; + var $14683=$14682; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $357=$14683; + var $14684=$357; + var $14685=(($14684)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14686=(($14685)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14687=$14686; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14688=(($14687+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14689=HEAP32[(($14688)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $14703 = $14689;label = 2420; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2419: + $364=$14664; + var $14691=$364; + var $14692=(($14691)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $363=$14692; + var $14693=$363; + var $14694=$14693; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $362=$14694; + var $14695=$362; + var $14696=(($14695)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14697=(($14696)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14698=$14697; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14699=(($14698+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $14700=(($14699)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $361=$14700; + var $14701=$361; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $360=$14701; + var $14702=$360; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $14703 = $14702;label = 2420; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2420: + var $14703; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $356=$14703; + var $14704=$356; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($14658, $14704) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2421; break; } else { label = 2435; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2421: + $2763=0; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($14657, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2435; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2762) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2422; break; } else { label = 2434; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2422: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream36); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2442; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2423: + var $14709$0 = ___cxa_find_matching_catch(-1, -1); $14709$1 = tempRet0; + var $14710=$14709$0; + $2542=$14710; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14711=$14709$1; + $2543=$14711; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2426; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2424: + var $14713$0 = ___cxa_find_matching_catch(-1, -1); $14713$1 = tempRet0; + var $14714=$14713$0; + $2542=$14714; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14715=$14713$1; + $2543=$14715; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2758) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2425; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2425: + label = 2426; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2426: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2759) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2427; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2427: + label = 2840; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2428: + var $14720$0 = ___cxa_find_matching_catch(-1, -1); $14720$1 = tempRet0; + var $14721=$14720$0; + $2542=$14721; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14722=$14720$1; + $2543=$14722; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2440; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2429: + var $14724$0 = ___cxa_find_matching_catch(-1, -1); $14724$1 = tempRet0; + var $14725=$14724$0; + $2542=$14725; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14726=$14724$1; + $2543=$14726; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2432; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2430: + var $14728$0 = ___cxa_find_matching_catch(-1, -1); $14728$1 = tempRet0; + var $14729=$14728$0; + $2542=$14729; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14730=$14728$1; + $2543=$14730; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2760) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2431; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2431: + label = 2432; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2432: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2761) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2433; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2433: + label = 2440; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2434: + var $14735$0 = ___cxa_find_matching_catch(-1, -1); $14735$1 = tempRet0; + var $14736=$14735$0; + $2542=$14736; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14737=$14735$1; + $2543=$14737; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2437; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2435: + var $14739$0 = ___cxa_find_matching_catch(-1, -1); $14739$1 = tempRet0; + var $14740=$14739$0; + $2542=$14740; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14741=$14739$1; + $2543=$14741; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2762) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2436; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2436: + label = 2437; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2437: + var $14744=$2763; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14744) { label = 2438; break; } else { label = 2439; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2438: + ___cxa_free_exception($14657); //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2439; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2439: + label = 2440; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2440: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream36) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2441; break; } else { label = 2841; break; } //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2441: + label = 2840; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2442: + label = 2443; break; //@line 178 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2443: + label = 2444; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2444: + __ZN6StringC1EPKc($2765, ((82040)|0)); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2764, $2765, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2445; break; } else { label = 2489; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2445: + var $14753 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2764, ((82040)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2446; break; } else { label = 2490; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2446: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2764) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2447; break; } else { label = 2489; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2447: + __ZN6StringD1Ev($2765); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($14753) { label = 2448; break; } else { label = 2508; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2448: + $352=$std_stringstream37; + $353=24; + var $14757=$352; + var $14758=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14759=(($14758+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14760=$14759; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $351=$14760; + var $14761=$351; + var $14762=$14761; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $350=$14762; + var $14763=$350; + var $14764=$14763; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14764)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $14765=$14761; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14765)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $14766=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14766)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14767=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14768=(($14767+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14769=$14768; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14769)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14770=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14771=(($14770+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14772=$14771; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14772)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14773=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14774=(($14757+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14775=$14774; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $320=$14773; + $321=((109796)|0); + $322=$14775; + var $14776=$320; + var $14777=$321; + var $14778=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14779=(($14777+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14780=$322; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $317=$14778; + $318=$14779; + $319=$14780; + var $14781=$317; + var $14782=$318; + var $14783=HEAP32[(($14782)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14784=$14781; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14784)>>2)]=$14783; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14785=(($14782+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14786=HEAP32[(($14785)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14787=$14781; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14788=HEAP32[(($14787)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14789=((($14788)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14790=$14789; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14791=HEAP32[(($14790)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14792=$14781; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14793=(($14792+$14791)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14794=$14793; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14794)>>2)]=$14786; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14795=(($14781+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14795)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $14796=$14781; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14797=HEAP32[(($14796)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14798=((($14797)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14799=$14798; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14800=HEAP32[(($14799)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14801=$14781; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14802=(($14801+$14800)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14803=$14802; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $14804=$319; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $315=$14803; + $316=$14804; + var $14805=$315; + var $14806=$14805; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14807=$316; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $14808=$14807; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($14806, $14808) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2449; break; } else { label = 2465; break; } + case 2449: + var $14809=(($14805+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14809)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $14810=(($14805+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($14810)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $14811=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14812=(($14811+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14813=$14812; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14814=(($14777+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $313=$14813; + $314=$14814; + var $14815=$313; + var $14816=$314; + var $14817=HEAP32[(($14816)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14818=$14815; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14818)>>2)]=$14817; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14819=(($14816+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14820=HEAP32[(($14819)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14821=$14815; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14822=HEAP32[(($14821)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14823=((($14822)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14824=$14823; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14825=HEAP32[(($14824)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14826=$14815; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14827=(($14826+$14825)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14828=$14827; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14828)>>2)]=$14820; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $14829=HEAP32[(($14777)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14830=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14830)>>2)]=$14829; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14831=(($14777+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14832=HEAP32[(($14831)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14833=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14834=HEAP32[(($14833)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14835=((($14834)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14836=$14835; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14837=HEAP32[(($14836)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14838=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14839=(($14838+$14837)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14840=$14839; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14840)>>2)]=$14832; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14841=(($14777+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14842=HEAP32[(($14841)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14843=$14776; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14844=(($14843+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14845=$14844; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14845)>>2)]=$14842; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $14846=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14846)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14847=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14848=(($14847+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14849=$14848; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14849)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14850=$14757; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14851=(($14850+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14852=$14851; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14852)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14853=(($14757+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14854=$353; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $348=$14853; + $349=$14854; + var $14855=$348; + var $14856=$349; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $343=$14855; + $344=$14856; + var $14857=$343; + var $14858=$14857; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($14858) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2450; break; } else { label = 2466; break; } + case 2450: + var $14859=$14857; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14859)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14860=(($14857+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $342=$14860; + var $14861=$342; + $341=$14861; + var $14862=$341; + var $14863=$14862; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14864=(($14862)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $340=$14864; + var $14865=$340; + $339=$14865; + var $14866=$339; + var $14867=$14866; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $338=$14867; + var $14868=$338; + var $14869=$14868; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $337=$14869; + var $14870=$337; + var $14871=(($14868)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $336=$14862; + var $14872=$336; + var $14873=(($14872)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $335=$14873; + var $14874=$335; + var $14875=$14874; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $334=$14875; + var $14876=$334; + var $14877=(($14876)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14878=(($14877)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14879=$14878; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14880=(($14879)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i513=$14880; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i514=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2451; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2451: + var $14882=$__i_i_i_i_i_i_i514; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14883=(($14882)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14883) { label = 2452; break; } else { label = 2453; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2452: + var $14885=$__i_i_i_i_i_i_i514; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14886=$__a_i_i_i_i_i_i513; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14887=(($14886+($14885<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14887)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14888=$__i_i_i_i_i_i_i514; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14889=((($14888)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i514=$14889; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2451; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2453: + var $14890=(($14857+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14890)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14891=(($14857+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $14892=$344; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($14891)>>2)]=$14892; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $333=$347; + var $14893=$333; + $332=$14893; + var $14894=$332; + var $14895=$14894; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $14896=(($14894)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $331=$14896; + var $14897=$331; + $330=$14897; + var $14898=$330; + var $14899=$14898; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $329=$14899; + var $14900=$329; + var $14901=$14900; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $328=$14901; + var $14902=$328; + var $14903=(($14900)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $327=$14894; + var $14904=$327; + var $14905=(($14904)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $326=$14905; + var $14906=$326; + var $14907=$14906; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $325=$14907; + var $14908=$325; + var $14909=(($14908)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $14910=(($14909)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14911=$14910; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $14912=(($14911)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i511=$14912; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i512=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2454; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2454: + var $14914=$__i_i_i_i2_i_i_i512; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14915=(($14914)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($14915) { label = 2455; break; } else { label = 2456; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2455: + var $14917=$__i_i_i_i2_i_i_i512; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14918=$__a_i_i_i1_i_i_i511; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14919=(($14918+($14917<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($14919)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $14920=$__i_i_i_i2_i_i_i512; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $14921=((($14920)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i512=$14921; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2454; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2456: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($14857, $347) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2457; break; } else { label = 2459; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2457: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($347) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2472; break; } else { label = 2458; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2458: + var $14924$0 = ___cxa_find_matching_catch(-1, -1); $14924$1 = tempRet0; + var $14925=$14924$0; + $345=$14925; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14926=$14924$1; + $346=$14926; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2461; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2459: + var $14928$0 = ___cxa_find_matching_catch(-1, -1); $14928$1 = tempRet0; + var $14929=$14928$0; + $345=$14929; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $14930=$14928$1; + $346=$14930; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($347) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2460; break; } else { label = 2464; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2460: + label = 2461; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2461: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($14860) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2462; break; } else { label = 2464; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2462: + var $14934=$14857; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($14934) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2463; break; } else { label = 2464; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2463: + var $14936=$345; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14937=$346; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $14938$0=$14936; + var $14938$1=0; + var $14939$0=$14938$0; + var $14939$1=$14937; + var $eh_lpad_body_i519$1 = $14939$1;var $eh_lpad_body_i519$0 = $14939$0;label = 2467; break; + case 2464: + var $14941$0 = ___cxa_find_matching_catch(-1, -1,0); $14941$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2465: + var $14943$0 = ___cxa_find_matching_catch(-1, -1); $14943$1 = tempRet0; + var $14944=$14943$0; + $354=$14944; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14945=$14943$1; + $355=$14945; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2469; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2466: + var $14947$0 = ___cxa_find_matching_catch(-1, -1); $14947$1 = tempRet0; + var $eh_lpad_body_i519$1 = $14947$1;var $eh_lpad_body_i519$0 = $14947$0;label = 2467; break; + case 2467: + var $eh_lpad_body_i519$0; + var $eh_lpad_body_i519$1; + var $14948=$eh_lpad_body_i519$0; + $354=$14948; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14949=$eh_lpad_body_i519$1; + $355=$14949; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $14950=$14757; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($14950, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2468; break; } else { label = 2471; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2468: + label = 2469; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2469: + var $14953=$14757; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14954=(($14953+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14955=$14954; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($14955) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2470; break; } else { label = 2471; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2470: + var $14957=$354; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14958=$355; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $14959$0=$14957; + var $14959$1=0; + var $14960$0=$14959$0; + var $14960$1=$14958; + ___resumeException($14960$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2471: + var $14962$0 = ___cxa_find_matching_catch(-1, -1,0); $14962$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2472: + var $14963=$std_stringstream37; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14964=(($14963+8)|0); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14965=$14964; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $14966 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14965, ((81672)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2473; break; } else { label = 2494; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2473: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2767, ((82040)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2474; break; } else { label = 2494; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2474: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2766, $2767, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2475; break; } else { label = 2495; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2475: + var $14970 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($14966, $2766) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2476; break; } else { label = 2496; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2476: + var $14972 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14970, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2477; break; } else { label = 2496; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2477: + var $14974 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14972, ((82040)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2478; break; } else { label = 2496; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2478: + var $14976 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($14974, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2479; break; } else { label = 2496; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2479: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2766) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2480; break; } else { label = 2495; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2480: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2767) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2481; break; } else { label = 2494; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2481: + var $14980=___cxa_allocate_exception(8); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2769=1; + var $14981=$14980; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $312=$std_stringstream37; + var $14982=$312; + var $14983=(($14982+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2768, $14983) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2482; break; } else { label = 2500; break; } + case 2482: + label = 2483; break; + case 2483: + $311=$2768; + var $14985=$311; + $310=$14985; + var $14986=$310; + $309=$14986; + var $14987=$309; + $308=$14987; + var $14988=$308; + var $14989=(($14988)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $307=$14989; + var $14990=$307; + var $14991=$14990; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $306=$14991; + var $14992=$306; + var $14993=(($14992)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $14994=(($14993)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14995=$14994; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14996=(($14995)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14997=$14996; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14998=HEAP8[($14997)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $14999=(($14998)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15000=$14999 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15001=(($15000)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($15001) { label = 2484; break; } else { label = 2485; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2484: + $300=$14987; + var $15003=$300; + var $15004=(($15003)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $299=$15004; + var $15005=$299; + var $15006=$15005; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $298=$15006; + var $15007=$298; + var $15008=(($15007)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15009=(($15008)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15010=$15009; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15011=(($15010+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15012=HEAP32[(($15011)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15026 = $15012;label = 2486; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2485: + $305=$14987; + var $15014=$305; + var $15015=(($15014)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $304=$15015; + var $15016=$304; + var $15017=$15016; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $303=$15017; + var $15018=$303; + var $15019=(($15018)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15020=(($15019)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15021=$15020; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15022=(($15021+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15023=(($15022)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $302=$15023; + var $15024=$302; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $301=$15024; + var $15025=$301; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $15026 = $15025;label = 2486; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2486: + var $15026; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $297=$15026; + var $15027=$297; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($14981, $15027) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2487; break; } else { label = 2501; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2487: + $2769=0; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($14980, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2501; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2768) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2488; break; } else { label = 2500; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2488: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream37); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2508; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2489: + var $15032$0 = ___cxa_find_matching_catch(-1, -1); $15032$1 = tempRet0; + var $15033=$15032$0; + $2542=$15033; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15034=$15032$1; + $2543=$15034; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2492; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2490: + var $15036$0 = ___cxa_find_matching_catch(-1, -1); $15036$1 = tempRet0; + var $15037=$15036$0; + $2542=$15037; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15038=$15036$1; + $2543=$15038; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2764) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2491; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2491: + label = 2492; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2492: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2765) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2493; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2493: + label = 2840; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2494: + var $15043$0 = ___cxa_find_matching_catch(-1, -1); $15043$1 = tempRet0; + var $15044=$15043$0; + $2542=$15044; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15045=$15043$1; + $2543=$15045; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2506; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2495: + var $15047$0 = ___cxa_find_matching_catch(-1, -1); $15047$1 = tempRet0; + var $15048=$15047$0; + $2542=$15048; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15049=$15047$1; + $2543=$15049; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2498; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2496: + var $15051$0 = ___cxa_find_matching_catch(-1, -1); $15051$1 = tempRet0; + var $15052=$15051$0; + $2542=$15052; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15053=$15051$1; + $2543=$15053; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2766) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2497; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2497: + label = 2498; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2498: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2767) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2499; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2499: + label = 2506; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2500: + var $15058$0 = ___cxa_find_matching_catch(-1, -1); $15058$1 = tempRet0; + var $15059=$15058$0; + $2542=$15059; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15060=$15058$1; + $2543=$15060; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2503; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2501: + var $15062$0 = ___cxa_find_matching_catch(-1, -1); $15062$1 = tempRet0; + var $15063=$15062$0; + $2542=$15063; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15064=$15062$1; + $2543=$15064; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2768) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2502; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2502: + label = 2503; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2503: + var $15067=$2769; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15067) { label = 2504; break; } else { label = 2505; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2504: + ___cxa_free_exception($14980); //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2505; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2505: + label = 2506; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2506: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream37) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2507; break; } else { label = 2841; break; } //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2507: + label = 2840; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2508: + label = 2509; break; //@line 179 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2509: + label = 2510; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2510: + __ZN6StringC1EPKc($2771, ((80968)|0)); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2770, $2771, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2511; break; } else { label = 2555; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2511: + var $15076 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2770, ((80968)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2512; break; } else { label = 2556; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2512: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2770) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2513; break; } else { label = 2555; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2513: + __ZN6StringD1Ev($2771); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15076) { label = 2514; break; } else { label = 2574; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2514: + $293=$std_stringstream38; + $294=24; + var $15080=$293; + var $15081=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15082=(($15081+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15083=$15082; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $292=$15083; + var $15084=$292; + var $15085=$15084; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $291=$15085; + var $15086=$291; + var $15087=$15086; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15087)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $15088=$15084; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15088)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $15089=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15089)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15090=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15091=(($15090+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15092=$15091; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15092)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15093=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15094=(($15093+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15095=$15094; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15095)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15096=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15097=(($15080+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15098=$15097; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $261=$15096; + $262=((109796)|0); + $263=$15098; + var $15099=$261; + var $15100=$262; + var $15101=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15102=(($15100+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15103=$263; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $258=$15101; + $259=$15102; + $260=$15103; + var $15104=$258; + var $15105=$259; + var $15106=HEAP32[(($15105)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15107=$15104; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15107)>>2)]=$15106; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15108=(($15105+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15109=HEAP32[(($15108)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15110=$15104; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15111=HEAP32[(($15110)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15112=((($15111)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15113=$15112; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15114=HEAP32[(($15113)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15115=$15104; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15116=(($15115+$15114)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15117=$15116; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15117)>>2)]=$15109; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15118=(($15104+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15118)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15119=$15104; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15120=HEAP32[(($15119)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15121=((($15120)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15122=$15121; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15123=HEAP32[(($15122)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15124=$15104; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15125=(($15124+$15123)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15126=$15125; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15127=$260; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $256=$15126; + $257=$15127; + var $15128=$256; + var $15129=$15128; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15130=$257; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15131=$15130; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($15129, $15131) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2515; break; } else { label = 2531; break; } + case 2515: + var $15132=(($15128+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15132)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $15133=(($15128+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15133)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $15134=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15135=(($15134+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15136=$15135; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15137=(($15100+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $254=$15136; + $255=$15137; + var $15138=$254; + var $15139=$255; + var $15140=HEAP32[(($15139)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15141=$15138; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15141)>>2)]=$15140; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15142=(($15139+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15143=HEAP32[(($15142)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15144=$15138; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15145=HEAP32[(($15144)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15146=((($15145)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15147=$15146; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15148=HEAP32[(($15147)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15149=$15138; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15150=(($15149+$15148)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15151=$15150; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15151)>>2)]=$15143; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15152=HEAP32[(($15100)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15153=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15153)>>2)]=$15152; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15154=(($15100+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15155=HEAP32[(($15154)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15156=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15157=HEAP32[(($15156)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15158=((($15157)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15159=$15158; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15160=HEAP32[(($15159)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15161=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15162=(($15161+$15160)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15163=$15162; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15163)>>2)]=$15155; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15164=(($15100+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15165=HEAP32[(($15164)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15166=$15099; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15167=(($15166+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15168=$15167; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15168)>>2)]=$15165; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15169=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15169)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15170=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15171=(($15170+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15172=$15171; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15172)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15173=$15080; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15174=(($15173+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15175=$15174; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15175)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15176=(($15080+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15177=$294; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $289=$15176; + $290=$15177; + var $15178=$289; + var $15179=$290; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $284=$15178; + $285=$15179; + var $15180=$284; + var $15181=$15180; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($15181) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2516; break; } else { label = 2532; break; } + case 2516: + var $15182=$15180; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15182)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15183=(($15180+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $283=$15183; + var $15184=$283; + $282=$15184; + var $15185=$282; + var $15186=$15185; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15187=(($15185)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $281=$15187; + var $15188=$281; + $280=$15188; + var $15189=$280; + var $15190=$15189; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $279=$15190; + var $15191=$279; + var $15192=$15191; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $278=$15192; + var $15193=$278; + var $15194=(($15191)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $277=$15185; + var $15195=$277; + var $15196=(($15195)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $276=$15196; + var $15197=$276; + var $15198=$15197; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $275=$15198; + var $15199=$275; + var $15200=(($15199)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15201=(($15200)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15202=$15201; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15203=(($15202)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i526=$15203; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i527=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2517; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2517: + var $15205=$__i_i_i_i_i_i_i527; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15206=(($15205)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15206) { label = 2518; break; } else { label = 2519; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2518: + var $15208=$__i_i_i_i_i_i_i527; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15209=$__a_i_i_i_i_i_i526; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15210=(($15209+($15208<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15210)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15211=$__i_i_i_i_i_i_i527; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15212=((($15211)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i527=$15212; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2517; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2519: + var $15213=(($15180+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15213)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15214=(($15180+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15215=$285; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15214)>>2)]=$15215; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $274=$288; + var $15216=$274; + $273=$15216; + var $15217=$273; + var $15218=$15217; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15219=(($15217)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $272=$15219; + var $15220=$272; + $271=$15220; + var $15221=$271; + var $15222=$15221; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $270=$15222; + var $15223=$270; + var $15224=$15223; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $269=$15224; + var $15225=$269; + var $15226=(($15223)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $268=$15217; + var $15227=$268; + var $15228=(($15227)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $267=$15228; + var $15229=$267; + var $15230=$15229; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $266=$15230; + var $15231=$266; + var $15232=(($15231)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15233=(($15232)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15234=$15233; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15235=(($15234)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i524=$15235; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i525=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2520; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2520: + var $15237=$__i_i_i_i2_i_i_i525; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15238=(($15237)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15238) { label = 2521; break; } else { label = 2522; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2521: + var $15240=$__i_i_i_i2_i_i_i525; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15241=$__a_i_i_i1_i_i_i524; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15242=(($15241+($15240<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15242)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15243=$__i_i_i_i2_i_i_i525; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15244=((($15243)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i525=$15244; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2520; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2522: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($15180, $288) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2523; break; } else { label = 2525; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2523: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($288) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2538; break; } else { label = 2524; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2524: + var $15247$0 = ___cxa_find_matching_catch(-1, -1); $15247$1 = tempRet0; + var $15248=$15247$0; + $286=$15248; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15249=$15247$1; + $287=$15249; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2527; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2525: + var $15251$0 = ___cxa_find_matching_catch(-1, -1); $15251$1 = tempRet0; + var $15252=$15251$0; + $286=$15252; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15253=$15251$1; + $287=$15253; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($288) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2526; break; } else { label = 2530; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2526: + label = 2527; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2527: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($15183) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2528; break; } else { label = 2530; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2528: + var $15257=$15180; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($15257) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2529; break; } else { label = 2530; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2529: + var $15259=$286; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15260=$287; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15261$0=$15259; + var $15261$1=0; + var $15262$0=$15261$0; + var $15262$1=$15260; + var $eh_lpad_body_i532$1 = $15262$1;var $eh_lpad_body_i532$0 = $15262$0;label = 2533; break; + case 2530: + var $15264$0 = ___cxa_find_matching_catch(-1, -1,0); $15264$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2531: + var $15266$0 = ___cxa_find_matching_catch(-1, -1); $15266$1 = tempRet0; + var $15267=$15266$0; + $295=$15267; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15268=$15266$1; + $296=$15268; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2535; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2532: + var $15270$0 = ___cxa_find_matching_catch(-1, -1); $15270$1 = tempRet0; + var $eh_lpad_body_i532$1 = $15270$1;var $eh_lpad_body_i532$0 = $15270$0;label = 2533; break; + case 2533: + var $eh_lpad_body_i532$0; + var $eh_lpad_body_i532$1; + var $15271=$eh_lpad_body_i532$0; + $295=$15271; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15272=$eh_lpad_body_i532$1; + $296=$15272; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15273=$15080; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($15273, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2534; break; } else { label = 2537; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2534: + label = 2535; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2535: + var $15276=$15080; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15277=(($15276+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15278=$15277; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($15278) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2536; break; } else { label = 2537; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2536: + var $15280=$295; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15281=$296; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15282$0=$15280; + var $15282$1=0; + var $15283$0=$15282$0; + var $15283$1=$15281; + ___resumeException($15283$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2537: + var $15285$0 = ___cxa_find_matching_catch(-1, -1,0); $15285$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2538: + var $15286=$std_stringstream38; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15287=(($15286+8)|0); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15288=$15287; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15289 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15288, ((80456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2539; break; } else { label = 2560; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2539: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2773, ((80968)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2540; break; } else { label = 2560; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2540: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2772, $2773, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2541; break; } else { label = 2561; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2541: + var $15293 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($15289, $2772) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2542; break; } else { label = 2562; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2542: + var $15295 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15293, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2543; break; } else { label = 2562; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2543: + var $15297 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15295, ((80968)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2544; break; } else { label = 2562; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2544: + var $15299 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15297, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2545; break; } else { label = 2562; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2545: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2772) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2546; break; } else { label = 2561; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2546: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2773) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2547; break; } else { label = 2560; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2547: + var $15303=___cxa_allocate_exception(8); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2775=1; + var $15304=$15303; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $253=$std_stringstream38; + var $15305=$253; + var $15306=(($15305+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2774, $15306) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2548; break; } else { label = 2566; break; } + case 2548: + label = 2549; break; + case 2549: + $252=$2774; + var $15308=$252; + $251=$15308; + var $15309=$251; + $250=$15309; + var $15310=$250; + $249=$15310; + var $15311=$249; + var $15312=(($15311)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $248=$15312; + var $15313=$248; + var $15314=$15313; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $247=$15314; + var $15315=$247; + var $15316=(($15315)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15317=(($15316)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15318=$15317; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15319=(($15318)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15320=$15319; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15321=HEAP8[($15320)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15322=(($15321)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15323=$15322 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15324=(($15323)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($15324) { label = 2550; break; } else { label = 2551; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2550: + $241=$15310; + var $15326=$241; + var $15327=(($15326)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $240=$15327; + var $15328=$240; + var $15329=$15328; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $239=$15329; + var $15330=$239; + var $15331=(($15330)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15332=(($15331)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15333=$15332; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15334=(($15333+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15335=HEAP32[(($15334)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15349 = $15335;label = 2552; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2551: + $246=$15310; + var $15337=$246; + var $15338=(($15337)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $245=$15338; + var $15339=$245; + var $15340=$15339; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $244=$15340; + var $15341=$244; + var $15342=(($15341)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15343=(($15342)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15344=$15343; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15345=(($15344+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15346=(($15345)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $243=$15346; + var $15347=$243; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $242=$15347; + var $15348=$242; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $15349 = $15348;label = 2552; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2552: + var $15349; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $238=$15349; + var $15350=$238; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($15304, $15350) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2553; break; } else { label = 2567; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2553: + $2775=0; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($15303, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2567; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2774) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2554; break; } else { label = 2566; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2554: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream38); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2574; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2555: + var $15355$0 = ___cxa_find_matching_catch(-1, -1); $15355$1 = tempRet0; + var $15356=$15355$0; + $2542=$15356; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15357=$15355$1; + $2543=$15357; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2558; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2556: + var $15359$0 = ___cxa_find_matching_catch(-1, -1); $15359$1 = tempRet0; + var $15360=$15359$0; + $2542=$15360; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15361=$15359$1; + $2543=$15361; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2770) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2557; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2557: + label = 2558; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2558: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2771) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2559; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2559: + label = 2840; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2560: + var $15366$0 = ___cxa_find_matching_catch(-1, -1); $15366$1 = tempRet0; + var $15367=$15366$0; + $2542=$15367; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15368=$15366$1; + $2543=$15368; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2572; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2561: + var $15370$0 = ___cxa_find_matching_catch(-1, -1); $15370$1 = tempRet0; + var $15371=$15370$0; + $2542=$15371; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15372=$15370$1; + $2543=$15372; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2564; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2562: + var $15374$0 = ___cxa_find_matching_catch(-1, -1); $15374$1 = tempRet0; + var $15375=$15374$0; + $2542=$15375; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15376=$15374$1; + $2543=$15376; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2772) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2563; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2563: + label = 2564; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2564: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2773) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2565; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2565: + label = 2572; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2566: + var $15381$0 = ___cxa_find_matching_catch(-1, -1); $15381$1 = tempRet0; + var $15382=$15381$0; + $2542=$15382; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15383=$15381$1; + $2543=$15383; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2569; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2567: + var $15385$0 = ___cxa_find_matching_catch(-1, -1); $15385$1 = tempRet0; + var $15386=$15385$0; + $2542=$15386; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15387=$15385$1; + $2543=$15387; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2774) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2568; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2568: + label = 2569; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2569: + var $15390=$2775; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15390) { label = 2570; break; } else { label = 2571; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2570: + ___cxa_free_exception($15303); //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2571; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2571: + label = 2572; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2572: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream38) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2573; break; } else { label = 2841; break; } //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2573: + label = 2840; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2574: + label = 2575; break; //@line 180 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2575: + label = 2576; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2576: + __ZN6StringC1EPKc($2777, ((80048)|0)); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2776, $2777, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2577; break; } else { label = 2621; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2577: + var $15399 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2776, ((79832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2578; break; } else { label = 2622; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2578: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2776) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2579; break; } else { label = 2621; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2579: + __ZN6StringD1Ev($2777); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15399) { label = 2580; break; } else { label = 2640; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2580: + $234=$std_stringstream39; + $235=24; + var $15403=$234; + var $15404=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15405=(($15404+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15406=$15405; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $233=$15406; + var $15407=$233; + var $15408=$15407; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $232=$15408; + var $15409=$232; + var $15410=$15409; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15410)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $15411=$15407; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15411)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $15412=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15412)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15413=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15414=(($15413+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15415=$15414; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15415)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15416=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15417=(($15416+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15418=$15417; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15418)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15419=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15420=(($15403+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15421=$15420; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $202=$15419; + $203=((109796)|0); + $204=$15421; + var $15422=$202; + var $15423=$203; + var $15424=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15425=(($15423+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15426=$204; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $199=$15424; + $200=$15425; + $201=$15426; + var $15427=$199; + var $15428=$200; + var $15429=HEAP32[(($15428)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15430=$15427; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15430)>>2)]=$15429; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15431=(($15428+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15432=HEAP32[(($15431)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15433=$15427; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15434=HEAP32[(($15433)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15435=((($15434)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15436=$15435; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15437=HEAP32[(($15436)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15438=$15427; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15439=(($15438+$15437)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15440=$15439; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15440)>>2)]=$15432; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15441=(($15427+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15441)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15442=$15427; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15443=HEAP32[(($15442)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15444=((($15443)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15445=$15444; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15446=HEAP32[(($15445)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15447=$15427; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15448=(($15447+$15446)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15449=$15448; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15450=$201; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $197=$15449; + $198=$15450; + var $15451=$197; + var $15452=$15451; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15453=$198; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15454=$15453; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($15452, $15454) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2581; break; } else { label = 2597; break; } + case 2581: + var $15455=(($15451+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15455)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $15456=(($15451+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15456)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $15457=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15458=(($15457+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15459=$15458; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15460=(($15423+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $195=$15459; + $196=$15460; + var $15461=$195; + var $15462=$196; + var $15463=HEAP32[(($15462)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15464=$15461; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15464)>>2)]=$15463; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15465=(($15462+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15466=HEAP32[(($15465)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15467=$15461; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15468=HEAP32[(($15467)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15469=((($15468)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15470=$15469; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15471=HEAP32[(($15470)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15472=$15461; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15473=(($15472+$15471)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15474=$15473; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15474)>>2)]=$15466; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15475=HEAP32[(($15423)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15476=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15476)>>2)]=$15475; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15477=(($15423+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15478=HEAP32[(($15477)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15479=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15480=HEAP32[(($15479)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15481=((($15480)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15482=$15481; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15483=HEAP32[(($15482)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15484=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15485=(($15484+$15483)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15486=$15485; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15486)>>2)]=$15478; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15487=(($15423+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15488=HEAP32[(($15487)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15489=$15422; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15490=(($15489+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15491=$15490; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15491)>>2)]=$15488; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15492=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15492)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15493=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15494=(($15493+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15495=$15494; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15495)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15496=$15403; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15497=(($15496+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15498=$15497; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15498)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15499=(($15403+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15500=$235; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $230=$15499; + $231=$15500; + var $15501=$230; + var $15502=$231; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $225=$15501; + $226=$15502; + var $15503=$225; + var $15504=$15503; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($15504) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2582; break; } else { label = 2598; break; } + case 2582: + var $15505=$15503; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15505)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15506=(($15503+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $224=$15506; + var $15507=$224; + $223=$15507; + var $15508=$223; + var $15509=$15508; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15510=(($15508)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $222=$15510; + var $15511=$222; + $221=$15511; + var $15512=$221; + var $15513=$15512; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $220=$15513; + var $15514=$220; + var $15515=$15514; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $219=$15515; + var $15516=$219; + var $15517=(($15514)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $218=$15508; + var $15518=$218; + var $15519=(($15518)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $217=$15519; + var $15520=$217; + var $15521=$15520; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $216=$15521; + var $15522=$216; + var $15523=(($15522)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15524=(($15523)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15525=$15524; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15526=(($15525)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i539=$15526; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i540=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2583; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2583: + var $15528=$__i_i_i_i_i_i_i540; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15529=(($15528)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15529) { label = 2584; break; } else { label = 2585; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2584: + var $15531=$__i_i_i_i_i_i_i540; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15532=$__a_i_i_i_i_i_i539; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15533=(($15532+($15531<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15533)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15534=$__i_i_i_i_i_i_i540; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15535=((($15534)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i540=$15535; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2583; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2585: + var $15536=(($15503+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15536)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15537=(($15503+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15538=$226; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15537)>>2)]=$15538; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $215=$229; + var $15539=$215; + $214=$15539; + var $15540=$214; + var $15541=$15540; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15542=(($15540)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $213=$15542; + var $15543=$213; + $212=$15543; + var $15544=$212; + var $15545=$15544; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $211=$15545; + var $15546=$211; + var $15547=$15546; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $210=$15547; + var $15548=$210; + var $15549=(($15546)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $209=$15540; + var $15550=$209; + var $15551=(($15550)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $208=$15551; + var $15552=$208; + var $15553=$15552; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $207=$15553; + var $15554=$207; + var $15555=(($15554)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15556=(($15555)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15557=$15556; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15558=(($15557)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i537=$15558; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i538=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2586; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2586: + var $15560=$__i_i_i_i2_i_i_i538; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15561=(($15560)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15561) { label = 2587; break; } else { label = 2588; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2587: + var $15563=$__i_i_i_i2_i_i_i538; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15564=$__a_i_i_i1_i_i_i537; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15565=(($15564+($15563<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15565)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15566=$__i_i_i_i2_i_i_i538; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15567=((($15566)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i538=$15567; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2586; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2588: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($15503, $229) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2589; break; } else { label = 2591; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2589: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($229) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2604; break; } else { label = 2590; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2590: + var $15570$0 = ___cxa_find_matching_catch(-1, -1); $15570$1 = tempRet0; + var $15571=$15570$0; + $227=$15571; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15572=$15570$1; + $228=$15572; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2593; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2591: + var $15574$0 = ___cxa_find_matching_catch(-1, -1); $15574$1 = tempRet0; + var $15575=$15574$0; + $227=$15575; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15576=$15574$1; + $228=$15576; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($229) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2592; break; } else { label = 2596; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2592: + label = 2593; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2593: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($15506) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2594; break; } else { label = 2596; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2594: + var $15580=$15503; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($15580) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2595; break; } else { label = 2596; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2595: + var $15582=$227; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15583=$228; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15584$0=$15582; + var $15584$1=0; + var $15585$0=$15584$0; + var $15585$1=$15583; + var $eh_lpad_body_i545$1 = $15585$1;var $eh_lpad_body_i545$0 = $15585$0;label = 2599; break; + case 2596: + var $15587$0 = ___cxa_find_matching_catch(-1, -1,0); $15587$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2597: + var $15589$0 = ___cxa_find_matching_catch(-1, -1); $15589$1 = tempRet0; + var $15590=$15589$0; + $236=$15590; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15591=$15589$1; + $237=$15591; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2601; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2598: + var $15593$0 = ___cxa_find_matching_catch(-1, -1); $15593$1 = tempRet0; + var $eh_lpad_body_i545$1 = $15593$1;var $eh_lpad_body_i545$0 = $15593$0;label = 2599; break; + case 2599: + var $eh_lpad_body_i545$0; + var $eh_lpad_body_i545$1; + var $15594=$eh_lpad_body_i545$0; + $236=$15594; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15595=$eh_lpad_body_i545$1; + $237=$15595; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15596=$15403; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($15596, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2600; break; } else { label = 2603; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2600: + label = 2601; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2601: + var $15599=$15403; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15600=(($15599+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15601=$15600; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($15601) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2602; break; } else { label = 2603; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2602: + var $15603=$236; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15604=$237; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15605$0=$15603; + var $15605$1=0; + var $15606$0=$15605$0; + var $15606$1=$15604; + ___resumeException($15606$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2603: + var $15608$0 = ___cxa_find_matching_catch(-1, -1,0); $15608$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2604: + var $15609=$std_stringstream39; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15610=(($15609+8)|0); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15611=$15610; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15612 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15611, ((79544)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2605; break; } else { label = 2626; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2605: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2779, ((80048)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2606; break; } else { label = 2626; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2606: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2778, $2779, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2607; break; } else { label = 2627; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2607: + var $15616 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($15612, $2778) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2608; break; } else { label = 2628; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2608: + var $15618 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15616, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2609; break; } else { label = 2628; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2609: + var $15620 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15618, ((79832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2610; break; } else { label = 2628; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2610: + var $15622 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15620, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2611; break; } else { label = 2628; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2611: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2778) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2612; break; } else { label = 2627; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2612: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2779) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2613; break; } else { label = 2626; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2613: + var $15626=___cxa_allocate_exception(8); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2781=1; + var $15627=$15626; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $194=$std_stringstream39; + var $15628=$194; + var $15629=(($15628+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2780, $15629) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2614; break; } else { label = 2632; break; } + case 2614: + label = 2615; break; + case 2615: + $193=$2780; + var $15631=$193; + $192=$15631; + var $15632=$192; + $191=$15632; + var $15633=$191; + $190=$15633; + var $15634=$190; + var $15635=(($15634)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $189=$15635; + var $15636=$189; + var $15637=$15636; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $188=$15637; + var $15638=$188; + var $15639=(($15638)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15640=(($15639)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15641=$15640; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15642=(($15641)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15643=$15642; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15644=HEAP8[($15643)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15645=(($15644)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15646=$15645 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15647=(($15646)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($15647) { label = 2616; break; } else { label = 2617; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2616: + $182=$15633; + var $15649=$182; + var $15650=(($15649)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $181=$15650; + var $15651=$181; + var $15652=$15651; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $180=$15652; + var $15653=$180; + var $15654=(($15653)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15655=(($15654)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15656=$15655; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15657=(($15656+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15658=HEAP32[(($15657)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15672 = $15658;label = 2618; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2617: + $187=$15633; + var $15660=$187; + var $15661=(($15660)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $186=$15661; + var $15662=$186; + var $15663=$15662; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $185=$15663; + var $15664=$185; + var $15665=(($15664)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15666=(($15665)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15667=$15666; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15668=(($15667+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15669=(($15668)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $184=$15669; + var $15670=$184; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $183=$15670; + var $15671=$183; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $15672 = $15671;label = 2618; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2618: + var $15672; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $179=$15672; + var $15673=$179; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($15627, $15673) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2619; break; } else { label = 2633; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2619: + $2781=0; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($15626, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2633; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2780) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2620; break; } else { label = 2632; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2620: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream39); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2640; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2621: + var $15678$0 = ___cxa_find_matching_catch(-1, -1); $15678$1 = tempRet0; + var $15679=$15678$0; + $2542=$15679; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15680=$15678$1; + $2543=$15680; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2624; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2622: + var $15682$0 = ___cxa_find_matching_catch(-1, -1); $15682$1 = tempRet0; + var $15683=$15682$0; + $2542=$15683; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15684=$15682$1; + $2543=$15684; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2776) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2623; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2623: + label = 2624; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2624: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2777) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2625; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2625: + label = 2840; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2626: + var $15689$0 = ___cxa_find_matching_catch(-1, -1); $15689$1 = tempRet0; + var $15690=$15689$0; + $2542=$15690; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15691=$15689$1; + $2543=$15691; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2638; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2627: + var $15693$0 = ___cxa_find_matching_catch(-1, -1); $15693$1 = tempRet0; + var $15694=$15693$0; + $2542=$15694; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15695=$15693$1; + $2543=$15695; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2630; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2628: + var $15697$0 = ___cxa_find_matching_catch(-1, -1); $15697$1 = tempRet0; + var $15698=$15697$0; + $2542=$15698; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15699=$15697$1; + $2543=$15699; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2778) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2629; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2629: + label = 2630; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2630: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2779) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2631; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2631: + label = 2638; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2632: + var $15704$0 = ___cxa_find_matching_catch(-1, -1); $15704$1 = tempRet0; + var $15705=$15704$0; + $2542=$15705; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15706=$15704$1; + $2543=$15706; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2635; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2633: + var $15708$0 = ___cxa_find_matching_catch(-1, -1); $15708$1 = tempRet0; + var $15709=$15708$0; + $2542=$15709; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15710=$15708$1; + $2543=$15710; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2780) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2634; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2634: + label = 2635; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2635: + var $15713=$2781; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15713) { label = 2636; break; } else { label = 2637; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2636: + ___cxa_free_exception($15626); //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2637; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2637: + label = 2638; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2638: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream39) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2639; break; } else { label = 2841; break; } //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2639: + label = 2840; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2640: + label = 2641; break; //@line 181 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2641: + label = 2642; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2642: + __ZN6StringC1EPKc($2783, ((79320)|0)); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2782, $2783, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2643; break; } else { label = 2687; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2643: + var $15722 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2782, ((79096)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2644; break; } else { label = 2688; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2644: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2782) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2645; break; } else { label = 2687; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2645: + __ZN6StringD1Ev($2783); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($15722) { label = 2646; break; } else { label = 2706; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2646: + $175=$std_stringstream40; + $176=24; + var $15726=$175; + var $15727=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15728=(($15727+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15729=$15728; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $174=$15729; + var $15730=$174; + var $15731=$15730; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $173=$15731; + var $15732=$173; + var $15733=$15732; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15733)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $15734=$15730; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15734)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $15735=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15735)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15736=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15737=(($15736+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15738=$15737; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15738)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15739=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15740=(($15739+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15741=$15740; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15741)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15742=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15743=(($15726+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15744=$15743; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $143=$15742; + $144=((109796)|0); + $145=$15744; + var $15745=$143; + var $15746=$144; + var $15747=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15748=(($15746+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15749=$145; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $140=$15747; + $141=$15748; + $142=$15749; + var $15750=$140; + var $15751=$141; + var $15752=HEAP32[(($15751)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15753=$15750; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15753)>>2)]=$15752; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15754=(($15751+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15755=HEAP32[(($15754)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15756=$15750; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15757=HEAP32[(($15756)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15758=((($15757)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15759=$15758; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15760=HEAP32[(($15759)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15761=$15750; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15762=(($15761+$15760)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15763=$15762; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15763)>>2)]=$15755; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15764=(($15750+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15764)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $15765=$15750; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15766=HEAP32[(($15765)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15767=((($15766)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15768=$15767; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15769=HEAP32[(($15768)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15770=$15750; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15771=(($15770+$15769)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15772=$15771; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $15773=$142; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $138=$15772; + $139=$15773; + var $15774=$138; + var $15775=$15774; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15776=$139; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $15777=$15776; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($15775, $15777) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2647; break; } else { label = 2663; break; } + case 2647: + var $15778=(($15774+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15778)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $15779=(($15774+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($15779)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $15780=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15781=(($15780+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15782=$15781; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15783=(($15746+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $136=$15782; + $137=$15783; + var $15784=$136; + var $15785=$137; + var $15786=HEAP32[(($15785)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15787=$15784; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15787)>>2)]=$15786; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15788=(($15785+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15789=HEAP32[(($15788)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15790=$15784; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15791=HEAP32[(($15790)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15792=((($15791)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15793=$15792; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15794=HEAP32[(($15793)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15795=$15784; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15796=(($15795+$15794)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15797=$15796; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15797)>>2)]=$15789; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $15798=HEAP32[(($15746)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15799=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15799)>>2)]=$15798; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15800=(($15746+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15801=HEAP32[(($15800)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15802=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15803=HEAP32[(($15802)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15804=((($15803)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15805=$15804; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15806=HEAP32[(($15805)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15807=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15808=(($15807+$15806)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15809=$15808; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15809)>>2)]=$15801; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15810=(($15746+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15811=HEAP32[(($15810)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15812=$15745; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15813=(($15812+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15814=$15813; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15814)>>2)]=$15811; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $15815=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15815)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15816=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15817=(($15816+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15818=$15817; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15818)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15819=$15726; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15820=(($15819+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15821=$15820; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15821)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15822=(($15726+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15823=$176; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $171=$15822; + $172=$15823; + var $15824=$171; + var $15825=$172; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $166=$15824; + $167=$15825; + var $15826=$166; + var $15827=$15826; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($15827) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2648; break; } else { label = 2664; break; } + case 2648: + var $15828=$15826; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15828)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15829=(($15826+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $165=$15829; + var $15830=$165; + $164=$15830; + var $15831=$164; + var $15832=$15831; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15833=(($15831)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $163=$15833; + var $15834=$163; + $162=$15834; + var $15835=$162; + var $15836=$15835; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $161=$15836; + var $15837=$161; + var $15838=$15837; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $160=$15838; + var $15839=$160; + var $15840=(($15837)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $159=$15831; + var $15841=$159; + var $15842=(($15841)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $158=$15842; + var $15843=$158; + var $15844=$15843; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $157=$15844; + var $15845=$157; + var $15846=(($15845)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15847=(($15846)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15848=$15847; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15849=(($15848)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i552=$15849; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i553=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2649; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2649: + var $15851=$__i_i_i_i_i_i_i553; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15852=(($15851)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15852) { label = 2650; break; } else { label = 2651; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2650: + var $15854=$__i_i_i_i_i_i_i553; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15855=$__a_i_i_i_i_i_i552; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15856=(($15855+($15854<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15856)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15857=$__i_i_i_i_i_i_i553; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15858=((($15857)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i553=$15858; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2649; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2651: + var $15859=(($15826+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15859)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15860=(($15826+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $15861=$167; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($15860)>>2)]=$15861; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $156=$170; + var $15862=$156; + $155=$15862; + var $15863=$155; + var $15864=$15863; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $15865=(($15863)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $154=$15865; + var $15866=$154; + $153=$15866; + var $15867=$153; + var $15868=$15867; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $152=$15868; + var $15869=$152; + var $15870=$15869; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $151=$15870; + var $15871=$151; + var $15872=(($15869)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $150=$15863; + var $15873=$150; + var $15874=(($15873)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $149=$15874; + var $15875=$149; + var $15876=$15875; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $148=$15876; + var $15877=$148; + var $15878=(($15877)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $15879=(($15878)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15880=$15879; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $15881=(($15880)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i550=$15881; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i551=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2652; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2652: + var $15883=$__i_i_i_i2_i_i_i551; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15884=(($15883)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($15884) { label = 2653; break; } else { label = 2654; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2653: + var $15886=$__i_i_i_i2_i_i_i551; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15887=$__a_i_i_i1_i_i_i550; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15888=(($15887+($15886<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($15888)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $15889=$__i_i_i_i2_i_i_i551; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $15890=((($15889)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i551=$15890; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2652; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2654: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($15826, $170) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2655; break; } else { label = 2657; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2655: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($170) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2670; break; } else { label = 2656; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2656: + var $15893$0 = ___cxa_find_matching_catch(-1, -1); $15893$1 = tempRet0; + var $15894=$15893$0; + $168=$15894; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15895=$15893$1; + $169=$15895; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2659; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2657: + var $15897$0 = ___cxa_find_matching_catch(-1, -1); $15897$1 = tempRet0; + var $15898=$15897$0; + $168=$15898; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $15899=$15897$1; + $169=$15899; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($170) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2658; break; } else { label = 2662; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2658: + label = 2659; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2659: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($15829) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2660; break; } else { label = 2662; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2660: + var $15903=$15826; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($15903) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2661; break; } else { label = 2662; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2661: + var $15905=$168; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15906=$169; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $15907$0=$15905; + var $15907$1=0; + var $15908$0=$15907$0; + var $15908$1=$15906; + var $eh_lpad_body_i558$1 = $15908$1;var $eh_lpad_body_i558$0 = $15908$0;label = 2665; break; + case 2662: + var $15910$0 = ___cxa_find_matching_catch(-1, -1,0); $15910$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2663: + var $15912$0 = ___cxa_find_matching_catch(-1, -1); $15912$1 = tempRet0; + var $15913=$15912$0; + $177=$15913; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15914=$15912$1; + $178=$15914; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2667; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2664: + var $15916$0 = ___cxa_find_matching_catch(-1, -1); $15916$1 = tempRet0; + var $eh_lpad_body_i558$1 = $15916$1;var $eh_lpad_body_i558$0 = $15916$0;label = 2665; break; + case 2665: + var $eh_lpad_body_i558$0; + var $eh_lpad_body_i558$1; + var $15917=$eh_lpad_body_i558$0; + $177=$15917; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15918=$eh_lpad_body_i558$1; + $178=$15918; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $15919=$15726; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($15919, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2666; break; } else { label = 2669; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2666: + label = 2667; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2667: + var $15922=$15726; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15923=(($15922+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15924=$15923; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($15924) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2668; break; } else { label = 2669; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2668: + var $15926=$177; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15927=$178; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $15928$0=$15926; + var $15928$1=0; + var $15929$0=$15928$0; + var $15929$1=$15927; + ___resumeException($15929$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2669: + var $15931$0 = ___cxa_find_matching_catch(-1, -1,0); $15931$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2670: + var $15932=$std_stringstream40; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15933=(($15932+8)|0); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15934=$15933; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $15935 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15934, ((78680)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2671; break; } else { label = 2692; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2671: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2785, ((79320)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2672; break; } else { label = 2692; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2672: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2784, $2785, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2673; break; } else { label = 2693; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2673: + var $15939 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($15935, $2784) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2674; break; } else { label = 2694; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2674: + var $15941 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15939, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2675; break; } else { label = 2694; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2675: + var $15943 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15941, ((79096)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2676; break; } else { label = 2694; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2676: + var $15945 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($15943, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2677; break; } else { label = 2694; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2677: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2784) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2678; break; } else { label = 2693; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2678: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2785) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2679; break; } else { label = 2692; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2679: + var $15949=___cxa_allocate_exception(8); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2787=1; + var $15950=$15949; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $135=$std_stringstream40; + var $15951=$135; + var $15952=(($15951+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2786, $15952) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2680; break; } else { label = 2698; break; } + case 2680: + label = 2681; break; + case 2681: + $134=$2786; + var $15954=$134; + $133=$15954; + var $15955=$133; + $132=$15955; + var $15956=$132; + $131=$15956; + var $15957=$131; + var $15958=(($15957)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $130=$15958; + var $15959=$130; + var $15960=$15959; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $129=$15960; + var $15961=$129; + var $15962=(($15961)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15963=(($15962)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15964=$15963; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15965=(($15964)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15966=$15965; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15967=HEAP8[($15966)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15968=(($15967)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15969=$15968 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $15970=(($15969)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($15970) { label = 2682; break; } else { label = 2683; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2682: + $123=$15956; + var $15972=$123; + var $15973=(($15972)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $122=$15973; + var $15974=$122; + var $15975=$15974; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $121=$15975; + var $15976=$121; + var $15977=(($15976)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15978=(($15977)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15979=$15978; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15980=(($15979+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15981=HEAP32[(($15980)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $15995 = $15981;label = 2684; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2683: + $128=$15956; + var $15983=$128; + var $15984=(($15983)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $127=$15984; + var $15985=$127; + var $15986=$15985; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $126=$15986; + var $15987=$126; + var $15988=(($15987)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $15989=(($15988)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15990=$15989; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15991=(($15990+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $15992=(($15991)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $125=$15992; + var $15993=$125; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $124=$15993; + var $15994=$124; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $15995 = $15994;label = 2684; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2684: + var $15995; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $120=$15995; + var $15996=$120; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($15950, $15996) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2685; break; } else { label = 2699; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2685: + $2787=0; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($15949, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2699; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2786) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2686; break; } else { label = 2698; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2686: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream40); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2706; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2687: + var $16001$0 = ___cxa_find_matching_catch(-1, -1); $16001$1 = tempRet0; + var $16002=$16001$0; + $2542=$16002; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16003=$16001$1; + $2543=$16003; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2690; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2688: + var $16005$0 = ___cxa_find_matching_catch(-1, -1); $16005$1 = tempRet0; + var $16006=$16005$0; + $2542=$16006; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16007=$16005$1; + $2543=$16007; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2782) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2689; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2689: + label = 2690; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2690: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2783) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2691; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2691: + label = 2840; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2692: + var $16012$0 = ___cxa_find_matching_catch(-1, -1); $16012$1 = tempRet0; + var $16013=$16012$0; + $2542=$16013; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16014=$16012$1; + $2543=$16014; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2704; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2693: + var $16016$0 = ___cxa_find_matching_catch(-1, -1); $16016$1 = tempRet0; + var $16017=$16016$0; + $2542=$16017; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16018=$16016$1; + $2543=$16018; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2696; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2694: + var $16020$0 = ___cxa_find_matching_catch(-1, -1); $16020$1 = tempRet0; + var $16021=$16020$0; + $2542=$16021; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16022=$16020$1; + $2543=$16022; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2784) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2695; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2695: + label = 2696; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2696: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2785) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2697; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2697: + label = 2704; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2698: + var $16027$0 = ___cxa_find_matching_catch(-1, -1); $16027$1 = tempRet0; + var $16028=$16027$0; + $2542=$16028; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16029=$16027$1; + $2543=$16029; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2701; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2699: + var $16031$0 = ___cxa_find_matching_catch(-1, -1); $16031$1 = tempRet0; + var $16032=$16031$0; + $2542=$16032; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16033=$16031$1; + $2543=$16033; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2786) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2700; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2700: + label = 2701; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2701: + var $16036=$2787; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($16036) { label = 2702; break; } else { label = 2703; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2702: + ___cxa_free_exception($15949); //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2703; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2703: + label = 2704; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2704: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream40) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2705; break; } else { label = 2841; break; } //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2705: + label = 2840; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2706: + label = 2707; break; //@line 182 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2707: + label = 2708; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2708: + __ZN6StringC1EPKc($2789, ((78400)|0)); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2788, $2789, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2709; break; } else { label = 2753; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2709: + var $16045 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2788, ((78240)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2710; break; } else { label = 2754; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2710: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2788) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2711; break; } else { label = 2753; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2711: + __ZN6StringD1Ev($2789); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($16045) { label = 2712; break; } else { label = 2772; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2712: + $116=$std_stringstream41; + $117=24; + var $16049=$116; + var $16050=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16051=(($16050+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16052=$16051; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $115=$16052; + var $16053=$115; + var $16054=$16053; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $114=$16054; + var $16055=$114; + var $16056=$16055; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16056)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $16057=$16053; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16057)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $16058=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16058)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16059=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16060=(($16059+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16061=$16060; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16061)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16062=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16063=(($16062+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16064=$16063; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16064)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16065=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16066=(($16049+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16067=$16066; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $84=$16065; + $85=((109796)|0); + $86=$16067; + var $16068=$84; + var $16069=$85; + var $16070=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16071=(($16069+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16072=$86; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $81=$16070; + $82=$16071; + $83=$16072; + var $16073=$81; + var $16074=$82; + var $16075=HEAP32[(($16074)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16076=$16073; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16076)>>2)]=$16075; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16077=(($16074+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16078=HEAP32[(($16077)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16079=$16073; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16080=HEAP32[(($16079)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16081=((($16080)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16082=$16081; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16083=HEAP32[(($16082)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16084=$16073; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16085=(($16084+$16083)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16086=$16085; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16086)>>2)]=$16078; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16087=(($16073+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16087)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16088=$16073; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16089=HEAP32[(($16088)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16090=((($16089)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16091=$16090; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16092=HEAP32[(($16091)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16093=$16073; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16094=(($16093+$16092)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16095=$16094; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16096=$83; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $79=$16095; + $80=$16096; + var $16097=$79; + var $16098=$16097; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $16099=$80; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $16100=$16099; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($16098, $16100) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2713; break; } else { label = 2729; break; } + case 2713: + var $16101=(($16097+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16101)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $16102=(($16097+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16102)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $16103=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16104=(($16103+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16105=$16104; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16106=(($16069+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $77=$16105; + $78=$16106; + var $16107=$77; + var $16108=$78; + var $16109=HEAP32[(($16108)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16110=$16107; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16110)>>2)]=$16109; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16111=(($16108+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16112=HEAP32[(($16111)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16113=$16107; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16114=HEAP32[(($16113)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16115=((($16114)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16116=$16115; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16117=HEAP32[(($16116)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16118=$16107; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16119=(($16118+$16117)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16120=$16119; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16120)>>2)]=$16112; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16121=HEAP32[(($16069)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16122=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16122)>>2)]=$16121; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16123=(($16069+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16124=HEAP32[(($16123)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16125=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16126=HEAP32[(($16125)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16127=((($16126)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16128=$16127; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16129=HEAP32[(($16128)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16130=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16131=(($16130+$16129)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16132=$16131; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16132)>>2)]=$16124; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16133=(($16069+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16134=HEAP32[(($16133)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16135=$16068; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16136=(($16135+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16137=$16136; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16137)>>2)]=$16134; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16138=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16138)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16139=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16140=(($16139+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16141=$16140; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16141)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16142=$16049; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16143=(($16142+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16144=$16143; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16144)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16145=(($16049+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16146=$117; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $112=$16145; + $113=$16146; + var $16147=$112; + var $16148=$113; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $107=$16147; + $108=$16148; + var $16149=$107; + var $16150=$16149; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($16150) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2714; break; } else { label = 2730; break; } + case 2714: + var $16151=$16149; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16151)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16152=(($16149+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $106=$16152; + var $16153=$106; + $105=$16153; + var $16154=$105; + var $16155=$16154; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $16156=(($16154)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $104=$16156; + var $16157=$104; + $103=$16157; + var $16158=$103; + var $16159=$16158; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $102=$16159; + var $16160=$102; + var $16161=$16160; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $101=$16161; + var $16162=$101; + var $16163=(($16160)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $100=$16154; + var $16164=$100; + var $16165=(($16164)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $99=$16165; + var $16166=$99; + var $16167=$16166; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $98=$16167; + var $16168=$98; + var $16169=(($16168)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $16170=(($16169)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16171=$16170; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16172=(($16171)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i565=$16172; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i566=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2715; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2715: + var $16174=$__i_i_i_i_i_i_i566; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16175=(($16174)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($16175) { label = 2716; break; } else { label = 2717; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2716: + var $16177=$__i_i_i_i_i_i_i566; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16178=$__a_i_i_i_i_i_i565; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16179=(($16178+($16177<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($16179)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16180=$__i_i_i_i_i_i_i566; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16181=((($16180)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i566=$16181; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2715; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2717: + var $16182=(($16149+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16182)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16183=(($16149+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16184=$108; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16183)>>2)]=$16184; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $97=$111; + var $16185=$97; + $96=$16185; + var $16186=$96; + var $16187=$16186; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $16188=(($16186)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $95=$16188; + var $16189=$95; + $94=$16189; + var $16190=$94; + var $16191=$16190; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $93=$16191; + var $16192=$93; + var $16193=$16192; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $92=$16193; + var $16194=$92; + var $16195=(($16192)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $91=$16186; + var $16196=$91; + var $16197=(($16196)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $90=$16197; + var $16198=$90; + var $16199=$16198; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $89=$16199; + var $16200=$89; + var $16201=(($16200)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $16202=(($16201)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16203=$16202; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16204=(($16203)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i563=$16204; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i564=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2718; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2718: + var $16206=$__i_i_i_i2_i_i_i564; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16207=(($16206)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($16207) { label = 2719; break; } else { label = 2720; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2719: + var $16209=$__i_i_i_i2_i_i_i564; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16210=$__a_i_i_i1_i_i_i563; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16211=(($16210+($16209<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($16211)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16212=$__i_i_i_i2_i_i_i564; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16213=((($16212)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i564=$16213; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2718; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2720: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($16149, $111) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2721; break; } else { label = 2723; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2721: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($111) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2736; break; } else { label = 2722; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2722: + var $16216$0 = ___cxa_find_matching_catch(-1, -1); $16216$1 = tempRet0; + var $16217=$16216$0; + $109=$16217; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $16218=$16216$1; + $110=$16218; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2725; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2723: + var $16220$0 = ___cxa_find_matching_catch(-1, -1); $16220$1 = tempRet0; + var $16221=$16220$0; + $109=$16221; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $16222=$16220$1; + $110=$16222; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($111) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2724; break; } else { label = 2728; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2724: + label = 2725; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2725: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($16152) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2726; break; } else { label = 2728; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2726: + var $16226=$16149; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($16226) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2727; break; } else { label = 2728; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2727: + var $16228=$109; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $16229=$110; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $16230$0=$16228; + var $16230$1=0; + var $16231$0=$16230$0; + var $16231$1=$16229; + var $eh_lpad_body_i571$1 = $16231$1;var $eh_lpad_body_i571$0 = $16231$0;label = 2731; break; + case 2728: + var $16233$0 = ___cxa_find_matching_catch(-1, -1,0); $16233$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2729: + var $16235$0 = ___cxa_find_matching_catch(-1, -1); $16235$1 = tempRet0; + var $16236=$16235$0; + $118=$16236; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16237=$16235$1; + $119=$16237; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2733; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2730: + var $16239$0 = ___cxa_find_matching_catch(-1, -1); $16239$1 = tempRet0; + var $eh_lpad_body_i571$1 = $16239$1;var $eh_lpad_body_i571$0 = $16239$0;label = 2731; break; + case 2731: + var $eh_lpad_body_i571$0; + var $eh_lpad_body_i571$1; + var $16240=$eh_lpad_body_i571$0; + $118=$16240; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16241=$eh_lpad_body_i571$1; + $119=$16241; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16242=$16049; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($16242, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2732; break; } else { label = 2735; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2732: + label = 2733; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2733: + var $16245=$16049; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16246=(($16245+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16247=$16246; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($16247) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2734; break; } else { label = 2735; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2734: + var $16249=$118; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16250=$119; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16251$0=$16249; + var $16251$1=0; + var $16252$0=$16251$0; + var $16252$1=$16250; + ___resumeException($16252$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2735: + var $16254$0 = ___cxa_find_matching_catch(-1, -1,0); $16254$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2736: + var $16255=$std_stringstream41; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16256=(($16255+8)|0); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16257=$16256; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16258 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16257, ((77520)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2737; break; } else { label = 2758; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2737: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2791, ((78400)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2738; break; } else { label = 2758; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2738: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2790, $2791, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2739; break; } else { label = 2759; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2739: + var $16262 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($16258, $2790) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2740; break; } else { label = 2760; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2740: + var $16264 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16262, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2741; break; } else { label = 2760; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2741: + var $16266 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16264, ((78240)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2742; break; } else { label = 2760; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2742: + var $16268 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16266, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2743; break; } else { label = 2760; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2743: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2790) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2744; break; } else { label = 2759; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2744: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2791) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2745; break; } else { label = 2758; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2745: + var $16272=___cxa_allocate_exception(8); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2793=1; + var $16273=$16272; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $76=$std_stringstream41; + var $16274=$76; + var $16275=(($16274+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2792, $16275) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2746; break; } else { label = 2764; break; } + case 2746: + label = 2747; break; + case 2747: + $75=$2792; + var $16277=$75; + $74=$16277; + var $16278=$74; + $73=$16278; + var $16279=$73; + $72=$16279; + var $16280=$72; + var $16281=(($16280)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $71=$16281; + var $16282=$71; + var $16283=$16282; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $70=$16283; + var $16284=$70; + var $16285=(($16284)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16286=(($16285)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16287=$16286; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16288=(($16287)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16289=$16288; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16290=HEAP8[($16289)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16291=(($16290)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16292=$16291 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16293=(($16292)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($16293) { label = 2748; break; } else { label = 2749; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2748: + $64=$16279; + var $16295=$64; + var $16296=(($16295)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $63=$16296; + var $16297=$63; + var $16298=$16297; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $62=$16298; + var $16299=$62; + var $16300=(($16299)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16301=(($16300)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16302=$16301; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16303=(($16302+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16304=HEAP32[(($16303)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16318 = $16304;label = 2750; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2749: + $69=$16279; + var $16306=$69; + var $16307=(($16306)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $68=$16307; + var $16308=$68; + var $16309=$16308; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $67=$16309; + var $16310=$67; + var $16311=(($16310)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16312=(($16311)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16313=$16312; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16314=(($16313+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16315=(($16314)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $66=$16315; + var $16316=$66; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $65=$16316; + var $16317=$65; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $16318 = $16317;label = 2750; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2750: + var $16318; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $61=$16318; + var $16319=$61; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($16273, $16319) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2751; break; } else { label = 2765; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2751: + $2793=0; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($16272, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2765; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2792) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2752; break; } else { label = 2764; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2752: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream41); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2772; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2753: + var $16324$0 = ___cxa_find_matching_catch(-1, -1); $16324$1 = tempRet0; + var $16325=$16324$0; + $2542=$16325; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16326=$16324$1; + $2543=$16326; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2756; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2754: + var $16328$0 = ___cxa_find_matching_catch(-1, -1); $16328$1 = tempRet0; + var $16329=$16328$0; + $2542=$16329; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16330=$16328$1; + $2543=$16330; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2788) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2755; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2755: + label = 2756; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2756: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2789) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2757; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2757: + label = 2840; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2758: + var $16335$0 = ___cxa_find_matching_catch(-1, -1); $16335$1 = tempRet0; + var $16336=$16335$0; + $2542=$16336; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16337=$16335$1; + $2543=$16337; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2770; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2759: + var $16339$0 = ___cxa_find_matching_catch(-1, -1); $16339$1 = tempRet0; + var $16340=$16339$0; + $2542=$16340; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16341=$16339$1; + $2543=$16341; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2762; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2760: + var $16343$0 = ___cxa_find_matching_catch(-1, -1); $16343$1 = tempRet0; + var $16344=$16343$0; + $2542=$16344; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16345=$16343$1; + $2543=$16345; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2790) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2761; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2761: + label = 2762; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2762: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2791) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2763; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2763: + label = 2770; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2764: + var $16350$0 = ___cxa_find_matching_catch(-1, -1); $16350$1 = tempRet0; + var $16351=$16350$0; + $2542=$16351; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16352=$16350$1; + $2543=$16352; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2767; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2765: + var $16354$0 = ___cxa_find_matching_catch(-1, -1); $16354$1 = tempRet0; + var $16355=$16354$0; + $2542=$16355; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16356=$16354$1; + $2543=$16356; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2792) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2766; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2766: + label = 2767; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2767: + var $16359=$2793; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($16359) { label = 2768; break; } else { label = 2769; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2768: + ___cxa_free_exception($16272); //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2769; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2769: + label = 2770; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2770: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream41) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2771; break; } else { label = 2841; break; } //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2771: + label = 2840; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2772: + label = 2773; break; //@line 184 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2773: + label = 2774; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2774: + __ZN6StringC1EPKc($2795, ((77208)|0)); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2794, $2795, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2775; break; } else { label = 2819; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2775: + var $16368 = (function() { try { __THREW__ = 0; return __ZNK6StringneEPKc($2794, ((76984)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2776; break; } else { label = 2820; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2776: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2794) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2777; break; } else { label = 2819; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2777: + __ZN6StringD1Ev($2795); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($16368) { label = 2778; break; } else { label = 2838; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2778: + $57=$std_stringstream42; + $58=24; + var $16372=$57; + var $16373=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16374=(($16373+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16375=$16374; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $56=$16375; + var $16376=$56; + var $16377=$16376; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + $55=$16377; + var $16378=$55; + var $16379=$16378; //@line 328 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16379)>>2)]=((107288)|0); //@line 328 "G:/emscripten/system/include/libcxx/ios" + var $16380=$16376; //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16380)>>2)]=((106832)|0); //@line 622 "G:/emscripten/system/include/libcxx/iosfwd" + var $16381=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16381)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16382=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16383=(($16382+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16384=$16383; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16384)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16385=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16386=(($16385+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16387=$16386; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16387)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16388=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16389=(($16372+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16390=$16389; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $25=$16388; + $26=((109796)|0); + $27=$16390; + var $16391=$25; + var $16392=$26; + var $16393=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16394=(($16392+4)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16395=$27; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $22=$16393; + $23=$16394; + $24=$16395; + var $16396=$22; + var $16397=$23; + var $16398=HEAP32[(($16397)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16399=$16396; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16399)>>2)]=$16398; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16400=(($16397+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16401=HEAP32[(($16400)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16402=$16396; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16403=HEAP32[(($16402)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16404=((($16403)-(12))|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16405=$16404; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16406=HEAP32[(($16405)>>2)]; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16407=$16396; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16408=(($16407+$16406)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16409=$16408; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16409)>>2)]=$16401; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16410=(($16396+4)|0); //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16410)>>2)]=0; //@line 293 "G:/emscripten/system/include/libcxx/iosfwd" + var $16411=$16396; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16412=HEAP32[(($16411)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16413=((($16412)-(12))|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16414=$16413; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16415=HEAP32[(($16414)>>2)]; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16416=$16396; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16417=(($16416+$16415)|0); //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16418=$16417; //@line 294 "G:/emscripten/system/include/libcxx/istream" + var $16419=$24; //@line 294 "G:/emscripten/system/include/libcxx/istream" + $20=$16418; + $21=$16419; + var $16420=$20; + var $16421=$16420; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $16422=$21; //@line 659 "G:/emscripten/system/include/libcxx/ios" + var $16423=$16422; //@line 659 "G:/emscripten/system/include/libcxx/ios" + (function() { try { __THREW__ = 0; return __ZNSt3__18ios_base4initEPv($16421, $16423) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2779; break; } else { label = 2795; break; } + case 2779: + var $16424=(($16420+72)|0); //@line 660 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16424)>>2)]=0; //@line 660 "G:/emscripten/system/include/libcxx/ios" + var $16425=(($16420+76)|0); //@line 661 "G:/emscripten/system/include/libcxx/ios" + HEAP32[(($16425)>>2)]=-1; //@line 661 "G:/emscripten/system/include/libcxx/ios" + var $16426=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16427=(($16426+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16428=$16427; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16429=(($16392+12)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + $18=$16428; + $19=$16429; + var $16430=$18; + var $16431=$19; + var $16432=HEAP32[(($16431)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16433=$16430; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16433)>>2)]=$16432; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16434=(($16431+4)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16435=HEAP32[(($16434)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16436=$16430; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16437=HEAP32[(($16436)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16438=((($16437)-(12))|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16439=$16438; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16440=HEAP32[(($16439)>>2)]; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16441=$16430; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16442=(($16441+$16440)|0); //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16443=$16442; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16443)>>2)]=$16435; //@line 205 "G:/emscripten/system/include/libcxx/iosfwd" + var $16444=HEAP32[(($16392)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16445=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16445)>>2)]=$16444; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16446=(($16392+20)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16447=HEAP32[(($16446)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16448=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16449=HEAP32[(($16448)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16450=((($16449)-(12))|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16451=$16450; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16452=HEAP32[(($16451)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16453=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16454=(($16453+$16452)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16455=$16454; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16455)>>2)]=$16447; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16456=(($16392+24)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16457=HEAP32[(($16456)>>2)]; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16458=$16391; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16459=(($16458+8)|0); //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16460=$16459; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16460)>>2)]=$16457; //@line 1487 "G:/emscripten/system/include/libcxx/iosfwd" + var $16461=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16461)>>2)]=((108180)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16462=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16463=(($16462+64)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16464=$16463; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16464)>>2)]=((108220)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16465=$16372; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16466=(($16465+8)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16467=$16466; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16467)>>2)]=((108200)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16468=(($16372+12)|0); //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16469=$58; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + $53=$16468; + $54=$16469; + var $16470=$53; + var $16471=$54; //@line 244 "G:/emscripten/system/include/libcxx/iosfwd" + $48=$16470; + $49=$16471; + var $16472=$48; + var $16473=$16472; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEEC2Ev($16473) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2780; break; } else { label = 2796; break; } + case 2780: + var $16474=$16472; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16474)>>2)]=((108360)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16475=(($16472+32)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $47=$16475; + var $16476=$47; + $46=$16476; + var $16477=$46; + var $16478=$16477; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $16479=(($16477)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $45=$16479; + var $16480=$45; + $44=$16480; + var $16481=$44; + var $16482=$16481; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $43=$16482; + var $16483=$43; + var $16484=$16483; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $42=$16484; + var $16485=$42; + var $16486=(($16483)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $41=$16477; + var $16487=$41; + var $16488=(($16487)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $40=$16488; + var $16489=$40; + var $16490=$16489; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $39=$16490; + var $16491=$39; + var $16492=(($16491)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $16493=(($16492)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16494=$16493; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16495=(($16494)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i_i_i_i578=$16495; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i579=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2781; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2781: + var $16497=$__i_i_i_i_i_i_i579; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16498=(($16497)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($16498) { label = 2782; break; } else { label = 2783; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2782: + var $16500=$__i_i_i_i_i_i_i579; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16501=$__a_i_i_i_i_i_i578; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16502=(($16501+($16500<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($16502)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16503=$__i_i_i_i_i_i_i579; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16504=((($16503)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i_i_i_i579=$16504; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2781; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2783: + var $16505=(($16472+44)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16505)>>2)]=0; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16506=(($16472+48)|0); //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + var $16507=$49; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + HEAP32[(($16506)>>2)]=$16507; //@line 242 "G:/emscripten/system/include/libcxx/iosfwd" + $38=$52; + var $16508=$38; + $37=$16508; + var $16509=$37; + var $16510=$16509; //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + var $16511=(($16509)|0); //@line 1794 "G:/emscripten/system/include/libcxx/iosfwd" + $36=$16511; + var $16512=$36; + $35=$16512; + var $16513=$35; + var $16514=$16513; //@line 2374 "G:/emscripten/system/include/libcxx/memory" + $34=$16514; + var $16515=$34; + var $16516=$16515; //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $33=$16516; + var $16517=$33; + var $16518=(($16515)|0); //@line 2187 "G:/emscripten/system/include/libcxx/memory" + $32=$16509; + var $16519=$32; + var $16520=(($16519)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $31=$16520; + var $16521=$31; + var $16522=$16521; //@line 2432 "G:/emscripten/system/include/libcxx/memory" + $30=$16522; + var $16523=$30; + var $16524=(($16523)|0); //@line 2253 "G:/emscripten/system/include/libcxx/memory" + var $16525=(($16524)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16526=$16525; //@line 1610 "G:/emscripten/system/include/libcxx/string" + var $16527=(($16526)|0); //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__a_i_i_i1_i_i_i576=$16527; //@line 1610 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i577=0; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2784; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2784: + var $16529=$__i_i_i_i2_i_i_i577; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16530=(($16529)>>>(0)) < 3; //@line 1611 "G:/emscripten/system/include/libcxx/string" + if ($16530) { label = 2785; break; } else { label = 2786; break; } //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2785: + var $16532=$__i_i_i_i2_i_i_i577; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16533=$__a_i_i_i1_i_i_i576; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16534=(($16533+($16532<<2))|0); //@line 1612 "G:/emscripten/system/include/libcxx/string" + HEAP32[(($16534)>>2)]=0; //@line 1612 "G:/emscripten/system/include/libcxx/string" + var $16535=$__i_i_i_i2_i_i_i577; //@line 1611 "G:/emscripten/system/include/libcxx/string" + var $16536=((($16535)+(1))|0); //@line 1611 "G:/emscripten/system/include/libcxx/string" + $__i_i_i_i2_i_i_i577=$16536; //@line 1611 "G:/emscripten/system/include/libcxx/string" + label = 2784; break; //@line 1611 "G:/emscripten/system/include/libcxx/string" + case 2786: + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strERKNS_12basic_stringIcS2_S4_EE($16472, $52) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2787; break; } else { label = 2789; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2787: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($52) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2802; break; } else { label = 2788; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2788: + var $16539$0 = ___cxa_find_matching_catch(-1, -1); $16539$1 = tempRet0; + var $16540=$16539$0; + $50=$16540; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $16541=$16539$1; + $51=$16541; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + label = 2791; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2789: + var $16543$0 = ___cxa_find_matching_catch(-1, -1); $16543$1 = tempRet0; + var $16544=$16543$0; + $50=$16544; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + var $16545=$16543$1; + $51=$16545; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($52) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2790; break; } else { label = 2794; break; } //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2790: + label = 2791; break; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2791: + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($16475) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2792; break; } else { label = 2794; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2792: + var $16549=$16472; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__115basic_streambufIcNS_11char_traitsIcEEED2Ev($16549) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2793; break; } else { label = 2794; break; } //@line 244 "G:/emscripten/system/include/libcxx/sstream" + case 2793: + var $16551=$50; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $16552=$51; //@line 244 "G:/emscripten/system/include/libcxx/sstream" + var $16553$0=$16551; + var $16553$1=0; + var $16554$0=$16553$0; + var $16554$1=$16552; + var $eh_lpad_body_i584$1 = $16554$1;var $eh_lpad_body_i584$0 = $16554$0;label = 2797; break; + case 2794: + var $16556$0 = ___cxa_find_matching_catch(-1, -1,0); $16556$1 = tempRet0; + __ZSt9terminatev(); //@line 243 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 243 "G:/emscripten/system/include/libcxx/sstream" + case 2795: + var $16558$0 = ___cxa_find_matching_catch(-1, -1); $16558$1 = tempRet0; + var $16559=$16558$0; + $59=$16559; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16560=$16558$1; + $60=$16560; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + label = 2799; break; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + case 2796: + var $16562$0 = ___cxa_find_matching_catch(-1, -1); $16562$1 = tempRet0; + var $eh_lpad_body_i584$1 = $16562$1;var $eh_lpad_body_i584$0 = $16562$0;label = 2797; break; + case 2797: + var $eh_lpad_body_i584$0; + var $eh_lpad_body_i584$1; + var $16563=$eh_lpad_body_i584$0; + $59=$16563; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16564=$eh_lpad_body_i584$1; + $60=$16564; //@line 893 "G:/emscripten/system/include/libcxx/iosfwd" + var $16565=$16372; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__114basic_iostreamIcNS_11char_traitsIcEEED2Ev($16565, ((109796)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2798; break; } else { label = 2801; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2798: + label = 2799; break; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2799: + var $16568=$16372; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16569=(($16568+64)|0); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16570=$16569; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNSt3__19basic_iosIcNS_11char_traitsIcEEED2Ev($16570) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2800; break; } else { label = 2801; break; } //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2800: + var $16572=$59; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16573=$60; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + var $16574$0=$16572; + var $16574$1=0; + var $16575$0=$16574$0; + var $16575$1=$16573; + ___resumeException($16575$0) //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2801: + var $16577$0 = ___cxa_find_matching_catch(-1, -1,0); $16577$1 = tempRet0; + __ZSt9terminatev(); //@line 894 "G:/emscripten/system/include/libcxx/sstream" + throw "Reached an unreachable!"; //@line 894 "G:/emscripten/system/include/libcxx/sstream" + case 2802: + var $16578=$std_stringstream42; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16579=(($16578+8)|0); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16580=$16579; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16581 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16580, ((76768)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2803; break; } else { label = 2824; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2803: + (function() { try { __THREW__ = 0; return __ZN6StringC1EPKc($2797, ((77208)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2804; break; } else { label = 2824; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2804: + (function() { try { __THREW__ = 0; return __ZN4File13NormalizePathERK6Stringc($2796, $2797, 47) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2805; break; } else { label = 2825; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2805: + var $16585 = (function() { try { __THREW__ = 0; return __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK6String($16581, $2796) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2806; break; } else { label = 2826; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2806: + var $16587 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16585, ((66832)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2807; break; } else { label = 2826; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2807: + var $16589 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16587, ((76984)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2808; break; } else { label = 2826; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2808: + var $16591 = (function() { try { __THREW__ = 0; return __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc($16589, ((64456)|0)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2809; break; } else { label = 2826; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2809: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2796) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2810; break; } else { label = 2825; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2810: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2797) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2811; break; } else { label = 2824; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2811: + var $16595=___cxa_allocate_exception(8); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $2799=1; + var $16596=$16595; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + $17=$std_stringstream42; + var $16597=$17; + var $16598=(($16597+12)|0); //@line 958 "G:/emscripten/system/include/libcxx/sstream" + (function() { try { __THREW__ = 0; return __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv($2798, $16598) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2812; break; } else { label = 2830; break; } + case 2812: + label = 2813; break; + case 2813: + $16=$2798; + var $16600=$16; + $15=$16600; + var $16601=$15; + $14=$16601; + var $16602=$14; + $13=$16602; + var $16603=$13; + var $16604=(($16603)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + $12=$16604; + var $16605=$12; + var $16606=$16605; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $11=$16606; + var $16607=$11; + var $16608=(($16607)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16609=(($16608)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16610=$16609; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16611=(($16610)|0); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16612=$16611; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16613=HEAP8[($16612)]; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16614=(($16613)&(255)); //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16615=$16614 & 1; //@line 1520 "G:/emscripten/system/include/libcxx/string" + var $16616=(($16615)|(0))!=0; //@line 1520 "G:/emscripten/system/include/libcxx/string" + if ($16616) { label = 2814; break; } else { label = 2815; break; } //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2814: + $5=$16602; + var $16618=$5; + var $16619=(($16618)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + $4=$16619; + var $16620=$4; + var $16621=$16620; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $3=$16621; + var $16622=$3; + var $16623=(($16622)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16624=(($16623)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16625=$16624; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16626=(($16625+8)|0); //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16627=HEAP32[(($16626)>>2)]; //@line 1593 "G:/emscripten/system/include/libcxx/string" + var $16641 = $16627;label = 2816; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2815: + $10=$16602; + var $16629=$10; + var $16630=(($16629)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $9=$16630; + var $16631=$9; + var $16632=$16631; //@line 2433 "G:/emscripten/system/include/libcxx/memory" + $8=$16632; + var $16633=$8; + var $16634=(($16633)|0); //@line 2254 "G:/emscripten/system/include/libcxx/memory" + var $16635=(($16634)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16636=$16635; //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16637=(($16636+1)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + var $16638=(($16637)|0); //@line 1599 "G:/emscripten/system/include/libcxx/string" + $7=$16638; + var $16639=$7; //@line 960 "G:/emscripten/system/include/libcxx/memory" + $6=$16639; + var $16640=$6; //@line 627 "G:/emscripten/system/include/libcxx/memory" + var $16641 = $16640;label = 2816; break; //@line 1605 "G:/emscripten/system/include/libcxx/string" + case 2816: + var $16641; //@line 1605 "G:/emscripten/system/include/libcxx/string" + $2=$16641; + var $16642=$2; //@line 1086 "G:/emscripten/system/include/libcxx/memory" + (function() { try { __THREW__ = 0; return __ZNSt13runtime_errorC2EPKc($16596, $16642) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2817; break; } else { label = 2831; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2817: + $2799=0; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return ___cxa_throw($16595, 113416, (584)) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2842; break; } else { label = 2831; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2798) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2818; break; } else { label = 2830; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2818: + __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream42); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2838; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2819: + var $16647$0 = ___cxa_find_matching_catch(-1, -1); $16647$1 = tempRet0; + var $16648=$16647$0; + $2542=$16648; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16649=$16647$1; + $2543=$16649; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2822; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2820: + var $16651$0 = ___cxa_find_matching_catch(-1, -1); $16651$1 = tempRet0; + var $16652=$16651$0; + $2542=$16652; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16653=$16651$1; + $2543=$16653; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2794) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2821; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2821: + label = 2822; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2822: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2795) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2823; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2823: + label = 2840; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2824: + var $16658$0 = ___cxa_find_matching_catch(-1, -1); $16658$1 = tempRet0; + var $16659=$16658$0; + $2542=$16659; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16660=$16658$1; + $2543=$16660; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2836; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2825: + var $16662$0 = ___cxa_find_matching_catch(-1, -1); $16662$1 = tempRet0; + var $16663=$16662$0; + $2542=$16663; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16664=$16662$1; + $2543=$16664; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2828; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2826: + var $16666$0 = ___cxa_find_matching_catch(-1, -1); $16666$1 = tempRet0; + var $16667=$16666$0; + $2542=$16667; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16668=$16666$1; + $2543=$16668; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2796) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2827; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2827: + label = 2828; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2828: + (function() { try { __THREW__ = 0; return __ZN6StringD1Ev($2797) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2829; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2829: + label = 2836; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2830: + var $16673$0 = ___cxa_find_matching_catch(-1, -1); $16673$1 = tempRet0; + var $16674=$16673$0; + $2542=$16674; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16675=$16673$1; + $2543=$16675; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2833; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2831: + var $16677$0 = ___cxa_find_matching_catch(-1, -1); $16677$1 = tempRet0; + var $16678=$16677$0; + $2542=$16678; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16679=$16677$1; + $2543=$16679; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + (function() { try { __THREW__ = 0; return __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($2798) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2832; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2832: + label = 2833; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2833: + var $16682=$2799; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + if ($16682) { label = 2834; break; } else { label = 2835; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2834: + ___cxa_free_exception($16595); //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + label = 2835; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2835: + label = 2836; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2836: + (function() { try { __THREW__ = 0; return __ZNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev($std_stringstream42) } catch(e) { if (typeof e != "number") throw e; if (ABORT) throw e; __THREW__ = 1; return null } })();if (!__THREW__) { label = 2837; break; } else { label = 2841; break; } //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2837: + label = 2840; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2838: + label = 2839; break; //@line 185 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2839: + STACKTOP = sp; + return; //@line 186 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2840: + var $16690=$2542; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16691=$2543; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + var $16692$0=$16690; + var $16692$1=0; + var $16693$0=$16692$0; + var $16693$1=$16691; + ___resumeException($16693$0) //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2841: + var $16695$0 = ___cxa_find_matching_catch(-1, -1,0); $16695$1 = tempRet0; + __ZSt9terminatev(); //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + throw "Reached an unreachable!"; //@line 136 "G:/gfxapiSlave/win7-emcc/GraphicsEngine/../CodeLib/src/../tests/FileTests.cpp" + case 2842: + throw "Reached an unreachable!"; + default: assert(0, "bad label: " + label); + } + }} + +// Just stub out the few variables that the above function refers to. +STACKTOP=0; +function assert(){} +STACK_MAX=10241024; +function __ZN6StringC1EPKc(){} +function __ZN4File13NormalizePathERK6Stringc(){} +function __ZNK6StringneEPKc(){} +function __ZN6StringD1Ev(){} + +// Call the function to crash. +__Z30TestFunc_TestFileNormalizePathR4Test(0); + +</script> +</html> diff --git a/js/xpconnect/crashtests/938297.html b/js/xpconnect/crashtests/938297.html new file mode 100644 index 0000000000..bd2018659b --- /dev/null +++ b/js/xpconnect/crashtests/938297.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<script> + +function boom() +{ + var frame = document.getElementById("f"); + var frameWin = frame.contentWindow; + var frameDoc = frame.contentDocument; + frameDoc.write("<body>"); + frameDoc.close(); + frameWin.history.pushState(null, 'title', 'pushState47.html'); + document.body.removeChild(frame); + frameWin.history.state; +} + +</script> +</head> +<body onload="boom();"> +<iframe id="f" src="data:text/html,1"></iframe> +</body> +</html> diff --git a/js/xpconnect/crashtests/977538.html b/js/xpconnect/crashtests/977538.html new file mode 100644 index 0000000000..9bfaf084f7 --- /dev/null +++ b/js/xpconnect/crashtests/977538.html @@ -0,0 +1,20 @@ +<script>
+function f() {
+ var buffer = new Uint8Array(8);
+
+ for (var i=0; i<100; i++) {}
+
+ buffer[0] = 0xff;
+ buffer[1] = 0xff;
+ buffer[2] = 0xff;
+ buffer[3] = 0xff;
+ buffer[4] = 0xff;
+ buffer[5] = 0xff;
+ buffer[6] = 0x0f;
+ buffer[7] = 0x00;
+
+ var view = new DataView(buffer.buffer);
+ view.getFloat64(0);
+}
+f();
+</script>
diff --git a/js/xpconnect/crashtests/crashtests.list b/js/xpconnect/crashtests/crashtests.list new file mode 100644 index 0000000000..129c34db27 --- /dev/null +++ b/js/xpconnect/crashtests/crashtests.list @@ -0,0 +1,55 @@ +load 117307-1.html +load 193710.html +pref(extensions.InstallTrigger.enabled,true) pref(extensions.InstallTriggerImpl.enabled,true) load 290162-1.html +load 326615-1.html +load 328553-1.html +load 346258-1.html +load 346512-1.xhtml +load 382133-1.html +load 386680-1.html +load 394810-1.html +load 400349-1.html +load 403356-1.html +load 418139-1.svg +load 420513-1.html +load 453935-1.html +load 467693-1.html +load 468552-1.html +load 475185-1.html +load 475291-1.html +load 503286-1.html +load 504000-1.html +load 509075-1.html +load 512815-1.html +load 515726-1.html +load 545291-1.html +load 558979.html +load 601284-1.html +load 603146-1.html +load 603858-1.html +load 608963.html +pref(extensions.InstallTrigger.enabled,true) pref(extensions.InstallTriggerImpl.enabled,true) load 616930-1.html +# This test has jit-related infinite recursion, which is slow enough to cause +# timeouts on mac. See bug 908895. +skip-if(cocoaWidget&&isDebugBuild) load 639737-1.html +pref(extensions.InstallTrigger.enabled,true) pref(extensions.InstallTriggerImpl.enabled,true) load 648206-1.html +load 720305-1.html +load 721910.html +load 723465.html +load 732870.html +load 751995.html +load 761831.html +asserts(0-1) load 752038.html # We may hit bug 645229 here. +load 753162.html +load 754311.html +asserts(0-1) load 786142.html # We may hit bug 645229 here. +load 797583.html +load 806751.html +load 833856.html +load 851418.html +load 854139.html +load 854604.html +pref(dom.use_xbl_scopes_for_remote_xul,true) load 898939.html +pref(security.fileuri.strict_origin_policy,false) load 938297.html +load 977538.html +load 1577573.html diff --git a/js/xpconnect/idl/moz.build b/js/xpconnect/idl/moz.build new file mode 100644 index 0000000000..d8ad0cde64 --- /dev/null +++ b/js/xpconnect/idl/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +XPIDL_SOURCES += [ + "mozIJSSubScriptLoader.idl", + "nsIXPCScriptable.idl", + "xpccomponents.idl", + "xpcIJSWeakReference.idl", +] + +XPIDL_MODULE = "xpconnect" diff --git a/js/xpconnect/idl/mozIJSSubScriptLoader.idl b/js/xpconnect/idl/mozIJSSubScriptLoader.idl new file mode 100644 index 0000000000..aad85e5cd3 --- /dev/null +++ b/js/xpconnect/idl/mozIJSSubScriptLoader.idl @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface nsIURI; +interface nsIPrincipal; +interface nsIObserver; + +/** + * Interface for synchronous script loads from local file: or jar: sources. + * For asynchronous script loads, ChromeUtils.compileScript() should be used + * instead. + */ +[scriptable, builtinclass, uuid(19533e7b-f321-4ef1-bc59-6e812dc2a733)] +interface mozIJSSubScriptLoader : nsISupports +{ + /** + * This method should only be called from JS! + * In JS, the signature looks like: + * rv loadSubScript (url [, obj] [, charset]); + * @param url the url of the UTF-8-encoded sub-script, it MUST be either a + * file:, resource:, blob:, or chrome: url, and MUST be local. + * @param obj an optional object to evaluate the script onto, it + * defaults to the global object of the caller. + * @retval rv the value returned by the sub-script + */ + [implicit_jscontext] + jsval loadSubScript(in AString url, [optional] in jsval obj); + + /** + * This method should only be called from JS! + * In JS, the signature looks like: + * rv = loadSubScript (url, optionsObject) + * @param url the url of the UTF-8-encoded sub-script, which MUST be either + * a file:, resource:, blob:, or chrome: url, and MUST be local. + * @param optionsObject an object with parameters. Valid parameters are: + * - target: an object to evaluate onto (default: global object of the caller) + * - ignoreCache: if set to true, will bypass the cache for reading the file. + * - async: if set to true, the script will be loaded + * asynchronously, and a Promise is returned which + * resolves to its result when execution is complete. + * - wantReturnValue: If true, the script will return + * the value of the last statement that it evaluated. + * This option disables most optimizations in the + * top-level scope, and should be avoided if at all + * possible. Defaults to false. + * @retval rv the value returned by the sub-script + */ + [implicit_jscontext] + jsval loadSubScriptWithOptions(in AString url, in jsval options); +}; diff --git a/js/xpconnect/idl/nsIXPCScriptable.idl b/js/xpconnect/idl/nsIXPCScriptable.idl new file mode 100644 index 0000000000..aa8df7bb66 --- /dev/null +++ b/js/xpconnect/idl/nsIXPCScriptable.idl @@ -0,0 +1,121 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsIClassInfo.idl" + +%{C++ +#ifdef XP_WIN +#undef GetClassName +#endif + +#include "js/TypeDecls.h" + +namespace JS { +class CallArgs; +} + +%} + +interface nsIXPConnectWrappedNative; + +[ptr] native JSContextPtr(JSContext); +[ptr] native JSObjectPtr(JSObject); +[ptr] native JSValPtr(JS::Value); +[ptr] native JSGCContextPtr(JS::GCContext); +[ref] native JSCallArgsRef(const JS::CallArgs); +[ptr] native JSClassPtr(const JSClass); + native JSMutableHandleIdVector(JS::MutableHandleVector<JS::PropertyKey>); + +%{ C++ + // nsIXPCScriptable flags (only 32 bits available!). They are defined via + // #defines so they can be used in #ifndef guards in xpc_map_end.h. + + #define XPC_SCRIPTABLE_WANT_PRECREATE (1 << 0) + // (1 << 1) is unused + // (1 << 2) is unused + // (1 << 3) is unused + #define XPC_SCRIPTABLE_WANT_NEWENUMERATE (1 << 4) + #define XPC_SCRIPTABLE_WANT_RESOLVE (1 << 5) + #define XPC_SCRIPTABLE_WANT_FINALIZE (1 << 6) + #define XPC_SCRIPTABLE_WANT_CALL (1 << 7) + #define XPC_SCRIPTABLE_WANT_CONSTRUCT (1 << 8) + #define XPC_SCRIPTABLE_WANT_HASINSTANCE (1 << 9) + #define XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY (1 << 10) + #define XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY (1 << 11) + // (1 << 12) is unused + #define XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE (1 << 13) + // (1 << 14) is unused + // (1 << 15) is unused + #define XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE (1 << 16) + // (1 << 17) is unused + #define XPC_SCRIPTABLE_IS_GLOBAL_OBJECT (1 << 18) + #define XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES (1 << 19) +%} + +/** + * Note: This is not really an XPCOM interface. For example, callers must + * guarantee that they set the *_retval of the various methods that return a + * boolean to PR_TRUE before making the call. Implementations may skip writing + * to *_retval unless they want to return PR_FALSE. + */ +[uuid(19b70b26-7c3f-437f-a04a-2a8f9e28b617)] +interface nsIXPCScriptable : nsISupports +{ + readonly attribute AUTF8String className; + [notxpcom,nostdcall] uint32_t getScriptableFlags(); + [notxpcom,nostdcall] JSClassPtr getJSClass(); + + void preCreate(in nsISupports nativeObj, in JSContextPtr cx, + in JSObjectPtr globalObj, out JSObjectPtr parentObj); + + boolean newEnumerate(in nsIXPConnectWrappedNative wrapper, + in JSContextPtr cx, in JSObjectPtr obj, + in JSMutableHandleIdVector properties, + in boolean enumerableOnly); + + boolean resolve(in nsIXPConnectWrappedNative wrapper, + in JSContextPtr cx, in JSObjectPtr obj, in jsid id, + out boolean resolvedp); + + void finalize(in nsIXPConnectWrappedNative wrapper, + in JSGCContextPtr gcx, in JSObjectPtr obj); + + boolean call(in nsIXPConnectWrappedNative wrapper, + in JSContextPtr cx, in JSObjectPtr obj, + in JSCallArgsRef args); + + boolean construct(in nsIXPConnectWrappedNative wrapper, + in JSContextPtr cx, in JSObjectPtr obj, + in JSCallArgsRef args); + + boolean hasInstance(in nsIXPConnectWrappedNative wrapper, + in JSContextPtr cx, in JSObjectPtr obj, + in jsval val, out boolean bp); + +%{ C++ + #define GET_IT(f_, c_) \ + bool f_() { \ + return 0 != (GetScriptableFlags() & XPC_SCRIPTABLE_##c_); \ + } + + GET_IT(WantPreCreate, WANT_PRECREATE) + GET_IT(WantNewEnumerate, WANT_NEWENUMERATE) + GET_IT(WantResolve, WANT_RESOLVE) + GET_IT(WantFinalize, WANT_FINALIZE) + GET_IT(WantCall, WANT_CALL) + GET_IT(WantConstruct, WANT_CONSTRUCT) + GET_IT(WantHasInstance, WANT_HASINSTANCE) + GET_IT(UseJSStubForAddProperty, USE_JSSTUB_FOR_ADDPROPERTY) + GET_IT(UseJSStubForDelProperty, USE_JSSTUB_FOR_DELPROPERTY) + GET_IT(DontEnumQueryInterface, DONT_ENUM_QUERY_INTERFACE) + GET_IT(AllowPropModsDuringResolve, ALLOW_PROP_MODS_DURING_RESOLVE) + GET_IT(IsGlobalObject, IS_GLOBAL_OBJECT) + GET_IT(DontReflectInterfaceNames, DONT_REFLECT_INTERFACE_NAMES) + + #undef GET_IT +%} +}; diff --git a/js/xpconnect/idl/xpcIJSWeakReference.idl b/js/xpconnect/idl/xpcIJSWeakReference.idl new file mode 100644 index 0000000000..a9d2cc7444 --- /dev/null +++ b/js/xpconnect/idl/xpcIJSWeakReference.idl @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +[scriptable, builtinclass, uuid(75767928-ecb1-4e6c-9f55-c118b297fcef)] +interface xpcIJSWeakReference : nsISupports +{ + /** + * To be called from JS only. + * + * Returns the referenced JS object or null if the JS object has + * been garbage collected. + */ + [implicit_jscontext] jsval get(); +}; diff --git a/js/xpconnect/idl/xpccomponents.idl b/js/xpconnect/idl/xpccomponents.idl new file mode 100644 index 0000000000..b9cea20141 --- /dev/null +++ b/js/xpconnect/idl/xpccomponents.idl @@ -0,0 +1,886 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +%{C++ +#include "jspubtd.h" +%} + +interface xpcIJSWeakReference; +interface nsIClassInfo; +interface nsICommandParams; +interface nsIComponentManager; +interface nsICycleCollectorListener; +interface nsIDocumentEncoder; +interface nsIEditorSpellCheck; +interface nsIFile; +interface nsILoadContext; +interface nsIPersistentProperties; +interface nsIURI; +interface nsIPrincipal; +interface nsIStackFrame; +webidl Element; + +/** +* interface of Components.interfaces +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(b8c31bba-79db-4a1d-930d-4cdd68713f9e)] +interface nsIXPCComponents_Interfaces : nsISupports +{ +}; + +/** +* interface of Components.classes +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(978ff520-d26c-11d2-9842-006008962422)] +interface nsIXPCComponents_Classes : nsISupports +{ +}; + +/** +* interface of Components.results +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(2fc229a0-5860-11d3-9899-006008962422)] +interface nsIXPCComponents_Results : nsISupports +{ +}; + +/** +* interface of Components.ID +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(7994a6e0-e028-11d3-8f5d-0010a4e73d9a)] +interface nsIXPCComponents_ID : nsISupports +{ +}; + +/** +* interface of Components.Exception +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(5bf039c0-e028-11d3-8f5d-0010a4e73d9a)] +interface nsIXPCComponents_Exception : nsISupports +{ +}; + +/** +* interface of Components.Constructor +* (interesting stuff only reflected into JavaScript) +*/ +[scriptable, builtinclass, uuid(88655640-e028-11d3-8f5d-0010a4e73d9a)] +interface nsIXPCComponents_Constructor : nsISupports +{ +}; + +/** +* interface of object returned by Components.utils.Sandbox. +*/ +[scriptable, builtinclass, uuid(4f8ae0dc-d266-4a32-875b-6a9de71a8ce9)] +interface nsIXPCComponents_utils_Sandbox : nsISupports +{ +}; + +/** + * interface for callback to be passed to Cu.schedulePreciseGC + */ +[scriptable, function, uuid(71000535-b0fd-44d1-8ce0-909760e3953c)] +interface nsIScheduledGCCallback : nsISupports +{ + void callback(); +}; + +/** +* interface of Components.utils +*/ +[scriptable, builtinclass, uuid(86003fe3-ee9a-4620-91dc-eef8b1e58815)] +interface nsIXPCComponents_Utils : nsISupports +{ + /* + * Prints the provided message to stderr. + */ + void printStderr(in AUTF8String message); + + /* + * reportError is designed to be called from JavaScript only. + * + * It will report a JS Error object to the JS console, and return. It + * is meant for use in exception handler blocks which want to "eat" + * an exception, but still want to report it to the console. + * + * It must be called with one param, usually an object which was caught by + * an exception handler. If it is not a JS error object, the parameter + * is converted to a string and reported as a new error. + * + * If called with two parameters, and the first parameter is not an + * object, the second parameter is used as the stack for the error report. + */ + [implicit_jscontext] + void reportError(in jsval error, [optional] in jsval stack); + + + /** + * Cu.Sandbox is used to create a sandbox object + * + * let sandbox = Cu.Sandbox(principal[, options]); + * + * Using new Cu.Sandbox(...) to create a sandbox has the same effect as + * calling Cu.Sandbox(...) without new. + * + * In JS, Cu.Sandbox uses the following parameters: + * + * @param {Principal} principal + * The security principal defined for a sandbox determines what code + * running in that sandbox will be allowed to do. The principal may be one + * of four types: the system principal, a content principal, an expanded + * principal or a null principal. Depending on the principal type, + * this argument can be a nsIPrincipal, a Window, a String, an Array + * or null. See below. + * A content principal can be provided by passing a nsIPrincipal, a + * DOM Window, or a string URI (not recommended). + * An expanded (or extended) principal is an array of principals, + * where each item can be either a nsIPrincipal, a DOM window or a + * string URI. + * A null principal can either be specified by passing `null` or + * created explicitly with `Cc["@mozilla.org/nullprincipal;1"].createInstance(Ci.nsIPrincipal);` + * @param {Object} options + * Optional parameters, valid properties are: + * - allowWaivers: {Boolean} Allows the caller to waive Xrays, in case + * Xrays were used. Defaults to true. + * - discardSource: {Boolean} For certain globals, we know enough about + * the code that will run in them that we can discard script source + * entirely. A discarded source will be re-read when stringifying + * functions. + * Defaults to false. + * - forceSecureContext: {Boolean} Determines whether content windows and + * workers are marked as "Secure Context"s. If principal is the system + * principal, the value is forced to true. Otherwise defaults to false. + * - freshCompartment: {Boolean} Whether the sandbox should be created + * using a new compartment. Defaults to false. + * - freshZone: {Boolean} if true creates a new GC region separate from + * both the calling context's and the sandbox prototype's region. + * Defaults to false. + * - invisibleToDebugger: {Boolean} Whether this sandbox and its scripts + * can be accessed by the JavaScript Debugger. + * Defaults to false. + * - isWebExtensionContentScript: {Boolean} Whether this sandbox + * corresponds to a WebExtension content script, and should receive + * various bits of special compatibility behavior. + * Defaults to false. + * - metadata: {Object} Object to use as the metadata for the sandbox. See + * setSandboxMetadata. + * - originAttributes: {Object} Dictionary of origin attributes to use if + * the principal was provided as a string. + * - sameZoneAs: {Object} Javascript Object in whose garbage collection + * region the sandbox should be created. This helps to improve memory + * usage by allowing sandboxes to be discarded when that zone goes away. + * It also improves performance and memory usage by allowing strings + * to be passed between the compartments without copying or using + * wrappers. + * Content scripts should pass the window they're running in as this + * parameter, in order to ensure that the script is cleaned up at the + * same time as the content itself. + * - sandboxName: {String} Identifies the sandbox in about:memory. This + * property is optional, but very useful for tracking memory usage. A + * recommended value for this property is an absolute path to the script + * responsible for creating the sandbox. If you don't specify a sandbox + * name it will default to the caller's filename. + * - sandboxPrototype: {Object} Prototype object for the sandbox. The + * sandbox will inherit the contents of this object if it's provided. + * Passing a content window object, setting wantXrays:true (default) and + * using an extended principal provides a clean, isolated execution + * environment in which javascript code that needs Web APIs (such as + * accessing the window's DOM) can be executed without interference from + * untrusted content code. + * - userContextId: {Number} The id of the user context this sandbox is + * inside. Defaults to 0. + * - wantComponents: {Boolean} Indicates whether the Components object is + * available or not in the sandbox. If the sandbox interacts with + * untrusted content this should be set to false when possible to + * further reduce possible attack surface. + * Defaults to true. + * - wantExportHelpers: {Boolean} if true, then createObjectIn(), + * evalInWindow(), and exportFunction() are available in the sandbox. + * Defaults to false. + * - wantGlobalProperties: {Array<String>} Each string is the name of an + * object that you want to make available as a global to code running in + * the sandbox. Possible values: Blob, ChromeUtils, CSS, CSSRule, + * Directory, DOMParser, Element, Event, File, FileReader, FormData, + * InspectorUtils, MessageChannel, Node, NodeFilter, PromiseDebugging, + * TextDecoder, TextEncoder, URL, URLSearchParams, XMLHttpRequest, + * XMLSerializer, atob, btoa, caches, crypto, fetch, indexedDB, + * rtcIdentityProvider + * - wantXrays: {Boolean} Whether the sandbox wants Xray vision with + * respect to same-origin objects outside the sandbox. + * Note that wantXrays is essentially deprecated. The preferred method + * of handling this now is to give the sandbox an expanded principal + * which inherits from the principal of the content compartment the + * sandbox will interact with. That lets the sandbox see the content + * compartment through X-ray wrappers, and gives any object passed from + * the sandbox to the content compartment opaque security wrappers unless + * export helpers are explicitly used. + * "Xray vision" is exactly the same Xray behavior that script always + * gets, by default, when working with DOM objects across origin + * boundaries. This is primarily visible for chrome code accessing + * content. However, it also occurs during cross-origin access between + * two content pages, since each page sees a "vanilla" view of the + * other. The protection is bidirectional: the caller sees the bonafide + * DOM objects without being confused by sneakily-redefined properties, + * and the target receives appropriate privacy from having its expandos + * inspected by untrusted callers. In situations where only + * unidirectional protection is needed, callers have the option to waive + * the X-ray behavior using wrappedJSObject or XPCNativeWrapper.unwrap(). + * In general, when accessing same-origin content, script gets a + * Transparent wrapper rather than an Xray wrapper. However, sandboxes + * are often used when chrome wants to run script as another origin, + * possibly to interact with the page. In this case, same-origin Xrays + * are desirable, and wantXrays should be set to true. + * Defaults to true. + */ + readonly attribute nsIXPCComponents_utils_Sandbox Sandbox; + + [implicit_jscontext] + jsval createServicesCache(); + + /* + * evalInSandbox is designed to be called from JavaScript only. + * + * evalInSandbox evaluates the provided source string in the given sandbox. + * It returns the result of the evaluation to the caller. + * + * var s = new C.u.Sandbox("http://www.mozilla.org"); + * var res = C.u.evalInSandbox("var five = 5; 2 + five", s); + * var outerFive = s.five; + * s.seven = res; + * var thirtyFive = C.u.evalInSandbox("five * seven", s); + */ + [implicit_jscontext,optional_argc] + jsval evalInSandbox(in AString source, in jsval sandbox, + [optional] in jsval version, + [optional] in AUTF8String filename, + [optional] in long lineNo, + [optional] in bool enforceFilenameRestrictions); + + /* + * Get the sandbox for running JS-implemented UA widgets (video controls etc.), + * hosted inside UA-created Shadow DOM. + */ + [implicit_jscontext] + jsval getUAWidgetScope(in nsIPrincipal principal); + + /* + * getSandboxMetadata is designed to be called from JavaScript only. + * + * getSandboxMetadata retrieves the metadata associated with + * a sandbox object. It will return undefined if there + * is no metadata attached to the sandbox. + * + * var s = C.u.Sandbox(..., { metadata: "metadata" }); + * var metadata = C.u.getSandboxMetadata(s); + */ + [implicit_jscontext] + jsval getSandboxMetadata(in jsval sandbox); + + /* + * setSandboxMetadata is designed to be called from JavaScript only. + * + * setSandboxMetadata sets the metadata associated with + * a sandbox object. + * + * Note that the metadata object will be copied before being used. + * The copy will be performed using the structured clone algorithm. + * Note that this algorithm does not support reflectors and + * it will throw if it encounters them. + */ + [implicit_jscontext] + void setSandboxMetadata(in jsval sandbox, in jsval metadata); + + /* + * import is designed to be called from JavaScript only. + * + * Synchronously loads and evaluates the js file located at + * 'registryLocation' with a new, fully privileged global object. + * + * If 'targetObj' is specified and equal to null, returns the + * module's global object. Otherwise (if 'targetObj' is not + * specified, or 'targetObj' is != null) looks for a property + * 'EXPORTED_SYMBOLS' on the new global object. 'EXPORTED_SYMBOLS' + * is expected to be an array of strings identifying properties on + * the global object. These properties will be installed as + * properties on 'targetObj', or, if 'targetObj' is not specified, + * on the caller's global object. If 'EXPORTED_SYMBOLS' is not + * found, an error is thrown. + * + * @param resourceURI A resource:// URI string to load the module from. + * @param targetObj the object to install the exported properties on. + * If this parameter is a primitive value, this method throws + * an exception. + * @returns the module code's global object. + * + * The implementation maintains a hash of registryLocation->global obj. + * Subsequent invocations of importModule with 'registryLocation' + * pointing to the same file will not cause the module to be re-evaluated, + * but the symbols in EXPORTED_SYMBOLS will be exported into the + * specified target object and the global object returned as above. + */ + [implicit_jscontext,optional_argc] + jsval import(in AUTF8String aResourceURI, [optional] in jsval targetObj); + + /** + * Returns true if the JSM is loaded into the system global previously via + * the import method above, or corresponding ESM is loaded. Returns false + * otherwise. + * + * @param resourceURI A resource:// URI string representing the location of + * the js file to be checked if it is already loaded or not. + * @returns boolean, true if the js file has been loaded via import. false + * otherwise + */ + boolean isModuleLoaded(in AUTF8String aResourceURI); + + + /** + * Returns true if the JSM is loaded into the system global previously via + * the import method above. Returns false otherwise. + */ + boolean isJSModuleLoaded(in AUTF8String aResourceURI); + + /** + * Returns true if the ESM is loaded into the system global previously via + * the ChromeUtils.importESModule method etc. Returns false otherwise. + */ + boolean isESModuleLoaded(in AUTF8String aResourceURI); + + /* + * Unloads the JS module at 'registryLocation'. Existing references to the + * module will continue to work but any subsequent import of the module will + * reload it and give new reference. If the JS module hasn't yet been + * imported then this method will do nothing. + * + * @param resourceURI A resource:// URI string to unload the module from. + */ + void unload(in AUTF8String registryLocation); + + /* + * Imports global properties (like DOM constructors) into the scope, defining + * them on the caller's global. aPropertyList should be an array of property + * names. + * + * See xpc::GlobalProperties::Parse for the current list of supported + * properties. + */ + [implicit_jscontext] + void importGlobalProperties(in jsval aPropertyList); + + /* + * To be called from JS only. + * + * Return a weak reference for the given JS object. + */ + [implicit_jscontext] + xpcIJSWeakReference getWeakReference(in jsval obj); + + /* + * To be called from JS only. + * + * Force an immediate garbage collection cycle. + */ + [implicit_jscontext] + void forceGC(); + + /* + * To be called from JS only. + * + * Force an immediate cycle collection cycle. + */ + void forceCC([optional] in nsICycleCollectorListener aListener); + + /* + * To be called from JS only. C++ callers should use the + * nsCycleCollector_createLogger() function instead. + * + * Create an instance of the built-in cycle collector logger object. + */ + nsICycleCollectorListener createCCLogger(); + + /* + * To be called from JS only. + * + * If any incremental CC is in progress, finish it. For testing. + */ + void finishCC(); + + /* + * To be called from JS only. + * + * Do some cycle collector work, with the given work budget. + * The cost of calling Traverse() on a single object is set as 1. + * For testing. + */ + void ccSlice(in long long budget); + + /* + * To be called from JS only. + * + * Return the longest cycle collector slice time since the last + * time clearMaxCCTime() was called. + */ + long getMaxCCSliceTimeSinceClear(); + + /* + * To be called from JS only. + * + * Reset the internal max slice time value used for + * getMaxCCSliceTimeSinceClear(). + */ + void clearMaxCCTime(); + + /* + * To be called from JS only. + * + * Force an immediate shrinking garbage collection cycle. + */ + [implicit_jscontext] + void forceShrinkingGC(); + + /* + * Schedule a garbage collection cycle for a point in the future when no JS + * is running. Call the provided function once this has occurred. + */ + void schedulePreciseGC(in nsIScheduledGCCallback callback); + + /* + * Schedule a shrinking garbage collection cycle for a point in the future + * when no JS is running. Call the provided function once this has occured. + */ + void schedulePreciseShrinkingGC(in nsIScheduledGCCallback callback); + + /* + * In a debug build, unlink any ghost windows. This is only for debugging + * leaks, and can cause bad things to happen if called. + */ + void unlinkGhostWindows(); + + /* + * In an NS_FREE_PERMANENT_DATA build, intentionally leak a C++ object. This + * is needed to test leak checking. + */ + void intentionallyLeak(); + + [implicit_jscontext] + jsval getJSTestingFunctions(); + + /** + * Returns an object containing `filename` and `lineNumber` properties + * describing the source location of the given function. + */ + [implicit_jscontext] + jsval getFunctionSourceLocation(in jsval func); + + /* + * To be called from JS only. + * + * Call 'function', using the provided stack as the async stack responsible + * for the call, and propagate its return value or the exception it throws. + * The function is called with no arguments, and 'this' is 'undefined'. + * + * The code in the function will see the given stack frame as the + * asyncCaller of its own stack frame, instead of the current caller. + */ + [implicit_jscontext] + jsval callFunctionWithAsyncStack(in jsval function, in nsIStackFrame stack, + in AString asyncCause); + + /* + * To be called from JS only. + * + * Returns the global object with which the given object is associated. + * + * @param obj The JavaScript object whose global is to be gotten. + * @return the corresponding global. + */ + [implicit_jscontext] + jsval getGlobalForObject(in jsval obj); + + /* + * To be called from JS only. + * + * Returns the true if the object is a (scripted) proxy. + * NOTE: Security wrappers are unwrapped first before the check. + */ + [implicit_jscontext] + boolean isProxy(in jsval vobject); + + /* + * To be called from JS only. + * + * Instead of simply wrapping a function into another compartment, + * this helper function creates a native function in the target + * compartment and forwards the call to the original function. + * That call will be different than a regular JS function call in + * that, the |this| is left unbound, and all the non-native JS + * object arguments will be cloned using the structured clone + * algorithm. + * The return value is the new forwarder function, wrapped into + * the caller's compartment. + * The 3rd argument is an optional options object: + * - defineAs: the name of the property that will + * be set on the target scope, with + * the forwarder function as the value. + */ + [implicit_jscontext] + jsval exportFunction(in jsval vfunction, in jsval vscope, [optional] in jsval voptions); + + /* + * To be called from JS only. + * + * Returns an object created in |vobj|'s compartment. + * If defineAs property on the options object is a non-null ID, + * the new object will be added to vobj as a property. Also, the + * returned new object is always automatically waived (see waiveXrays). + */ + [implicit_jscontext] + jsval createObjectIn(in jsval vobj, [optional] in jsval voptions); + + /* + * To be called from JS only. + * + * Ensures that all functions come from vobj's scope (and aren't cross + * compartment wrappers). + */ + [implicit_jscontext] + void makeObjectPropsNormal(in jsval vobj); + + /** + * Determines whether this object is backed by a DeadObjectProxy. + * + * Dead-wrapper objects hold no other objects alive (they have no outgoing + * reference edges) and will throw if you touch them (e.g. by + * reading/writing a property). + */ + bool isDeadWrapper(in jsval obj); + + /** + * Determines whether this value is a remote object proxy, such as + * RemoteWindowProxy or RemoteLocationProxy, for an out-of-process frame. + * + * Remote object proxies do not grant chrome callers the same exemptions + * to the same-origin-policy that in-process wrappers typically do, so + * this can be used to determine whether access to cross-origin proxies is + * safe: + * + * if (!Cu.isRemoteProxy(frame.contentWindow)) { + * frame.contentWindow.doCrossOriginThing(); + * } + */ + bool isRemoteProxy(in jsval val); + + /* + * To be called from JS only. This is for Gecko internal use only, and may + * disappear at any moment. + * + * Forces a recomputation of all wrappers in and out of the compartment + * containing |vobj|. If |vobj| is not an object, all wrappers system-wide + * are recomputed. + */ + [implicit_jscontext] + void recomputeWrappers([optional] in jsval vobj); + + /* + * To be called from JS only. This is for Gecko internal use only, and may + * disappear at any moment. + * + * Enables Xray vision for same-compartment access for the compartment + * indicated by |vscope|. All outgoing wrappers are recomputed. + * + * This must not be called on chrome (system-principal) scopes. + */ + [implicit_jscontext] + void setWantXrays(in jsval vscope); + + /* + * Dispatches a runnable to the current/main thread. If |scope| is passed, + * the runnable will be dispatch in the compartment of |scope|, which + * affects which error reporter gets called. + */ + [implicit_jscontext] + void dispatch(in jsval runnable, [optional] in jsval scope); + + /* + * Bug 1621603 - Remove strict_mode. + * + * Do not use this API! Instead use "use strict"; at the top of your JS + * file. + */ + [implicit_jscontext] + attribute boolean strict_mode; + + // Returns true if we're running in automation and certain security + // restrictions can be eased. + readonly attribute boolean isInAutomation; + + // Called by automated tests to exit immediately after we are done getting + // test results. + void exitIfInAutomation(); + + void crashIfNotInAutomation(); + + [implicit_jscontext] + void setGCZeal(in long zeal); + + [implicit_jscontext] + void nukeSandbox(in jsval obj); + + /* + * API to dynamically block script for a given global. This takes effect + * immediately, unlike other APIs that only affect newly-created globals. + * + * The machinery here maintains a counter, and allows script only if each + * call to blockScriptForGlobal() has been matched with a call to + * unblockScriptForGlobal(). The caller _must_ make sure never to call + * unblock() more times than it calls block(), since that could potentially + * interfere with another consumer's script blocking. + */ + + [implicit_jscontext] + void blockScriptForGlobal(in jsval global); + + [implicit_jscontext] + void unblockScriptForGlobal(in jsval global); + + /** + * Check whether the given object is an opaque wrapper (PermissiveXrayOpaque). + */ + bool isOpaqueWrapper(in jsval obj); + + /** + * Check whether the given object is an XrayWrapper. + */ + bool isXrayWrapper(in jsval obj); + + /** + * Waive Xray on a given value. Identity op for primitives. + */ + [implicit_jscontext] + jsval waiveXrays(in jsval aVal); + + /** + * Strip off Xray waivers on a given value. Identity op for primitives. + */ + [implicit_jscontext] + jsval unwaiveXrays(in jsval aVal); + + /** + * Gets the name of the JSClass of the object. + * + * if |aUnwrap| is true, all wrappers are unwrapped first. Unless you're + * specifically trying to detect whether the object is a proxy, this is + * probably what you want. + */ + [implicit_jscontext] + string getClassName(in jsval aObj, in bool aUnwrap); + + /** + * Get a DOM classinfo for the given classname. Only some class + * names are supported. + */ + nsIClassInfo getDOMClassInfo(in AString aClassName); + + /** + * Gets the incument global for the execution of this function. For internal + * and testing use only. + * + * If |callback| is passed, it is invoked with the incumbent global as its + * sole argument. This allows the incumbent global to be measured in callback + * environments with no scripted frames on the stack. + */ + [implicit_jscontext] + jsval getIncumbentGlobal([optional] in jsval callback); + + /** + * Returns a name for the given function or object which is useful for + * debugging. It will be very similar to the name displayed in call + * stacks. + + * Objects which contain a single enumerable property which is a function + * will generate a name based on that function. Any other non-function + * objects will return "nonfunction". + */ + [implicit_jscontext] + ACString getDebugName(in jsval obj); + + /** + * Retrieve the last time, in microseconds since epoch, that a given + * watchdog-related event occured. + * + * Valid categories: + * "ContextStateChange" - Context switching between active and inactive states + * "WatchdogWakeup" - Watchdog waking up from sleeping + * "WatchdogHibernateStart" - Watchdog begins hibernating + * "WatchdogHibernateStop" - Watchdog stops hibernating + */ + PRTime getWatchdogTimestamp(in AString aCategory); + + [implicit_jscontext] + jsval getJSEngineTelemetryValue(); + + /* + * Clone an object into a scope. + * The 3rd argument is an optional options object: + * - cloneFunctions: boolean. If true, functions in the value are + * wrapped in a function forwarder that appears to be a native function in + * the content scope. Defaults to false. + * - wrapReflectors: boolean. If true, DOM objects are passed through the + * clone directly with cross-compartment wrappers. Otherwise, the clone + * fails when such an object is encountered. Defaults to false. + */ + [implicit_jscontext] + jsval cloneInto(in jsval value, in jsval scope, [optional] in jsval options); + + /* + * When C++-Implemented code does security checks, it can generally query + * the subject principal (i.e. the principal of the most-recently-executed + * script) in order to determine the responsible party. However, when an API + * is implemented in JS, this doesn't work - the most-recently-executed + * script is always the System-Principaled API implementation. So we need + * another mechanism. + * + * Hence the notion of the "WebIDL Caller". If the current Entry Script on + * the Script Settings Stack represents the invocation of JS-implemented + * WebIDL, this API returns the principal of the caller at the time + * of invocation. Otherwise (i.e. outside of JS-implemented WebIDL), this + * function throws. If it throws, you probably shouldn't be using it. + */ + nsIPrincipal getWebIDLCallerPrincipal(); + + /* + * Gets the principal of a script object, after unwrapping any cross- + * compartment wrappers. + */ + [implicit_jscontext] + nsIPrincipal getObjectPrincipal(in jsval obj); + + /* + * Gets the URI or identifier string associated with an object's + * realm (the same one used by the memory reporter machinery). + * + * Unwraps cross-compartment wrappers first. + * + * The string formats and values may change at any time. Do not depend on + * this from addon code. + */ + [implicit_jscontext] + ACString getRealmLocation(in jsval obj); + + /* + * Return a fractional number of milliseconds from process + * startup, measured with a monotonic clock. + */ + double now(); + + /* + * Reads the given file and returns its contents. If called during early + * startup, the file will be pre-read on a background thread during profile + * startup so its contents will be available the next time they're read. + * + * The file must be a text file encoded in UTF-8. Otherwise the result is + * undefined. + */ + AUTF8String readUTF8File(in nsIFile file); + + /* + * Reads the given local file URL and returns its contents. This has the + * same semantics of readUTF8File. + * Only supports file URLs or URLs that point into one of the omnijars. + */ + AUTF8String readUTF8URI(in nsIURI url); + + /* Create a spellchecker object. */ + nsIEditorSpellCheck createSpellChecker(); + + /* Create a commandline object. + * + * @return a new `nsICommandLine` instance. + * + * @param args + * The arguments of the command line, not including the app/program itself. + * @param workingDir + * An optional working directory for the command line. + * @param state + * The command line's state, one of `nsICommandLine.STATE_INITIAL_LAUNCH`, + * `nsICommandLine.STATE_REMOTE_AUTO`, or + * `nsICommandLine.STATE_REMOTE_EXPLICIT`. + */ + nsISupports createCommandLine(in Array<ACString> args, + in nsIFile workingDir, + in unsigned long state); + + /* Create a command params object. */ + nsICommandParams createCommandParams(); + + /* Create a loadcontext object. */ + nsILoadContext createLoadContext(); + + /* Create a private loadcontext object. */ + nsILoadContext createPrivateLoadContext(); + + /* Create a persistent property object. */ + nsIPersistentProperties createPersistentProperties(); + + /* Create a document encoder object. */ + nsIDocumentEncoder createDocumentEncoder(in string contentType); + + /* Create an HTML copy encoder object. */ + nsIDocumentEncoder createHTMLCopyEncoder(); + + // These attributes are for startup testing purposes. They are not expected + // to be used for production code. + + // Array of the URI of JSM and ESM loaded, converting ESM URI into JSM URI. + readonly attribute Array<ACString> loadedModules; + + // Array of the URI of JSM loaded. + readonly attribute Array<ACString> loadedJSModules; + + // Array of the URI of ESM loaded. + readonly attribute Array<ACString> loadedESModules; + + + // This function will only return useful values if the + // "browser.startup.record" preference was true at the time the JS file + // was loaded. + ACString getModuleImportStack(in AUTF8String aLocation); +}; + +/** +* Interface for the 'Components' object. +*/ + +[scriptable, builtinclass, uuid(aa28aaf6-70ce-4b03-9514-afe43c7dfda8)] +interface nsIXPCComponents : nsISupports +{ + readonly attribute nsIXPCComponents_Interfaces interfaces; + readonly attribute nsIXPCComponents_Results results; + + boolean isSuccessCode(in nsresult result); + + readonly attribute nsIXPCComponents_Classes classes; + // Will return null if there is no JS stack right now. + readonly attribute nsIStackFrame stack; + readonly attribute nsIComponentManager manager; + readonly attribute nsIXPCComponents_Utils utils; + + readonly attribute nsIXPCComponents_ID ID; + readonly attribute nsIXPCComponents_Exception Exception; + readonly attribute nsIXPCComponents_Constructor Constructor; + + [implicit_jscontext] + // A javascript component can set |returnCode| to specify an nsresult to + // be returned without throwing an exception. + attribute jsval returnCode; +}; diff --git a/js/xpconnect/loader/AutoMemMap.cpp b/js/xpconnect/loader/AutoMemMap.cpp new file mode 100644 index 0000000000..f8c75ea445 --- /dev/null +++ b/js/xpconnect/loader/AutoMemMap.cpp @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "AutoMemMap.h" +#include "ScriptPreloader-inl.h" + +#include "mozilla/Unused.h" +#include "mozilla/ipc/FileDescriptor.h" +#include "nsIFile.h" + +#include <private/pprio.h> + +namespace mozilla { +namespace loader { + +using namespace mozilla::ipc; + +AutoMemMap::~AutoMemMap() { reset(); } + +FileDescriptor AutoMemMap::cloneFileDescriptor() const { + if (fd.get()) { + auto handle = + FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd.get())); + return FileDescriptor(handle); + } + return FileDescriptor(); +} + +Result<Ok, nsresult> AutoMemMap::init(nsIFile* file, int flags, int mode, + PRFileMapProtect prot) { + MOZ_ASSERT(!fd); + + MOZ_TRY(file->OpenNSPRFileDesc(flags, mode, &fd.rwget())); + + return initInternal(prot); +} + +Result<Ok, nsresult> AutoMemMap::init(const FileDescriptor& file, + PRFileMapProtect prot, size_t maybeSize) { + MOZ_ASSERT(!fd); + if (!file.IsValid()) { + return Err(NS_ERROR_INVALID_ARG); + } + + auto handle = file.ClonePlatformHandle(); + + fd = PR_ImportFile(PROsfd(handle.get())); + if (!fd) { + return Err(NS_ERROR_FAILURE); + } + Unused << handle.release(); + + return initInternal(prot, maybeSize); +} + +Result<Ok, nsresult> AutoMemMap::initInternal(PRFileMapProtect prot, + size_t maybeSize) { + MOZ_ASSERT(!fileMap); + MOZ_ASSERT(!addr); + + if (maybeSize > 0) { + // Some OSes' shared memory objects can't be stat()ed, either at + // all (Android) or without loosening the sandbox (Mac) so just + // use the size. + size_ = maybeSize; + } else { + // But if we don't have the size, assume it's a regular file and + // ask for it. + PRFileInfo64 fileInfo; + MOZ_TRY(PR_GetOpenFileInfo64(fd.get(), &fileInfo)); + + if (fileInfo.size > UINT32_MAX) { + return Err(NS_ERROR_INVALID_ARG); + } + size_ = fileInfo.size; + } + + fileMap = PR_CreateFileMap(fd, 0, prot); + if (!fileMap) { + return Err(NS_ERROR_FAILURE); + } + + addr = PR_MemMap(fileMap, 0, size_); + if (!addr) { + return Err(NS_ERROR_FAILURE); + } + + return Ok(); +} + +#ifdef XP_WIN + +Result<Ok, nsresult> AutoMemMap::initWithHandle(const FileDescriptor& file, + size_t size, + PRFileMapProtect prot) { + MOZ_ASSERT(!fd); + MOZ_ASSERT(!handle_); + if (!file.IsValid()) { + return Err(NS_ERROR_INVALID_ARG); + } + + handle_ = file.ClonePlatformHandle().release(); + + MOZ_ASSERT(!addr); + + size_ = size; + + addr = MapViewOfFile( + handle_, prot == PR_PROT_READONLY ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, + 0, 0, size); + if (!addr) { + return Err(NS_ERROR_FAILURE); + } + + return Ok(); +} + +FileDescriptor AutoMemMap::cloneHandle() const { + return FileDescriptor(handle_); +} + +#else + +Result<Ok, nsresult> AutoMemMap::initWithHandle(const FileDescriptor& file, + size_t size, + PRFileMapProtect prot) { + MOZ_DIAGNOSTIC_ASSERT(size > 0); + return init(file, prot, size); +} + +FileDescriptor AutoMemMap::cloneHandle() const { return cloneFileDescriptor(); } + +#endif + +void AutoMemMap::reset() { + if (addr && !persistent_) { + Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS); + addr = nullptr; + } + if (fileMap) { + Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS); + fileMap = nullptr; + } +#ifdef XP_WIN + if (handle_) { + CloseHandle(handle_); + handle_ = nullptr; + } +#endif + fd.dispose(); +} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/AutoMemMap.h b/js/xpconnect/loader/AutoMemMap.h new file mode 100644 index 0000000000..54180d09e3 --- /dev/null +++ b/js/xpconnect/loader/AutoMemMap.h @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef loader_AutoMemMap_h +#define loader_AutoMemMap_h + +#include "mozilla/FileUtils.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/RangedPtr.h" +#include "mozilla/Result.h" + +#include <prio.h> + +class nsIFile; + +namespace mozilla { +namespace ipc { +class FileDescriptor; +} + +namespace loader { + +class AutoMemMap { + typedef mozilla::ipc::FileDescriptor FileDescriptor; + + public: + AutoMemMap() = default; + + ~AutoMemMap(); + + Result<Ok, nsresult> init(nsIFile* file, int flags = PR_RDONLY, int mode = 0, + PRFileMapProtect prot = PR_PROT_READONLY); + + Result<Ok, nsresult> init(const FileDescriptor& file, + PRFileMapProtect prot = PR_PROT_READONLY, + size_t maybeSize = 0); + + // Initializes the mapped memory with a shared memory handle. On + // Unix-like systems, this is identical to the above init() method. On + // Windows, the FileDescriptor must be a handle for a file mapping, + // rather than a file descriptor. + Result<Ok, nsresult> initWithHandle(const FileDescriptor& file, size_t size, + PRFileMapProtect prot = PR_PROT_READONLY); + + void reset(); + + bool initialized() const { return addr; } + + uint32_t size() const { return size_; } + + template <typename T = void> + RangedPtr<T> get() { + MOZ_ASSERT(addr); + return {static_cast<T*>(addr), size_}; + } + + template <typename T = void> + const RangedPtr<T> get() const { + MOZ_ASSERT(addr); + return {static_cast<T*>(addr), size_}; + } + + size_t nonHeapSizeOfExcludingThis() { return size_; } + + FileDescriptor cloneFileDescriptor() const; + FileDescriptor cloneHandle() const; + + // Makes this mapping persistent. After calling this, the mapped memory + // will remained mapped, even after this instance is destroyed. + void setPersistent() { persistent_ = true; } + + private: + Result<Ok, nsresult> initInternal(PRFileMapProtect prot, + size_t maybeSize = 0); + + AutoFDClose fd; + PRFileMap* fileMap = nullptr; + +#ifdef XP_WIN + // We can't include windows.h in this header, since it gets included + // by some binding headers (which are explicitly incompatible with + // windows.h). So we can't use the HANDLE type here. + void* handle_ = nullptr; +#endif + + uint32_t size_ = 0; + void* addr = nullptr; + + bool persistent_ = 0; + + AutoMemMap(const AutoMemMap&) = delete; + void operator=(const AutoMemMap&) = delete; +}; + +} // namespace loader +} // namespace mozilla + +#endif // loader_AutoMemMap_h diff --git a/js/xpconnect/loader/ChromeScriptLoader.cpp b/js/xpconnect/loader/ChromeScriptLoader.cpp new file mode 100644 index 0000000000..22035d75b0 --- /dev/null +++ b/js/xpconnect/loader/ChromeScriptLoader.cpp @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "PrecompiledScript.h" + +#include "nsIIncrementalStreamLoader.h" +#include "nsIURI.h" +#include "nsIChannel.h" +#include "nsNetUtil.h" +#include "nsThreadUtils.h" + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/CompilationAndEvaluation.h" +#include "js/experimental/JSStencil.h" // JS::CompileGlobalScriptToStencil, JS::InstantiateGlobalStencil, JS::OffThreadCompileToStencil +#include "js/SourceText.h" +#include "js/Utility.h" + +#include "mozilla/Attributes.h" +#include "mozilla/SchedulerGroup.h" +#include "mozilla/dom/ChromeUtils.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/HoldDropJSObjects.h" +#include "nsCCUncollectableMarker.h" +#include "nsCycleCollectionParticipant.h" +#include "nsGlobalWindowInner.h" + +using namespace JS; +using namespace mozilla; +using namespace mozilla::dom; + +class AsyncScriptCompiler final : public nsIIncrementalStreamLoaderObserver, + public Runnable { + public: + // Note: References to this class are never held by cycle-collected objects. + // If at any point a reference is returned to a caller, please update this + // class to implement cycle collection. + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER + NS_DECL_NSIRUNNABLE + + AsyncScriptCompiler(JSContext* aCx, nsIGlobalObject* aGlobal, + const nsACString& aURL, Promise* aPromise) + : mozilla::Runnable("AsyncScriptCompiler"), + mOptions(aCx), + mURL(aURL), + mGlobalObject(aGlobal), + mPromise(aPromise), + mToken(nullptr), + mScriptLength(0) {} + + [[nodiscard]] nsresult Start(JSContext* aCx, + const CompileScriptOptionsDictionary& aOptions, + nsIPrincipal* aPrincipal); + + inline void SetToken(JS::OffThreadToken* aToken) { mToken = aToken; } + + protected: + virtual ~AsyncScriptCompiler() { + if (mPromise->State() == Promise::PromiseState::Pending) { + mPromise->MaybeReject(NS_ERROR_FAILURE); + } + } + + private: + void Reject(JSContext* aCx); + void Reject(JSContext* aCx, const char* aMxg); + + bool StartCompile(JSContext* aCx); + void FinishCompile(JSContext* aCx); + void Finish(JSContext* aCx, RefPtr<JS::Stencil> aStencil); + + OwningCompileOptions mOptions; + nsCString mURL; + nsCOMPtr<nsIGlobalObject> mGlobalObject; + RefPtr<Promise> mPromise; + nsString mCharset; + JS::OffThreadToken* mToken; + UniquePtr<Utf8Unit[], JS::FreePolicy> mScriptText; + size_t mScriptLength; +}; + +NS_IMPL_QUERY_INTERFACE_INHERITED(AsyncScriptCompiler, Runnable, + nsIIncrementalStreamLoaderObserver) +NS_IMPL_ADDREF_INHERITED(AsyncScriptCompiler, Runnable) +NS_IMPL_RELEASE_INHERITED(AsyncScriptCompiler, Runnable) + +nsresult AsyncScriptCompiler::Start( + JSContext* aCx, const CompileScriptOptionsDictionary& aOptions, + nsIPrincipal* aPrincipal) { + mCharset = aOptions.mCharset; + + CompileOptions options(aCx); + options.setFile(mURL.get()).setNoScriptRval(!aOptions.mHasReturnValue); + + if (!aOptions.mLazilyParse) { + options.setForceFullParse(); + } + + if (NS_WARN_IF(!mOptions.copy(aCx, options))) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), mURL); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIChannel> channel; + rv = NS_NewChannel( + getter_AddRefs(channel), uri, aPrincipal, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT); + NS_ENSURE_SUCCESS(rv, rv); + + // allow deprecated HTTP request from SystemPrincipal + nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo(); + loadInfo->SetAllowDeprecatedSystemRequests(true); + nsCOMPtr<nsIIncrementalStreamLoader> loader; + rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), this); + NS_ENSURE_SUCCESS(rv, rv); + + return channel->AsyncOpen(loader); +} + +static void OffThreadScriptLoaderCallback(JS::OffThreadToken* aToken, + void* aCallbackData) { + RefPtr<AsyncScriptCompiler> scriptCompiler = + dont_AddRef(static_cast<AsyncScriptCompiler*>(aCallbackData)); + + scriptCompiler->SetToken(aToken); + + SchedulerGroup::Dispatch(TaskCategory::Other, scriptCompiler.forget()); +} + +bool AsyncScriptCompiler::StartCompile(JSContext* aCx) { + JS::SourceText<Utf8Unit> srcBuf; + if (!srcBuf.init(aCx, std::move(mScriptText), mScriptLength)) { + return false; + } + + if (JS::CanCompileOffThread(aCx, mOptions, mScriptLength)) { + if (!JS::CompileToStencilOffThread(aCx, mOptions, srcBuf, + OffThreadScriptLoaderCallback, + static_cast<void*>(this))) { + return false; + } + + NS_ADDREF(this); + return true; + } + + RefPtr<Stencil> stencil = + JS::CompileGlobalScriptToStencil(aCx, mOptions, srcBuf); + if (!stencil) { + return false; + } + + Finish(aCx, stencil); + return true; +} + +NS_IMETHODIMP +AsyncScriptCompiler::Run() { + AutoJSAPI jsapi; + if (jsapi.Init(mGlobalObject)) { + FinishCompile(jsapi.cx()); + } else { + jsapi.Init(); + JS::CancelOffThreadToken(jsapi.cx(), mToken); + + mPromise->MaybeReject(NS_ERROR_FAILURE); + } + + return NS_OK; +} + +void AsyncScriptCompiler::FinishCompile(JSContext* aCx) { + RefPtr<JS::Stencil> stencil = JS::FinishOffThreadStencil(aCx, mToken); + if (stencil) { + Finish(aCx, stencil); + } else { + Reject(aCx); + } +} + +void AsyncScriptCompiler::Finish(JSContext* aCx, RefPtr<JS::Stencil> aStencil) { + RefPtr<PrecompiledScript> result = + new PrecompiledScript(mGlobalObject, aStencil, mOptions); + + mPromise->MaybeResolve(result); +} + +void AsyncScriptCompiler::Reject(JSContext* aCx) { + RootedValue value(aCx, JS::UndefinedValue()); + if (JS_GetPendingException(aCx, &value)) { + JS_ClearPendingException(aCx); + } + mPromise->MaybeReject(value); +} + +void AsyncScriptCompiler::Reject(JSContext* aCx, const char* aMsg) { + nsAutoString msg; + msg.AppendASCII(aMsg); + msg.AppendLiteral(": "); + AppendUTF8toUTF16(mURL, msg); + + RootedValue exn(aCx); + if (xpc::NonVoidStringToJsval(aCx, msg, &exn)) { + JS_SetPendingException(aCx, exn); + } + + Reject(aCx); +} + +NS_IMETHODIMP +AsyncScriptCompiler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader, + nsISupports* aContext, + uint32_t aDataLength, + const uint8_t* aData, + uint32_t* aConsumedData) { + return NS_OK; +} + +NS_IMETHODIMP +AsyncScriptCompiler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader, + nsISupports* aContext, nsresult aStatus, + uint32_t aLength, const uint8_t* aBuf) { + AutoJSAPI jsapi; + if (!jsapi.Init(mGlobalObject)) { + mPromise->MaybeReject(NS_ERROR_FAILURE); + return NS_OK; + } + + JSContext* cx = jsapi.cx(); + + if (NS_FAILED(aStatus)) { + Reject(cx, "Unable to load script"); + return NS_OK; + } + + nsresult rv = ScriptLoader::ConvertToUTF8( + nullptr, aBuf, aLength, mCharset, nullptr, mScriptText, mScriptLength); + if (NS_FAILED(rv)) { + Reject(cx, "Unable to decode script"); + return NS_OK; + } + + if (!StartCompile(cx)) { + Reject(cx); + } + + return NS_OK; +} + +namespace mozilla { +namespace dom { + +/* static */ +already_AddRefed<Promise> ChromeUtils::CompileScript( + GlobalObject& aGlobal, const nsAString& aURL, + const CompileScriptOptionsDictionary& aOptions, ErrorResult& aRv) { + nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports()); + MOZ_ASSERT(global); + + RefPtr<Promise> promise = Promise::Create(global, aRv); + if (aRv.Failed()) { + return nullptr; + } + + NS_ConvertUTF16toUTF8 url(aURL); + RefPtr<AsyncScriptCompiler> compiler = + new AsyncScriptCompiler(aGlobal.Context(), global, url, promise); + + nsresult rv = compiler->Start(aGlobal.Context(), aOptions, + aGlobal.GetSubjectPrincipal()); + if (NS_FAILED(rv)) { + promise->MaybeReject(rv); + } + + return promise.forget(); +} + +PrecompiledScript::PrecompiledScript(nsISupports* aParent, + RefPtr<JS::Stencil> aStencil, + JS::ReadOnlyCompileOptions& aOptions) + : mParent(aParent), + mStencil(aStencil), + mURL(aOptions.filename()), + mHasReturnValue(!aOptions.noScriptRval) { + MOZ_ASSERT(aParent); + MOZ_ASSERT(aStencil); +#ifdef DEBUG + JS::InstantiateOptions options(aOptions); + options.assertDefault(); +#endif +}; + +void PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal, + const ExecuteInGlobalOptions& aOptions, + MutableHandleValue aRval, + ErrorResult& aRv) { + { + RootedObject targetObj(aCx, JS_FindCompilationScope(aCx, aGlobal)); + // Use AutoEntryScript for its ReportException method call. + // This will ensure notified any exception happening in the content script + // directly to the console, so that exceptions are flagged with the right + // innerWindowID. It helps these exceptions to appear in the page's web + // console. + AutoEntryScript aes(targetObj, "pre-compiled-script execution"); + JSContext* cx = aes.cx(); + + // See assertion in constructor. + JS::InstantiateOptions options; + Rooted<JSScript*> script( + cx, JS::InstantiateGlobalStencil(cx, options, mStencil)); + if (!script) { + aRv.NoteJSContextException(aCx); + return; + } + + if (!JS_ExecuteScript(cx, script, aRval)) { + JS::RootedValue exn(cx); + if (aOptions.mReportExceptions) { + // Note that ReportException will consume the exception. + aes.ReportException(); + } else { + // Set the exception on our caller's cx. + aRv.MightThrowJSException(); + aRv.StealExceptionFromJSContext(cx); + } + return; + } + } + + JS_WrapValue(aCx, aRval); +} + +void PrecompiledScript::GetUrl(nsAString& aUrl) { CopyUTF8toUTF16(mURL, aUrl); } + +bool PrecompiledScript::HasReturnValue() { return mHasReturnValue; } + +JSObject* PrecompiledScript::WrapObject(JSContext* aCx, + HandleObject aGivenProto) { + return PrecompiledScript_Binding::Wrap(aCx, this, aGivenProto); +} + +bool PrecompiledScript::IsBlackForCC(bool aTracingNeeded) { + return (nsCCUncollectableMarker::sGeneration && HasKnownLiveWrapper() && + (!aTracingNeeded || HasNothingToTrace(this))); +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PrecompiledScript, mParent) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PrecompiledScript) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(PrecompiledScript) + return tmp->IsBlackForCC(false); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(PrecompiledScript) + return tmp->IsBlackForCC(true); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(PrecompiledScript) + return tmp->IsBlackForCC(false); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(PrecompiledScript) +NS_IMPL_CYCLE_COLLECTING_RELEASE(PrecompiledScript) + +} // namespace dom +} // namespace mozilla diff --git a/js/xpconnect/loader/ComponentModuleLoader.cpp b/js/xpconnect/loader/ComponentModuleLoader.cpp new file mode 100644 index 0000000000..9f293fdcc0 --- /dev/null +++ b/js/xpconnect/loader/ComponentModuleLoader.cpp @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ComponentModuleLoader.h" + +#include "nsISupportsImpl.h" + +#include "js/loader/ModuleLoadRequest.h" +#include "js/RootingAPI.h" // JS::Rooted +#include "js/PropertyAndElement.h" // JS_SetProperty +#include "js/Value.h" // JS::Value, JS::NumberValue +#include "mozJSModuleLoader.h" + +using namespace JS::loader; + +namespace mozilla { +namespace loader { + +////////////////////////////////////////////////////////////// +// ComponentScriptLoader +////////////////////////////////////////////////////////////// + +NS_IMPL_ISUPPORTS0(ComponentScriptLoader) + +nsIURI* ComponentScriptLoader::GetBaseURI() const { return nullptr; } + +void ComponentScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest, + nsresult aResult) const {} + +void ComponentScriptLoader::ReportWarningToConsole( + ScriptLoadRequest* aRequest, const char* aMessageName, + const nsTArray<nsString>& aParams) const {} + +nsresult ComponentScriptLoader::FillCompileOptionsForRequest( + JSContext* cx, ScriptLoadRequest* aRequest, JS::CompileOptions* aOptions, + JS::MutableHandle<JSScript*> aIntroductionScript) { + return NS_OK; +} + +////////////////////////////////////////////////////////////// +// ComponentModuleLoader +////////////////////////////////////////////////////////////// + +NS_IMPL_ADDREF_INHERITED(ComponentModuleLoader, JS::loader::ModuleLoaderBase) +NS_IMPL_RELEASE_INHERITED(ComponentModuleLoader, JS::loader::ModuleLoaderBase) + +NS_IMPL_CYCLE_COLLECTION_INHERITED(ComponentModuleLoader, + JS::loader::ModuleLoaderBase, mLoadRequests) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ComponentModuleLoader) +NS_INTERFACE_MAP_END_INHERITING(JS::loader::ModuleLoaderBase) + +ComponentModuleLoader::ComponentModuleLoader( + ComponentScriptLoader* aScriptLoader, nsIGlobalObject* aGlobalObject) + : ModuleLoaderBase(aScriptLoader, aGlobalObject, new SyncEventTarget()) {} + +ComponentModuleLoader::~ComponentModuleLoader() { + MOZ_ASSERT(mLoadRequests.isEmpty()); +} + +already_AddRefed<ModuleLoadRequest> ComponentModuleLoader::CreateStaticImport( + nsIURI* aURI, ModuleLoadRequest* aParent) { + RefPtr<ComponentLoadContext> context = new ComponentLoadContext(); + RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest( + aURI, aParent->mFetchOptions, dom::SRIMetadata(), aParent->mURI, context, + false, /* is top level */ + false, /* is dynamic import */ + this, aParent->mVisitedSet, aParent->GetRootModule()); + return request.forget(); +} + +already_AddRefed<ModuleLoadRequest> ComponentModuleLoader::CreateDynamicImport( + JSContext* aCx, nsIURI* aURI, LoadedScript* aMaybeActiveScript, + JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier, + JS::Handle<JSObject*> aPromise) { + return nullptr; // Not yet implemented. +} + +bool ComponentModuleLoader::CanStartLoad(ModuleLoadRequest* aRequest, + nsresult* aRvOut) { + return mozJSModuleLoader::IsTrustedScheme(aRequest->mURI); +} + +nsresult ComponentModuleLoader::StartFetch(ModuleLoadRequest* aRequest) { + MOZ_ASSERT(aRequest->HasLoadContext()); + + aRequest->mBaseURL = aRequest->mURI; + + // Loading script source and compilation are intertwined in + // mozJSModuleLoader. Perform both operations here but only report load + // failures. Compilation failure is reported in CompileFetchedModule. + + dom::AutoJSAPI jsapi; + if (!jsapi.Init(GetGlobalObject())) { + return NS_ERROR_FAILURE; + } + + JSContext* cx = jsapi.cx(); + JS::RootedScript script(cx); + nsresult rv = + mozJSModuleLoader::LoadSingleModuleScript(this, cx, aRequest, &script); + MOZ_ASSERT_IF(jsapi.HasException(), NS_FAILED(rv)); + MOZ_ASSERT(bool(script) == NS_SUCCEEDED(rv)); + + // Check for failure to load script source and abort. + bool threwException = jsapi.HasException(); + if (NS_FAILED(rv) && !threwException) { + nsAutoCString uri; + nsresult rv2 = aRequest->mURI->GetSpec(uri); + NS_ENSURE_SUCCESS(rv2, rv2); + + JS_ReportErrorUTF8(cx, "Failed to load %s", PromiseFlatCString(uri).get()); + + // Remember the error for MaybeReportLoadError. + if (!mLoadException.initialized()) { + mLoadException.init(cx); + } + if (!jsapi.StealException(&mLoadException)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (mLoadException.isObject()) { + // Expose `nsresult`. + JS::Rooted<JS::Value> resultVal(cx, JS::NumberValue(uint32_t(rv))); + JS::Rooted<JSObject*> exceptionObj(cx, &mLoadException.toObject()); + if (!JS_SetProperty(cx, exceptionObj, "result", resultVal)) { + // Ignore the error and keep reporting the exception without the result + // property. + JS_ClearPendingException(cx); + } + } + + return rv; + } + + // Otherwise remember the results in this context so we can report them later. + ComponentLoadContext* context = aRequest->GetComponentLoadContext(); + context->mRv = rv; + if (threwException) { + context->mExceptionValue.init(cx); + if (!jsapi.StealException(&context->mExceptionValue)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + if (script) { + context->mScript.init(cx); + context->mScript = script; + } + + mLoadRequests.AppendElement(aRequest); + + return NS_OK; +} + +nsresult ComponentModuleLoader::CompileFetchedModule( + JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::CompileOptions& aOptions, + ModuleLoadRequest* aRequest, JS::MutableHandle<JSObject*> aModuleOut) { + // Compilation already happened in StartFetch. Report the result here. + ComponentLoadContext* context = aRequest->GetComponentLoadContext(); + nsresult rv = context->mRv; + if (context->mScript) { + aModuleOut.set(JS::GetModuleObject(context->mScript)); + context->mScript = nullptr; + } + if (NS_FAILED(rv)) { + JS_SetPendingException(aCx, context->mExceptionValue); + context->mExceptionValue = JS::UndefinedValue(); + } + + MOZ_ASSERT(JS_IsExceptionPending(aCx) == NS_FAILED(rv)); + MOZ_ASSERT(bool(aModuleOut) == NS_SUCCEEDED(rv)); + + return rv; +} + +void ComponentModuleLoader::MaybeReportLoadError(JSContext* aCx) { + if (JS_IsExceptionPending(aCx)) { + // Do not override. + return; + } + + if (mLoadException.isUndefined()) { + return; + } + + JS_SetPendingException(aCx, mLoadException); + mLoadException = JS::UndefinedValue(); +} + +void ComponentModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {} + +nsresult ComponentModuleLoader::ProcessRequests() { + // Work list to drive module loader since this is all synchronous. + while (!mLoadRequests.isEmpty()) { + RefPtr<ScriptLoadRequest> request = mLoadRequests.StealFirst(); + nsresult rv = OnFetchComplete(request->AsModuleRequest(), NS_OK); + if (NS_FAILED(rv)) { + mLoadRequests.CancelRequestsAndClear(); + return rv; + } + } + + return NS_OK; +} + +////////////////////////////////////////////////////////////// +// ComponentModuleLoader::SyncEventTarget +////////////////////////////////////////////////////////////// + +NS_IMPL_ADDREF(ComponentModuleLoader::SyncEventTarget) +NS_IMPL_RELEASE(ComponentModuleLoader::SyncEventTarget) + +NS_INTERFACE_MAP_BEGIN(ComponentModuleLoader::SyncEventTarget) + NS_INTERFACE_MAP_ENTRY(nsISerialEventTarget) + NS_INTERFACE_MAP_ENTRY(nsIEventTarget) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::DispatchFromScript( + nsIRunnable* aRunnable, uint32_t aFlags) { + nsCOMPtr<nsIRunnable> event(aRunnable); + return Dispatch(event.forget(), aFlags); +} + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::Dispatch( + already_AddRefed<nsIRunnable> aRunnable, uint32_t aFlags) { + MOZ_ASSERT(IsOnCurrentThreadInfallible()); + + nsCOMPtr<nsIRunnable> runnable(aRunnable); + runnable->Run(); + + return NS_OK; +} + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::DelayedDispatch( + already_AddRefed<nsIRunnable>, uint32_t) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::RegisterShutdownTask( + nsITargetShutdownTask* aTask) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::UnregisterShutdownTask( + nsITargetShutdownTask* aTask) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +ComponentModuleLoader::SyncEventTarget::IsOnCurrentThread( + bool* aIsOnCurrentThread) { + MOZ_ASSERT(aIsOnCurrentThread); + *aIsOnCurrentThread = IsOnCurrentThreadInfallible(); + return NS_OK; +} + +NS_IMETHODIMP_(bool) +ComponentModuleLoader::SyncEventTarget::IsOnCurrentThreadInfallible() { + return NS_IsMainThread(); +} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/ComponentModuleLoader.h b/js/xpconnect/loader/ComponentModuleLoader.h new file mode 100644 index 0000000000..7dd39dd342 --- /dev/null +++ b/js/xpconnect/loader/ComponentModuleLoader.h @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_loader_ComponentModuleLoader_h +#define mozilla_loader_ComponentModuleLoader_h + +#include "js/loader/LoadContextBase.h" +#include "js/loader/ModuleLoaderBase.h" + +#include "SkipCheckForBrokenURLOrZeroSized.h" + +class mozJSModuleLoader; + +namespace mozilla { +namespace loader { + +class ComponentScriptLoader : public JS::loader::ScriptLoaderInterface { + public: + NS_DECL_ISUPPORTS + + private: + ~ComponentScriptLoader() = default; + + nsIURI* GetBaseURI() const override; + + void ReportErrorToConsole(ScriptLoadRequest* aRequest, + nsresult aResult) const override; + + void ReportWarningToConsole(ScriptLoadRequest* aRequest, + const char* aMessageName, + const nsTArray<nsString>& aParams) const override; + + nsresult FillCompileOptionsForRequest( + JSContext* cx, ScriptLoadRequest* aRequest, JS::CompileOptions* aOptions, + JS::MutableHandle<JSScript*> aIntroductionScript) override; +}; + +class ComponentModuleLoader : public JS::loader::ModuleLoaderBase { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ComponentModuleLoader, + JS::loader::ModuleLoaderBase) + + ComponentModuleLoader(ComponentScriptLoader* aScriptLoader, + nsIGlobalObject* aGlobalObject); + + [[nodiscard]] nsresult ProcessRequests(); + + void MaybeReportLoadError(JSContext* aCx); + + private: + // An event target that dispatches runnables by executing them + // immediately. This is used to drive mozPromise dispatch for + // ComponentModuleLoader. + class SyncEventTarget : public nsISerialEventTarget { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIEVENTTARGET_FULL + private: + virtual ~SyncEventTarget() = default; + }; + + ~ComponentModuleLoader(); + + already_AddRefed<ModuleLoadRequest> CreateStaticImport( + nsIURI* aURI, ModuleLoadRequest* aParent) override; + + already_AddRefed<ModuleLoadRequest> CreateDynamicImport( + JSContext* aCx, nsIURI* aURI, LoadedScript* aMaybeActiveScript, + JS::Handle<JS::Value> aReferencingPrivate, + JS::Handle<JSString*> aSpecifier, + JS::Handle<JSObject*> aPromise) override; + + bool CanStartLoad(ModuleLoadRequest* aRequest, nsresult* aRvOut) override; + + nsresult StartFetch(ModuleLoadRequest* aRequest) override; + + nsresult CompileFetchedModule( + JSContext* aCx, JS::Handle<JSObject*> aGlobal, + JS::CompileOptions& aOptions, ModuleLoadRequest* aRequest, + JS::MutableHandle<JSObject*> aModuleScript) override; + + void OnModuleLoadComplete(ModuleLoadRequest* aRequest) override; + + JS::loader::ScriptLoadRequestList mLoadRequests; + + // If any of module scripts failed to load, exception is set here until it's + // reported by MaybeReportLoadError. + JS::PersistentRooted<JS::Value> mLoadException; +}; + +// Data specific to ComponentModuleLoader that is associated with each load +// request. +class ComponentLoadContext : public JS::loader::LoadContextBase { + public: + ComponentLoadContext() + : LoadContextBase(JS::loader::ContextKind::Component) {} + + public: + // The result of compiling a module script. These fields are used temporarily + // before being passed to the module loader. + nsresult mRv; + + SkipCheckForBrokenURLOrZeroSized mSkipCheck; + + // The exception thrown during compiling a module script. These fields are + // used temporarily before being passed to the module loader. + JS::PersistentRooted<JS::Value> mExceptionValue; + + JS::PersistentRooted<JSScript*> mScript; +}; + +} // namespace loader +} // namespace mozilla + +#endif // mozilla_loader_ComponentModuleLoader_h diff --git a/js/xpconnect/loader/ComponentUtils.sys.mjs b/js/xpconnect/loader/ComponentUtils.sys.mjs new file mode 100644 index 0000000000..cfffb96ef7 --- /dev/null +++ b/js/xpconnect/loader/ComponentUtils.sys.mjs @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=2 et filetype=javascript + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Deprecated utilities for JavaScript components loaded by the JS component + * loader. + */ + +const nsIFactoryQI = ChromeUtils.generateQI(["nsIFactory"]); + +export var ComponentUtils = { + /** + * Generates a singleton nsIFactory implementation that can be used as + * an argument to nsIComponentRegistrar.registerFactory. + * @param aServiceConstructor + * Constructor function of the component. + */ + generateSingletonFactory(aServiceConstructor) { + return { + _instance: null, + createInstance(aIID) { + if (this._instance === null) { + this._instance = new aServiceConstructor(); + } + return this._instance.QueryInterface(aIID); + }, + QueryInterface: nsIFactoryQI, + }; + }, +}; diff --git a/js/xpconnect/loader/IOBuffers.h b/js/xpconnect/loader/IOBuffers.h new file mode 100644 index 0000000000..e26b0c3bca --- /dev/null +++ b/js/xpconnect/loader/IOBuffers.h @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef IOBuffers_h +#define IOBuffers_h + +#include "mozilla/Assertions.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/EndianUtils.h" +#include "mozilla/EnumSet.h" +#include "mozilla/Range.h" +#include "mozilla/Span.h" +#include "nsString.h" +#include "nsTArray.h" + +namespace mozilla { +namespace loader { + +class OutputBuffer { + public: + OutputBuffer() {} + + uint8_t* write(size_t size) { + auto buf = data.AppendElements(size); + cursor_ += size; + return buf; + } + + void codeUint8(const uint8_t& val) { *write(sizeof val) = val; } + + template <typename T> + void codeUint8(const EnumSet<T>& val) { + // EnumSets are always represented as uint32_t values, so we need to + // assert that the value actually fits in a uint8 before writing it. + uint32_t value = val.serialize(); + codeUint8(CheckedUint8(value).value()); + } + + void codeUint16(const uint16_t& val) { + LittleEndian::writeUint16(write(sizeof val), val); + } + + void codeUint32(const uint32_t& val) { + LittleEndian::writeUint32(write(sizeof val), val); + } + + void codeString(const nsCString& str) { + auto len = CheckedUint16(str.Length()).value(); + + codeUint16(len); + memcpy(write(len), str.BeginReading(), len); + } + + size_t cursor() const { return cursor_; } + + uint8_t* Get() { return data.Elements(); } + + const uint8_t* Get() const { return data.Elements(); } + + private: + nsTArray<uint8_t> data; + size_t cursor_ = 0; +}; + +class InputBuffer { + public: + explicit InputBuffer(const Range<uint8_t>& buffer) : data(buffer) {} + + const uint8_t* read(size_t size) { + MOZ_ASSERT(checkCapacity(size)); + + auto buf = &data[cursor_]; + cursor_ += size; + return buf; + } + + bool codeUint8(uint8_t& val) { + if (checkCapacity(sizeof val)) { + val = *read(sizeof val); + } + return !error_; + } + + template <typename T> + bool codeUint8(EnumSet<T>& val) { + uint8_t value; + if (codeUint8(value)) { + val.deserialize(value); + } + return !error_; + } + + bool codeUint16(uint16_t& val) { + if (checkCapacity(sizeof val)) { + val = LittleEndian::readUint16(read(sizeof val)); + } + return !error_; + } + + bool codeUint32(uint32_t& val) { + if (checkCapacity(sizeof val)) { + val = LittleEndian::readUint32(read(sizeof val)); + } + return !error_; + } + + bool codeString(nsCString& str) { + uint16_t len; + if (codeUint16(len)) { + if (checkCapacity(len)) { + str.SetLength(len); + memcpy(str.BeginWriting(), read(len), len); + } + } + return !error_; + } + + bool error() { return error_; } + + bool finished() { return error_ || !remainingCapacity(); } + + size_t remainingCapacity() { return data.length() - cursor_; } + + size_t cursor() const { return cursor_; } + + const uint8_t* Get() const { return data.begin().get(); } + + private: + bool checkCapacity(size_t size) { + if (size > remainingCapacity()) { + error_ = true; + } + return !error_; + } + + bool error_ = false; + + public: + const Range<uint8_t>& data; + size_t cursor_ = 0; +}; + +} // namespace loader +} // namespace mozilla + +#endif // IOBuffers_h diff --git a/js/xpconnect/loader/JSMEnvironmentProxy.cpp b/js/xpconnect/loader/JSMEnvironmentProxy.cpp new file mode 100644 index 0000000000..6c4a532d44 --- /dev/null +++ b/js/xpconnect/loader/JSMEnvironmentProxy.cpp @@ -0,0 +1,260 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "JSMEnvironmentProxy.h" + +#include "mozilla/Assertions.h" // MOZ_ASSERT +#include "mozilla/Maybe.h" // mozilla::Maybe + +#include <stddef.h> // size_t + +#include "jsapi.h" // JS_HasExtensibleLexicalEnvironment, JS_ExtensibleLexicalEnvironment +#include "js/Class.h" // JS::ObjectOpResult +#include "js/ErrorReport.h" // JS_ReportOutOfMemory +#include "js/GCVector.h" // JS::RootedVector +#include "js/Id.h" // JS::PropertyKey +#include "js/PropertyAndElement.h" // JS::IdVector, JS_HasPropertyById, JS_HasOwnPropertyById, JS_GetPropertyById, JS_Enumerate +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById +#include "js/Proxy.h" // js::ProxyOptions, js::NewProxyObject, js::GetProxyPrivate +#include "js/RootingAPI.h" // JS::Rooted, JS::Handle, JS::MutableHandle +#include "js/TypeDecls.h" // JSContext, JSObject, JS::MutableHandleVector +#include "js/Value.h" // JS::Value, JS::UndefinedValue, JS_UNINITIALIZED_LEXICAL +#include "js/friend/ErrorMessages.h" // JSMSG_* + +namespace mozilla { +namespace loader { + +struct JSMEnvironmentProxyHandler : public js::BaseProxyHandler { + JSMEnvironmentProxyHandler() : BaseProxyHandler(&gFamily, false) {} + + bool defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::Handle<JS::PropertyDescriptor> aDesc, + JS::ObjectOpResult& aResult) const override { + return aResult.fail(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE); + } + + bool getPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandle<JSObject*> aProtop) const override { + aProtop.set(nullptr); + return true; + } + + bool setPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JSObject*> aProto, + JS::ObjectOpResult& aResult) const override { + if (!aProto) { + return aResult.succeed(); + } + return aResult.failCantSetProto(); + } + + bool getPrototypeIfOrdinary( + JSContext* aCx, JS::Handle<JSObject*> aProxy, bool* aIsOrdinary, + JS::MutableHandle<JSObject*> aProtop) const override { + *aIsOrdinary = false; + return true; + } + + bool setImmutablePrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + bool* aSucceeded) const override { + *aSucceeded = true; + return true; + } + + bool preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::ObjectOpResult& aResult) const override { + aResult.succeed(); + return true; + } + + bool isExtensible(JSContext* aCx, JS::Handle<JSObject*> aProxy, + bool* aExtensible) const override { + *aExtensible = false; + return true; + } + + bool set(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, JS::Handle<JS::Value> aValue, + JS::Handle<JS::Value> aReceiver, + JS::ObjectOpResult& aResult) const override { + return aResult.failReadOnly(); + } + + bool delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::ObjectOpResult& aResult) const override { + return aResult.failCantDelete(); + } + + bool getOwnPropertyDescriptor( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) + const override; + bool has(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, bool* aBp) const override; + bool get(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::Value> aReceiver, JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<JS::Value> aVp) const override; + bool ownPropertyKeys( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandleVector<JS::PropertyKey> aProps) const override; + + private: + static JSObject* getGlobal(JSContext* aCx, JS::Handle<JSObject*> aProxy) { + JS::Rooted<JSObject*> globalObj(aCx, + &js::GetProxyPrivate(aProxy).toObject()); + return globalObj; + } + + public: + static const char gFamily; + static const JSMEnvironmentProxyHandler gHandler; +}; + +const JSMEnvironmentProxyHandler JSMEnvironmentProxyHandler::gHandler; +const char JSMEnvironmentProxyHandler::gFamily = 0; + +JSObject* ResolveModuleObjectPropertyById(JSContext* aCx, + JS::Handle<JSObject*> aModObj, + JS::Handle<JS::PropertyKey> aId) { + if (JS_HasExtensibleLexicalEnvironment(aModObj)) { + JS::Rooted<JSObject*> lexical(aCx, + JS_ExtensibleLexicalEnvironment(aModObj)); + bool found; + if (!JS_HasOwnPropertyById(aCx, lexical, aId, &found)) { + return nullptr; + } + if (found) { + return lexical; + } + } + return aModObj; +} + +JSObject* ResolveModuleObjectProperty(JSContext* aCx, + JS::Handle<JSObject*> aModObj, + const char* aName) { + if (JS_HasExtensibleLexicalEnvironment(aModObj)) { + JS::RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj)); + bool found; + if (!JS_HasOwnProperty(aCx, lexical, aName, &found)) { + return nullptr; + } + if (found) { + return lexical; + } + } + return aModObj; +} + +bool JSMEnvironmentProxyHandler::getOwnPropertyDescriptor( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) const { + JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy)); + JS::Rooted<JSObject*> holder( + aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId)); + if (!JS_GetOwnPropertyDescriptorById(aCx, holder, aId, aDesc)) { + return false; + } + + if (aDesc.get().isNothing()) { + return true; + } + + JS::PropertyDescriptor& desc = *aDesc.get(); + + if (desc.hasValue()) { + if (desc.value().isMagic(JS_UNINITIALIZED_LEXICAL)) { + desc.setValue(JS::UndefinedValue()); + } + } + + desc.setConfigurable(false); + desc.setEnumerable(true); + if (!desc.isAccessorDescriptor()) { + desc.setWritable(false); + } + + return true; +} + +bool JSMEnvironmentProxyHandler::has(JSContext* aCx, + JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + bool* aBp) const { + JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy)); + JS::Rooted<JSObject*> holder( + aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId)); + return JS_HasPropertyById(aCx, holder, aId, aBp); +} + +bool JSMEnvironmentProxyHandler::get(JSContext* aCx, + JS::Handle<JSObject*> aProxy, + JS::Handle<JS::Value> aReceiver, + JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<JS::Value> aVp) const { + JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy)); + JS::Rooted<JSObject*> holder( + aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId)); + if (!JS_GetPropertyById(aCx, holder, aId, aVp)) { + return false; + } + + if (aVp.isMagic(JS_UNINITIALIZED_LEXICAL)) { + aVp.setUndefined(); + } + + return true; +} + +bool JSMEnvironmentProxyHandler::ownPropertyKeys( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandleVector<JS::PropertyKey> aProps) const { + JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy)); + JS::Rooted<JS::IdVector> globalIds(aCx, JS::IdVector(aCx)); + if (!JS_Enumerate(aCx, globalObj, &globalIds)) { + return false; + } + + for (size_t i = 0; i < globalIds.length(); i++) { + if (!aProps.append(globalIds[i])) { + JS_ReportOutOfMemory(aCx); + return false; + } + } + + JS::RootedObject lexicalEnv(aCx, JS_ExtensibleLexicalEnvironment(globalObj)); + JS::Rooted<JS::IdVector> lexicalIds(aCx, JS::IdVector(aCx)); + if (!JS_Enumerate(aCx, lexicalEnv, &lexicalIds)) { + return false; + } + + for (size_t i = 0; i < lexicalIds.length(); i++) { + if (!aProps.append(lexicalIds[i])) { + JS_ReportOutOfMemory(aCx); + return false; + } + } + + return true; +} + +JSObject* CreateJSMEnvironmentProxy(JSContext* aCx, + JS::Handle<JSObject*> aGlobalObj) { + js::ProxyOptions options; + options.setLazyProto(true); + + JS::Rooted<JS::Value> globalVal(aCx, JS::ObjectValue(*aGlobalObj)); + return NewProxyObject(aCx, &JSMEnvironmentProxyHandler::gHandler, globalVal, + nullptr, options); +} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/JSMEnvironmentProxy.h b/js/xpconnect/loader/JSMEnvironmentProxy.h new file mode 100644 index 0000000000..f45d7e3801 --- /dev/null +++ b/js/xpconnect/loader/JSMEnvironmentProxy.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_loader_JSMEnvironmentProxy_h +#define mozilla_loader_JSMEnvironmentProxy_h + +#include "js/Id.h" // JS::PropertyKey +#include "js/TypeDecls.h" // JSContext, JSObject +#include "js/RootingAPI.h" // JS::Handle + +namespace mozilla { +namespace loader { + +JSObject* ResolveModuleObjectPropertyById(JSContext* aCx, + JS::Handle<JSObject*> aModObj, + JS::Handle<JS::PropertyKey> aId); + +JSObject* ResolveModuleObjectProperty(JSContext* aCx, + JS::Handle<JSObject*> aModObj, + const char* aName); + +JSObject* CreateJSMEnvironmentProxy(JSContext* aCx, + JS::Handle<JSObject*> aGlobalObj); + +} // namespace loader +} // namespace mozilla + +#endif // mozilla_loader_JSMEnvironmentProxy_h diff --git a/js/xpconnect/loader/ModuleEnvironmentProxy.cpp b/js/xpconnect/loader/ModuleEnvironmentProxy.cpp new file mode 100644 index 0000000000..d513bc6194 --- /dev/null +++ b/js/xpconnect/loader/ModuleEnvironmentProxy.cpp @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ModuleEnvironmentProxy.h" + +#include "mozilla/Assertions.h" // MOZ_ASSERT +#include "mozilla/Maybe.h" // mozilla::Maybe + +#include <stddef.h> // size_t + +#include "js/Class.h" // JS::ObjectOpResult +#include "js/ErrorReport.h" // JS_ReportOutOfMemory +#include "js/GCVector.h" // JS::RootedVector +#include "js/Id.h" // JS::PropertyKey +#include "js/PropertyAndElement.h" // JS::IdVector, JS_HasPropertyById, JS_GetPropertyById, JS_Enumerate +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById +#include "js/Proxy.h" // js::ProxyOptions, js::NewProxyObject, js::GetProxyPrivate +#include "js/RootingAPI.h" // JS::Rooted, JS::Handle, JS::MutableHandle +#include "js/TypeDecls.h" // JSContext, JSObject, JS::MutableHandleVector +#include "js/Value.h" // JS::Value +#include "js/friend/ErrorMessages.h" // JSMSG_* +#include "js/String.h" +#include "js/Modules.h" + +namespace mozilla { +namespace loader { + +struct ModuleEnvironmentProxyHandler : public js::BaseProxyHandler { + ModuleEnvironmentProxyHandler() : js::BaseProxyHandler(&gFamily, false) {} + + bool defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::Handle<JS::PropertyDescriptor> aDesc, + JS::ObjectOpResult& aResult) const override { + return aResult.fail(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE); + } + + bool getPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandle<JSObject*> aProtop) const override { + aProtop.set(nullptr); + return true; + } + + bool setPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JSObject*> aProto, + JS::ObjectOpResult& aResult) const override { + if (!aProto) { + return aResult.succeed(); + } + return aResult.failCantSetProto(); + } + + bool getPrototypeIfOrdinary( + JSContext* aCx, JS::Handle<JSObject*> aProxy, bool* aIsOrdinary, + JS::MutableHandle<JSObject*> aProtop) const override { + *aIsOrdinary = false; + return true; + } + + bool setImmutablePrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy, + bool* aSucceeded) const override { + *aSucceeded = true; + return true; + } + + bool preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::ObjectOpResult& aResult) const override { + aResult.succeed(); + return true; + } + + bool isExtensible(JSContext* aCx, JS::Handle<JSObject*> aProxy, + bool* aExtensible) const override { + *aExtensible = false; + return true; + } + + bool set(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, JS::Handle<JS::Value> aValue, + JS::Handle<JS::Value> aReceiver, + JS::ObjectOpResult& aResult) const override { + return aResult.failReadOnly(); + } + + bool delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::ObjectOpResult& aResult) const override { + return aResult.failCantDelete(); + } + + bool getOwnPropertyDescriptor( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) + const override; + bool has(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, bool* aBp) const override; + bool get(JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::Value> receiver, JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<JS::Value> aVp) const override; + bool ownPropertyKeys( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandleVector<JS::PropertyKey> aProps) const override; + + private: + static JSObject* getEnvironment(JS::Handle<JSObject*> aProxy) { + return &js::GetProxyPrivate(aProxy).toObject(); + } + + static bool equalsNamespace(JSContext* aCx, JS::Handle<JS::PropertyKey> aId, + bool* aMatch) { + if (!aId.isString()) { + *aMatch = false; + return true; + } + return JS_StringEqualsLiteral(aCx, aId.toString(), "*namespace*", aMatch); + } + + public: + static const char gFamily; + static const ModuleEnvironmentProxyHandler gHandler; +}; + +const ModuleEnvironmentProxyHandler ModuleEnvironmentProxyHandler::gHandler; +const char ModuleEnvironmentProxyHandler::gFamily = 0; + +bool ModuleEnvironmentProxyHandler::getOwnPropertyDescriptor( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) const { + bool isNamespace; + if (!equalsNamespace(aCx, aId, &isNamespace)) { + return false; + } + if (isNamespace) { + aDesc.reset(); + return true; + } + + JS::Rooted<JSObject*> envObj(aCx, getEnvironment(aProxy)); + if (!JS_GetOwnPropertyDescriptorById(aCx, envObj, aId, aDesc)) { + return false; + } + + if (aDesc.get().isNothing()) { + return true; + } + + JS::PropertyDescriptor& desc = *aDesc.get(); + + desc.setConfigurable(false); + desc.setWritable(false); + desc.setEnumerable(true); + + return true; +} + +bool ModuleEnvironmentProxyHandler::has(JSContext* aCx, + JS::Handle<JSObject*> aProxy, + JS::Handle<JS::PropertyKey> aId, + bool* aBp) const { + bool isNamespace; + if (!equalsNamespace(aCx, aId, &isNamespace)) { + return false; + } + if (isNamespace) { + *aBp = false; + return true; + } + + JS::Rooted<JSObject*> envObj(aCx, getEnvironment(aProxy)); + return JS_HasOwnPropertyById(aCx, envObj, aId, aBp); +} + +bool ModuleEnvironmentProxyHandler::get( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::Handle<JS::Value> aReceiver, JS::Handle<JS::PropertyKey> aId, + JS::MutableHandle<JS::Value> aVp) const { + bool isNamespace; + if (!equalsNamespace(aCx, aId, &isNamespace)) { + return false; + } + if (isNamespace) { + aVp.setUndefined(); + return true; + } + + JS::Rooted<JSObject*> envObj(aCx, getEnvironment(aProxy)); + return JS_GetPropertyById(aCx, envObj, aId, aVp); +} + +bool ModuleEnvironmentProxyHandler::ownPropertyKeys( + JSContext* aCx, JS::Handle<JSObject*> aProxy, + JS::MutableHandleVector<JS::PropertyKey> aProps) const { + JS::Rooted<JSObject*> envObj(aCx, getEnvironment(aProxy)); + JS::Rooted<JS::IdVector> ids(aCx, JS::IdVector(aCx)); + if (!JS_Enumerate(aCx, envObj, &ids)) { + return false; + } + + for (size_t i = 0; i < ids.length(); i++) { + bool isNamespace; + if (!equalsNamespace(aCx, ids[i], &isNamespace)) { + return false; + } + if (isNamespace) { + continue; + } + if (!aProps.append(ids[i])) { + JS_ReportOutOfMemory(aCx); + return false; + } + } + + return true; +} + +JSObject* CreateModuleEnvironmentProxy(JSContext* aCx, + JS::Handle<JSObject*> aModuleObj) { + js::ProxyOptions options; + options.setLazyProto(true); + + JS::Rooted<JSObject*> envObj(aCx, JS::GetModuleEnvironment(aCx, aModuleObj)); + if (!envObj) { + return nullptr; + } + + JS::Rooted<JS::Value> envVal(aCx, JS::ObjectValue(*envObj)); + return NewProxyObject(aCx, &ModuleEnvironmentProxyHandler::gHandler, envVal, + nullptr, options); +} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/ModuleEnvironmentProxy.h b/js/xpconnect/loader/ModuleEnvironmentProxy.h new file mode 100644 index 0000000000..d59f6de5b3 --- /dev/null +++ b/js/xpconnect/loader/ModuleEnvironmentProxy.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_loader_ModuleEnvironmentProxy_h +#define mozilla_loader_ModuleEnvironmentProxy_h + +#include "js/TypeDecls.h" // JSContext, JSObject +#include "js/RootingAPI.h" // JS::Handle + +namespace mozilla { +namespace loader { + +// Create an object that works in the same way as global object returned by +// `Cu.import`. This proxy exposes all global variables, including lexical +// variables. +// +// This is a temporary workaround to support not-in-tree code that depends on +// `Cu.import` return value. +// +// This will eventually be removed once ESM-ification finishes. +JSObject* CreateModuleEnvironmentProxy(JSContext* aCx, + JS::Handle<JSObject*> aModuleObj); + +} // namespace loader +} // namespace mozilla + +#endif // mozilla_loader_ModuleEnvironmentProxy_h diff --git a/js/xpconnect/loader/PScriptCache.ipdl b/js/xpconnect/loader/PScriptCache.ipdl new file mode 100644 index 0000000000..e22166c16d --- /dev/null +++ b/js/xpconnect/loader/PScriptCache.ipdl @@ -0,0 +1,36 @@ +/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PContent; + +include "mozilla/loader/ScriptCacheActors.h"; + +using class mozilla::TimeStamp from "mozilla/TimeStamp.h"; +using struct mozilla::void_t from "mozilla/ipc/IPCCore.h"; + +namespace mozilla { +namespace loader { + +struct ScriptData { + nsCString url; + nsCString cachePath; + TimeStamp loadTime; + // This will be an empty array if script data is present in the previous + // session's cache. + uint8_t[] xdrData; +}; + +[ManualDealloc, ChildImpl="ScriptCacheChild", ParentImpl="ScriptCacheParent"] +protocol PScriptCache +{ + manager PContent; + +parent: + async __delete__(ScriptData[] scripts); +}; + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/PrecompiledScript.h b/js/xpconnect/loader/PrecompiledScript.h new file mode 100644 index 0000000000..2b49c05373 --- /dev/null +++ b/js/xpconnect/loader/PrecompiledScript.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_PrecompiledScript_h +#define mozilla_dom_PrecompiledScript_h + +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/PrecompiledScriptBinding.h" +#include "mozilla/RefPtr.h" + +#include "js/experimental/JSStencil.h" +#include "js/TypeDecls.h" + +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" + +namespace JS { +class ReadOnlyCompileOptions; +} + +namespace mozilla { +namespace dom { +class PrecompiledScript : public nsISupports, public nsWrapperCache { + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS(PrecompiledScript) + + explicit PrecompiledScript(nsISupports* aParent, RefPtr<JS::Stencil> aStencil, + JS::ReadOnlyCompileOptions& aOptions); + + void ExecuteInGlobal(JSContext* aCx, JS::Handle<JSObject*> aGlobal, + const ExecuteInGlobalOptions& aOptions, + JS::MutableHandle<JS::Value> aRval, ErrorResult& aRv); + + void GetUrl(nsAString& aUrl); + + bool HasReturnValue(); + + nsISupports* GetParentObject() const { return mParent; } + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle<JSObject*> aGivenProto) override; + + protected: + virtual ~PrecompiledScript() = default; + + private: + bool IsBlackForCC(bool aTracingNeeded); + + nsCOMPtr<nsISupports> mParent; + + RefPtr<JS::Stencil> mStencil; + nsCString mURL; + const bool mHasReturnValue; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_PrecompiledScript_h diff --git a/js/xpconnect/loader/ScriptCacheActors.cpp b/js/xpconnect/loader/ScriptCacheActors.cpp new file mode 100644 index 0000000000..9b44f0ffe6 --- /dev/null +++ b/js/xpconnect/loader/ScriptCacheActors.cpp @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/ScriptPreloader.h" +#include "ScriptPreloader-inl.h" +#include "mozilla/loader/ScriptCacheActors.h" + +#include "mozilla/dom/ContentParent.h" + +namespace mozilla { +namespace loader { + +void ScriptCacheChild::Init(const Maybe<FileDescriptor>& cacheFile, + bool wantCacheData) { + mWantCacheData = wantCacheData; + + auto& cache = ScriptPreloader::GetChildSingleton(); + Unused << cache.InitCache(cacheFile, this); + + if (!wantCacheData) { + // If the parent process isn't expecting any cache data from us, we're + // done. + Send__delete__(this, AutoTArray<ScriptData, 0>()); + } +} + +// Finalize the script cache for the content process, and send back data about +// any scripts executed up to this point. +void ScriptCacheChild::SendScriptsAndFinalize( + ScriptPreloader::ScriptHash& scripts) { + MOZ_ASSERT(mWantCacheData); + + AutoSafeJSAPI jsapi; + + auto matcher = ScriptPreloader::Match<ScriptPreloader::ScriptStatus::Saved>(); + + nsTArray<ScriptData> dataArray; + for (auto& script : IterHash(scripts, matcher)) { + if (!script->mSize && !script->XDREncode(jsapi.cx())) { + continue; + } + + auto data = dataArray.AppendElement(); + + data->url() = script->mURL; + data->cachePath() = script->mCachePath; + data->loadTime() = script->mLoadTime; + + if (script->HasBuffer()) { + auto& xdrData = script->Buffer(); + data->xdrData().AppendElements(xdrData.begin(), xdrData.length()); + script->FreeData(); + } + } + + Send__delete__(this, dataArray); +} + +void ScriptCacheChild::ActorDestroy(ActorDestroyReason aWhy) { + auto& cache = ScriptPreloader::GetChildSingleton(); + cache.mChildActor = nullptr; +} + +IPCResult ScriptCacheParent::Recv__delete__(nsTArray<ScriptData>&& scripts) { + if (!mWantCacheData && scripts.Length()) { + return IPC_FAIL(this, "UnexpectedScriptData"); + } + + // We don't want any more data from the process at this point. + mWantCacheData = false; + + // Merge the child's script data with the parent's. + auto parent = static_cast<dom::ContentParent*>(Manager()); + auto processType = + ScriptPreloader::GetChildProcessType(parent->GetRemoteType()); + + auto& cache = ScriptPreloader::GetChildSingleton(); + for (auto& script : scripts) { + cache.NoteStencil(script.url(), script.cachePath(), processType, + std::move(script.xdrData()), script.loadTime()); + } + + return IPC_OK(); +} + +void ScriptCacheParent::ActorDestroy(ActorDestroyReason aWhy) {} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/ScriptCacheActors.h b/js/xpconnect/loader/ScriptCacheActors.h new file mode 100644 index 0000000000..92148464ea --- /dev/null +++ b/js/xpconnect/loader/ScriptCacheActors.h @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef ScriptCache_h +#define ScriptCache_h + +#include "mozilla/ScriptPreloader.h" +#include "mozilla/loader/PScriptCacheChild.h" +#include "mozilla/loader/PScriptCacheParent.h" + +namespace mozilla { +namespace ipc { +class FileDescriptor; +} + +namespace loader { + +using mozilla::ipc::FileDescriptor; +using mozilla::ipc::IPCResult; + +class ScriptCacheParent final : public PScriptCacheParent { + friend class PScriptCacheParent; + + public: + explicit ScriptCacheParent(bool wantCacheData) + : mWantCacheData(wantCacheData) {} + + protected: + IPCResult Recv__delete__(nsTArray<ScriptData>&& scripts); + + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + + private: + bool mWantCacheData; +}; + +class ScriptCacheChild final : public PScriptCacheChild { + friend class mozilla::ScriptPreloader; + + public: + ScriptCacheChild() = default; + + void Init(const Maybe<FileDescriptor>& cacheFile, bool wantCacheData); + + protected: + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + + void SendScriptsAndFinalize(ScriptPreloader::ScriptHash& scripts); + + private: + bool mWantCacheData = false; +}; + +} // namespace loader +} // namespace mozilla + +#endif // ScriptCache_h diff --git a/js/xpconnect/loader/ScriptPreloader-inl.h b/js/xpconnect/loader/ScriptPreloader-inl.h new file mode 100644 index 0000000000..5908600616 --- /dev/null +++ b/js/xpconnect/loader/ScriptPreloader-inl.h @@ -0,0 +1,167 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef ScriptPreloader_inl_h +#define ScriptPreloader_inl_h + +#include "mozilla/Attributes.h" +#include "mozilla/Assertions.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/EndianUtils.h" +#include "mozilla/EnumSet.h" +#include "mozilla/Range.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/Unused.h" +#include "mozilla/dom/ScriptSettings.h" +#include "nsString.h" +#include "nsTArray.h" + +#include <prio.h> + +namespace mozilla { + +namespace loader { + +using mozilla::dom::AutoJSAPI; + +static inline Result<Ok, nsresult> Write(PRFileDesc* fd, const void* data, + int32_t len) { + if (PR_Write(fd, data, len) != len) { + return Err(NS_ERROR_FAILURE); + } + return Ok(); +} + +static inline Result<Ok, nsresult> WritePadding(PRFileDesc* fd, + uint8_t padding) { + static const char paddingBytes[8] = "PADBYTE"; + MOZ_DIAGNOSTIC_ASSERT(padding <= sizeof(paddingBytes)); + + if (padding == 0) { + return Ok(); + } + + if (PR_Write(fd, static_cast<const void*>(paddingBytes), padding) != + padding) { + return Err(NS_ERROR_FAILURE); + } + return Ok(); +} + +struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI { + AutoSafeJSAPI() { Init(); } +}; + +template <typename T> +struct Matcher; + +// Wraps the iterator for a nsTHashTable so that it may be used as a range +// iterator. Each iterator result acts as a smart pointer to the hash element, +// and has a Remove() method which will remove the element from the hash. +// +// It also accepts an optional Matcher instance against which to filter the +// elements which should be iterated over. +// +// Example: +// +// for (auto& elem : HashElemIter<HashType>(hash)) { +// if (elem->IsDead()) { +// elem.Remove(); +// } +// } +template <typename T> +class HashElemIter { + using Iterator = typename T::Iterator; + using ElemType = typename T::UserDataType; + + T& hash_; + Matcher<ElemType>* matcher_; + Iterator iter_; + + public: + explicit HashElemIter(T& hash, Matcher<ElemType>* matcher = nullptr) + : hash_(hash), matcher_(matcher), iter_(hash.Iter()) {} + + class Elem { + friend class HashElemIter<T>; + + HashElemIter<T>& iter_; + bool done_; + + Elem(HashElemIter& iter, bool done) : iter_(iter), done_(done) { + skipNonMatching(); + } + + Iterator& iter() { return iter_.iter_; } + + void skipNonMatching() { + if (iter_.matcher_) { + while (!done_ && !iter_.matcher_->Matches(get())) { + iter().Next(); + done_ = iter().Done(); + } + } + } + + public: + Elem& operator*() { return *this; } + + ElemType get() { + if (done_) { + return nullptr; + } + return iter().UserData(); + } + + const ElemType get() const { return const_cast<Elem*>(this)->get(); } + + ElemType operator->() { return get(); } + + const ElemType operator->() const { return get(); } + + operator ElemType() { return get(); } + + void Remove() { iter().Remove(); } + + Elem& operator++() { + MOZ_ASSERT(!done_); + + iter().Next(); + done_ = iter().Done(); + + skipNonMatching(); + return *this; + } + + bool operator!=(Elem& other) const { + return done_ != other.done_ || this->get() != other.get(); + } + }; + + Elem begin() { return Elem(*this, iter_.Done()); } + + Elem end() { return Elem(*this, true); } +}; + +template <typename T> +HashElemIter<T> IterHash(T& hash, + Matcher<typename T::UserDataType>* matcher = nullptr) { + return HashElemIter<T>(hash, matcher); +} + +template <typename T, typename F> +bool Find(T&& iter, F&& match) { + for (auto& elem : iter) { + if (match(elem)) { + return true; + } + } + return false; +} + +}; // namespace loader +}; // namespace mozilla + +#endif // ScriptPreloader_inl_h diff --git a/js/xpconnect/loader/ScriptPreloader.cpp b/js/xpconnect/loader/ScriptPreloader.cpp new file mode 100644 index 0000000000..22b788127c --- /dev/null +++ b/js/xpconnect/loader/ScriptPreloader.cpp @@ -0,0 +1,1319 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ScriptPreloader-inl.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/Monitor.h" + +#include "mozilla/ScriptPreloader.h" +#include "mozilla/loader/ScriptCacheActors.h" + +#include "mozilla/URLPreloader.h" + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Components.h" +#include "mozilla/FileUtils.h" +#include "mozilla/IOBuffers.h" +#include "mozilla/Logging.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/Services.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/Document.h" +#include "mozilla/scache/StartupCache.h" + +#include "crc32c.h" +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions +#include "js/experimental/JSStencil.h" +#include "js/Transcoding.h" +#include "MainThreadUtils.h" +#include "nsDebug.h" +#include "nsDirectoryServiceUtils.h" +#include "nsIFile.h" +#include "nsIObserverService.h" +#include "nsJSUtils.h" +#include "nsMemoryReporterManager.h" +#include "nsNetUtil.h" +#include "nsProxyRelease.h" +#include "nsThreadUtils.h" +#include "nsXULAppAPI.h" +#include "xpcpublic.h" + +#define STARTUP_COMPLETE_TOPIC "browser-delayed-startup-finished" +#define DOC_ELEM_INSERTED_TOPIC "document-element-inserted" +#define CONTENT_DOCUMENT_LOADED_TOPIC "content-document-loaded" +#define CACHE_WRITE_TOPIC "browser-idle-startup-tasks-finished" +#define XPCOM_SHUTDOWN_TOPIC "xpcom-shutdown" +#define CACHE_INVALIDATE_TOPIC "startupcache-invalidate" + +// The maximum time we'll wait for a child process to finish starting up before +// we send its script data back to the parent. +constexpr uint32_t CHILD_STARTUP_TIMEOUT_MS = 8000; + +namespace mozilla { +namespace { +static LazyLogModule gLog("ScriptPreloader"); + +#define LOG(level, ...) MOZ_LOG(gLog, LogLevel::level, (__VA_ARGS__)) +} // namespace + +using mozilla::dom::AutoJSAPI; +using mozilla::dom::ContentChild; +using mozilla::dom::ContentParent; +using namespace mozilla::loader; +using mozilla::scache::StartupCache; + +using namespace JS; + +ProcessType ScriptPreloader::sProcessType; + +nsresult ScriptPreloader::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) { + MOZ_COLLECT_REPORT( + "explicit/script-preloader/heap/saved-scripts", KIND_HEAP, UNITS_BYTES, + SizeOfHashEntries<ScriptStatus::Saved>(mScripts, MallocSizeOf), + "Memory used to hold the scripts which have been executed in this " + "session, and will be written to the startup script cache file."); + + MOZ_COLLECT_REPORT( + "explicit/script-preloader/heap/restored-scripts", KIND_HEAP, UNITS_BYTES, + SizeOfHashEntries<ScriptStatus::Restored>(mScripts, MallocSizeOf), + "Memory used to hold the scripts which have been restored from the " + "startup script cache file, but have not been executed in this session."); + + MOZ_COLLECT_REPORT("explicit/script-preloader/heap/other", KIND_HEAP, + UNITS_BYTES, ShallowHeapSizeOfIncludingThis(MallocSizeOf), + "Memory used by the script cache service itself."); + + // Since the mem-mapped cache file is mapped into memory, we want to report + // it as explicit memory somewhere. But since the child cache is shared + // between all processes, we don't want to report it as explicit memory for + // all of them. So we report it as explicit only in the parent process, and + // non-explicit everywhere else. + if (XRE_IsParentProcess()) { + MOZ_COLLECT_REPORT("explicit/script-preloader/non-heap/memmapped-cache", + KIND_NONHEAP, UNITS_BYTES, + mCacheData->nonHeapSizeOfExcludingThis(), + "The memory-mapped startup script cache file."); + } else { + MOZ_COLLECT_REPORT("script-preloader-memmapped-cache", KIND_NONHEAP, + UNITS_BYTES, mCacheData->nonHeapSizeOfExcludingThis(), + "The memory-mapped startup script cache file."); + } + + return NS_OK; +} + +StaticRefPtr<ScriptPreloader> ScriptPreloader::gScriptPreloader; +StaticRefPtr<ScriptPreloader> ScriptPreloader::gChildScriptPreloader; +UniquePtr<AutoMemMap> ScriptPreloader::gCacheData; +UniquePtr<AutoMemMap> ScriptPreloader::gChildCacheData; + +ScriptPreloader& ScriptPreloader::GetSingleton() { + if (!gScriptPreloader) { + if (XRE_IsParentProcess()) { + gCacheData = MakeUnique<AutoMemMap>(); + gScriptPreloader = new ScriptPreloader(gCacheData.get()); + gScriptPreloader->mChildCache = &GetChildSingleton(); + Unused << gScriptPreloader->InitCache(); + } else { + gScriptPreloader = &GetChildSingleton(); + } + } + + return *gScriptPreloader; +} + +// The child singleton is available in all processes, including the parent, and +// is used for scripts which are expected to be loaded into child processes +// (such as process and frame scripts), or scripts that have already been loaded +// into a child. The child caches are managed as follows: +// +// - Every startup, we open the cache file from the last session, move it to a +// new location, and begin pre-loading the scripts that are stored in it. There +// is a separate cache file for parent and content processes, but the parent +// process opens both the parent and content cache files. +// +// - Once startup is complete, we write a new cache file for the next session, +// containing only the scripts that were used during early startup, so we +// don't waste pre-loading scripts that may not be needed. +// +// - For content processes, opening and writing the cache file is handled in the +// parent process. The first content process of each type sends back the data +// for scripts that were loaded in early startup, and the parent merges them +// and writes them to a cache file. +// +// - Currently, content processes only benefit from the cache data written +// during the *previous* session. Ideally, new content processes should +// probably use the cache data written during this session if there was no +// previous cache file, but I'd rather do that as a follow-up. +ScriptPreloader& ScriptPreloader::GetChildSingleton() { + if (!gChildScriptPreloader) { + gChildCacheData = MakeUnique<AutoMemMap>(); + gChildScriptPreloader = new ScriptPreloader(gChildCacheData.get()); + if (XRE_IsParentProcess()) { + Unused << gChildScriptPreloader->InitCache(u"scriptCache-child"_ns); + } + } + + return *gChildScriptPreloader; +} + +/* static */ +void ScriptPreloader::DeleteSingleton() { + gScriptPreloader = nullptr; + gChildScriptPreloader = nullptr; +} + +/* static */ +void ScriptPreloader::DeleteCacheDataSingleton() { + MOZ_ASSERT(!gScriptPreloader); + MOZ_ASSERT(!gChildScriptPreloader); + + gCacheData = nullptr; + gChildCacheData = nullptr; +} + +void ScriptPreloader::InitContentChild(ContentParent& parent) { + auto& cache = GetChildSingleton(); + cache.mSaveMonitor.AssertOnWritingThread(); + + // We want startup script data from the first process of a given type. + // That process sends back its script data before it executes any + // untrusted code, and then we never accept further script data for that + // type of process for the rest of the session. + // + // The script data from each process type is merged with the data from the + // parent process's frame and process scripts, and shared between all + // content process types in the next session. + // + // Note that if the first process of a given type crashes or shuts down + // before sending us its script data, we silently ignore it, and data for + // that process type is not included in the next session's cache. This + // should be a sufficiently rare occurrence that it's not worth trying to + // handle specially. + auto processType = GetChildProcessType(parent.GetRemoteType()); + bool wantScriptData = !cache.mInitializedProcesses.contains(processType); + cache.mInitializedProcesses += processType; + + auto fd = cache.mCacheData->cloneFileDescriptor(); + // Don't send original cache data to new processes if the cache has been + // invalidated. + if (fd.IsValid() && !cache.mCacheInvalidated) { + Unused << parent.SendPScriptCacheConstructor(fd, wantScriptData); + } else { + Unused << parent.SendPScriptCacheConstructor(NS_ERROR_FILE_NOT_FOUND, + wantScriptData); + } +} + +ProcessType ScriptPreloader::GetChildProcessType(const nsACString& remoteType) { + if (remoteType == EXTENSION_REMOTE_TYPE) { + return ProcessType::Extension; + } + if (remoteType == PRIVILEGEDABOUT_REMOTE_TYPE) { + return ProcessType::PrivilegedAbout; + } + return ProcessType::Web; +} + +ScriptPreloader::ScriptPreloader(AutoMemMap* cacheData) + : mCacheData(cacheData), + mMonitor("[ScriptPreloader.mMonitor]"), + mSaveMonitor("[ScriptPreloader.mSaveMonitor]", this) { + // We do not set the process type for child processes here because the + // remoteType in ContentChild is not ready yet. + if (XRE_IsParentProcess()) { + sProcessType = ProcessType::Parent; + } + + nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); + MOZ_RELEASE_ASSERT(obs); + + if (XRE_IsParentProcess()) { + // In the parent process, we want to freeze the script cache as soon + // as idle tasks for the first browser window have completed. + obs->AddObserver(this, STARTUP_COMPLETE_TOPIC, false); + obs->AddObserver(this, CACHE_WRITE_TOPIC, false); + } + + obs->AddObserver(this, XPCOM_SHUTDOWN_TOPIC, false); + obs->AddObserver(this, CACHE_INVALIDATE_TOPIC, false); +} + +ScriptPreloader::~ScriptPreloader() { Cleanup(); } + +void ScriptPreloader::Cleanup() { + mScripts.Clear(); + UnregisterWeakMemoryReporter(this); +} + +void ScriptPreloader::StartCacheWrite() { + MOZ_DIAGNOSTIC_ASSERT(!mSaveThread); + + Unused << NS_NewNamedThread("SaveScripts", getter_AddRefs(mSaveThread), this); + + nsCOMPtr<nsIAsyncShutdownClient> barrier = GetShutdownBarrier(); + barrier->AddBlocker(this, NS_LITERAL_STRING_FROM_CSTRING(__FILE__), __LINE__, + u""_ns); +} + +void ScriptPreloader::InvalidateCache() { + { + mMonitor.AssertNotCurrentThreadOwns(); + MonitorAutoLock mal(mMonitor); + + // Wait for pending off-thread parses to finish, since they depend on the + // memory allocated by our CachedScripts, and can't be canceled + // asynchronously. + FinishPendingParses(mal); + + // Pending scripts should have been cleared by the above, and new parses + // should not have been queued. + MOZ_ASSERT(mParsingScripts.empty()); + MOZ_ASSERT(mParsingSources.empty()); + MOZ_ASSERT(mPendingScripts.isEmpty()); + + mScripts.Clear(); + + // If we've already finished saving the cache at this point, start a new + // delayed save operation. This will write out an empty cache file in place + // of any cache file we've already written out this session, which will + // prevent us from falling back to the current session's cache file on the + // next startup. + if (mSaveComplete && !mSaveThread && mChildCache) { + mSaveComplete = false; + + StartCacheWrite(); + } + } + + { + MonitorSingleWriterAutoLock saveMonitorAutoLock(mSaveMonitor); + + mCacheInvalidated = true; + } + + // If we're waiting on a timeout to finish saving, interrupt it and just save + // immediately. + mSaveMonitor.NotifyAll(); +} + +nsresult ScriptPreloader::Observe(nsISupports* subject, const char* topic, + const char16_t* data) { + nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); + if (!strcmp(topic, STARTUP_COMPLETE_TOPIC)) { + obs->RemoveObserver(this, STARTUP_COMPLETE_TOPIC); + + MOZ_ASSERT(XRE_IsParentProcess()); + + mStartupFinished = true; + URLPreloader::GetSingleton().SetStartupFinished(); + } else if (!strcmp(topic, CACHE_WRITE_TOPIC)) { + obs->RemoveObserver(this, CACHE_WRITE_TOPIC); + + MOZ_ASSERT(mStartupFinished); + MOZ_ASSERT(XRE_IsParentProcess()); + + if (mChildCache && !mSaveComplete && !mSaveThread) { + StartCacheWrite(); + } + } else if (mContentStartupFinishedTopic.Equals(topic)) { + // If this is an uninitialized about:blank viewer or a chrome: document + // (which should always be an XBL binding document), ignore it. We don't + // have to worry about it loading malicious content. + if (nsCOMPtr<dom::Document> doc = do_QueryInterface(subject)) { + nsCOMPtr<nsIURI> uri = doc->GetDocumentURI(); + + if ((NS_IsAboutBlank(uri) && + doc->GetReadyStateEnum() == doc->READYSTATE_UNINITIALIZED) || + uri->SchemeIs("chrome")) { + return NS_OK; + } + } + FinishContentStartup(); + } else if (!strcmp(topic, "timer-callback")) { + FinishContentStartup(); + } else if (!strcmp(topic, XPCOM_SHUTDOWN_TOPIC)) { + // Wait for any pending parses to finish at this point, to avoid creating + // new stencils during destroying the JS runtime. + MonitorAutoLock mal(mMonitor); + FinishPendingParses(mal); + } else if (!strcmp(topic, CACHE_INVALIDATE_TOPIC)) { + InvalidateCache(); + } + + return NS_OK; +} + +void ScriptPreloader::FinishContentStartup() { + MOZ_ASSERT(XRE_IsContentProcess()); + +#ifdef DEBUG + if (mContentStartupFinishedTopic.Equals(CONTENT_DOCUMENT_LOADED_TOPIC)) { + MOZ_ASSERT(sProcessType == ProcessType::PrivilegedAbout); + } else { + MOZ_ASSERT(sProcessType != ProcessType::PrivilegedAbout); + } +#endif /* DEBUG */ + + nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); + obs->RemoveObserver(this, mContentStartupFinishedTopic.get()); + + mSaveTimer = nullptr; + + mStartupFinished = true; + + if (mChildActor) { + mChildActor->SendScriptsAndFinalize(mScripts); + } + +#ifdef XP_WIN + // Record the amount of USS at startup. This is Windows-only for now, + // we could turn it on for Linux relatively cheaply. On macOS it can have + // a perf impact. Only record this for non-privileged processes because + // privileged processes record this value at a different time, leading to + // a higher value which skews the telemetry. + if (sProcessType != ProcessType::PrivilegedAbout) { + mozilla::Telemetry::Accumulate( + mozilla::Telemetry::MEMORY_UNIQUE_CONTENT_STARTUP, + nsMemoryReporterManager::ResidentUnique() / 1024); + } +#endif +} + +bool ScriptPreloader::WillWriteScripts() { + return !mDataPrepared && (XRE_IsParentProcess() || mChildActor); +} + +Result<nsCOMPtr<nsIFile>, nsresult> ScriptPreloader::GetCacheFile( + const nsAString& suffix) { + NS_ENSURE_TRUE(mProfD, Err(NS_ERROR_NOT_INITIALIZED)); + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY(mProfD->Clone(getter_AddRefs(cacheFile))); + + MOZ_TRY(cacheFile->AppendNative("startupCache"_ns)); + Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777); + + MOZ_TRY(cacheFile->Append(mBaseName + suffix)); + + return std::move(cacheFile); +} + +static const uint8_t MAGIC[] = "mozXDRcachev003"; + +Result<Ok, nsresult> ScriptPreloader::OpenCache() { + if (StartupCache::GetIgnoreDiskCache()) { + return Err(NS_ERROR_ABORT); + } + + MOZ_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD))); + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY_VAR(cacheFile, GetCacheFile(u".bin"_ns)); + + bool exists; + MOZ_TRY(cacheFile->Exists(&exists)); + if (exists) { + MOZ_TRY(cacheFile->MoveTo(nullptr, mBaseName + u"-current.bin"_ns)); + } else { + MOZ_TRY(cacheFile->SetLeafName(mBaseName + u"-current.bin"_ns)); + MOZ_TRY(cacheFile->Exists(&exists)); + if (!exists) { + return Err(NS_ERROR_FILE_NOT_FOUND); + } + } + + MOZ_TRY(mCacheData->init(cacheFile)); + + return Ok(); +} + +// Opens the script cache file for this session, and initializes the script +// cache based on its contents. See WriteCache for details of the cache file. +Result<Ok, nsresult> ScriptPreloader::InitCache(const nsAString& basePath) { + mSaveMonitor.AssertOnWritingThread(); + mCacheInitialized = true; + mBaseName = basePath; + + RegisterWeakMemoryReporter(this); + + if (!XRE_IsParentProcess()) { + return Ok(); + } + + // Grab the compilation scope before initializing the URLPreloader, since + // it's not safe to run component loader code during its critical section. + AutoSafeJSAPI jsapi; + JS::RootedObject scope(jsapi.cx(), xpc::CompilationScope()); + + // Note: Code on the main thread *must not access Omnijar in any way* until + // this AutoBeginReading guard is destroyed. + URLPreloader::AutoBeginReading abr; + + MOZ_TRY(OpenCache()); + + return InitCacheInternal(scope); +} + +Result<Ok, nsresult> ScriptPreloader::InitCache( + const Maybe<ipc::FileDescriptor>& cacheFile, ScriptCacheChild* cacheChild) { + mSaveMonitor.AssertOnWritingThread(); + MOZ_ASSERT(XRE_IsContentProcess()); + + mCacheInitialized = true; + mChildActor = cacheChild; + sProcessType = + GetChildProcessType(dom::ContentChild::GetSingleton()->GetRemoteType()); + + nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); + MOZ_RELEASE_ASSERT(obs); + + if (sProcessType == ProcessType::PrivilegedAbout) { + // Since we control all of the documents loaded in the privileged + // content process, we can increase the window of active time for the + // ScriptPreloader to include the scripts that are loaded until the + // first document finishes loading. + mContentStartupFinishedTopic.AssignLiteral(CONTENT_DOCUMENT_LOADED_TOPIC); + } else { + // In the child process, we need to freeze the script cache before any + // untrusted code has been executed. The insertion of the first DOM + // document element may sometimes be earlier than is ideal, but at + // least it should always be safe. + mContentStartupFinishedTopic.AssignLiteral(DOC_ELEM_INSERTED_TOPIC); + } + obs->AddObserver(this, mContentStartupFinishedTopic.get(), false); + + RegisterWeakMemoryReporter(this); + + auto cleanup = MakeScopeExit([&] { + // If the parent is expecting cache data from us, make sure we send it + // before it writes out its cache file. For normal proceses, this isn't + // a concern, since they begin loading documents quite early. For the + // preloaded process, we may end up waiting a long time (or, indeed, + // never loading a document), so we need an additional timeout. + if (cacheChild) { + NS_NewTimerWithObserver(getter_AddRefs(mSaveTimer), this, + CHILD_STARTUP_TIMEOUT_MS, + nsITimer::TYPE_ONE_SHOT); + } + }); + + if (cacheFile.isNothing()) { + return Ok(); + } + + MOZ_TRY(mCacheData->init(cacheFile.ref())); + + return InitCacheInternal(); +} + +Result<Ok, nsresult> ScriptPreloader::InitCacheInternal( + JS::HandleObject scope) { + auto size = mCacheData->size(); + + uint32_t headerSize; + uint32_t crc; + if (size < sizeof(MAGIC) + sizeof(headerSize) + sizeof(crc)) { + return Err(NS_ERROR_UNEXPECTED); + } + + auto data = mCacheData->get<uint8_t>(); + MOZ_RELEASE_ASSERT(JS::IsTranscodingBytecodeAligned(data.get())); + + auto end = data + size; + + if (memcmp(MAGIC, data.get(), sizeof(MAGIC))) { + return Err(NS_ERROR_UNEXPECTED); + } + data += sizeof(MAGIC); + + headerSize = LittleEndian::readUint32(data.get()); + data += sizeof(headerSize); + + crc = LittleEndian::readUint32(data.get()); + data += sizeof(crc); + + if (data + headerSize > end) { + return Err(NS_ERROR_UNEXPECTED); + } + + if (crc != ComputeCrc32c(~0, data.get(), headerSize)) { + return Err(NS_ERROR_UNEXPECTED); + } + + { + auto cleanup = MakeScopeExit([&]() { mScripts.Clear(); }); + + LinkedList<CachedStencil> scripts; + + Range<uint8_t> header(data, data + headerSize); + data += headerSize; + + // Reconstruct alignment padding if required. + size_t currentOffset = data - mCacheData->get<uint8_t>(); + data += JS::AlignTranscodingBytecodeOffset(currentOffset) - currentOffset; + + InputBuffer buf(header); + + size_t offset = 0; + while (!buf.finished()) { + auto script = MakeUnique<CachedStencil>(*this, buf); + MOZ_RELEASE_ASSERT(script); + + auto scriptData = data + script->mOffset; + if (!JS::IsTranscodingBytecodeAligned(scriptData.get())) { + return Err(NS_ERROR_UNEXPECTED); + } + + if (scriptData + script->mSize > end) { + return Err(NS_ERROR_UNEXPECTED); + } + + // Make sure offsets match what we'd expect based on script ordering and + // size, as a basic sanity check. + if (script->mOffset != offset) { + return Err(NS_ERROR_UNEXPECTED); + } + offset += script->mSize; + + script->mXDRRange.emplace(scriptData, scriptData + script->mSize); + + // Don't pre-decode the script unless it was used in this process type + // during the previous session. + if (script->mOriginalProcessTypes.contains(CurrentProcessType())) { + scripts.insertBack(script.get()); + } else { + script->mReadyToExecute = true; + } + + const auto& cachePath = script->mCachePath; + mScripts.InsertOrUpdate(cachePath, std::move(script)); + } + + if (buf.error()) { + return Err(NS_ERROR_UNEXPECTED); + } + + mPendingScripts = std::move(scripts); + cleanup.release(); + } + + DecodeNextBatch(OFF_THREAD_FIRST_CHUNK_SIZE, scope); + return Ok(); +} + +void ScriptPreloader::PrepareCacheWriteInternal() { + MOZ_ASSERT(NS_IsMainThread()); + + mMonitor.AssertCurrentThreadOwns(); + + auto cleanup = MakeScopeExit([&]() { + if (mChildCache) { + mChildCache->PrepareCacheWrite(); + } + }); + + if (mDataPrepared) { + return; + } + + AutoSafeJSAPI jsapi; + JSAutoRealm ar(jsapi.cx(), xpc::PrivilegedJunkScope()); + bool found = false; + for (auto& script : IterHash(mScripts, Match<ScriptStatus::Saved>())) { + // Don't write any scripts that are also in the child cache. They'll be + // loaded from the child cache in that case, so there's no need to write + // them twice. + CachedStencil* childScript = + mChildCache ? mChildCache->mScripts.Get(script->mCachePath) : nullptr; + if (childScript && !childScript->mProcessTypes.isEmpty()) { + childScript->UpdateLoadTime(script->mLoadTime); + childScript->mProcessTypes += script->mProcessTypes; + script.Remove(); + continue; + } + + if (!(script->mProcessTypes == script->mOriginalProcessTypes)) { + // Note: EnumSet doesn't support operator!=, hence the weird form above. + found = true; + } + + if (!script->mSize && !script->XDREncode(jsapi.cx())) { + script.Remove(); + } + } + + if (!found) { + mSaveComplete = true; + return; + } + + mDataPrepared = true; +} + +void ScriptPreloader::PrepareCacheWrite() { + MonitorAutoLock mal(mMonitor); + + PrepareCacheWriteInternal(); +} + +// Writes out a script cache file for the scripts accessed during early +// startup in this session. The cache file is a little-endian binary file with +// the following format: +// +// - A uint32 containing the size of the header block. +// +// - A header entry for each file stored in the cache containing: +// - The URL that the script was originally read from. +// - Its cache key. +// - The offset of its XDR data within the XDR data block. +// - The size of its XDR data in the XDR data block. +// - A bit field describing which process types the script is used in. +// +// - A block of XDR data for the encoded scripts, with each script's data at +// an offset from the start of the block, as specified above. +Result<Ok, nsresult> ScriptPreloader::WriteCache() { + MOZ_ASSERT(!NS_IsMainThread()); + mSaveMonitor.AssertCurrentThreadOwns(); + + if (!mDataPrepared && !mSaveComplete) { + MonitorSingleWriterAutoUnlock mau(mSaveMonitor); + + NS_DispatchAndSpinEventLoopUntilComplete( + "ScriptPreloader::PrepareCacheWrite"_ns, + GetMainThreadSerialEventTarget(), + NewRunnableMethod("ScriptPreloader::PrepareCacheWrite", this, + &ScriptPreloader::PrepareCacheWrite)); + } + + if (mSaveComplete) { + // If we don't have anything we need to save, we're done. + return Ok(); + } + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY_VAR(cacheFile, GetCacheFile(u"-new.bin"_ns)); + + bool exists; + MOZ_TRY(cacheFile->Exists(&exists)); + if (exists) { + MOZ_TRY(cacheFile->Remove(false)); + } + + { + AutoFDClose fd; + MOZ_TRY(cacheFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, 0644, + &fd.rwget())); + + // We also need to hold mMonitor while we're touching scripts in + // mScripts, or they may be freed before we're done with them. + mMonitor.AssertNotCurrentThreadOwns(); + MonitorAutoLock mal(mMonitor); + + nsTArray<CachedStencil*> scripts; + for (auto& script : IterHash(mScripts, Match<ScriptStatus::Saved>())) { + scripts.AppendElement(script); + } + + // Sort scripts by load time, with async loaded scripts before sync scripts. + // Since async scripts are always loaded immediately at startup, it helps to + // have them stored contiguously. + scripts.Sort(CachedStencil::Comparator()); + + OutputBuffer buf; + size_t offset = 0; + for (auto script : scripts) { + script->mOffset = offset; + MOZ_DIAGNOSTIC_ASSERT( + JS::IsTranscodingBytecodeOffsetAligned(script->mOffset)); + script->Code(buf); + + offset += script->mSize; + MOZ_DIAGNOSTIC_ASSERT( + JS::IsTranscodingBytecodeOffsetAligned(script->mSize)); + } + + uint8_t headerSize[4]; + LittleEndian::writeUint32(headerSize, buf.cursor()); + + uint8_t crc[4]; + LittleEndian::writeUint32(crc, ComputeCrc32c(~0, buf.Get(), buf.cursor())); + + MOZ_TRY(Write(fd, MAGIC, sizeof(MAGIC))); + MOZ_TRY(Write(fd, headerSize, sizeof(headerSize))); + MOZ_TRY(Write(fd, crc, sizeof(crc))); + MOZ_TRY(Write(fd, buf.Get(), buf.cursor())); + + // Align the start of the scripts section to the transcode alignment. + size_t written = sizeof(MAGIC) + sizeof(headerSize) + buf.cursor(); + size_t padding = JS::AlignTranscodingBytecodeOffset(written) - written; + if (padding) { + MOZ_TRY(WritePadding(fd, padding)); + written += padding; + } + + for (auto script : scripts) { + MOZ_DIAGNOSTIC_ASSERT(JS::IsTranscodingBytecodeOffsetAligned(written)); + MOZ_TRY(Write(fd, script->Range().begin().get(), script->mSize)); + + written += script->mSize; + // We can only free the XDR data if the stencil isn't borrowing data from + // it. + if (script->mStencil && !JS::StencilIsBorrowed(script->mStencil)) { + script->FreeData(); + } + } + } + + MOZ_TRY(cacheFile->MoveTo(nullptr, mBaseName + u".bin"_ns)); + + return Ok(); +} + +nsresult ScriptPreloader::GetName(nsACString& aName) { + aName.AssignLiteral("ScriptPreloader"); + return NS_OK; +} + +// Runs in the mSaveThread thread, and writes out the cache file for the next +// session after a reasonable delay. +nsresult ScriptPreloader::Run() { + MonitorSingleWriterAutoLock mal(mSaveMonitor); + + // Ideally wait about 10 seconds before saving, to avoid unnecessary IO + // during early startup. But only if the cache hasn't been invalidated, + // since that can trigger a new write during shutdown, and we don't want to + // cause shutdown hangs. + if (!mCacheInvalidated) { + mal.Wait(TimeDuration::FromSeconds(10)); + } + + auto result = URLPreloader::GetSingleton().WriteCache(); + Unused << NS_WARN_IF(result.isErr()); + + result = WriteCache(); + Unused << NS_WARN_IF(result.isErr()); + + { + MonitorSingleWriterAutoLock lock(mChildCache->mSaveMonitor); + result = mChildCache->WriteCache(); + } + Unused << NS_WARN_IF(result.isErr()); + + NS_DispatchToMainThread( + NewRunnableMethod("ScriptPreloader::CacheWriteComplete", this, + &ScriptPreloader::CacheWriteComplete), + NS_DISPATCH_NORMAL); + return NS_OK; +} + +void ScriptPreloader::CacheWriteComplete() { + mSaveThread->AsyncShutdown(); + mSaveThread = nullptr; + mSaveComplete = true; + + nsCOMPtr<nsIAsyncShutdownClient> barrier = GetShutdownBarrier(); + barrier->RemoveBlocker(this); +} + +void ScriptPreloader::NoteStencil(const nsCString& url, + const nsCString& cachePath, + JS::Stencil* stencil, bool isRunOnce) { + if (!Active()) { + if (isRunOnce) { + if (auto script = mScripts.Get(cachePath)) { + script->mIsRunOnce = true; + script->MaybeDropStencil(); + } + } + return; + } + + // Don't bother trying to cache any URLs with cache-busting query + // parameters. + if (cachePath.FindChar('?') >= 0) { + return; + } + + // Don't bother caching files that belong to the mochitest harness. + constexpr auto mochikitPrefix = "chrome://mochikit/"_ns; + if (StringHead(url, mochikitPrefix.Length()) == mochikitPrefix) { + return; + } + + auto* script = + mScripts.GetOrInsertNew(cachePath, *this, url, cachePath, stencil); + if (isRunOnce) { + script->mIsRunOnce = true; + } + + if (!script->MaybeDropStencil() && !script->mStencil) { + MOZ_ASSERT(stencil); + script->mStencil = stencil; + script->mReadyToExecute = true; + } + + script->UpdateLoadTime(TimeStamp::Now()); + script->mProcessTypes += CurrentProcessType(); +} + +void ScriptPreloader::NoteStencil(const nsCString& url, + const nsCString& cachePath, + ProcessType processType, + nsTArray<uint8_t>&& xdrData, + TimeStamp loadTime) { + // After data has been prepared, there's no point in noting further scripts, + // since the cache either has already been written, or is about to be + // written. Any time prior to the data being prepared, we can safely mutate + // mScripts without locking. After that point, the save thread is free to + // access it, and we can't alter it without locking. + if (mDataPrepared) { + return; + } + + auto* script = + mScripts.GetOrInsertNew(cachePath, *this, url, cachePath, nullptr); + + if (!script->HasRange()) { + MOZ_ASSERT(!script->HasArray()); + + script->mSize = xdrData.Length(); + script->mXDRData.construct<nsTArray<uint8_t>>( + std::forward<nsTArray<uint8_t>>(xdrData)); + + auto& data = script->Array(); + script->mXDRRange.emplace(data.Elements(), data.Length()); + } + + if (!script->mSize && !script->mStencil) { + // If the content process is sending us an entry for a stencil + // which was in the cache at startup, it expects us to already have this + // script data, so it doesn't send it. + // + // However, the cache may have been invalidated at this point (usually + // due to the add-on manager installing or uninstalling a legacy + // extension during very early startup), which means we may no longer + // have an entry for this script. Since that means we have no data to + // write to the new cache, and no JSScript to generate it from, we need + // to discard this entry. + mScripts.Remove(cachePath); + return; + } + + script->UpdateLoadTime(loadTime); + script->mProcessTypes += processType; +} + +/* static */ +void ScriptPreloader::FillCompileOptionsForCachedStencil( + JS::CompileOptions& options) { + // Users of the cache do not require return values, so inform the JS parser in + // order for it to generate simpler bytecode. + options.setNoScriptRval(true); + + // The ScriptPreloader trades off having bytecode available but not source + // text. This means the JS syntax-only parser is not used. If `toString` is + // called on functions in these scripts, the source-hook will fetch it over, + // so using `toString` of functions should be avoided in chrome js. + options.setSourceIsLazy(true); +} + +/* static */ +void ScriptPreloader::FillDecodeOptionsForCachedStencil( + JS::DecodeOptions& options) { + // ScriptPreloader's XDR buffer is alive during the Stencil is alive. + // The decoded stencil can borrow from it. + // + // NOTE: The XDR buffer is alive during the entire browser lifetime only + // when it's mmapped. + options.borrowBuffer = true; +} + +already_AddRefed<JS::Stencil> ScriptPreloader::GetCachedStencil( + JSContext* cx, const JS::DecodeOptions& options, const nsCString& path) { + MOZ_RELEASE_ASSERT( + !(XRE_IsContentProcess() && !mCacheInitialized), + "ScriptPreloader must be initialized before getting cached " + "scripts in the content process."); + + // If a script is used by both the parent and the child, it's stored only + // in the child cache. + if (mChildCache) { + RefPtr<JS::Stencil> stencil = + mChildCache->GetCachedStencilInternal(cx, options, path); + if (stencil) { + Telemetry::AccumulateCategorical( + Telemetry::LABELS_SCRIPT_PRELOADER_REQUESTS::HitChild); + return stencil.forget(); + } + } + + RefPtr<JS::Stencil> stencil = GetCachedStencilInternal(cx, options, path); + Telemetry::AccumulateCategorical( + stencil ? Telemetry::LABELS_SCRIPT_PRELOADER_REQUESTS::Hit + : Telemetry::LABELS_SCRIPT_PRELOADER_REQUESTS::Miss); + return stencil.forget(); +} + +already_AddRefed<JS::Stencil> ScriptPreloader::GetCachedStencilInternal( + JSContext* cx, const JS::DecodeOptions& options, const nsCString& path) { + auto* cachedScript = mScripts.Get(path); + if (cachedScript) { + return WaitForCachedStencil(cx, options, cachedScript); + } + return nullptr; +} + +already_AddRefed<JS::Stencil> ScriptPreloader::WaitForCachedStencil( + JSContext* cx, const JS::DecodeOptions& options, CachedStencil* script) { + // Always check for finished operations so that we can move on to decoding the + // next batch as soon as possible after the pending batch is ready. If we wait + // until we hit an unfinished script, we wind up having at most one batch of + // buffered scripts, and occasionally under-running that buffer. + if (JS::OffThreadToken* token = mToken.exchange(nullptr)) { + FinishOffThreadDecode(token); + } + + if (!script->mReadyToExecute) { + LOG(Info, "Must wait for async script load: %s\n", script->mURL.get()); + auto start = TimeStamp::Now(); + + // If script is small enough, we'd rather recompile on main-thread than wait + // for a decode task to complete. + if (script->mSize < MAX_MAINTHREAD_DECODE_SIZE) { + LOG(Info, "Script is small enough to recompile on main thread\n"); + + script->mReadyToExecute = true; + Telemetry::ScalarAdd( + Telemetry::ScalarID::SCRIPT_PRELOADER_MAINTHREAD_RECOMPILE, 1); + } else { + MonitorAutoLock mal(mMonitor); + + // Process script batches until our target is found. + while (!script->mReadyToExecute) { + if (JS::OffThreadToken* token = mToken.exchange(nullptr)) { + MonitorAutoUnlock mau(mMonitor); + FinishOffThreadDecode(token); + } else { + MOZ_ASSERT(!mParsingScripts.empty()); + mWaitingForDecode = true; + mal.Wait(); + mWaitingForDecode = false; + } + } + } + + double waitedMS = (TimeStamp::Now() - start).ToMilliseconds(); + Telemetry::Accumulate(Telemetry::SCRIPT_PRELOADER_WAIT_TIME, int(waitedMS)); + LOG(Debug, "Waited %fms\n", waitedMS); + } + + return script->GetStencil(cx, options); +} + +/* static */ +void ScriptPreloader::OffThreadDecodeCallback(JS::OffThreadToken* token, + void* context) { + auto cache = static_cast<ScriptPreloader*>(context); + + // Make the token available to main-thread asynchronously. The lock below is + // used for Wait/Notify machinery and isn't needed to update the token itself. + MOZ_ALWAYS_FALSE(cache->mToken.exchange(token)); + + cache->mMonitor.AssertNotCurrentThreadOwns(); + MonitorAutoLock mal(cache->mMonitor); + + if (cache->mWaitingForDecode) { + // Wake up the blocked main thread. + mal.Notify(); + } else if (!cache->mFinishDecodeRunnablePending) { + // Issue a Runnable to ensure batches continue to decode even if the next + // WaitForCachedScript call has not happened yet. + cache->mFinishDecodeRunnablePending = true; + NS_DispatchToMainThread( + NewRunnableMethod("ScriptPreloader::DoFinishOffThreadDecode", cache, + &ScriptPreloader::DoFinishOffThreadDecode)); + } +} + +void ScriptPreloader::FinishPendingParses(MonitorAutoLock& aMal) { + mMonitor.AssertCurrentThreadOwns(); + + // Clear out scripts that we have not issued batch for yet. + mPendingScripts.clear(); + + // Process any pending decodes that are in flight. + while (!mParsingScripts.empty()) { + if (JS::OffThreadToken* token = mToken.exchange(nullptr)) { + MonitorAutoUnlock mau(mMonitor); + FinishOffThreadDecode(token); + } else { + mWaitingForDecode = true; + aMal.Wait(); + mWaitingForDecode = false; + } + } +} + +void ScriptPreloader::DoFinishOffThreadDecode() { + { + MonitorAutoLock mal(mMonitor); + mFinishDecodeRunnablePending = false; + } + + if (JS::OffThreadToken* token = mToken.exchange(nullptr)) { + FinishOffThreadDecode(token); + } +} + +void ScriptPreloader::FinishOffThreadDecode(JS::OffThreadToken* token) { + mMonitor.AssertNotCurrentThreadOwns(); + MOZ_ASSERT(token); + + auto cleanup = MakeScopeExit([&]() { + mParsingSources.clear(); + mParsingScripts.clear(); + + DecodeNextBatch(OFF_THREAD_CHUNK_SIZE); + }); + + AutoSafeJSAPI jsapi; + JSContext* cx = jsapi.cx(); + + JSAutoRealm ar(cx, xpc::CompilationScope()); + Vector<RefPtr<JS::Stencil>> stencils; + + // If this fails, we still need to mark the scripts as finished. Any that + // weren't successfully compiled in this operation (which should never + // happen under ordinary circumstances) will be re-decoded on the main + // thread, and raise the appropriate errors when they're executed. + // + // The exception from the off-thread decode operation will be reported when + // we pop the AutoJSAPI off the stack. + Unused << JS::FinishDecodeMultiStencilsOffThread(cx, token, &stencils); + + unsigned i = 0; + for (auto script : mParsingScripts) { + LOG(Debug, "Finished off-thread decode of %s\n", script->mURL.get()); + if (i < stencils.length()) { + script->mStencil = stencils[i++].forget(); + } + script->mReadyToExecute = true; + } +} + +void ScriptPreloader::DecodeNextBatch(size_t chunkSize, + JS::HandleObject scope) { + MOZ_ASSERT(mParsingSources.length() == 0); + MOZ_ASSERT(mParsingScripts.length() == 0); + + auto cleanup = MakeScopeExit([&]() { + mParsingScripts.clearAndFree(); + mParsingSources.clearAndFree(); + }); + + auto start = TimeStamp::Now(); + LOG(Debug, "Off-thread decoding scripts...\n"); + + size_t size = 0; + for (CachedStencil* next = mPendingScripts.getFirst(); next;) { + auto* script = next; + next = script->getNext(); + + MOZ_ASSERT(script->IsMemMapped()); + + // Skip any scripts that we decoded on the main thread rather than + // waiting for an off-thread operation to complete. + if (script->mReadyToExecute) { + script->remove(); + continue; + } + // If we have enough data for one chunk and this script would put us + // over our chunk size limit, we're done. + if (size > SMALL_SCRIPT_CHUNK_THRESHOLD && + size + script->mSize > chunkSize) { + break; + } + if (!mParsingScripts.append(script) || + !mParsingSources.emplaceBack(script->Range(), script->mURL.get(), 0)) { + break; + } + + LOG(Debug, "Beginning off-thread decode of script %s (%u bytes)\n", + script->mURL.get(), script->mSize); + + script->remove(); + size += script->mSize; + } + + if (size == 0 && mPendingScripts.isEmpty()) { + return; + } + + AutoSafeJSAPI jsapi; + JSContext* cx = jsapi.cx(); + JSAutoRealm ar(cx, scope ? scope : xpc::CompilationScope()); + + JS::CompileOptions options(cx); + FillCompileOptionsForCachedStencil(options); + + // All XDR buffers are mmapped and live longer than JS runtime. + // The bytecode can be borrowed from the buffer. + options.borrowBuffer = true; + options.usePinnedBytecode = true; + + JS::DecodeOptions decodeOptions(options); + + if (!JS::CanDecodeOffThread(cx, decodeOptions, size) || + !JS::DecodeMultiStencilsOffThread(cx, decodeOptions, mParsingSources, + OffThreadDecodeCallback, + static_cast<void*>(this))) { + // If we fail here, we don't move on to process the next batch, so make + // sure we don't have any other scripts left to process. + MOZ_ASSERT(mPendingScripts.isEmpty()); + for (auto script : mPendingScripts) { + script->mReadyToExecute = true; + } + + LOG(Info, "Can't decode %lu bytes of scripts off-thread", + (unsigned long)size); + for (auto script : mParsingScripts) { + script->mReadyToExecute = true; + } + return; + } + + cleanup.release(); + + LOG(Debug, "Initialized decoding of %u scripts (%u bytes) in %fms\n", + (unsigned)mParsingSources.length(), (unsigned)size, + (TimeStamp::Now() - start).ToMilliseconds()); +} + +ScriptPreloader::CachedStencil::CachedStencil(ScriptPreloader& cache, + InputBuffer& buf) + : mCache(cache) { + Code(buf); + + // Swap the mProcessTypes and mOriginalProcessTypes values, since we want to + // start with an empty set of processes loaded into for this session, and + // compare against last session's values later. + mOriginalProcessTypes = mProcessTypes; + mProcessTypes = {}; +} + +bool ScriptPreloader::CachedStencil::XDREncode(JSContext* cx) { + auto cleanup = MakeScopeExit([&]() { MaybeDropStencil(); }); + + mXDRData.construct<JS::TranscodeBuffer>(); + + JS::TranscodeResult code = JS::EncodeStencil(cx, mStencil, Buffer()); + if (code == JS::TranscodeResult::Ok) { + mXDRRange.emplace(Buffer().begin(), Buffer().length()); + mSize = Range().length(); + return true; + } + mXDRData.destroy(); + JS_ClearPendingException(cx); + return false; +} + +already_AddRefed<JS::Stencil> ScriptPreloader::CachedStencil::GetStencil( + JSContext* cx, const JS::DecodeOptions& options) { + MOZ_ASSERT(mReadyToExecute); + if (mStencil) { + return do_AddRef(mStencil); + } + + if (!HasRange()) { + // We've already executed the script, and thrown it away. But it wasn't + // in the cache at startup, so we don't have any data to decode. Give + // up. + return nullptr; + } + + // If we have no script at this point, the script was too small to decode + // off-thread, or it was needed before the off-thread compilation was + // finished, and is small enough to decode on the main thread rather than + // wait for the off-thread decoding to finish. In either case, we decode + // it synchronously the first time it's needed. + + auto start = TimeStamp::Now(); + LOG(Info, "Decoding stencil %s on main thread...\n", mURL.get()); + + RefPtr<JS::Stencil> stencil; + if (JS::DecodeStencil(cx, options, Range(), getter_AddRefs(stencil)) == + JS::TranscodeResult::Ok) { + // Lock the monitor here to avoid data races on mScript + // from other threads like the cache writing thread. + // + // It is possible that we could end up decoding the same + // script twice, because DecodeScript isn't being guarded + // by the monitor; however, to encourage off-thread decode + // to proceed for other scripts we don't hold the monitor + // while doing main thread decode, merely while updating + // mScript. + mCache.mMonitor.AssertNotCurrentThreadOwns(); + MonitorAutoLock mal(mCache.mMonitor); + + mStencil = stencil.forget(); + + if (mCache.mSaveComplete) { + // We can only free XDR data if the stencil isn't borrowing data out of + // it. + if (!JS::StencilIsBorrowed(mStencil)) { + FreeData(); + } + } + } + + LOG(Debug, "Finished decoding in %fms", + (TimeStamp::Now() - start).ToMilliseconds()); + + return do_AddRef(mStencil); +} + +// nsIAsyncShutdownBlocker + +nsresult ScriptPreloader::GetName(nsAString& aName) { + aName.AssignLiteral(u"ScriptPreloader: Saving bytecode cache"); + return NS_OK; +} + +nsresult ScriptPreloader::GetState(nsIPropertyBag** aState) { + *aState = nullptr; + return NS_OK; +} + +nsresult ScriptPreloader::BlockShutdown( + nsIAsyncShutdownClient* aBarrierClient) { + // If we're waiting on a timeout to finish saving, interrupt it and just save + // immediately. + mSaveMonitor.NotifyAll(); + return NS_OK; +} + +already_AddRefed<nsIAsyncShutdownClient> ScriptPreloader::GetShutdownBarrier() { + nsCOMPtr<nsIAsyncShutdownService> svc = components::AsyncShutdown::Service(); + MOZ_RELEASE_ASSERT(svc); + + nsCOMPtr<nsIAsyncShutdownClient> barrier; + Unused << svc->GetXpcomWillShutdown(getter_AddRefs(barrier)); + MOZ_RELEASE_ASSERT(barrier); + + return barrier.forget(); +} + +NS_IMPL_ISUPPORTS(ScriptPreloader, nsIObserver, nsIRunnable, nsIMemoryReporter, + nsINamed, nsIAsyncShutdownBlocker) + +#undef LOG + +} // namespace mozilla diff --git a/js/xpconnect/loader/ScriptPreloader.h b/js/xpconnect/loader/ScriptPreloader.h new file mode 100644 index 0000000000..e1868b6f40 --- /dev/null +++ b/js/xpconnect/loader/ScriptPreloader.h @@ -0,0 +1,543 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef ScriptPreloader_h +#define ScriptPreloader_h + +#include "mozilla/Atomics.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/EnumSet.h" +#include "mozilla/LinkedList.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Maybe.h" +#include "mozilla/MaybeOneOf.h" +#include "mozilla/Monitor.h" +#include "mozilla/Range.h" +#include "mozilla/Vector.h" +#include "mozilla/Result.h" +#include "mozilla/loader/AutoMemMap.h" +#include "MainThreadUtils.h" +#include "nsClassHashtable.h" +#include "nsIAsyncShutdown.h" +#include "nsIFile.h" +#include "nsIMemoryReporter.h" +#include "nsIObserver.h" +#include "nsIThread.h" +#include "nsITimer.h" + +#include "js/CompileOptions.h" // JS::DecodeOptions +#include "js/experimental/JSStencil.h" +#include "js/GCAnnotations.h" // for JS_HAZ_NON_GC_POINTER +#include "js/RootingAPI.h" // for Handle, Heap +#include "js/Transcoding.h" // for TranscodeBuffer, TranscodeRange, TranscodeSources +#include "js/TypeDecls.h" // for HandleObject, HandleScript + +#include <prio.h> + +namespace JS { +class CompileOptions; +class OffThreadToken; +} // namespace JS + +namespace mozilla { +namespace dom { +class ContentParent; +} +namespace ipc { +class FileDescriptor; +} +namespace loader { +class InputBuffer; +class ScriptCacheChild; + +enum class ProcessType : uint8_t { + Uninitialized, + Parent, + Web, + Extension, + PrivilegedAbout, +}; + +template <typename T> +struct Matcher { + virtual bool Matches(T) = 0; +}; +} // namespace loader + +using namespace mozilla::loader; + +class ScriptPreloader : public nsIObserver, + public nsIMemoryReporter, + public nsIRunnable, + public nsINamed, + public nsIAsyncShutdownBlocker, + public SingleWriterLockOwner { + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) + + friend class mozilla::loader::ScriptCacheChild; + + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + NS_DECL_NSIMEMORYREPORTER + NS_DECL_NSIRUNNABLE + NS_DECL_NSINAMED + NS_DECL_NSIASYNCSHUTDOWNBLOCKER + + private: + static StaticRefPtr<ScriptPreloader> gScriptPreloader; + static StaticRefPtr<ScriptPreloader> gChildScriptPreloader; + static UniquePtr<AutoMemMap> gCacheData; + static UniquePtr<AutoMemMap> gChildCacheData; + + public: + static ScriptPreloader& GetSingleton(); + static ScriptPreloader& GetChildSingleton(); + + static void DeleteSingleton(); + static void DeleteCacheDataSingleton(); + + static ProcessType GetChildProcessType(const nsACString& remoteType); + + // Fill some options that should be consistent across all scripts stored + // into preloader cache. + static void FillCompileOptionsForCachedStencil(JS::CompileOptions& options); + static void FillDecodeOptionsForCachedStencil(JS::DecodeOptions& options); + + bool OnWritingThread() const override { return NS_IsMainThread(); } + + // Retrieves the stencil with the given cache key from the cache. + // Returns null if the stencil is not cached. + already_AddRefed<JS::Stencil> GetCachedStencil( + JSContext* cx, const JS::DecodeOptions& options, const nsCString& path); + + // Notes the execution of a script with the given URL and cache key. + // Depending on the stage of startup, the script may be serialized and + // stored to the startup script cache. + // + // If isRunOnce is true, this script is expected to run only once per + // process per browser session. A cached instance will not be kept alive + // for repeated execution. + void NoteStencil(const nsCString& url, const nsCString& cachePath, + JS::Stencil* stencil, bool isRunOnce = false); + + // Notes the IPC arrival of the XDR data of a stencil compiled by some + // child process. See ScriptCacheChild::SendScriptsAndFinalize. + void NoteStencil(const nsCString& url, const nsCString& cachePath, + ProcessType processType, nsTArray<uint8_t>&& xdrData, + TimeStamp loadTime); + + // Initializes the script cache from the startup script cache file. + Result<Ok, nsresult> InitCache(const nsAString& = u"scriptCache"_ns); + + Result<Ok, nsresult> InitCache(const Maybe<ipc::FileDescriptor>& cacheFile, + ScriptCacheChild* cacheChild); + + bool Active() const { return mCacheInitialized && !mStartupFinished; } + + private: + Result<Ok, nsresult> InitCacheInternal(JS::Handle<JSObject*> scope = nullptr); + already_AddRefed<JS::Stencil> GetCachedStencilInternal( + JSContext* cx, const JS::DecodeOptions& options, const nsCString& path); + + public: + static ProcessType CurrentProcessType() { + MOZ_ASSERT(sProcessType != ProcessType::Uninitialized); + return sProcessType; + } + + static void InitContentChild(dom::ContentParent& parent); + + protected: + virtual ~ScriptPreloader(); + + private: + enum class ScriptStatus { + Restored, + Saved, + }; + + // Represents a cached script stencil, either initially read from the + // cache file, to be added to the next session's stencil cache file, or + // both. + // + // - Read from the cache, and being decoded off thread. In this case, + // mReadyToExecute is false, and mToken is null. + // - Off-thread decode has finished, but the stencil has not yet been + // executed. In this case, mReadyToExecute is true, and mToken has a + // non-null value. + // - Read from the cache, but too small or needed to immediately to be + // compiled off-thread. In this case, mReadyToExecute is true, and both + // mToken and mStencil are null. + // - Fully decoded, and ready to be added to the next session's cache + // file. In this case, mReadyToExecute is true, and mStencil is non-null. + // + // A stencil to be added to the next session's cache file always has a + // non-null mStencil value. If it was read from the last session's cache + // file, it also has a non-empty mXDRRange range, which will be stored in + // the next session's cache file. If it was compiled in this session, its + // mXDRRange will initially be empty, and its mXDRData buffer will be + // populated just before it is written to the cache file. + class CachedStencil : public LinkedListElement<CachedStencil> { + public: + CachedStencil(CachedStencil&&) = delete; + + CachedStencil(ScriptPreloader& cache, const nsCString& url, + const nsCString& cachePath, JS::Stencil* stencil) + : mCache(cache), + mURL(url), + mCachePath(cachePath), + mStencil(stencil), + mReadyToExecute(true), + mIsRunOnce(false) {} + + inline CachedStencil(ScriptPreloader& cache, InputBuffer& buf); + + ~CachedStencil() = default; + + ScriptStatus Status() const { + return mProcessTypes.isEmpty() ? ScriptStatus::Restored + : ScriptStatus::Saved; + } + + // For use with nsTArray::Sort. + // + // Orders scripts by script load time, so that scripts which are needed + // earlier are stored earlier, and scripts needed at approximately the + // same time are stored approximately contiguously. + struct Comparator { + bool Equals(const CachedStencil* a, const CachedStencil* b) const { + return a->mLoadTime == b->mLoadTime; + } + + bool LessThan(const CachedStencil* a, const CachedStencil* b) const { + return a->mLoadTime < b->mLoadTime; + } + }; + + struct StatusMatcher final : public Matcher<CachedStencil*> { + explicit StatusMatcher(ScriptStatus status) : mStatus(status) {} + + virtual bool Matches(CachedStencil* script) override { + return script->Status() == mStatus; + } + + const ScriptStatus mStatus; + }; + + void FreeData() { + // If the script data isn't mmapped, we need to release both it + // and the Range that points to it at the same time. + if (!IsMemMapped()) { + mXDRRange.reset(); + mXDRData.destroy(); + } + } + + void UpdateLoadTime(const TimeStamp& loadTime) { + if (mLoadTime.IsNull() || loadTime < mLoadTime) { + mLoadTime = loadTime; + } + } + + // Checks whether the cached JSScript for this entry will be needed + // again and, if not, drops it and returns true. This is the case for + // run-once scripts that do not still need to be encoded into the + // cache. + // + // If this method returns false, callers may set mScript to a cached + // JSScript instance for this entry. If it returns true, they should + // not. + bool MaybeDropStencil() { + if (mIsRunOnce && (HasRange() || !mCache.WillWriteScripts())) { + mStencil = nullptr; + return true; + } + return false; + } + + // Encodes this script into XDR data, and stores the result in mXDRData. + // Returns true on success, false on failure. + bool XDREncode(JSContext* cx); + + // Encodes or decodes this script, in the storage format required by the + // script cache file. + template <typename Buffer> + void Code(Buffer& buffer) { + buffer.codeString(mURL); + buffer.codeString(mCachePath); + buffer.codeUint32(mOffset); + buffer.codeUint32(mSize); + buffer.codeUint8(mProcessTypes); + } + + // Returns the XDR data generated for this script during this session. See + // mXDRData. + JS::TranscodeBuffer& Buffer() { + MOZ_ASSERT(HasBuffer()); + return mXDRData.ref<JS::TranscodeBuffer>(); + } + + bool HasBuffer() { return mXDRData.constructed<JS::TranscodeBuffer>(); } + + // Returns the read-only XDR data for this script. See mXDRRange. + const JS::TranscodeRange& Range() { + MOZ_ASSERT(HasRange()); + return mXDRRange.ref(); + } + + bool HasRange() { return mXDRRange.isSome(); } + + bool IsMemMapped() const { return mXDRData.empty(); } + + nsTArray<uint8_t>& Array() { + MOZ_ASSERT(HasArray()); + return mXDRData.ref<nsTArray<uint8_t>>(); + } + + bool HasArray() { return mXDRData.constructed<nsTArray<uint8_t>>(); } + + already_AddRefed<JS::Stencil> GetStencil(JSContext* cx, + const JS::DecodeOptions& options); + + size_t HeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { + auto size = mallocSizeOf(this); + + if (HasArray()) { + size += Array().ShallowSizeOfExcludingThis(mallocSizeOf); + } else if (HasBuffer()) { + size += Buffer().sizeOfExcludingThis(mallocSizeOf); + } + + if (mStencil) { + size += JS::SizeOfStencil(mStencil, mallocSizeOf); + } + + // Note: mURL and mCachePath use the same string for scripts loaded + // by the message manager. The following statement avoids + // double-measuring in that case. + size += (mURL.SizeOfExcludingThisIfUnshared(mallocSizeOf) + + mCachePath.SizeOfExcludingThisEvenIfShared(mallocSizeOf)); + + return size; + } + + ScriptPreloader& mCache; + + // The URL from which this script was initially read and compiled. + nsCString mURL; + // A unique identifier for this script's filesystem location, used as a + // primary cache lookup value. + nsCString mCachePath; + + // The offset of this script in the cache file, from the start of the XDR + // data block. + uint32_t mOffset = 0; + // The size of this script's encoded XDR data. + uint32_t mSize = 0; + + TimeStamp mLoadTime{}; + + RefPtr<JS::Stencil> mStencil; + + // True if this script is ready to be executed. This means that either the + // off-thread portion of an off-thread decode has finished, or the script + // is too small to be decoded off-thread, and may be immediately decoded + // whenever it is first executed. + bool mReadyToExecute = false; + + // True if this script is expected to run once per process. If so, its + // JSScript instance will be dropped as soon as the script has + // executed and been encoded into the cache. + bool mIsRunOnce = false; + + // The set of processes in which this script has been used. + EnumSet<ProcessType> mProcessTypes{}; + + // The set of processes which the script was loaded into during the + // last session, as read from the cache file. + EnumSet<ProcessType> mOriginalProcessTypes{}; + + // The read-only XDR data for this script, which was either read from an + // existing cache file, or generated by encoding a script which was + // compiled during this session. + Maybe<JS::TranscodeRange> mXDRRange; + + // XDR data which was generated from a script compiled during this + // session, and will be written to the cache file. + // + // The format is JS::TranscodeBuffer if the script was XDR'd as part + // of this process, or nsTArray<> if the script was transfered by IPC + // from a child process. + MaybeOneOf<JS::TranscodeBuffer, nsTArray<uint8_t>> mXDRData; + } JS_HAZ_NON_GC_POINTER; + + template <ScriptStatus status> + static Matcher<CachedStencil*>* Match() { + static CachedStencil::StatusMatcher matcher{status}; + return &matcher; + } + + // There's a significant setup cost for each off-thread decode operation, + // so scripts are decoded in chunks to minimize the overhead. There's a + // careful balancing act in choosing the size of chunks, to minimize the + // number of decode operations, while also minimizing the number of buffer + // underruns that require the main thread to wait for a script to finish + // decoding. + // + // For the first chunk, we don't have much time between the start of the + // decode operation and the time the first script is needed, so that chunk + // needs to be fairly small. After the first chunk is finished, we have + // some buffered scripts to fall back on, and a lot more breathing room, + // so the chunks can be a bit bigger, but still not too big. + static constexpr int OFF_THREAD_FIRST_CHUNK_SIZE = 128 * 1024; + static constexpr int OFF_THREAD_CHUNK_SIZE = 512 * 1024; + + // Ideally, we want every chunk to be smaller than the chunk sizes + // specified above. However, if we have some number of small scripts + // followed by a huge script that would put us over the normal chunk size, + // we're better off processing them as a single chunk. + // + // In order to guarantee that the JS engine will process a chunk + // off-thread, it needs to be at least 100K (which is an implementation + // detail that can change at any time), so make sure that we always hit at + // least that size, with a bit of breathing room to be safe. + static constexpr int SMALL_SCRIPT_CHUNK_THRESHOLD = 128 * 1024; + + // The maximum size of scripts to re-decode on the main thread if off-thread + // decoding hasn't finished yet. In practice, we don't hit this very often, + // but when we do, re-decoding some smaller scripts on the main thread gives + // the background decoding a chance to catch up without blocking the main + // thread for quite as long. + static constexpr int MAX_MAINTHREAD_DECODE_SIZE = 50 * 1024; + + explicit ScriptPreloader(AutoMemMap* cacheData); + + void Cleanup(); + + void FinishPendingParses(MonitorAutoLock& aMal); + void InvalidateCache(); + + // Opens the cache file for reading. + Result<Ok, nsresult> OpenCache(); + + // Writes a new cache file to disk. Must not be called on the main thread. + Result<Ok, nsresult> WriteCache() MOZ_REQUIRES(mSaveMonitor); + + void StartCacheWrite(); + + // Prepares scripts for writing to the cache, serializing new scripts to + // XDR, and calculating their size-based offsets. + void PrepareCacheWrite(); + + void PrepareCacheWriteInternal(); + + void CacheWriteComplete(); + + void FinishContentStartup(); + + // Returns true if scripts added to the cache now will be encoded and + // written to the cache. If we've already encoded scripts for the cache + // write, or this is a content process which hasn't been asked to return + // script bytecode, this will return false. + bool WillWriteScripts(); + + // Returns a file pointer for the cache file with the given name in the + // current profile. + Result<nsCOMPtr<nsIFile>, nsresult> GetCacheFile(const nsAString& suffix); + + // Waits for the given cached script to finish compiling off-thread, or + // decodes it synchronously on the main thread, as appropriate. + already_AddRefed<JS::Stencil> WaitForCachedStencil( + JSContext* cx, const JS::DecodeOptions& options, CachedStencil* script); + + void DecodeNextBatch(size_t chunkSize, JS::Handle<JSObject*> scope = nullptr); + + static void OffThreadDecodeCallback(JS::OffThreadToken* token, void* context); + void FinishOffThreadDecode(JS::OffThreadToken* token); + void DoFinishOffThreadDecode(); + + already_AddRefed<nsIAsyncShutdownClient> GetShutdownBarrier(); + + size_t ShallowHeapSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { + return (mallocSizeOf(this) + + mScripts.ShallowSizeOfExcludingThis(mallocSizeOf) + + mallocSizeOf(mSaveThread.get()) + mallocSizeOf(mProfD.get())); + } + + using ScriptHash = nsClassHashtable<nsCStringHashKey, CachedStencil>; + + template <ScriptStatus status> + static size_t SizeOfHashEntries(ScriptHash& scripts, + mozilla::MallocSizeOf mallocSizeOf) { + size_t size = 0; + for (auto elem : IterHash(scripts, Match<status>())) { + size += elem->HeapSizeOfIncludingThis(mallocSizeOf); + } + return size; + } + + ScriptHash mScripts; + + // True after we've shown the first window, and are no longer adding new + // scripts to the cache. + bool mStartupFinished = false; + + bool mCacheInitialized = false; + bool mSaveComplete = false; + bool mDataPrepared = false; + // May only be changed on the main thread, while `mSaveMonitor` is held. + bool mCacheInvalidated MOZ_GUARDED_BY(mSaveMonitor) = false; + + // The list of scripts that we read from the initial startup cache file, + // but have yet to initiate a decode task for. + LinkedList<CachedStencil> mPendingScripts; + + // The lists of scripts and their sources that make up the chunk currently + // being decoded in a background thread. + JS::TranscodeSources mParsingSources; + Vector<CachedStencil*> mParsingScripts; + + // The token for the completed off-thread decode task. + Atomic<JS::OffThreadToken*, ReleaseAcquire> mToken{nullptr}; + + // True if a runnable has been dispatched to the main thread to finish an + // off-thread decode operation. Access only while 'mMonitor' is held. + bool mFinishDecodeRunnablePending MOZ_GUARDED_BY(mMonitor) = false; + + // True is main-thread is blocked and we should notify with Monitor. Access + // only while `mMonitor` is held. + bool mWaitingForDecode MOZ_GUARDED_BY(mMonitor) = false; + + // The process type of the current process. + static ProcessType sProcessType; + + // The process types for which remote processes have been initialized, and + // are expected to send back script data. + EnumSet<ProcessType> mInitializedProcesses{}; + + RefPtr<ScriptPreloader> mChildCache; + ScriptCacheChild* mChildActor = nullptr; + + nsString mBaseName; + nsCString mContentStartupFinishedTopic; + + nsCOMPtr<nsIFile> mProfD; + nsCOMPtr<nsIThread> mSaveThread; + nsCOMPtr<nsITimer> mSaveTimer; + + // The mmapped cache data from this session's cache file. + // The instance is held by either `gCacheData` or `gChildCacheData` static + // fields, and its lifetime is guaranteed to be longer than ScriptPreloader + // instance. + AutoMemMap* mCacheData; + + Monitor mMonitor; + MonitorSingleWriter mSaveMonitor MOZ_ACQUIRED_BEFORE(mMonitor); +}; + +} // namespace mozilla + +#endif // ScriptPreloader_h diff --git a/js/xpconnect/loader/SkipCheckForBrokenURLOrZeroSized.h b/js/xpconnect/loader/SkipCheckForBrokenURLOrZeroSized.h new file mode 100644 index 0000000000..3a413b898f --- /dev/null +++ b/js/xpconnect/loader/SkipCheckForBrokenURLOrZeroSized.h @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h +#define mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h + +#include <stdint.h> // uint8_t + +namespace mozilla { +namespace loader { + +// Represents the `aSkipCheckForBrokenURLOrZeroSized` parameter for +// `NS_NewChannel` function. +enum class SkipCheckForBrokenURLOrZeroSized : uint8_t { No, Yes }; + +} // namespace loader +} // namespace mozilla + +#endif // mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h diff --git a/js/xpconnect/loader/URLPreloader.cpp b/js/xpconnect/loader/URLPreloader.cpp new file mode 100644 index 0000000000..c5bcbad5bb --- /dev/null +++ b/js/xpconnect/loader/URLPreloader.cpp @@ -0,0 +1,707 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ScriptPreloader-inl.h" +#include "mozilla/URLPreloader.h" +#include "mozilla/loader/AutoMemMap.h" + +#include "mozilla/ArrayUtils.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/FileUtils.h" +#include "mozilla/IOBuffers.h" +#include "mozilla/Logging.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/Services.h" +#include "mozilla/Unused.h" +#include "mozilla/Vector.h" +#include "mozilla/scache/StartupCache.h" + +#include "crc32c.h" +#include "MainThreadUtils.h" +#include "nsPrintfCString.h" +#include "nsDebug.h" +#include "nsIFile.h" +#include "nsIFileURL.h" +#include "nsNetUtil.h" +#include "nsPromiseFlatString.h" +#include "nsProxyRelease.h" +#include "nsThreadUtils.h" +#include "nsXULAppAPI.h" +#include "nsZipArchive.h" +#include "xpcpublic.h" + +namespace mozilla { +namespace { +static LazyLogModule gURLLog("URLPreloader"); + +#define LOG(level, ...) MOZ_LOG(gURLLog, LogLevel::level, (__VA_ARGS__)) + +template <typename T> +bool StartsWith(const T& haystack, const T& needle) { + return StringHead(haystack, needle.Length()) == needle; +} +} // anonymous namespace + +using namespace mozilla::loader; +using mozilla::scache::StartupCache; + +nsresult URLPreloader::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) { + MOZ_COLLECT_REPORT("explicit/url-preloader/other", KIND_HEAP, UNITS_BYTES, + ShallowSizeOfIncludingThis(MallocSizeOf), + "Memory used by the URL preloader service itself."); + + for (const auto& elem : mCachedURLs.Values()) { + nsAutoCString pathName; + pathName.Append(elem->mPath); + // The backslashes will automatically be replaced with slashes in + // about:memory, without splitting each path component into a separate + // branch in the memory report tree. + pathName.ReplaceChar('/', '\\'); + + nsPrintfCString path("explicit/url-preloader/cached-urls/%s/[%s]", + elem->TypeString(), pathName.get()); + + aHandleReport->Callback( + ""_ns, path, KIND_HEAP, UNITS_BYTES, + elem->SizeOfIncludingThis(MallocSizeOf), + nsLiteralCString("Memory used to hold cache data for files which " + "have been read or pre-loaded during this session."), + aData); + } + + return NS_OK; +} + +// static +already_AddRefed<URLPreloader> URLPreloader::Create(bool* aInitialized) { + // The static APIs like URLPreloader::Read work in the child process because + // they fall back to a synchronous read. The actual preloader must be + // explicitly initialized, and this should only be done in the parent. + MOZ_RELEASE_ASSERT(XRE_IsParentProcess()); + + RefPtr<URLPreloader> preloader = new URLPreloader(); + if (preloader->InitInternal().isOk()) { + *aInitialized = true; + RegisterWeakMemoryReporter(preloader); + } else { + *aInitialized = false; + } + + return preloader.forget(); +} + +URLPreloader& URLPreloader::GetSingleton() { + if (!sSingleton) { + sSingleton = Create(&sInitialized); + ClearOnShutdown(&sSingleton); + } + + return *sSingleton; +} + +bool URLPreloader::sInitialized = false; + +StaticRefPtr<URLPreloader> URLPreloader::sSingleton; + +URLPreloader::~URLPreloader() { + if (sInitialized) { + UnregisterWeakMemoryReporter(this); + sInitialized = false; + } +} + +Result<Ok, nsresult> URLPreloader::InitInternal() { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + + if (Omnijar::HasOmnijar(Omnijar::GRE)) { + MOZ_TRY(Omnijar::GetURIString(Omnijar::GRE, mGREPrefix)); + } + if (Omnijar::HasOmnijar(Omnijar::APP)) { + MOZ_TRY(Omnijar::GetURIString(Omnijar::APP, mAppPrefix)); + } + + nsresult rv; + nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv); + MOZ_TRY(rv); + + nsCOMPtr<nsIProtocolHandler> ph; + MOZ_TRY(ios->GetProtocolHandler("resource", getter_AddRefs(ph))); + + mResProto = do_QueryInterface(ph, &rv); + MOZ_TRY(rv); + + mChromeReg = services::GetChromeRegistry(); + if (!mChromeReg) { + return Err(NS_ERROR_UNEXPECTED); + } + + MOZ_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD))); + + return Ok(); +} + +URLPreloader& URLPreloader::ReInitialize() { + MOZ_ASSERT(sSingleton); + sSingleton = nullptr; + sSingleton = Create(&sInitialized); + return *sSingleton; +} + +Result<nsCOMPtr<nsIFile>, nsresult> URLPreloader::GetCacheFile( + const nsAString& suffix) { + if (!mProfD) { + return Err(NS_ERROR_NOT_INITIALIZED); + } + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY(mProfD->Clone(getter_AddRefs(cacheFile))); + + MOZ_TRY(cacheFile->AppendNative("startupCache"_ns)); + Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777); + + MOZ_TRY(cacheFile->Append(u"urlCache"_ns + suffix)); + + return std::move(cacheFile); +} + +static const uint8_t URL_MAGIC[] = "mozURLcachev003"; + +Result<nsCOMPtr<nsIFile>, nsresult> URLPreloader::FindCacheFile() { + if (StartupCache::GetIgnoreDiskCache()) { + return Err(NS_ERROR_ABORT); + } + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY_VAR(cacheFile, GetCacheFile(u".bin"_ns)); + + bool exists; + MOZ_TRY(cacheFile->Exists(&exists)); + if (exists) { + MOZ_TRY(cacheFile->MoveTo(nullptr, u"urlCache-current.bin"_ns)); + } else { + MOZ_TRY(cacheFile->SetLeafName(u"urlCache-current.bin"_ns)); + MOZ_TRY(cacheFile->Exists(&exists)); + if (!exists) { + return Err(NS_ERROR_FILE_NOT_FOUND); + } + } + + return std::move(cacheFile); +} + +Result<Ok, nsresult> URLPreloader::WriteCache() { + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_DIAGNOSTIC_ASSERT(mStartupFinished); + + // The script preloader might call us a second time, if it has to re-write + // its cache after a cache flush. We don't care about cache flushes, since + // our cache doesn't store any file data, only paths. And we currently clear + // our cached file list after the first write, which means that a second + // write would (aside from breaking the invariant that we never touch + // mCachedURLs off-main-thread after the first write, and trigger a data + // race) mean we get no pre-loading on the next startup. + if (mCacheWritten) { + return Ok(); + } + mCacheWritten = true; + + LOG(Debug, "Writing cache..."); + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY_VAR(cacheFile, GetCacheFile(u"-new.bin"_ns)); + + bool exists; + MOZ_TRY(cacheFile->Exists(&exists)); + if (exists) { + MOZ_TRY(cacheFile->Remove(false)); + } + + { + AutoFDClose fd; + MOZ_TRY(cacheFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, 0644, + &fd.rwget())); + + nsTArray<URLEntry*> entries; + for (const auto& entry : mCachedURLs.Values()) { + if (entry->mReadTime) { + entries.AppendElement(entry.get()); + } + } + + entries.Sort(URLEntry::Comparator()); + + OutputBuffer buf; + for (auto entry : entries) { + entry->Code(buf); + } + + uint8_t headerSize[4]; + LittleEndian::writeUint32(headerSize, buf.cursor()); + + uint8_t crc[4]; + LittleEndian::writeUint32(crc, ComputeCrc32c(~0, buf.Get(), buf.cursor())); + + MOZ_TRY(Write(fd, URL_MAGIC, sizeof(URL_MAGIC))); + MOZ_TRY(Write(fd, headerSize, sizeof(headerSize))); + MOZ_TRY(Write(fd, crc, sizeof(crc))); + MOZ_TRY(Write(fd, buf.Get(), buf.cursor())); + } + + MOZ_TRY(cacheFile->MoveTo(nullptr, u"urlCache.bin"_ns)); + + NS_DispatchToMainThread( + NewRunnableMethod("URLPreloader::Cleanup", this, &URLPreloader::Cleanup)); + + return Ok(); +} + +void URLPreloader::Cleanup() { mCachedURLs.Clear(); } + +Result<Ok, nsresult> URLPreloader::ReadCache( + LinkedList<URLEntry>& pendingURLs) { + LOG(Debug, "Reading cache..."); + + nsCOMPtr<nsIFile> cacheFile; + MOZ_TRY_VAR(cacheFile, FindCacheFile()); + + AutoMemMap cache; + MOZ_TRY(cache.init(cacheFile)); + + auto size = cache.size(); + + uint32_t headerSize; + uint32_t crc; + if (size < sizeof(URL_MAGIC) + sizeof(headerSize) + sizeof(crc)) { + return Err(NS_ERROR_UNEXPECTED); + } + + auto data = cache.get<uint8_t>(); + auto end = data + size; + + if (memcmp(URL_MAGIC, data.get(), sizeof(URL_MAGIC))) { + return Err(NS_ERROR_UNEXPECTED); + } + data += sizeof(URL_MAGIC); + + headerSize = LittleEndian::readUint32(data.get()); + data += sizeof(headerSize); + + crc = LittleEndian::readUint32(data.get()); + data += sizeof(crc); + + if (data + headerSize > end) { + return Err(NS_ERROR_UNEXPECTED); + } + + if (crc != ComputeCrc32c(~0, data.get(), headerSize)) { + return Err(NS_ERROR_UNEXPECTED); + } + + { + mMonitor.AssertCurrentThreadOwns(); + + auto cleanup = MakeScopeExit([&]() { + while (auto* elem = pendingURLs.getFirst()) { + elem->remove(); + } + mCachedURLs.Clear(); + }); + + Range<uint8_t> header(data, data + headerSize); + data += headerSize; + + InputBuffer buf(header); + while (!buf.finished()) { + CacheKey key(buf); + + LOG(Debug, "Cached file: %s %s", key.TypeString(), key.mPath.get()); + + // Don't bother doing anything else if the key didn't load correctly. + // We're going to throw it out right away, and it is possible that this + // leads to pendingURLs getting into a weird state. + if (buf.error()) { + return Err(NS_ERROR_UNEXPECTED); + } + + auto entry = mCachedURLs.GetOrInsertNew(key, key); + entry->mResultCode = NS_ERROR_NOT_INITIALIZED; + + if (entry->isInList()) { +#ifdef NIGHTLY_BUILD + MOZ_DIAGNOSTIC_ASSERT(pendingURLs.contains(entry), + "Entry should be in pendingURLs"); + MOZ_DIAGNOSTIC_ASSERT(key.mPath.Length() > 0, + "Path should be non-empty"); + MOZ_DIAGNOSTIC_ASSERT(false, "Entry should be new and not in any list"); +#endif + return Err(NS_ERROR_UNEXPECTED); + } + + pendingURLs.insertBack(entry); + } + + MOZ_RELEASE_ASSERT(!buf.error(), + "We should have already bailed on an error"); + + cleanup.release(); + } + + return Ok(); +} + +void URLPreloader::BackgroundReadFiles() { + auto cleanup = MakeScopeExit([&]() { + auto lock = mReaderThread.Lock(); + auto& readerThread = lock.ref(); + NS_DispatchToMainThread(NewRunnableMethod( + "nsIThread::AsyncShutdown", readerThread, &nsIThread::AsyncShutdown)); + + readerThread = nullptr; + }); + + Vector<nsZipCursor> cursors; + LinkedList<URLEntry> pendingURLs; + { + MonitorAutoLock mal(mMonitor); + + if (ReadCache(pendingURLs).isErr()) { + mReaderInitialized = true; + mal.NotifyAll(); + return; + } + + int numZipEntries = 0; + for (auto entry : pendingURLs) { + if (entry->mType != entry->TypeFile) { + numZipEntries++; + } + } + MOZ_RELEASE_ASSERT(cursors.reserve(numZipEntries)); + + // Initialize the zip cursors for all files in Omnijar while the monitor + // is locked. Omnijar is not threadsafe, so the caller of + // AutoBeginReading guard must ensure that no code accesses Omnijar + // until this segment is done. Once the cursors have been initialized, + // the actual reading and decompression can safely be done off-thread, + // as is the case for thread-retargeted jar: channels. + for (auto entry : pendingURLs) { + if (entry->mType == entry->TypeFile) { + continue; + } + + RefPtr<nsZipArchive> zip = entry->Archive(); + if (!zip) { + MOZ_CRASH_UNSAFE_PRINTF( + "Failed to get Omnijar %s archive for entry (path: \"%s\")", + entry->TypeString(), entry->mPath.get()); + } + + auto item = zip->GetItem(entry->mPath.get()); + if (!item) { + entry->mResultCode = NS_ERROR_FILE_NOT_FOUND; + continue; + } + + size_t size = item->RealSize(); + + entry->mData.SetLength(size); + auto data = entry->mData.BeginWriting(); + + cursors.infallibleEmplaceBack(item, zip, reinterpret_cast<uint8_t*>(data), + size, true); + } + + mReaderInitialized = true; + mal.NotifyAll(); + } + + // Loop over the entries, read the file's contents, store them in the + // entry's mData pointer, and notify any waiting threads to check for + // completion. + uint32_t i = 0; + for (auto entry : pendingURLs) { + // If there is any other error code, the entry has already failed at + // this point, so don't bother trying to read it again. + if (entry->mResultCode != NS_ERROR_NOT_INITIALIZED) { + continue; + } + + nsresult rv = NS_OK; + + LOG(Debug, "Background reading %s file %s", entry->TypeString(), + entry->mPath.get()); + + if (entry->mType == entry->TypeFile) { + auto result = entry->Read(); + if (result.isErr()) { + rv = result.unwrapErr(); + } + } else { + auto& cursor = cursors[i++]; + + uint32_t len; + cursor.Copy(&len); + if (len != entry->mData.Length()) { + entry->mData.Truncate(); + rv = NS_ERROR_FAILURE; + } + } + + entry->mResultCode = rv; + mMonitor.NotifyAll(); + } + + // We're done reading pending entries, so clear the list. + pendingURLs.clear(); +} + +void URLPreloader::BeginBackgroundRead() { + auto lock = mReaderThread.Lock(); + auto& readerThread = lock.ref(); + if (!readerThread && !mReaderInitialized && sInitialized) { + nsresult rv; + rv = NS_NewNamedThread("BGReadURLs", getter_AddRefs(readerThread)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsCOMPtr<nsIRunnable> runnable = + NewRunnableMethod("URLPreloader::BackgroundReadFiles", this, + &URLPreloader::BackgroundReadFiles); + rv = readerThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + // If we can't launch the task, just destroy the thread + readerThread = nullptr; + return; + } + } +} + +Result<nsCString, nsresult> URLPreloader::ReadInternal(const CacheKey& key, + ReadType readType) { + if (mStartupFinished || !mReaderInitialized) { + URLEntry entry(key); + + return entry.Read(); + } + + auto entry = mCachedURLs.GetOrInsertNew(key, key); + + entry->UpdateUsedTime(); + + return entry->ReadOrWait(readType); +} + +Result<nsCString, nsresult> URLPreloader::ReadURIInternal(nsIURI* uri, + ReadType readType) { + CacheKey key; + MOZ_TRY_VAR(key, ResolveURI(uri)); + + return ReadInternal(key, readType); +} + +/* static */ Result<nsCString, nsresult> URLPreloader::Read(const CacheKey& key, + ReadType readType) { + // If we're being called before the preloader has been initialized (i.e., + // before the profile has been initialized), just fall back to a synchronous + // read. This happens when we're reading .ini and preference files that are + // needed to locate and initialize the profile. + if (!sInitialized) { + return URLEntry(key).Read(); + } + + return GetSingleton().ReadInternal(key, readType); +} + +/* static */ Result<nsCString, nsresult> URLPreloader::ReadURI( + nsIURI* uri, ReadType readType) { + if (!sInitialized) { + return Err(NS_ERROR_NOT_INITIALIZED); + } + + return GetSingleton().ReadURIInternal(uri, readType); +} + +/* static */ Result<nsCString, nsresult> URLPreloader::ReadFile( + nsIFile* file, ReadType readType) { + return Read(CacheKey(file), readType); +} + +/* static */ Result<nsCString, nsresult> URLPreloader::Read( + FileLocation& location, ReadType readType) { + if (location.IsZip()) { + if (location.GetBaseZip()) { + nsCString path; + location.GetPath(path); + return ReadZip(location.GetBaseZip(), path); + } + return URLEntry::ReadLocation(location); + } + + nsCOMPtr<nsIFile> file = location.GetBaseFile(); + return ReadFile(file, readType); +} + +/* static */ Result<nsCString, nsresult> URLPreloader::ReadZip( + nsZipArchive* zip, const nsACString& path, ReadType readType) { + // If the zip archive belongs to an Omnijar location, map it to a cache + // entry, and cache it as normal. Otherwise, simply read the entry + // synchronously, since other JAR archives are currently unsupported by the + // cache. + RefPtr<nsZipArchive> reader = Omnijar::GetReader(Omnijar::GRE); + if (zip == reader) { + CacheKey key(CacheKey::TypeGREJar, path); + return Read(key, readType); + } + + reader = Omnijar::GetReader(Omnijar::APP); + if (zip == reader) { + CacheKey key(CacheKey::TypeAppJar, path); + return Read(key, readType); + } + + // Not an Omnijar archive, so just read it directly. + FileLocation location(zip, PromiseFlatCString(path).BeginReading()); + return URLEntry::ReadLocation(location); +} + +Result<URLPreloader::CacheKey, nsresult> URLPreloader::ResolveURI(nsIURI* uri) { + nsCString spec; + nsCString scheme; + MOZ_TRY(uri->GetSpec(spec)); + MOZ_TRY(uri->GetScheme(scheme)); + + nsCOMPtr<nsIURI> resolved; + + // If the URI is a resource: or chrome: URI, first resolve it to the + // underlying URI that it wraps. + if (scheme.EqualsLiteral("resource")) { + MOZ_TRY(mResProto->ResolveURI(uri, spec)); + MOZ_TRY(NS_NewURI(getter_AddRefs(resolved), spec)); + } else if (scheme.EqualsLiteral("chrome")) { + MOZ_TRY(mChromeReg->ConvertChromeURL(uri, getter_AddRefs(resolved))); + MOZ_TRY(resolved->GetSpec(spec)); + } else { + resolved = uri; + } + MOZ_TRY(resolved->GetScheme(scheme)); + + // Try the GRE and App Omnijar prefixes. + if (mGREPrefix.Length() && StartsWith(spec, mGREPrefix)) { + return CacheKey(CacheKey::TypeGREJar, Substring(spec, mGREPrefix.Length())); + } + + if (mAppPrefix.Length() && StartsWith(spec, mAppPrefix)) { + return CacheKey(CacheKey::TypeAppJar, Substring(spec, mAppPrefix.Length())); + } + + // Try for a file URI. + if (scheme.EqualsLiteral("file")) { + nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(resolved); + MOZ_ASSERT(fileURL); + + nsCOMPtr<nsIFile> file; + MOZ_TRY(fileURL->GetFile(getter_AddRefs(file))); + + nsString path; + MOZ_TRY(file->GetPath(path)); + + return CacheKey(CacheKey::TypeFile, NS_ConvertUTF16toUTF8(path)); + } + + // Not a file or Omnijar URI, so currently unsupported. + return Err(NS_ERROR_INVALID_ARG); +} + +size_t URLPreloader::ShallowSizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) { + return (mallocSizeOf(this) + + mAppPrefix.SizeOfExcludingThisEvenIfShared(mallocSizeOf) + + mGREPrefix.SizeOfExcludingThisEvenIfShared(mallocSizeOf) + + mCachedURLs.ShallowSizeOfExcludingThis(mallocSizeOf)); +} + +Result<FileLocation, nsresult> URLPreloader::CacheKey::ToFileLocation() { + if (mType == TypeFile) { + nsCOMPtr<nsIFile> file; + MOZ_TRY(NS_NewLocalFile(NS_ConvertUTF8toUTF16(mPath), false, + getter_AddRefs(file))); + return FileLocation(file); + } + + RefPtr<nsZipArchive> zip = Archive(); + return FileLocation(zip, mPath.get()); +} + +Result<nsCString, nsresult> URLPreloader::URLEntry::Read() { + FileLocation location; + MOZ_TRY_VAR(location, ToFileLocation()); + + MOZ_TRY_VAR(mData, ReadLocation(location)); + return mData; +} + +/* static */ Result<nsCString, nsresult> URLPreloader::URLEntry::ReadLocation( + FileLocation& location) { + FileLocation::Data data; + MOZ_TRY(location.GetData(data)); + + uint32_t size; + MOZ_TRY(data.GetSize(&size)); + + nsCString result; + result.SetLength(size); + MOZ_TRY(data.Copy(result.BeginWriting(), size)); + + return std::move(result); +} + +Result<nsCString, nsresult> URLPreloader::URLEntry::ReadOrWait( + ReadType readType) { + auto now = TimeStamp::Now(); + LOG(Info, "Reading %s\n", mPath.get()); + auto cleanup = MakeScopeExit([&]() { + LOG(Info, "Read in %fms\n", (TimeStamp::Now() - now).ToMilliseconds()); + }); + + if (mResultCode == NS_ERROR_NOT_INITIALIZED) { + MonitorAutoLock mal(GetSingleton().mMonitor); + + while (mResultCode == NS_ERROR_NOT_INITIALIZED) { + mal.Wait(); + } + } + + if (mResultCode == NS_OK && mData.IsVoid()) { + LOG(Info, "Reading synchronously...\n"); + return Read(); + } + + if (NS_FAILED(mResultCode)) { + return Err(mResultCode); + } + + nsCString res = mData; + + if (readType == Forget) { + mData.SetIsVoid(true); + } + return res; +} + +inline URLPreloader::CacheKey::CacheKey(InputBuffer& buffer) { + Code(buffer); + MOZ_DIAGNOSTIC_ASSERT( + mType == TypeAppJar || mType == TypeGREJar || mType == TypeFile, + "mType should be valid"); +} + +NS_IMPL_ISUPPORTS(URLPreloader, nsIMemoryReporter) + +#undef LOG + +} // namespace mozilla diff --git a/js/xpconnect/loader/URLPreloader.h b/js/xpconnect/loader/URLPreloader.h new file mode 100644 index 0000000000..2573fc89a2 --- /dev/null +++ b/js/xpconnect/loader/URLPreloader.h @@ -0,0 +1,318 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef URLPreloader_h +#define URLPreloader_h + +#include "mozilla/DataMutex.h" +#include "mozilla/FileLocation.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/LinkedList.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Monitor.h" +#include "mozilla/Omnijar.h" +#include "mozilla/Range.h" +#include "mozilla/Vector.h" +#include "mozilla/Result.h" +#include "nsClassHashtable.h" +#include "nsHashKeys.h" +#include "nsIChromeRegistry.h" +#include "nsIFile.h" +#include "nsIURI.h" +#include "nsIMemoryReporter.h" +#include "nsIResProtocolHandler.h" +#include "nsIThread.h" +#include "nsReadableUtils.h" + +class nsZipArchive; + +namespace mozilla { +namespace loader { +class InputBuffer; +} + +using namespace mozilla::loader; + +class ScriptPreloader; + +/** + * A singleton class to manage loading local URLs during startup, recording + * them, and pre-loading them during early startup in the next session. URLs + * that are not already loaded (or already being pre-loaded) when required are + * read synchronously from disk, and (if startup is not already complete) + * added to the pre-load list for the next session. + */ +class URLPreloader final : public nsIMemoryReporter { + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) + + URLPreloader() = default; + + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIMEMORYREPORTER + + static URLPreloader& GetSingleton(); + + // The type of read operation to perform. + enum ReadType { + // Read the file and then immediately forget its data. + Forget, + // Read the file and retain its data for the next caller. + Retain, + }; + + // Helpers to read the contents of files or JAR archive entries with various + // representations. If the preloader has not yet been initialized, or the + // given location is not supported by the cache, the entries will be read + // synchronously, and not stored in the cache. + static Result<nsCString, nsresult> Read(FileLocation& location, + ReadType readType = Forget); + + static Result<nsCString, nsresult> ReadURI(nsIURI* uri, + ReadType readType = Forget); + + static Result<nsCString, nsresult> ReadFile(nsIFile* file, + ReadType readType = Forget); + + static Result<nsCString, nsresult> ReadZip(nsZipArchive* archive, + const nsACString& path, + ReadType readType = Forget); + + void SetStartupFinished() { mStartupFinished = true; } + + private: + struct CacheKey; + + Result<nsCString, nsresult> ReadInternal(const CacheKey& key, + ReadType readType); + + Result<nsCString, nsresult> ReadURIInternal(nsIURI* uri, ReadType readType); + + Result<nsCString, nsresult> ReadFileInternal(nsIFile* file, + ReadType readType); + + static Result<nsCString, nsresult> Read(const CacheKey& key, + ReadType readType); + + static bool sInitialized; + + static mozilla::StaticRefPtr<URLPreloader> sSingleton; + + protected: + friend class AddonManagerStartup; + friend class ScriptPreloader; + + virtual ~URLPreloader(); + + Result<Ok, nsresult> WriteCache(); + + static URLPreloader& ReInitialize(); + + // Clear leftover entries after the cache has been written. + void Cleanup(); + + // Begins reading files off-thread, and ensures that initialization has + // completed before leaving the current scope. The caller *must* ensure that + // no code on the main thread access Omnijar, either directly or indirectly, + // for the lifetime of this guard object. + struct MOZ_RAII AutoBeginReading final { + AutoBeginReading() { GetSingleton().BeginBackgroundRead(); } + + ~AutoBeginReading() { + auto& reader = GetSingleton(); + + MonitorAutoLock mal(reader.mMonitor); + + while (!reader.mReaderInitialized && URLPreloader::sInitialized) { + mal.Wait(); + } + } + }; + + private: + // Represents a key for an entry in the URI cache, based on its file or JAR + // location. + struct CacheKey { + // The type of the entry. TypeAppJar and TypeGREJar entries are in the + // app-specific or toolkit Omnijar files, and are handled specially. + // TypeFile entries are plain files in the filesystem. + enum EntryType : uint8_t { + TypeAppJar, + TypeGREJar, + TypeFile, + }; + + CacheKey() = default; + CacheKey(const CacheKey& other) = default; + + CacheKey(EntryType type, const nsACString& path) + : mType(type), mPath(path) {} + + explicit CacheKey(nsIFile* file) : mType(TypeFile) { + nsString path; + MOZ_ALWAYS_SUCCEEDS(file->GetPath(path)); + MOZ_DIAGNOSTIC_ASSERT(path.Length() > 0); + CopyUTF16toUTF8(path, mPath); + } + + explicit inline CacheKey(InputBuffer& buffer); + + // Encodes or decodes the cache key for storage in a session cache file. + template <typename Buffer> + void Code(Buffer& buffer) { + buffer.codeUint8(*reinterpret_cast<uint8_t*>(&mType)); + buffer.codeString(mPath); + MOZ_DIAGNOSTIC_ASSERT(mPath.Length() > 0); + } + + uint32_t Hash() const { return HashGeneric(mType, HashString(mPath)); } + + bool operator==(const CacheKey& other) const { + return mType == other.mType && mPath == other.mPath; + } + + // Returns the Omnijar type for this entry. This may *only* be called + // for Omnijar entries. + Omnijar::Type OmnijarType() { + switch (mType) { + case TypeAppJar: + return Omnijar::APP; + case TypeGREJar: + return Omnijar::GRE; + default: + MOZ_CRASH("Unexpected entry type"); + return Omnijar::GRE; + } + } + + const char* TypeString() const { + switch (mType) { + case TypeAppJar: + return "AppJar"; + case TypeGREJar: + return "GREJar"; + case TypeFile: + return "File"; + } + MOZ_ASSERT_UNREACHABLE("no such type"); + return ""; + } + + already_AddRefed<nsZipArchive> Archive() { + return Omnijar::GetReader(OmnijarType()); + } + + Result<FileLocation, nsresult> ToFileLocation(); + + EntryType mType = TypeFile; + + // The path of the entry. For Type*Jar entries, this is the path within + // the Omnijar archive. For TypeFile entries, this is the full path to + // the file. + nsCString mPath{}; + }; + + // Represents an entry in the URI cache. + struct URLEntry final : public CacheKey, public LinkedListElement<URLEntry> { + MOZ_IMPLICIT URLEntry(const CacheKey& key) + : CacheKey(key), mData(VoidCString()) {} + + explicit URLEntry(nsIFile* file) : CacheKey(file) {} + + // For use with nsTArray::Sort. + // + // Sorts entries by the time they were initially read during this + // session. + struct Comparator final { + bool Equals(const URLEntry* a, const URLEntry* b) const { + return a->mReadTime == b->mReadTime; + } + + bool LessThan(const URLEntry* a, const URLEntry* b) const { + return a->mReadTime < b->mReadTime; + } + }; + + // Sets the first-used time of this file to the earlier of its current + // first-use time or the given timestamp. + void UpdateUsedTime(const TimeStamp& time = TimeStamp::Now()) { + if (!mReadTime || time < mReadTime) { + mReadTime = time; + } + } + + Result<nsCString, nsresult> Read(); + static Result<nsCString, nsresult> ReadLocation(FileLocation& location); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { + return (mallocSizeOf(this) + + mPath.SizeOfExcludingThisEvenIfShared(mallocSizeOf) + + mData.SizeOfExcludingThisEvenIfShared(mallocSizeOf)); + } + + // Reads the contents of the file referenced by this entry, or wait for + // an off-thread read operation to finish if it is currently pending, + // and return the file's contents. + Result<nsCString, nsresult> ReadOrWait(ReadType readType); + + nsCString mData; + + TimeStamp mReadTime{}; + + nsresult mResultCode = NS_OK; + }; + + // Resolves the given URI to a CacheKey, if the URI is cacheable. + Result<CacheKey, nsresult> ResolveURI(nsIURI* uri); + + static already_AddRefed<URLPreloader> Create(bool* aInitialized); + + Result<Ok, nsresult> InitInternal(); + + // Returns a file pointer to the (possibly nonexistent) cache file with the + // given suffix. + Result<nsCOMPtr<nsIFile>, nsresult> GetCacheFile(const nsAString& suffix); + // Finds the correct cache file to use for this session. + Result<nsCOMPtr<nsIFile>, nsresult> FindCacheFile(); + + Result<Ok, nsresult> ReadCache(LinkedList<URLEntry>& pendingURLs); + + void BackgroundReadFiles(); + void BeginBackgroundRead(); + + using HashType = nsClassHashtable<nsGenericHashKey<CacheKey>, URLEntry>; + + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + bool mStartupFinished = false; + bool mReaderInitialized = false; + + // Only to be accessed from the cache write thread. + bool mCacheWritten = false; + + // The prefix URLs for files in the GRE and App omni jar archives. + nsCString mGREPrefix; + nsCString mAppPrefix; + + nsCOMPtr<nsIResProtocolHandler> mResProto; + nsCOMPtr<nsIChromeRegistry> mChromeReg; + nsCOMPtr<nsIFile> mProfD; + + // Note: We use a RefPtr rather than an nsCOMPtr here because the + // AssertNoQueryNeeded checks done by getter_AddRefs happen at a time that + // violate data access invariants. It's wrapped in a mutex because + // the reader thread needs to be able to null this out to terminate itself. + DataMutex<RefPtr<nsIThread>> mReaderThread{"ReaderThread"}; + + // A map of URL entries which have were either read this session, or read + // from the last session's cache file. + HashType mCachedURLs; + + Monitor mMonitor MOZ_UNANNOTATED{"[URLPreloader::mMutex]"}; +}; + +} // namespace mozilla + +#endif // URLPreloader_h diff --git a/js/xpconnect/loader/XPCOMUtils.sys.mjs b/js/xpconnect/loader/XPCOMUtils.sys.mjs new file mode 100644 index 0000000000..403b17e2be --- /dev/null +++ b/js/xpconnect/loader/XPCOMUtils.sys.mjs @@ -0,0 +1,580 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=2 et filetype=javascript + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; + +let global = Cu.getGlobalForObject({}); + +// Some global imports expose additional symbols; for example, +// `Cu.importGlobalProperties(["MessageChannel"])` imports `MessageChannel` +// and `MessagePort`. This table maps those extra symbols to the main +// import name. +const EXTRA_GLOBAL_NAME_TO_IMPORT_NAME = { + MessagePort: "MessageChannel", +}; + +/** + * Redefines the given property on the given object with the given + * value. This can be used to redefine getter properties which do not + * implement setters. + */ +function redefine(object, prop, value) { + Object.defineProperty(object, prop, { + configurable: true, + enumerable: true, + value, + writable: true, + }); + return value; +} + +export var XPCOMUtils = { + /** + * Defines a getter on a specified object that will be created upon first use. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter to define on aObject. + * @param aLambda + * A function that returns what the getter should return. This will + * only ever be called once. + */ + defineLazyGetter(aObject, aName, aLambda) { + ChromeUtils.defineLazyGetter(aObject, aName, aLambda); + }, + + /** + * Defines a getter on a specified object for a script. The script will not + * be loaded until first use. + * + * @param aObject + * The object to define the lazy getter on. + * @param aNames + * The name of the getter to define on aObject for the script. + * This can be a string if the script exports only one symbol, + * or an array of strings if the script can be first accessed + * from several different symbols. + * @param aResource + * The URL used to obtain the script. + */ + defineLazyScriptGetter(aObject, aNames, aResource) { + if (!Array.isArray(aNames)) { + aNames = [aNames]; + } + for (let name of aNames) { + Object.defineProperty(aObject, name, { + get() { + XPCOMUtils._scriptloader.loadSubScript(aResource, aObject); + return aObject[name]; + }, + set(value) { + redefine(aObject, name, value); + }, + configurable: true, + enumerable: true, + }); + } + }, + + /** + * Overrides the scriptloader definition for tests to help with globals + * tracking. Should only be used for tests. + * + * @param {object} aObject + * The alternative script loader object to use. + */ + overrideScriptLoaderForTests(aObject) { + Cu.crashIfNotInAutomation(); + delete this._scriptloader; + this._scriptloader = aObject; + }, + + /** + * Defines a getter property on the given object for each of the given + * global names as accepted by Cu.importGlobalProperties. These + * properties are imported into the shared JSM module global, and then + * copied onto the given object, no matter which global the object + * belongs to. + * + * @param {object} aObject + * The object on which to define the properties. + * @param {string[]} aNames + * The list of global properties to define. + */ + defineLazyGlobalGetters(aObject, aNames) { + for (let name of aNames) { + this.defineLazyGetter(aObject, name, () => { + if (!(name in global)) { + let importName = EXTRA_GLOBAL_NAME_TO_IMPORT_NAME[name] || name; + // eslint-disable-next-line mozilla/reject-importGlobalProperties, no-unused-vars + Cu.importGlobalProperties([importName]); + } + return global[name]; + }); + } + }, + + /** + * Defines a getter on a specified object for a service. The service will not + * be obtained until first use. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter to define on aObject for the service. + * @param aContract + * The contract used to obtain the service. + * @param aInterfaceName + * The name of the interface to query the service to. + */ + defineLazyServiceGetter(aObject, aName, aContract, aInterfaceName) { + this.defineLazyGetter(aObject, aName, () => { + if (aInterfaceName) { + return Cc[aContract].getService(Ci[aInterfaceName]); + } + return Cc[aContract].getService().wrappedJSObject; + }); + }, + + /** + * Defines a lazy service getter on a specified object for each + * property in the given object. + * + * @param aObject + * The object to define the lazy getter on. + * @param aServices + * An object with a property for each service to be + * imported, where the property name is the name of the + * symbol to define, and the value is a 1 or 2 element array + * containing the contract ID and, optionally, the interface + * name of the service, as passed to defineLazyServiceGetter. + */ + defineLazyServiceGetters(aObject, aServices) { + for (let [name, service] of Object.entries(aServices)) { + // Note: This is hot code, and cross-compartment array wrappers + // are not JIT-friendly to destructuring or spread operators, so + // we need to use indexed access instead. + this.defineLazyServiceGetter( + aObject, + name, + service[0], + service[1] || null + ); + } + }, + + /** + * Defines a getter on a specified object for a module. The module will not + * be imported until first use. The getter allows to execute setup and + * teardown code (e.g. to register/unregister to services) and accepts + * a proxy object which acts on behalf of the module until it is imported. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter to define on aObject for the module. + * @param aResource + * The URL used to obtain the module. + * @param aSymbol + * The name of the symbol exported by the module. + * This parameter is optional and defaults to aName. + * @param aPreLambda + * A function that is executed when the proxy is set up. + * This will only ever be called once. + * @param aPostLambda + * A function that is executed when the module has been imported to + * run optional teardown procedures on the proxy object. + * This will only ever be called once. + * @param aProxy + * An object which acts on behalf of the module to be imported until + * the module has been imported. + */ + defineLazyModuleGetter( + aObject, + aName, + aResource, + aSymbol, + aPreLambda, + aPostLambda, + aProxy + ) { + if (arguments.length == 3) { + ChromeUtils.defineModuleGetter(aObject, aName, aResource); + return; + } + + let proxy = aProxy || {}; + + if (typeof aPreLambda === "function") { + aPreLambda.apply(proxy); + } + + this.defineLazyGetter(aObject, aName, () => { + var temp = {}; + try { + temp = ChromeUtils.import(aResource); + + if (typeof aPostLambda === "function") { + aPostLambda.apply(proxy); + } + } catch (ex) { + console.error("Failed to load module " + aResource + "."); + throw ex; + } + return temp[aSymbol || aName]; + }); + }, + + /** + * Defines a lazy module getter on a specified object for each + * property in the given object. + * + * @param aObject + * The object to define the lazy getter on. + * @param aModules + * An object with a property for each module property to be + * imported, where the property name is the name of the + * imported symbol and the value is the module URI. + */ + defineLazyModuleGetters(aObject, aModules) { + for (let [name, module] of Object.entries(aModules)) { + ChromeUtils.defineModuleGetter(aObject, name, module); + } + }, + + /** + * Defines a getter on a specified object for preference value. The + * preference is read the first time that the property is accessed, + * and is thereafter kept up-to-date using a preference observer. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter property to define on aObject. + * @param aPreference + * The name of the preference to read. + * @param aDefaultPrefValue + * The default value to use, if the preference is not defined. + * This is the default value of the pref, before applying aTransform. + * @param aOnUpdate + * A function to call upon update. Receives as arguments + * `(aPreference, previousValue, newValue)` + * @param aTransform + * An optional function to transform the value. If provided, + * this function receives the new preference value as an argument + * and its return value is used by the getter. + */ + defineLazyPreferenceGetter( + aObject, + aName, + aPreference, + aDefaultPrefValue = null, + aOnUpdate = null, + aTransform = val => val + ) { + if (AppConstants.DEBUG && aDefaultPrefValue !== null) { + let prefType = Services.prefs.getPrefType(aPreference); + if (prefType != Ci.nsIPrefBranch.PREF_INVALID) { + // The pref may get defined after the lazy getter is called + // at which point the code here won't know the expected type. + let prefTypeForDefaultValue = { + boolean: Ci.nsIPrefBranch.PREF_BOOL, + number: Ci.nsIPrefBranch.PREF_INT, + string: Ci.nsIPrefBranch.PREF_STRING, + }[typeof aDefaultPrefValue]; + if (prefTypeForDefaultValue != prefType) { + throw new Error( + `Default value does not match preference type (Got ${prefTypeForDefaultValue}, expected ${prefType}) for ${aPreference}` + ); + } + } + } + + // Note: We need to keep a reference to this observer alive as long + // as aObject is alive. This means that all of our getters need to + // explicitly close over the variable that holds the object, and we + // cannot define a value in place of a getter after we read the + // preference. + let observer = { + QueryInterface: XPCU_lazyPreferenceObserverQI, + + value: undefined, + + observe(subject, topic, data) { + if (data == aPreference) { + if (aOnUpdate) { + let previous = this.value; + + // Fetch and cache value. + this.value = undefined; + let latest = lazyGetter(); + aOnUpdate(data, previous, latest); + } else { + // Empty cache, next call to the getter will cause refetch. + this.value = undefined; + } + } + }, + }; + + let defineGetter = get => { + Object.defineProperty(aObject, aName, { + configurable: true, + enumerable: true, + get, + }); + }; + + function lazyGetter() { + if (observer.value === undefined) { + let prefValue; + switch (Services.prefs.getPrefType(aPreference)) { + case Ci.nsIPrefBranch.PREF_STRING: + prefValue = Services.prefs.getStringPref(aPreference); + break; + + case Ci.nsIPrefBranch.PREF_INT: + prefValue = Services.prefs.getIntPref(aPreference); + break; + + case Ci.nsIPrefBranch.PREF_BOOL: + prefValue = Services.prefs.getBoolPref(aPreference); + break; + + case Ci.nsIPrefBranch.PREF_INVALID: + prefValue = aDefaultPrefValue; + break; + + default: + // This should never happen. + throw new Error( + `Error getting pref ${aPreference}; its value's type is ` + + `${Services.prefs.getPrefType(aPreference)}, which I don't ` + + `know how to handle.` + ); + } + + observer.value = aTransform(prefValue); + } + return observer.value; + } + + defineGetter(() => { + Services.prefs.addObserver(aPreference, observer, true); + + defineGetter(lazyGetter); + return lazyGetter(); + }); + }, + + /** + * Defines a non-writable property on an object. + */ + defineConstant(aObj, aName, aValue) { + Object.defineProperty(aObj, aName, { + value: aValue, + enumerable: true, + writable: false, + }); + }, + + /** + * Defines a proxy which acts as a lazy object getter that can be passed + * around as a reference, and will only be evaluated when something in + * that object gets accessed. + * + * The evaluation can be triggered by a function call, by getting or + * setting a property, calling this as a constructor, or enumerating + * the properties of this object (e.g. during an iteration). + * + * Please note that, even after evaluated, the object given to you + * remains being the proxy object (which forwards everything to the + * real object). This is important to correctly use these objects + * in pairs of add+remove listeners, for example. + * If your use case requires access to the direct object, you can + * get it through the untrap callback. + * + * @param aObject + * The object to define the lazy getter on. + * + * You can pass null to aObject if you just want to get this + * proxy through the return value. + * + * @param aName + * The name of the getter to define on aObject. + * + * @param aInitFuncOrResource + * A function or a module that defines what this object actually + * should be when it gets evaluated. This will only ever be called once. + * + * Short-hand: If you pass a string to this parameter, it will be treated + * as the URI of a module to be imported, and aName will be used as + * the symbol to retrieve from the module. + * + * @param aStubProperties + * In this parameter, you can provide an object which contains + * properties from the original object that, when accessed, will still + * prevent the entire object from being evaluated. + * + * These can be copies or simplified versions of the original properties. + * + * One example is to provide an alternative QueryInterface implementation + * to avoid the entire object from being evaluated when it's added as an + * observer (as addObserver calls object.QueryInterface(Ci.nsIObserver)). + * + * Once the object has been evaluated, the properties from the real + * object will be used instead of the ones provided here. + * + * @param aUntrapCallback + * A function that gets called once when the object has just been evaluated. + * You can use this to do some work (e.g. setting properties) that you need + * to do on this object but that can wait until it gets evaluated. + * + * Another use case for this is to use during code development to log when + * this object gets evaluated, to make sure you're not accidentally triggering + * it earlier than expected. + */ + defineLazyProxy( + aObject, + aName, + aInitFuncOrResource, + aStubProperties, + aUntrapCallback + ) { + let initFunc = aInitFuncOrResource; + + if (typeof aInitFuncOrResource == "string") { + initFunc = () => ChromeUtils.import(aInitFuncOrResource)[aName]; + } + + let handler = new LazyProxyHandler( + aName, + initFunc, + aStubProperties, + aUntrapCallback + ); + + /* + * We cannot simply create a lazy getter for the underlying + * object and pass it as the target of the proxy, because + * just passing it in `new Proxy` means it would get + * evaluated. Becase of this, a full handler needs to be + * implemented (the LazyProxyHandler). + * + * So, an empty object is used as the target, and the handler + * replaces it on every call with the real object. + */ + let proxy = new Proxy({}, handler); + + if (aObject) { + Object.defineProperty(aObject, aName, { + value: proxy, + enumerable: true, + writable: true, + }); + } + + return proxy; + }, +}; + +XPCOMUtils.defineLazyGetter(XPCOMUtils, "_scriptloader", () => { + return Services.scriptloader; +}); + +/** + * LazyProxyHandler + * This class implements the handler used + * in the proxy from defineLazyProxy. + * + * This handler forwards all calls to an underlying object, + * stored as `this.realObject`, which is obtained as the returned + * value from aInitFunc, which will be called on the first time + * time that it needs to be used (with an exception in the get() trap + * for the properties provided in the `aStubProperties` parameter). + */ + +class LazyProxyHandler { + constructor(aName, aInitFunc, aStubProperties, aUntrapCallback) { + this.pending = true; + this.name = aName; + this.initFuncOrResource = aInitFunc; + this.stubProperties = aStubProperties; + this.untrapCallback = aUntrapCallback; + } + + getObject() { + if (this.pending) { + this.realObject = this.initFuncOrResource.call(null); + + if (this.untrapCallback) { + this.untrapCallback.call(null, this.realObject); + this.untrapCallback = null; + } + + this.pending = false; + this.stubProperties = null; + } + return this.realObject; + } + + getPrototypeOf(target) { + return Reflect.getPrototypeOf(this.getObject()); + } + + setPrototypeOf(target, prototype) { + return Reflect.setPrototypeOf(this.getObject(), prototype); + } + + isExtensible(target) { + return Reflect.isExtensible(this.getObject()); + } + + preventExtensions(target) { + return Reflect.preventExtensions(this.getObject()); + } + + getOwnPropertyDescriptor(target, prop) { + return Reflect.getOwnPropertyDescriptor(this.getObject(), prop); + } + + defineProperty(target, prop, descriptor) { + return Reflect.defineProperty(this.getObject(), prop, descriptor); + } + + has(target, prop) { + return Reflect.has(this.getObject(), prop); + } + + get(target, prop, receiver) { + if ( + this.pending && + this.stubProperties && + Object.prototype.hasOwnProperty.call(this.stubProperties, prop) + ) { + return this.stubProperties[prop]; + } + return Reflect.get(this.getObject(), prop, receiver); + } + + set(target, prop, value, receiver) { + return Reflect.set(this.getObject(), prop, value, receiver); + } + + deleteProperty(target, prop) { + return Reflect.deleteProperty(this.getObject(), prop); + } + + ownKeys(target) { + return Reflect.ownKeys(this.getObject()); + } +} + +var XPCU_lazyPreferenceObserverQI = ChromeUtils.generateQI([ + "nsIObserver", + "nsISupportsWeakReference", +]); diff --git a/js/xpconnect/loader/moz.build b/js/xpconnect/loader/moz.build new file mode 100644 index 0000000000..44ec49c955 --- /dev/null +++ b/js/xpconnect/loader/moz.build @@ -0,0 +1,67 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + "AutoMemMap.cpp", + "ChromeScriptLoader.cpp", + "ComponentModuleLoader.cpp", + "JSMEnvironmentProxy.cpp", + "ModuleEnvironmentProxy.cpp", + "mozJSLoaderUtils.cpp", + "mozJSSubScriptLoader.cpp", + "nsImportModule.cpp", + "ScriptCacheActors.cpp", + "ScriptPreloader.cpp", + "URLPreloader.cpp", +] + +# mozJSModuleLoader.cpp cannot be built in unified mode because it uses +# windows.h +SOURCES += [ + "mozJSModuleLoader.cpp", +] + +IPDL_SOURCES += [ + "PScriptCache.ipdl", +] + +EXPORTS += ["nsImportModule.h"] + +EXPORTS.mozilla += [ + "AutoMemMap.h", + "IOBuffers.h", + "ScriptPreloader.h", + "URLPreloader.h", +] + +EXPORTS.mozilla.dom += [ + "PrecompiledScript.h", +] + +EXPORTS.mozilla.loader += [ + "AutoMemMap.h", + "ComponentModuleLoader.h", + "ScriptCacheActors.h", + "SkipCheckForBrokenURLOrZeroSized.h", +] + +EXTRA_JS_MODULES += [ + "ComponentUtils.sys.mjs", + "XPCOMUtils.sys.mjs", +] + +FINAL_LIBRARY = "xul" + +LOCAL_INCLUDES += [ + "../src", + "../wrappers", + "/dom/base", + "/js/loader", + "/xpcom/base/", + "/xpcom/io", # crc32c.h +] + +include("/ipc/chromium/chromium-config.mozbuild") diff --git a/js/xpconnect/loader/mozJSLoaderUtils.cpp b/js/xpconnect/loader/mozJSLoaderUtils.cpp new file mode 100644 index 0000000000..3f54e87d3b --- /dev/null +++ b/js/xpconnect/loader/mozJSLoaderUtils.cpp @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/scache/StartupCache.h" + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/CompileOptions.h" +#include "js/Transcoding.h" +#include "js/experimental/JSStencil.h" + +#include "mozilla/BasePrincipal.h" +#include "mozilla/Span.h" + +using namespace JS; +using namespace mozilla::scache; +using mozilla::UniquePtr; + +static nsresult HandleTranscodeResult(JSContext* cx, + JS::TranscodeResult result) { + if (result == JS::TranscodeResult::Ok) { + return NS_OK; + } + + if (result == JS::TranscodeResult::Throw) { + JS_ClearPendingException(cx); + return NS_ERROR_OUT_OF_MEMORY; + } + + MOZ_ASSERT(IsTranscodeFailureResult(result)); + return NS_ERROR_FAILURE; +} + +nsresult ReadCachedStencil(StartupCache* cache, nsACString& cachePath, + JSContext* cx, const JS::DecodeOptions& options, + JS::Stencil** stencilOut) { + MOZ_ASSERT(options.borrowBuffer); + MOZ_ASSERT(!options.usePinnedBytecode); + + const char* buf; + uint32_t len; + nsresult rv = + cache->GetBuffer(PromiseFlatCString(cachePath).get(), &buf, &len); + if (NS_FAILED(rv)) { + return rv; // don't warn since NOT_AVAILABLE is an ok error + } + + JS::TranscodeRange range(AsBytes(mozilla::Span(buf, len))); + JS::TranscodeResult code = JS::DecodeStencil(cx, options, range, stencilOut); + return HandleTranscodeResult(cx, code); +} + +nsresult WriteCachedStencil(StartupCache* cache, nsACString& cachePath, + JSContext* cx, JS::Stencil* stencil) { + JS::TranscodeBuffer buffer; + JS::TranscodeResult code = JS::EncodeStencil(cx, stencil, buffer); + if (code != JS::TranscodeResult::Ok) { + return HandleTranscodeResult(cx, code); + } + + size_t size = buffer.length(); + if (size > UINT32_MAX) { + return NS_ERROR_FAILURE; + } + + // Move the vector buffer into a unique pointer buffer. + mozilla::UniqueFreePtr<char[]> buf( + reinterpret_cast<char*>(buffer.extractOrCopyRawBuffer())); + nsresult rv = cache->PutBuffer(PromiseFlatCString(cachePath).get(), + std::move(buf), size); + return rv; +} diff --git a/js/xpconnect/loader/mozJSLoaderUtils.h b/js/xpconnect/loader/mozJSLoaderUtils.h new file mode 100644 index 0000000000..8c996c17be --- /dev/null +++ b/js/xpconnect/loader/mozJSLoaderUtils.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozJSLoaderUtils_h +#define mozJSLoaderUtils_h + +#include "nsString.h" + +#include "js/experimental/JSStencil.h" +#include "js/CompileOptions.h" // JS::DecodeOptions + +namespace mozilla { +namespace scache { +class StartupCache; +} // namespace scache +} // namespace mozilla + +nsresult ReadCachedStencil(mozilla::scache::StartupCache* cache, + nsACString& cachePath, JSContext* cx, + const JS::DecodeOptions& options, + JS::Stencil** stencilOut); + +nsresult WriteCachedStencil(mozilla::scache::StartupCache* cache, + nsACString& cachePath, JSContext* cx, + JS::Stencil* stencil); + +#endif /* mozJSLoaderUtils_h */ diff --git a/js/xpconnect/loader/mozJSModuleLoader.cpp b/js/xpconnect/loader/mozJSModuleLoader.cpp new file mode 100644 index 0000000000..50102f8770 --- /dev/null +++ b/js/xpconnect/loader/mozJSModuleLoader.cpp @@ -0,0 +1,1936 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Attributes.h" +#include "mozilla/ArrayUtils.h" // mozilla::ArrayLength +#include "mozilla/Utf8.h" // mozilla::Utf8Unit + +#include <cstdarg> + +#include "mozilla/Logging.h" +#ifdef ANDROID +# include <android/log.h> +#endif +#ifdef XP_WIN +# include <windows.h> +#endif + +#include "jsapi.h" +#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject +#include "js/CharacterEncoding.h" +#include "js/CompilationAndEvaluation.h" +#include "js/CompileOptions.h" // JS::CompileOptions +#include "js/ErrorReport.h" // JS_ReportErrorUTF8, JSErrorReport +#include "js/Exception.h" // JS_ErrorFromException +#include "js/friend/JSMEnvironment.h" // JS::ExecuteInJSMEnvironment, JS::GetJSMEnvironmentOfScriptedCaller, JS::NewJSMEnvironment +#include "js/friend/ErrorMessages.h" // JSMSG_* +#include "js/loader/ModuleLoadRequest.h" +#include "js/Object.h" // JS::GetCompartment +#include "js/Printf.h" +#include "js/PropertyAndElement.h" // JS_DefineFunctions, JS_DefineProperty, JS_Enumerate, JS_GetElement, JS_GetProperty, JS_GetPropertyById, JS_HasOwnProperty, JS_HasOwnPropertyById, JS_SetProperty, JS_SetPropertyById +#include "js/PropertySpec.h" +#include "js/SourceText.h" // JS::SourceText +#include "nsCOMPtr.h" +#include "nsDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsIFile.h" +#include "mozJSModuleLoader.h" +#include "mozJSLoaderUtils.h" +#include "nsIFileURL.h" +#include "nsIJARURI.h" +#include "nsIChannel.h" +#include "nsNetUtil.h" +#include "nsJSUtils.h" +#include "xpcprivate.h" +#include "xpcpublic.h" +#include "nsContentUtils.h" +#include "nsXULAppAPI.h" +#include "WrapperFactory.h" +#include "JSMEnvironmentProxy.h" +#include "ModuleEnvironmentProxy.h" +#include "JSServices.h" + +#include "mozilla/scache/StartupCache.h" +#include "mozilla/scache/StartupCacheUtils.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/MacroForEach.h" +#include "mozilla/Preferences.h" +#include "mozilla/ProfilerLabels.h" +#include "mozilla/ProfilerMarkers.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/ScriptPreloader.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/dom/AutoEntryScript.h" +#include "mozilla/dom/ReferrerPolicyBinding.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/Unused.h" + +using namespace mozilla; +using namespace mozilla::scache; +using namespace mozilla::loader; +using namespace xpc; +using namespace JS; + +#define JS_CACHE_PREFIX(aScopeType, aCompilationTarget) \ + "jsloader/" aScopeType "/" aCompilationTarget + +/** + * Buffer sizes for serialization and deserialization of scripts. + * FIXME: bug #411579 (tune this macro!) Last updated: Jan 2008 + */ +#define XPC_SERIALIZATION_BUFFER_SIZE (64 * 1024) +#define XPC_DESERIALIZATION_BUFFER_SIZE (12 * 8192) + +// MOZ_LOG=JSModuleLoader:5 +static LazyLogModule gJSCLLog("JSModuleLoader"); + +#define LOG(args) MOZ_LOG(gJSCLLog, mozilla::LogLevel::Debug, args) + +// Components.utils.import error messages +#define ERROR_SCOPE_OBJ "%s - Second argument must be an object." +#define ERROR_NO_TARGET_OBJECT "%s - Couldn't find target object for import." +#define ERROR_NOT_PRESENT "%s - EXPORTED_SYMBOLS is not present." +#define ERROR_NOT_AN_ARRAY "%s - EXPORTED_SYMBOLS is not an array." +#define ERROR_GETTING_ARRAY_LENGTH \ + "%s - Error getting array length of EXPORTED_SYMBOLS." +#define ERROR_ARRAY_ELEMENT "%s - EXPORTED_SYMBOLS[%d] is not a string." +#define ERROR_GETTING_SYMBOL "%s - Could not get symbol '%s'." +#define ERROR_SETTING_SYMBOL "%s - Could not set symbol '%s' on target object." +#define ERROR_UNINITIALIZED_SYMBOL \ + "%s - Symbol '%s' accessed before initialization. Cyclic import?" + +static constexpr char JSM_Suffix[] = ".jsm"; +static constexpr size_t JSM_SuffixLength = mozilla::ArrayLength(JSM_Suffix) - 1; +static constexpr char JSM_JS_Suffix[] = ".jsm.js"; +static constexpr size_t JSM_JS_SuffixLength = + mozilla::ArrayLength(JSM_JS_Suffix) - 1; +static constexpr char JS_Suffix[] = ".js"; +static constexpr size_t JS_SuffixLength = mozilla::ArrayLength(JS_Suffix) - 1; +static constexpr char MJS_Suffix[] = ".sys.mjs"; +static constexpr size_t MJS_SuffixLength = mozilla::ArrayLength(MJS_Suffix) - 1; + +static bool IsJSM(const nsACString& aLocation) { + if (aLocation.Length() < JSM_SuffixLength) { + return false; + } + const auto ext = Substring(aLocation, aLocation.Length() - JSM_SuffixLength); + return ext == JSM_Suffix; +} + +static bool IsJS(const nsACString& aLocation) { + if (aLocation.Length() < JS_SuffixLength) { + return false; + } + const auto ext = Substring(aLocation, aLocation.Length() - JS_SuffixLength); + return ext == JS_Suffix; +} + +static bool IsJSM_JS(const nsACString& aLocation) { + if (aLocation.Length() < JSM_JS_SuffixLength) { + return false; + } + const auto ext = + Substring(aLocation, aLocation.Length() - JSM_JS_SuffixLength); + return ext == JSM_JS_Suffix; +} + +static bool IsMJS(const nsACString& aLocation) { + if (aLocation.Length() < MJS_SuffixLength) { + return false; + } + const auto ext = Substring(aLocation, aLocation.Length() - MJS_SuffixLength); + return ext == MJS_Suffix; +} + +static void MJSToJSM(const nsACString& aLocation, nsAutoCString& aOut) { + MOZ_ASSERT(IsMJS(aLocation)); + aOut = Substring(aLocation, 0, aLocation.Length() - MJS_SuffixLength); + aOut += JSM_Suffix; +} + +static bool TryToMJS(const nsACString& aLocation, nsAutoCString& aOut) { + if (IsJSM(aLocation)) { + aOut = Substring(aLocation, 0, aLocation.Length() - JSM_SuffixLength); + aOut += MJS_Suffix; + return true; + } + + if (IsJSM_JS(aLocation)) { + aOut = Substring(aLocation, 0, aLocation.Length() - JSM_JS_SuffixLength); + aOut += MJS_Suffix; + return true; + } + + if (IsJS(aLocation)) { + aOut = Substring(aLocation, 0, aLocation.Length() - JS_SuffixLength); + aOut += MJS_Suffix; + return true; + } + + return false; +} + +static bool Dump(JSContext* cx, unsigned argc, Value* vp) { + if (!nsJSUtils::DumpEnabled()) { + return true; + } + + CallArgs args = CallArgsFromVp(argc, vp); + + if (args.length() == 0) { + return true; + } + + RootedString str(cx, JS::ToString(cx, args[0])); + if (!str) { + return false; + } + + JS::UniqueChars utf8str = JS_EncodeStringToUTF8(cx, str); + if (!utf8str) { + return false; + } + + MOZ_LOG(nsContentUtils::DOMDumpLog(), mozilla::LogLevel::Debug, + ("[Backstage.Dump] %s", utf8str.get())); +#ifdef ANDROID + __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.get()); +#endif +#ifdef XP_WIN + if (IsDebuggerPresent()) { + nsAutoJSString wstr; + if (!wstr.init(cx, str)) { + return false; + } + OutputDebugStringW(wstr.get()); + } +#endif + fputs(utf8str.get(), stdout); + fflush(stdout); + return true; +} + +static bool Debug(JSContext* cx, unsigned argc, Value* vp) { +#ifdef DEBUG + return Dump(cx, argc, vp); +#else + return true; +#endif +} + +static const JSFunctionSpec gGlobalFun[] = { + JS_FN("dump", Dump, 1, 0), JS_FN("debug", Debug, 1, 0), + JS_FN("atob", Atob, 1, 0), JS_FN("btoa", Btoa, 1, 0), JS_FS_END}; + +class MOZ_STACK_CLASS JSCLContextHelper { + public: + explicit JSCLContextHelper(JSContext* aCx); + ~JSCLContextHelper(); + + void reportErrorAfterPop(UniqueChars&& buf); + + private: + JSContext* mContext; + UniqueChars mBuf; + + // prevent copying and assignment + JSCLContextHelper(const JSCLContextHelper&) = delete; + const JSCLContextHelper& operator=(const JSCLContextHelper&) = delete; +}; + +static nsresult MOZ_FORMAT_PRINTF(2, 3) + ReportOnCallerUTF8(JSContext* callerContext, const char* format, ...) { + if (!callerContext) { + return NS_ERROR_FAILURE; + } + + va_list ap; + va_start(ap, format); + + UniqueChars buf = JS_vsmprintf(format, ap); + if (!buf) { + va_end(ap); + return NS_ERROR_OUT_OF_MEMORY; + } + + JS_ReportErrorUTF8(callerContext, "%s", buf.get()); + + va_end(ap); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(mozJSModuleLoader, nsIMemoryReporter) + +mozJSModuleLoader::mozJSModuleLoader() + : mImports(16), + mInProgressImports(16), + mFallbackImports(16), +#ifdef STARTUP_RECORDER_ENABLED + mImportStacks(16), +#endif + mLocations(16), + mInitialized(false), + mLoaderGlobal(dom::RootingCx()), + mServicesObj(dom::RootingCx()) { +} + +#define ENSURE_DEP(name) \ + { \ + nsresult rv = Ensure##name(); \ + NS_ENSURE_SUCCESS(rv, rv); \ + } +#define ENSURE_DEPS(...) MOZ_FOR_EACH(ENSURE_DEP, (), (__VA_ARGS__)); +#define BEGIN_ENSURE(self, ...) \ + { \ + if (m##self) return NS_OK; \ + ENSURE_DEPS(__VA_ARGS__); \ + } + +class MOZ_STACK_CLASS ModuleLoaderInfo { + public: + explicit ModuleLoaderInfo(const nsACString& aLocation, + SkipCheckForBrokenURLOrZeroSized aSkipCheck = + SkipCheckForBrokenURLOrZeroSized::No) + : mLocation(&aLocation), mIsModule(false), mSkipCheck(aSkipCheck) {} + explicit ModuleLoaderInfo(JS::loader::ModuleLoadRequest* aRequest) + : mLocation(nullptr), + mURI(aRequest->mURI), + mIsModule(true), + mSkipCheck(aRequest->GetComponentLoadContext()->mSkipCheck) {} + + SkipCheckForBrokenURLOrZeroSized getSkipCheckForBrokenURLOrZeroSized() const { + return mSkipCheck; + } + + void resetChannelWithCheckForBrokenURLOrZeroSized() { + MOZ_ASSERT(mSkipCheck == SkipCheckForBrokenURLOrZeroSized::Yes); + mSkipCheck = SkipCheckForBrokenURLOrZeroSized::No; + mScriptChannel = nullptr; + } + + nsIIOService* IOService() { + MOZ_ASSERT(mIOService); + return mIOService; + } + nsresult EnsureIOService() { + if (mIOService) { + return NS_OK; + } + nsresult rv; + mIOService = do_GetIOService(&rv); + return rv; + } + + nsIURI* URI() { + MOZ_ASSERT(mURI); + return mURI; + } + nsresult EnsureURI() { + BEGIN_ENSURE(URI, IOService); + MOZ_ASSERT(mLocation); + return mIOService->NewURI(*mLocation, nullptr, nullptr, + getter_AddRefs(mURI)); + } + + nsIChannel* ScriptChannel() { + MOZ_ASSERT(mScriptChannel); + return mScriptChannel; + } + nsresult EnsureScriptChannel() { + BEGIN_ENSURE(ScriptChannel, IOService, URI); + + // Skip check for missing URL when handling JSM-to-ESM fallback. + return NS_NewChannel( + getter_AddRefs(mScriptChannel), mURI, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_SCRIPT, + /* aCookieJarSettings = */ nullptr, + /* aPerformanceStorage = */ nullptr, + /* aLoadGroup = */ nullptr, /* aCallbacks = */ nullptr, + nsIRequest::LOAD_NORMAL, mIOService, /* aSandboxFlags = */ 0, + mSkipCheck == SkipCheckForBrokenURLOrZeroSized::Yes); + } + + nsIURI* ResolvedURI() { + MOZ_ASSERT(mResolvedURI); + return mResolvedURI; + } + nsresult EnsureResolvedURI() { + BEGIN_ENSURE(ResolvedURI, URI); + return ResolveURI(mURI, getter_AddRefs(mResolvedURI)); + } + + const nsACString& Key() { + MOZ_ASSERT(mLocation); + return *mLocation; + } + + [[nodiscard]] nsresult GetLocation(nsCString& aLocation) { + nsresult rv = EnsureURI(); + NS_ENSURE_SUCCESS(rv, rv); + return mURI->GetSpec(aLocation); + } + + bool IsModule() const { return mIsModule; } + + private: + const nsACString* mLocation; + nsCOMPtr<nsIIOService> mIOService; + nsCOMPtr<nsIURI> mURI; + nsCOMPtr<nsIChannel> mScriptChannel; + nsCOMPtr<nsIURI> mResolvedURI; + const bool mIsModule; + SkipCheckForBrokenURLOrZeroSized mSkipCheck; +}; + +template <typename... Args> +static nsresult ReportOnCallerUTF8(JSCLContextHelper& helper, + const char* format, ModuleLoaderInfo& info, + Args... args) { + nsCString location; + MOZ_TRY(info.GetLocation(location)); + + UniqueChars buf = JS_smprintf(format, location.get(), args...); + if (!buf) { + return NS_ERROR_OUT_OF_MEMORY; + } + + helper.reportErrorAfterPop(std::move(buf)); + return NS_ERROR_FAILURE; +} + +#undef BEGIN_ENSURE +#undef ENSURE_DEPS +#undef ENSURE_DEP + +mozJSModuleLoader::~mozJSModuleLoader() { + MOZ_ASSERT(!mInitialized, + "UnloadModules() was not explicitly called before cleaning up " + "mozJSModuleLoader"); + + if (mInitialized) { + UnloadModules(); + } +} + +StaticRefPtr<mozJSModuleLoader> mozJSModuleLoader::sSelf; +StaticRefPtr<mozJSModuleLoader> mozJSModuleLoader::sDevToolsLoader; + +void mozJSModuleLoader::FindTargetObject(JSContext* aCx, + MutableHandleObject aTargetObject) { + aTargetObject.set(JS::GetJSMEnvironmentOfScriptedCaller(aCx)); + + // The above could fail if the scripted caller is not a JSM (it could be a DOM + // scope, for instance). + // + // If the target object was not in the JSM shared global, return the global + // instead. This is needed when calling the subscript loader within a frame + // script, since it the FrameScript NSVO will have been found. + if (!aTargetObject || + !IsLoaderGlobal(JS::GetNonCCWObjectGlobal(aTargetObject))) { + aTargetObject.set(JS::GetScriptedCallerGlobal(aCx)); + + // Return nullptr if the scripted caller is in a different compartment. + if (JS::GetCompartment(aTargetObject) != js::GetContextCompartment(aCx)) { + aTargetObject.set(nullptr); + } + } +} + +void mozJSModuleLoader::InitStatics() { + MOZ_ASSERT(!sSelf); + sSelf = new mozJSModuleLoader(); + RegisterWeakMemoryReporter(sSelf); +} + +void mozJSModuleLoader::UnloadLoaders() { + if (sSelf) { + sSelf->Unload(); + } + if (sDevToolsLoader) { + sDevToolsLoader->Unload(); + } +} + +void mozJSModuleLoader::Unload() { + UnloadModules(); + + if (mModuleLoader) { + mModuleLoader->Shutdown(); + mModuleLoader = nullptr; + } +} + +void mozJSModuleLoader::ShutdownLoaders() { + MOZ_ASSERT(sSelf); + UnregisterWeakMemoryReporter(sSelf); + sSelf = nullptr; + + if (sDevToolsLoader) { + UnregisterWeakMemoryReporter(sDevToolsLoader); + sDevToolsLoader = nullptr; + } +} + +mozJSModuleLoader* mozJSModuleLoader::GetOrCreateDevToolsLoader() { + if (sDevToolsLoader) { + return sDevToolsLoader; + } + sDevToolsLoader = new mozJSModuleLoader(); + RegisterWeakMemoryReporter(sDevToolsLoader); + return sDevToolsLoader; +} + +// This requires that the keys be strings and the values be pointers. +template <class Key, class Data, class UserData, class Converter> +static size_t SizeOfTableExcludingThis( + const nsBaseHashtable<Key, Data, UserData, Converter>& aTable, + MallocSizeOf aMallocSizeOf) { + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (const auto& entry : aTable) { + n += entry.GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += entry.GetData()->SizeOfIncludingThis(aMallocSizeOf); + } + return n; +} + +#ifdef STARTUP_RECORDER_ENABLED +template <class Key, class Data, class UserData, class Converter> +static size_t SizeOfStringTableExcludingThis( + const nsBaseHashtable<Key, Data, UserData, Converter>& aTable, + MallocSizeOf aMallocSizeOf) { + size_t n = aTable.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (const auto& entry : aTable) { + n += entry.GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += entry.GetData().SizeOfExcludingThisIfUnshared(aMallocSizeOf); + } + return n; +} +#endif + +size_t mozJSModuleLoader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { + size_t n = aMallocSizeOf(this); + n += SizeOfTableExcludingThis(mImports, aMallocSizeOf); + n += mLocations.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += SizeOfTableExcludingThis(mInProgressImports, aMallocSizeOf); + n += SizeOfTableExcludingThis(mFallbackImports, aMallocSizeOf); +#ifdef STARTUP_RECORDER_ENABLED + n += SizeOfStringTableExcludingThis(mImportStacks, aMallocSizeOf); +#endif + return n; +} + +// Memory report paths are split on '/', with each module displayed as a +// separate layer of a visual tree. Any slashes which are meant to belong to a +// particular path module, rather than be used to build a hierarchy, therefore +// need to be replaced with backslashes, which are displayed as slashes in the +// UI. +// +// If `aAnonymize` is true, this function also attempts to translate any file: +// URLs to replace the path of the GRE directory with a placeholder containing +// no private information, and strips all other file: URIs of everything upto +// their last `/`. +static nsAutoCString MangleURL(const char* aURL, bool aAnonymize) { + nsAutoCString url(aURL); + + if (aAnonymize) { + static nsCString greDirURI; + if (greDirURI.IsEmpty()) { + nsCOMPtr<nsIFile> file; + Unused << NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(file)); + if (file) { + nsCOMPtr<nsIURI> uri; + NS_NewFileURI(getter_AddRefs(uri), file); + if (uri) { + uri->GetSpec(greDirURI); + RunOnShutdown([&]() { greDirURI.Truncate(0); }); + } + } + } + + url.ReplaceSubstring(greDirURI, "<GREDir>/"_ns); + + if (FindInReadable("file:"_ns, url)) { + if (StringBeginsWith(url, "jar:file:"_ns)) { + int32_t idx = url.RFindChar('!'); + url = "jar:file://<anonymized>!"_ns + Substring(url, idx); + } else { + int32_t idx = url.RFindChar('/'); + url = "file://<anonymized>/"_ns + Substring(url, idx); + } + } + } + + url.ReplaceChar('/', '\\'); + return url; +} + +NS_IMETHODIMP +mozJSModuleLoader::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) { + for (const auto& entry : mImports.Values()) { + nsAutoCString path("js-module-loader/modules/"); + path.Append(MangleURL(entry->location, aAnonymize)); + + aHandleReport->Callback(""_ns, path, KIND_NONHEAP, UNITS_COUNT, 1, + "Loaded JS modules"_ns, aData); + } + + return NS_OK; +} + +void mozJSModuleLoader::CreateLoaderGlobal(JSContext* aCx, + const nsACString& aLocation, + MutableHandleObject aGlobal) { + auto backstagePass = MakeRefPtr<BackstagePass>(); + RealmOptions options; + auto& creationOptions = options.creationOptions(); + + creationOptions.setFreezeBuiltins(true).setNewCompartmentInSystemZone(); + if (IsDevToolsLoader()) { + creationOptions.setInvisibleToDebugger(true); + } + xpc::SetPrefableRealmOptions(options); + + // Defer firing OnNewGlobalObject until after the __URI__ property has + // been defined so the JS debugger can tell what module the global is + // for + RootedObject global(aCx); + +#ifdef DEBUG + // See mozJSModuleLoader::DefineJSServices. + mIsInitializingLoaderGlobal = true; +#endif + nsresult rv = xpc::InitClassesWithNewWrappedGlobal( + aCx, static_cast<nsIGlobalObject*>(backstagePass), + nsContentUtils::GetSystemPrincipal(), xpc::DONT_FIRE_ONNEWGLOBALHOOK, + options, &global); +#ifdef DEBUG + mIsInitializingLoaderGlobal = false; +#endif + NS_ENSURE_SUCCESS_VOID(rv); + + NS_ENSURE_TRUE_VOID(global); + + backstagePass->SetGlobalObject(global); + + JSAutoRealm ar(aCx, global); + if (!JS_DefineFunctions(aCx, global, gGlobalFun)) { + return; + } + + if (!CreateJSServices(aCx)) { + return; + } + + if (!DefineJSServices(aCx, global)) { + return; + } + + // Set the location information for the new global, so that tools like + // about:memory may use that information + xpc::SetLocationForGlobal(global, aLocation); + + MOZ_ASSERT(!mModuleLoader); + RefPtr<ComponentScriptLoader> scriptLoader = new ComponentScriptLoader; + mModuleLoader = new ComponentModuleLoader(scriptLoader, backstagePass); + backstagePass->InitModuleLoader(mModuleLoader); + + aGlobal.set(global); +} + +JSObject* mozJSModuleLoader::GetSharedGlobal(JSContext* aCx) { + if (!mLoaderGlobal) { + JS::RootedObject globalObj(aCx); + + CreateLoaderGlobal( + aCx, IsDevToolsLoader() ? "DevTools global"_ns : "shared JSM global"_ns, + &globalObj); + + // If we fail to create a module global this early, we're not going to + // get very far, so just bail out now. + MOZ_RELEASE_ASSERT(globalObj); + mLoaderGlobal = globalObj; + + // AutoEntryScript required to invoke debugger hook, which is a + // Gecko-specific concept at present. + dom::AutoEntryScript aes(globalObj, "module loader report global"); + JS_FireOnNewGlobalObject(aes.cx(), globalObj); + } + + return mLoaderGlobal; +} + +/* static */ +nsresult mozJSModuleLoader::LoadSingleModuleScript( + ComponentModuleLoader* aModuleLoader, JSContext* aCx, + JS::loader::ModuleLoadRequest* aRequest, MutableHandleScript aScriptOut) { + AUTO_PROFILER_MARKER_TEXT( + "ChromeUtils.importESModule static import", JS, + MarkerOptions(MarkerStack::Capture(), + MarkerInnerWindowIdFromJSContext(aCx)), + nsContentUtils::TruncatedURLForDisplay(aRequest->mURI)); + + ModuleLoaderInfo info(aRequest); + nsresult rv = info.EnsureResolvedURI(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIFile> sourceFile; + rv = GetSourceFile(info.ResolvedURI(), getter_AddRefs(sourceFile)); + NS_ENSURE_SUCCESS(rv, rv); + + bool realFile = LocationIsRealFile(aRequest->mURI); + + RootedScript script(aCx); + rv = GetScriptForLocation(aCx, info, sourceFile, realFile, aScriptOut); + NS_ENSURE_SUCCESS(rv, rv); + +#ifdef STARTUP_RECORDER_ENABLED + if (aModuleLoader == sSelf->mModuleLoader) { + sSelf->RecordImportStack(aCx, aRequest); + } else { + MOZ_ASSERT(sDevToolsLoader); + MOZ_ASSERT(aModuleLoader == sDevToolsLoader->mModuleLoader); + sDevToolsLoader->RecordImportStack(aCx, aRequest); + } +#endif + + return NS_OK; +} + +/* static */ +nsresult mozJSModuleLoader::GetSourceFile(nsIURI* aResolvedURI, + nsIFile** aSourceFileOut) { + // Get the JAR if there is one. + nsCOMPtr<nsIJARURI> jarURI; + nsresult rv = NS_OK; + jarURI = do_QueryInterface(aResolvedURI, &rv); + nsCOMPtr<nsIFileURL> baseFileURL; + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIURI> baseURI; + while (jarURI) { + jarURI->GetJARFile(getter_AddRefs(baseURI)); + jarURI = do_QueryInterface(baseURI, &rv); + } + baseFileURL = do_QueryInterface(baseURI, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } else { + baseFileURL = do_QueryInterface(aResolvedURI, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + + return baseFileURL->GetFile(aSourceFileOut); +} + +/* static */ +bool mozJSModuleLoader::LocationIsRealFile(nsIURI* aURI) { + // We need to be extra careful checking for URIs pointing to files. + // EnsureFile may not always get called, especially on resource URIs so we + // need to call GetFile to make sure this is a valid file. + nsresult rv = NS_OK; + nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv); + nsCOMPtr<nsIFile> testFile; + if (NS_SUCCEEDED(rv)) { + fileURL->GetFile(getter_AddRefs(testFile)); + } + + return bool(testFile); +} + +JSObject* mozJSModuleLoader::PrepareObjectForLocation(JSContext* aCx, + nsIFile* aModuleFile, + nsIURI* aURI, + bool aRealFile) { + RootedObject globalObj(aCx, GetSharedGlobal(aCx)); + NS_ENSURE_TRUE(globalObj, nullptr); + JSAutoRealm ar(aCx, globalObj); + + // |thisObj| is the object we set properties on for a particular .jsm. + RootedObject thisObj(aCx, JS::NewJSMEnvironment(aCx)); + NS_ENSURE_TRUE(thisObj, nullptr); + + if (aRealFile) { + if (XRE_IsParentProcess()) { + RootedObject locationObj(aCx); + + nsresult rv = nsXPConnect::XPConnect()->WrapNative( + aCx, thisObj, aModuleFile, NS_GET_IID(nsIFile), + locationObj.address()); + NS_ENSURE_SUCCESS(rv, nullptr); + NS_ENSURE_TRUE(locationObj, nullptr); + + if (!JS_DefineProperty(aCx, thisObj, "__LOCATION__", locationObj, 0)) { + return nullptr; + } + } + } + + // Expose the URI from which the script was imported through a special + // variable that we insert into the JSM. + nsAutoCString nativePath; + NS_ENSURE_SUCCESS(aURI->GetSpec(nativePath), nullptr); + + RootedString exposedUri( + aCx, JS_NewStringCopyN(aCx, nativePath.get(), nativePath.Length())); + NS_ENSURE_TRUE(exposedUri, nullptr); + + if (!JS_DefineProperty(aCx, thisObj, "__URI__", exposedUri, 0)) { + return nullptr; + } + + return thisObj; +} + +static mozilla::Result<nsCString, nsresult> ReadScript( + ModuleLoaderInfo& aInfo) { + MOZ_TRY(aInfo.EnsureScriptChannel()); + + nsCOMPtr<nsIInputStream> scriptStream; + MOZ_TRY(aInfo.ScriptChannel()->Open(getter_AddRefs(scriptStream))); + + uint64_t len64; + uint32_t bytesRead; + + MOZ_TRY(scriptStream->Available(&len64)); + NS_ENSURE_TRUE(len64 < UINT32_MAX, Err(NS_ERROR_FILE_TOO_BIG)); + NS_ENSURE_TRUE(len64, Err(NS_ERROR_FAILURE)); + uint32_t len = (uint32_t)len64; + + /* malloc an internal buf the size of the file */ + nsCString str; + if (!str.SetLength(len, fallible)) { + return Err(NS_ERROR_OUT_OF_MEMORY); + } + + /* read the file in one swoop */ + MOZ_TRY(scriptStream->Read(str.BeginWriting(), len, &bytesRead)); + if (bytesRead != len) { + return Err(NS_BASE_STREAM_OSERROR); + } + + return std::move(str); +} + +nsresult mozJSModuleLoader::ObjectForLocation( + ModuleLoaderInfo& aInfo, nsIFile* aModuleFile, MutableHandleObject aObject, + MutableHandleScript aTableScript, char** aLocation, + bool aPropagateExceptions, MutableHandleValue aException) { + MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); + + dom::AutoJSAPI jsapi; + jsapi.Init(); + JSContext* cx = jsapi.cx(); + + nsresult rv = aInfo.EnsureURI(); + NS_ENSURE_SUCCESS(rv, rv); + + bool realFile = LocationIsRealFile(aInfo.URI()); + + RootedObject obj( + cx, PrepareObjectForLocation(cx, aModuleFile, aInfo.URI(), realFile)); + NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE); + MOZ_ASSERT(!JS_IsGlobalObject(obj)); + + JSAutoRealm ar(cx, obj); + + RootedScript script(cx); + rv = GetScriptForLocation(cx, aInfo, aModuleFile, realFile, &script, + aLocation); + if (NS_FAILED(rv)) { + // Propagate the exception, if one exists. Also, don't leave the stale + // exception on this context. + if (aPropagateExceptions && jsapi.HasException()) { + if (!jsapi.StealException(aException)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + return rv; + } + + // Assign aObject here so that it's available to recursive imports. + // See bug 384168. + aObject.set(obj); + + aTableScript.set(script); + + { // Scope for AutoEntryScript + AutoAllowLegacyScriptExecution exemption; + + // We're going to run script via JS_ExecuteScript, so we need an + // AutoEntryScript. This is Gecko-specific and not in any spec. + dom::AutoEntryScript aes(CurrentGlobalOrNull(cx), + "module loader load module"); + JSContext* aescx = aes.cx(); + + bool executeOk = false; + if (JS_IsGlobalObject(obj)) { + JS::RootedValue rval(cx); + executeOk = JS_ExecuteScript(aescx, script, &rval); + } else { + executeOk = JS::ExecuteInJSMEnvironment(aescx, script, obj); + } + + if (!executeOk) { + if (aPropagateExceptions && aes.HasException()) { + // Ignore return value because we're returning an error code + // anyway. + Unused << aes.StealException(aException); + } + aObject.set(nullptr); + aTableScript.set(nullptr); + return NS_ERROR_FAILURE; + } + } + + return rv; +} + +/* static */ +nsresult mozJSModuleLoader::GetScriptForLocation( + JSContext* aCx, ModuleLoaderInfo& aInfo, nsIFile* aModuleFile, + bool aUseMemMap, MutableHandleScript aScriptOut, char** aLocationOut) { + // JS compilation errors are returned via an exception on the context. + MOZ_ASSERT(!JS_IsExceptionPending(aCx)); + + aScriptOut.set(nullptr); + + nsAutoCString nativePath; + nsresult rv = aInfo.URI()->GetSpec(nativePath); + NS_ENSURE_SUCCESS(rv, rv); + + // Before compiling the script, first check to see if we have it in + // the preloader cache or the startupcache. Note: as a rule, preloader cache + // errors and startupcache errors are not fatal to loading the script, since + // we can always slow-load. + + bool storeIntoStartupCache = false; + StartupCache* cache = StartupCache::GetSingleton(); + + aInfo.EnsureResolvedURI(); + + nsAutoCString cachePath; + if (aInfo.IsModule()) { + rv = PathifyURI(JS_CACHE_PREFIX("non-syntactic", "module"), + aInfo.ResolvedURI(), cachePath); + } else { + rv = PathifyURI(JS_CACHE_PREFIX("non-syntactic", "script"), + aInfo.ResolvedURI(), cachePath); + } + NS_ENSURE_SUCCESS(rv, rv); + + JS::DecodeOptions decodeOptions; + ScriptPreloader::FillDecodeOptionsForCachedStencil(decodeOptions); + + RefPtr<JS::Stencil> stencil = + ScriptPreloader::GetSingleton().GetCachedStencil(aCx, decodeOptions, + cachePath); + + if (!stencil && cache) { + ReadCachedStencil(cache, cachePath, aCx, decodeOptions, + getter_AddRefs(stencil)); + if (!stencil) { + JS_ClearPendingException(aCx); + + storeIntoStartupCache = true; + } + } + + if (stencil) { + LOG(("Successfully loaded %s from cache\n", nativePath.get())); + } else { + // The script wasn't in the cache , so compile it now. + LOG(("Slow loading %s\n", nativePath.get())); + + CompileOptions options(aCx); + ScriptPreloader::FillCompileOptionsForCachedStencil(options); + options.setFileAndLine(nativePath.get(), 1); + if (aInfo.IsModule()) { + options.setModule(); + // Top level await is not supported in synchronously loaded modules. + options.topLevelAwait = false; + + // Make all top-level `vars` available in `ModuleEnvironmentObject`. + options.deoptimizeModuleGlobalVars = true; + } else { + options.setForceStrictMode(); + options.setNonSyntacticScope(true); + } + + // If we can no longer write to caches, we should stop using lazy sources + // and instead let normal syntax parsing occur. This can occur in content + // processes after the ScriptPreloader is flushed where we can read but no + // longer write. + if (!storeIntoStartupCache && !ScriptPreloader::GetSingleton().Active()) { + options.setSourceIsLazy(false); + } + + if (aUseMemMap) { + AutoMemMap map; + MOZ_TRY(map.init(aModuleFile)); + + // Note: exceptions will get handled further down; + // don't early return for them here. + auto buf = map.get<char>(); + + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (srcBuf.init(aCx, buf.get(), map.size(), + JS::SourceOwnership::Borrowed)) { + stencil = CompileStencil(aCx, options, srcBuf, aInfo.IsModule()); + } + } else { + nsCString str; + MOZ_TRY_VAR(str, ReadScript(aInfo)); + + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (srcBuf.init(aCx, str.get(), str.Length(), + JS::SourceOwnership::Borrowed)) { + stencil = CompileStencil(aCx, options, srcBuf, aInfo.IsModule()); + } + } + +#ifdef DEBUG + // The above shouldn't touch any options for instantiation. + JS::InstantiateOptions instantiateOptions(options); + instantiateOptions.assertDefault(); +#endif + + if (!stencil) { + return NS_ERROR_FAILURE; + } + } + + aScriptOut.set(InstantiateStencil(aCx, stencil, aInfo.IsModule())); + if (!aScriptOut) { + return NS_ERROR_FAILURE; + } + + // ScriptPreloader::NoteScript needs to be called unconditionally, to + // reflect the usage into the next session's cache. + ScriptPreloader::GetSingleton().NoteStencil(nativePath, cachePath, stencil); + + // Write to startup cache only when we didn't have any cache for the script + // and compiled it. + if (storeIntoStartupCache) { + MOZ_ASSERT(stencil); + + // We successfully compiled the script, so cache it. + rv = WriteCachedStencil(cache, cachePath, aCx, stencil); + + // Don't treat failure to write as fatal, since we might be working + // with a read-only cache. + if (NS_SUCCEEDED(rv)) { + LOG(("Successfully wrote to cache\n")); + } else { + LOG(("Failed to write to cache\n")); + } + } + + /* Owned by ModuleEntry. Freed when we remove from the table. */ + if (aLocationOut) { + *aLocationOut = ToNewCString(nativePath, mozilla::fallible); + if (!*aLocationOut) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + return NS_OK; +} + +void mozJSModuleLoader::UnloadModules() { + mInitialized = false; + + if (mLoaderGlobal) { + MOZ_ASSERT(JS_HasExtensibleLexicalEnvironment(mLoaderGlobal)); + JS::RootedObject lexicalEnv(dom::RootingCx(), + JS_ExtensibleLexicalEnvironment(mLoaderGlobal)); + JS_SetAllNonReservedSlotsToUndefined(lexicalEnv); + JS_SetAllNonReservedSlotsToUndefined(mLoaderGlobal); + mLoaderGlobal = nullptr; + } + mServicesObj = nullptr; + +#ifdef STARTUP_RECORDER_ENABLED + mImportStacks.Clear(); +#endif + mFallbackImports.Clear(); + mInProgressImports.Clear(); + mImports.Clear(); + mLocations.Clear(); +} + +/* static */ +already_AddRefed<Stencil> mozJSModuleLoader::CompileStencil( + JSContext* aCx, const JS::CompileOptions& aOptions, + JS::SourceText<mozilla::Utf8Unit>& aSource, bool aIsModule) { + if (aIsModule) { + return CompileModuleScriptToStencil(aCx, aOptions, aSource); + } + + return CompileGlobalScriptToStencil(aCx, aOptions, aSource); +} + +/* static */ +JSScript* mozJSModuleLoader::InstantiateStencil(JSContext* aCx, + JS::Stencil* aStencil, + bool aIsModule) { + JS::InstantiateOptions instantiateOptions; + + if (aIsModule) { + RootedObject module(aCx); + module = JS::InstantiateModuleStencil(aCx, instantiateOptions, aStencil); + if (!module) { + return nullptr; + } + + return JS::GetModuleScript(module); + } + + return JS::InstantiateGlobalStencil(aCx, instantiateOptions, aStencil); +} + +nsresult mozJSModuleLoader::ImportInto(const nsACString& registryLocation, + HandleValue targetValArg, JSContext* cx, + uint8_t optionalArgc, + MutableHandleValue retval) { + MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + + RootedValue targetVal(cx, targetValArg); + RootedObject targetObject(cx, nullptr); + + if (optionalArgc) { + // The caller passed in the optional second argument. Get it. + if (targetVal.isObject()) { + // If we're passing in something like a content DOM window, chances + // are the caller expects the properties to end up on the object + // proper and not on the Xray holder. This is dubious, but can be used + // during testing. Given that dumb callers can already leak JSMs into + // content by passing a raw content JS object (where Xrays aren't + // possible), we aim for consistency here. Waive xray. + if (WrapperFactory::IsXrayWrapper(&targetVal.toObject()) && + !WrapperFactory::WaiveXrayAndWrap(cx, &targetVal)) { + return NS_ERROR_FAILURE; + } + targetObject = &targetVal.toObject(); + } else if (!targetVal.isNull()) { + // If targetVal isNull(), we actually want to leave targetObject null. + // Not doing so breaks |make package|. + return ReportOnCallerUTF8(cx, ERROR_SCOPE_OBJ, + PromiseFlatCString(registryLocation).get()); + } + } else { + FindTargetObject(cx, &targetObject); + if (!targetObject) { + return ReportOnCallerUTF8(cx, ERROR_NO_TARGET_OBJECT, + PromiseFlatCString(registryLocation).get()); + } + } + + js::AssertSameCompartment(cx, targetObject); + + RootedObject global(cx); + nsresult rv = ImportInto(registryLocation, targetObject, cx, &global); + + if (global) { + if (!JS_WrapObject(cx, &global)) { + NS_ERROR("can't wrap return value"); + return NS_ERROR_FAILURE; + } + + retval.setObject(*global); + } + return rv; +} + +nsresult mozJSModuleLoader::IsModuleLoaded(const nsACString& aLocation, + bool* retval) { + MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + + mInitialized = true; + ModuleLoaderInfo info(aLocation); + if (mImports.Get(info.Key())) { + *retval = true; + return NS_OK; + } + + if (mModuleLoader) { + nsAutoCString mjsLocation; + if (!TryToMJS(aLocation, mjsLocation)) { + *retval = false; + return NS_OK; + } + + ModuleLoaderInfo mjsInfo(mjsLocation); + + nsresult rv = mjsInfo.EnsureURI(); + NS_ENSURE_SUCCESS(rv, rv); + + if (mModuleLoader->IsModuleFetched(mjsInfo.URI())) { + *retval = true; + return NS_OK; + } + } + + *retval = false; + return NS_OK; +} + +nsresult mozJSModuleLoader::IsJSModuleLoaded(const nsACString& aLocation, + bool* retval) { + MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + + mInitialized = true; + ModuleLoaderInfo info(aLocation); + if (mImports.Get(info.Key())) { + *retval = true; + return NS_OK; + } + + *retval = false; + return NS_OK; +} + +nsresult mozJSModuleLoader::IsESModuleLoaded(const nsACString& aLocation, + bool* retval) { + MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + + mInitialized = true; + ModuleLoaderInfo info(aLocation); + + nsresult rv = info.EnsureURI(); + NS_ENSURE_SUCCESS(rv, rv); + + if (mModuleLoader->IsModuleFetched(info.URI())) { + *retval = true; + return NS_OK; + } + + *retval = false; + return NS_OK; +} + +void mozJSModuleLoader::GetLoadedModules(nsTArray<nsCString>& aLoadedModules) { + aLoadedModules.SetCapacity(mImports.Count()); + for (const auto& data : mImports.Values()) { + aLoadedModules.AppendElement(data->location); + } +} + +nsresult mozJSModuleLoader::GetLoadedESModules( + nsTArray<nsCString>& aLoadedModules) { + return mModuleLoader->GetFetchedModuleURLs(aLoadedModules); +} + +nsresult mozJSModuleLoader::GetLoadedJSAndESModules( + nsTArray<nsCString>& aLoadedModules) { + GetLoadedModules(aLoadedModules); + + nsTArray<nsCString> modules; + nsresult rv = GetLoadedESModules(modules); + NS_ENSURE_SUCCESS(rv, rv); + + for (const auto& location : modules) { + if (IsMJS(location)) { + nsAutoCString jsmLocation; + // NOTE: Unconditionally convert to *.jsm. This doesn't cover *.js case + // but given `Cu.loadedModules` is rarely used for system modules, + // this won't cause much compat issue. + MJSToJSM(location, jsmLocation); + aLoadedModules.AppendElement(jsmLocation); + } + } + + return NS_OK; +} + +#ifdef STARTUP_RECORDER_ENABLED +void mozJSModuleLoader::RecordImportStack(JSContext* aCx, + const nsACString& aLocation) { + if (!Preferences::GetBool("browser.startup.record", false)) { + return; + } + + mImportStacks.InsertOrUpdate( + aLocation, xpc_PrintJSStack(aCx, false, false, false).get()); +} + +void mozJSModuleLoader::RecordImportStack( + JSContext* aCx, JS::loader::ModuleLoadRequest* aRequest) { + if (!Preferences::GetBool("browser.startup.record", false)) { + return; + } + + nsAutoCString location; + nsresult rv = aRequest->mURI->GetSpec(location); + if (NS_FAILED(rv)) { + return; + } + + auto recordJSStackOnly = [&]() { + mImportStacks.InsertOrUpdate( + location, xpc_PrintJSStack(aCx, false, false, false).get()); + }; + + if (aRequest->IsTopLevel()) { + recordJSStackOnly(); + return; + } + + nsAutoCString importerSpec; + rv = aRequest->mReferrer->GetSpec(importerSpec); + if (NS_FAILED(rv)) { + recordJSStackOnly(); + return; + } + + ModuleLoaderInfo importerInfo(importerSpec); + auto importerStack = mImportStacks.Lookup(importerInfo.Key()); + if (!importerStack) { + // The importer's stack is not collected, possibly due to OOM. + recordJSStackOnly(); + return; + } + + nsAutoCString stack; + + stack += "* import [\""; + stack += importerSpec; + stack += "\"]\n"; + stack += *importerStack; + + mImportStacks.InsertOrUpdate(location, stack); +} +#endif + +nsresult mozJSModuleLoader::GetModuleImportStack(const nsACString& aLocation, + nsACString& retval) { +#ifdef STARTUP_RECORDER_ENABLED + MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + + // When querying the DevTools loader, it may not be initialized yet + if (!mInitialized) { + return NS_ERROR_FAILURE; + } + + ModuleLoaderInfo info(aLocation); + auto str = mImportStacks.Lookup(info.Key()); + if (!str) { + return NS_ERROR_FAILURE; + } + + retval = *str; + return NS_OK; +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + +nsresult mozJSModuleLoader::ImportInto(const nsACString& aLocation, + HandleObject targetObj, JSContext* cx, + MutableHandleObject vp) { + vp.set(nullptr); + + JS::RootedObject exports(cx); + MOZ_TRY(Import(cx, aLocation, vp, &exports, !targetObj)); + + if (targetObj) { + JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx)); + if (!JS_Enumerate(cx, exports, &ids)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + JS::RootedValue value(cx); + JS::RootedId id(cx); + for (jsid idVal : ids) { + id = idVal; + if (!JS_GetPropertyById(cx, exports, id, &value) || + !JS_SetPropertyById(cx, targetObj, id, value)) { + return NS_ERROR_FAILURE; + } + } + } + + return NS_OK; +} + +nsresult mozJSModuleLoader::ExtractExports(JSContext* aCx, + ModuleLoaderInfo& aInfo, + ModuleEntry* aMod, + JS::MutableHandleObject aExports) { + // cxhelper must be created before jsapi, so that jsapi is destroyed and + // pops any context it has pushed before we report to the caller context. + JSCLContextHelper cxhelper(aCx); + + // Even though we are calling JS_SetPropertyById on targetObj, we want + // to ensure that we never run script here, so we use an AutoJSAPI and + // not an AutoEntryScript. + dom::AutoJSAPI jsapi; + jsapi.Init(); + JSContext* cx = jsapi.cx(); + JSAutoRealm ar(cx, aMod->obj); + + RootedValue symbols(cx); + { + RootedObject obj( + cx, ResolveModuleObjectProperty(cx, aMod->obj, "EXPORTED_SYMBOLS")); + if (!obj || !JS_GetProperty(cx, obj, "EXPORTED_SYMBOLS", &symbols)) { + return ReportOnCallerUTF8(cxhelper, ERROR_NOT_PRESENT, aInfo); + } + } + + bool isArray; + if (!JS::IsArrayObject(cx, symbols, &isArray)) { + return NS_ERROR_FAILURE; + } + if (!isArray) { + return ReportOnCallerUTF8(cxhelper, ERROR_NOT_AN_ARRAY, aInfo); + } + + RootedObject symbolsObj(cx, &symbols.toObject()); + + // Iterate over symbols array, installing symbols on targetObj: + + uint32_t symbolCount = 0; + if (!JS::GetArrayLength(cx, symbolsObj, &symbolCount)) { + return ReportOnCallerUTF8(cxhelper, ERROR_GETTING_ARRAY_LENGTH, aInfo); + } + +#ifdef DEBUG + nsAutoCString logBuffer; +#endif + + aExports.set(JS_NewPlainObject(cx)); + if (!aExports) { + return NS_ERROR_OUT_OF_MEMORY; + } + + bool missing = false; + + RootedValue value(cx); + RootedId symbolId(cx); + RootedObject symbolHolder(cx); + for (uint32_t i = 0; i < symbolCount; ++i) { + if (!JS_GetElement(cx, symbolsObj, i, &value) || !value.isString() || + !JS_ValueToId(cx, value, &symbolId)) { + return ReportOnCallerUTF8(cxhelper, ERROR_ARRAY_ELEMENT, aInfo, i); + } + + symbolHolder = ResolveModuleObjectPropertyById(cx, aMod->obj, symbolId); + if (!symbolHolder || + !JS_GetPropertyById(cx, symbolHolder, symbolId, &value)) { + RootedString symbolStr(cx, symbolId.toString()); + JS::UniqueChars bytes = JS_EncodeStringToUTF8(cx, symbolStr); + if (!bytes) { + return NS_ERROR_FAILURE; + } + return ReportOnCallerUTF8(cxhelper, ERROR_GETTING_SYMBOL, aInfo, + bytes.get()); + } + + // It's possible |value| is the uninitialized lexical MagicValue when + // there's a cyclic import: const obj = ChromeUtils.import("parent.jsm"). + if (value.isMagic(JS_UNINITIALIZED_LEXICAL)) { + RootedString symbolStr(cx, symbolId.toString()); + JS::UniqueChars bytes = JS_EncodeStringToUTF8(cx, symbolStr); + if (!bytes) { + return NS_ERROR_FAILURE; + } + return ReportOnCallerUTF8(cxhelper, ERROR_UNINITIALIZED_SYMBOL, aInfo, + bytes.get()); + } + + if (value.isUndefined()) { + missing = true; + } + + if (!JS_SetPropertyById(cx, aExports, symbolId, value)) { + RootedString symbolStr(cx, symbolId.toString()); + JS::UniqueChars bytes = JS_EncodeStringToUTF8(cx, symbolStr); + if (!bytes) { + return NS_ERROR_FAILURE; + } + return ReportOnCallerUTF8(cxhelper, ERROR_GETTING_SYMBOL, aInfo, + bytes.get()); + } +#ifdef DEBUG + if (i == 0) { + logBuffer.AssignLiteral("Installing symbols [ "); + } + JS::UniqueChars bytes = JS_EncodeStringToLatin1(cx, symbolId.toString()); + if (!!bytes) { + logBuffer.Append(bytes.get()); + } + logBuffer.Append(' '); + if (i == symbolCount - 1) { + nsCString location; + MOZ_TRY(aInfo.GetLocation(location)); + LOG(("%s] from %s\n", logBuffer.get(), location.get())); + } +#endif + } + + // Don't cache the exports object if any of its exported symbols are + // missing. If the module hasn't finished loading yet, they may be + // defined the next time we try to import it. + if (!missing) { + aMod->exports = aExports; + } + return NS_OK; +} + +/* static */ +bool mozJSModuleLoader::IsTrustedScheme(nsIURI* aURI) { + return aURI->SchemeIs("resource") || aURI->SchemeIs("chrome"); +} + +nsresult mozJSModuleLoader::Import(JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, + bool aIgnoreExports) { + mInitialized = true; + + AUTO_PROFILER_MARKER_TEXT( + "ChromeUtils.import", JS, + MarkerOptions(MarkerStack::Capture(), + MarkerInnerWindowIdFromJSContext(aCx)), + Substring(aLocation, 0, std::min(size_t(128), aLocation.Length()))); + + // The JSM may already be ESM-ified, and in that case the load is expected + // to fail. Suppress the error message, the crash, and also the telemetry + // event for the failure. + // + // If this load fails, it will be redirected to `.sys.mjs` URL + // in TryFallbackToImportESModule, and if the redirect also fails, + // the load is performed again below, with the check enabled. + ModuleLoaderInfo info(aLocation, SkipCheckForBrokenURLOrZeroSized::Yes); + + nsresult rv; + ModuleEntry* mod; + UniquePtr<ModuleEntry> newEntry; + if (!mImports.Get(info.Key(), &mod) && + !mInProgressImports.Get(info.Key(), &mod)) { + // We're trying to import a new JSM, but we're late in shutdown and this + // will likely not succeed and might even crash, so fail here. + if (PastShutdownPhase(ShutdownPhase::XPCOMShutdownFinal)) { + return NS_ERROR_ILLEGAL_DURING_SHUTDOWN; + } + + // If we've hit file-not-found and fallback was successful, + // return the cached data. + bool aFound; + rv = TryCachedFallbackToImportESModule( + aCx, aLocation, aModuleGlobal, aModuleExports, aIgnoreExports, &aFound); + NS_ENSURE_SUCCESS(rv, rv); + if (aFound) { + return NS_OK; + } + + newEntry = MakeUnique<ModuleEntry>(RootingContext::get(aCx)); + + // Note: This implies EnsureURI(). + MOZ_TRY(info.EnsureResolvedURI()); + + // Reject imports from untrusted sources. + if (!IsTrustedScheme(info.URI())) { + return NS_ERROR_DOM_SECURITY_ERR; + } + + nsCOMPtr<nsIFile> sourceFile; + rv = GetSourceFile(info.ResolvedURI(), getter_AddRefs(sourceFile)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = info.ResolvedURI()->GetSpec(newEntry->resolvedURL); + NS_ENSURE_SUCCESS(rv, rv); + + nsCString* existingPath; + if (mLocations.Get(newEntry->resolvedURL, &existingPath) && + *existingPath != info.Key()) { + return NS_ERROR_UNEXPECTED; + } + + mLocations.InsertOrUpdate(newEntry->resolvedURL, + MakeUnique<nsCString>(info.Key())); + + RootedValue exception(aCx); + { + mInProgressImports.InsertOrUpdate(info.Key(), newEntry.get()); + auto cleanup = + MakeScopeExit([&]() { mInProgressImports.Remove(info.Key()); }); + + rv = ObjectForLocation(info, sourceFile, &newEntry->obj, + &newEntry->thisObjectKey, &newEntry->location, + true, &exception); + } + + if (NS_FAILED(rv)) { + mLocations.Remove(newEntry->resolvedURL); + if (!exception.isUndefined()) { + // An exception was thrown during compilation. Propagate it + // out to our caller so they can report it. + bool isModuleSyntaxError = false; + + if (exception.isObject()) { + JS::Rooted<JSObject*> exceptionObj(aCx, &exception.toObject()); + JSAutoRealm ar(aCx, exceptionObj); + JSErrorReport* report = JS_ErrorFromException(aCx, exceptionObj); + if (report) { + switch (report->errorNumber) { + case JSMSG_IMPORT_DECL_AT_TOP_LEVEL: + case JSMSG_EXPORT_DECL_AT_TOP_LEVEL: + // If the exception is related to module syntax, it's most + // likely because of misuse of API. + // Provide better error message. + isModuleSyntaxError = true; + + JS_ReportErrorUTF8(aCx, + "ChromeUtils.import is called against " + "an ES module script (%s). Please use " + "ChromeUtils.importESModule instead " + "(SyntaxError: %s)", + aLocation.BeginReading(), + report->message().c_str()); + break; + default: + break; + } + } + } + + if (!isModuleSyntaxError) { + if (!JS_WrapValue(aCx, &exception)) { + return NS_ERROR_OUT_OF_MEMORY; + } + JS_SetPendingException(aCx, exception); + } + + return NS_ERROR_FAILURE; + } + + if (rv == NS_ERROR_FILE_NOT_FOUND || rv == NS_ERROR_FILE_ACCESS_DENIED) { + // NS_ERROR_FILE_ACCESS_DENIED happens if the access is blocked by + // sandbox. + rv = TryFallbackToImportESModule(aCx, aLocation, aModuleGlobal, + aModuleExports, aIgnoreExports); + + if (rv == NS_ERROR_FILE_NOT_FOUND || + rv == NS_ERROR_FILE_ACCESS_DENIED) { + // Both JSM and ESM are not found, with the check inside necko + // skipped (See EnsureScriptChannel and mSkipCheck). + // + // Perform the load again with the check enabled, so that + // logging, crash-on-autonation, and telemetry event happen. + if (NS_SUCCEEDED(info.EnsureURI()) && + !LocationIsRealFile(info.URI())) { + info.resetChannelWithCheckForBrokenURLOrZeroSized(); + (void)ReadScript(info); + } + } + + return rv; + } + + // Something failed, but we don't know what it is, guess. + return NS_ERROR_FILE_NOT_FOUND; + } + +#ifdef STARTUP_RECORDER_ENABLED + RecordImportStack(aCx, aLocation); +#endif + + mod = newEntry.get(); + } + + MOZ_ASSERT(mod->obj, "Import table contains entry with no object"); + JS::RootedObject globalProxy(aCx); + { + JSAutoRealm ar(aCx, mod->obj); + + globalProxy = CreateJSMEnvironmentProxy(aCx, mod->obj); + if (!globalProxy) { + return NS_ERROR_FAILURE; + } + } + if (!JS_WrapObject(aCx, &globalProxy)) { + return NS_ERROR_FAILURE; + } + aModuleGlobal.set(globalProxy); + + JS::RootedObject exports(aCx, mod->exports); + if (!exports && !aIgnoreExports) { + MOZ_TRY(ExtractExports(aCx, info, mod, &exports)); + } + + if (exports && !JS_WrapObject(aCx, &exports)) { + mLocations.Remove(newEntry->resolvedURL); + return NS_ERROR_FAILURE; + } + aModuleExports.set(exports); + + // Cache this module for later + if (newEntry) { + mImports.InsertOrUpdate(info.Key(), std::move(newEntry)); + } + + return NS_OK; +} + +nsresult mozJSModuleLoader::TryFallbackToImportESModule( + JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, bool aIgnoreExports) { + nsAutoCString mjsLocation; + if (!TryToMJS(aLocation, mjsLocation)) { + return NS_ERROR_FILE_NOT_FOUND; + } + + JS::RootedObject moduleNamespace(aCx); + // The fallback can fail if the URL was not for ESMified JSM. Suppress the + // error message, the crash, and also the telemetry event for the failure. + nsresult rv = ImportESModule(aCx, mjsLocation, &moduleNamespace, + SkipCheckForBrokenURLOrZeroSized::Yes); + if (rv == NS_ERROR_FILE_NOT_FOUND || rv == NS_ERROR_FILE_ACCESS_DENIED) { + // The error for ESModule shouldn't be exposed if the file does not exist, + // or the access is blocked by sandbox. + if (JS_IsExceptionPending(aCx)) { + JS_ClearPendingException(aCx); + } + } + NS_ENSURE_SUCCESS(rv, rv); + + JS::RootedObject globalProxy(aCx); + { + JSAutoRealm ar(aCx, moduleNamespace); + + JS::RootedObject moduleObject( + aCx, JS::GetModuleForNamespace(aCx, moduleNamespace)); + if (!moduleObject) { + return NS_ERROR_FAILURE; + } + + globalProxy = CreateModuleEnvironmentProxy(aCx, moduleObject); + if (!globalProxy) { + return NS_ERROR_FAILURE; + } + + // Cache the redirect to use in subsequent imports. + ModuleLoaderInfo info(aLocation); + auto newEntry = MakeUnique<FallbackModuleEntry>(RootingContext::get(aCx)); + newEntry->globalProxy = globalProxy; + newEntry->moduleNamespace = moduleNamespace; + mFallbackImports.InsertOrUpdate(info.Key(), std::move(newEntry)); + } + + if (!JS_WrapObject(aCx, &globalProxy)) { + return NS_ERROR_FAILURE; + } + aModuleGlobal.set(globalProxy); + + if (!aIgnoreExports) { + JS::RootedObject exports(aCx, moduleNamespace); + if (!JS_WrapObject(aCx, &exports)) { + return NS_ERROR_FAILURE; + } + aModuleExports.set(exports); + } + + return NS_OK; +} + +nsresult mozJSModuleLoader::TryCachedFallbackToImportESModule( + JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, bool aIgnoreExports, bool* aFound) { + ModuleLoaderInfo info(aLocation); + FallbackModuleEntry* fallbackMod; + if (!mFallbackImports.Get(info.Key(), &fallbackMod)) { + *aFound = false; + return NS_OK; + } + + JS::RootedObject globalProxy(aCx, fallbackMod->globalProxy); + if (!JS_WrapObject(aCx, &globalProxy)) { + return NS_ERROR_FAILURE; + } + aModuleGlobal.set(globalProxy); + + if (!aIgnoreExports) { + JS::RootedObject exports(aCx, fallbackMod->moduleNamespace); + if (!JS_WrapObject(aCx, &exports)) { + return NS_ERROR_FAILURE; + } + aModuleExports.set(exports); + } + + *aFound = true; + return NS_OK; +} + +nsresult mozJSModuleLoader::ImportESModule( + JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aModuleNamespace, + SkipCheckForBrokenURLOrZeroSized + aSkipCheck /* = SkipCheckForBrokenURLOrZeroSized::No */) { + using namespace JS::loader; + + mInitialized = true; + + // Called from ChromeUtils::ImportESModule. + nsCString str(aLocation); + + AUTO_PROFILER_MARKER_TEXT( + "ChromeUtils.importESModule", JS, + MarkerOptions(MarkerStack::Capture(), + MarkerInnerWindowIdFromJSContext(aCx)), + Substring(aLocation, 0, std::min(size_t(128), aLocation.Length()))); + + RootedObject globalObj(aCx, GetSharedGlobal(aCx)); + NS_ENSURE_TRUE(globalObj, NS_ERROR_FAILURE); + MOZ_ASSERT(xpc::Scriptability::Get(globalObj).Allowed()); + + // The module loader should be instantiated when fetching the shared global + MOZ_ASSERT(mModuleLoader); + + JSAutoRealm ar(aCx, globalObj); + + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), aLocation); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIPrincipal> principal = + mModuleLoader->GetGlobalObject()->PrincipalOrNull(); + MOZ_ASSERT(principal); + + RefPtr<ScriptFetchOptions> options = new ScriptFetchOptions( + CORS_NONE, dom::ReferrerPolicy::No_referrer, principal); + + RefPtr<ComponentLoadContext> context = new ComponentLoadContext(); + context->mSkipCheck = aSkipCheck; + + RefPtr<VisitedURLSet> visitedSet = + ModuleLoadRequest::NewVisitedSetForTopLevelImport(uri); + + RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest( + uri, options, dom::SRIMetadata(), + /* aReferrer = */ nullptr, context, + /* aIsTopLevel = */ true, + /* aIsDynamicImport = */ false, mModuleLoader, visitedSet, nullptr); + + rv = request->StartModuleLoad(); + if (NS_FAILED(rv)) { + mModuleLoader->MaybeReportLoadError(aCx); + return rv; + } + + rv = mModuleLoader->ProcessRequests(); + if (NS_FAILED(rv)) { + mModuleLoader->MaybeReportLoadError(aCx); + return rv; + } + + MOZ_ASSERT(request->IsReadyToRun()); + if (!request->mModuleScript) { + mModuleLoader->MaybeReportLoadError(aCx); + return NS_ERROR_FAILURE; + } + + // All modules are loaded. MaybeReportLoadError isn't necessary from here. + + if (!request->InstantiateModuleGraph()) { + return NS_ERROR_FAILURE; + } + + rv = mModuleLoader->EvaluateModuleInContext(aCx, request, + JS::ThrowModuleErrorsSync); + NS_ENSURE_SUCCESS(rv, rv); + if (JS_IsExceptionPending(aCx)) { + return NS_ERROR_FAILURE; + } + + RefPtr<ModuleScript> moduleScript = request->mModuleScript; + JS::Rooted<JSObject*> module(aCx, moduleScript->ModuleRecord()); + aModuleNamespace.set(JS::GetModuleNamespace(aCx, module)); + + return NS_OK; +} + +nsresult mozJSModuleLoader::Unload(const nsACString& aLocation) { + if (!mInitialized) { + return NS_OK; + } + + ModuleLoaderInfo info(aLocation); + + ModuleEntry* mod; + if (mImports.Get(info.Key(), &mod)) { + mLocations.Remove(mod->resolvedURL); + mImports.Remove(info.Key()); + } + + // If this is the last module to be unloaded, we will leak mLoaderGlobal + // until UnloadModules is called. So be it. + + return NS_OK; +} + +bool mozJSModuleLoader::CreateJSServices(JSContext* aCx) { + JSObject* services = NewJSServices(aCx); + if (!services) { + return false; + } + + mServicesObj = services; + return true; +} + +bool mozJSModuleLoader::DefineJSServices(JSContext* aCx, + JS::Handle<JSObject*> aGlobal) { + if (!mServicesObj) { + // This function is called whenever creating a new global that needs + // `Services`, including the loader's shared global. + // + // This function is no-op if it's called during creating the loader's + // shared global. + // + // See also CreateAndDefineJSServices. + MOZ_ASSERT(!mLoaderGlobal); + MOZ_ASSERT(mIsInitializingLoaderGlobal); + return true; + } + + JS::Rooted<JS::Value> services(aCx, ObjectValue(*mServicesObj)); + if (!JS_WrapValue(aCx, &services)) { + return false; + } + + JS::Rooted<JS::PropertyKey> servicesId( + aCx, XPCJSContext::Get()->GetStringID(XPCJSContext::IDX_SERVICES)); + return JS_DefinePropertyById(aCx, aGlobal, servicesId, services, 0); +} + +size_t mozJSModuleLoader::ModuleEntry::SizeOfIncludingThis( + MallocSizeOf aMallocSizeOf) const { + size_t n = aMallocSizeOf(this); + n += aMallocSizeOf(location); + + return n; +} + +//---------------------------------------------------------------------- + +JSCLContextHelper::JSCLContextHelper(JSContext* aCx) + : mContext(aCx), mBuf(nullptr) {} + +JSCLContextHelper::~JSCLContextHelper() { + if (mBuf) { + JS_ReportErrorUTF8(mContext, "%s", mBuf.get()); + } +} + +void JSCLContextHelper::reportErrorAfterPop(UniqueChars&& buf) { + MOZ_ASSERT(!mBuf, "Already called reportErrorAfterPop"); + mBuf = std::move(buf); +} diff --git a/js/xpconnect/loader/mozJSModuleLoader.h b/js/xpconnect/loader/mozJSModuleLoader.h new file mode 100644 index 0000000000..e5a114a193 --- /dev/null +++ b/js/xpconnect/loader/mozJSModuleLoader.h @@ -0,0 +1,264 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozJSModuleLoader_h +#define mozJSModuleLoader_h + +#include "ComponentModuleLoader.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/FileLocation.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/StaticPtr.h" +#include "nsIMemoryReporter.h" +#include "nsISupports.h" +#include "nsIURI.h" +#include "nsClassHashtable.h" +#include "jsapi.h" +#include "js/experimental/JSStencil.h" +#include "SkipCheckForBrokenURLOrZeroSized.h" + +#include "xpcpublic.h" + +class nsIFile; +class ModuleLoaderInfo; + +namespace mozilla { +class ScriptPreloader; +} // namespace mozilla + +namespace JS::loader { +class ModuleLoadRequest; +} // namespace JS::loader + +#if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION) || defined(DEBUG) +# define STARTUP_RECORDER_ENABLED +#endif + +class mozJSModuleLoader final : public nsIMemoryReporter { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIMEMORYREPORTER + + // Returns the list of all JSMs. + void GetLoadedModules(nsTArray<nsCString>& aLoadedModules); + + // Returns the list of all ESMs. + nsresult GetLoadedESModules(nsTArray<nsCString>& aLoadedModules); + + // Returns the list of all JSMs and ESMs. + nsresult GetLoadedJSAndESModules(nsTArray<nsCString>& aLoadedModules); + + nsresult GetModuleImportStack(const nsACString& aLocation, + nsACString& aRetval); + + void FindTargetObject(JSContext* aCx, JS::MutableHandleObject aTargetObject); + + static void InitStatics(); + static void UnloadLoaders(); + static void ShutdownLoaders(); + + static mozJSModuleLoader* Get() { + MOZ_ASSERT(sSelf, "Should have already created the module loader"); + return sSelf; + } + + static mozJSModuleLoader* GetDevToolsLoader() { return sDevToolsLoader; } + static mozJSModuleLoader* GetOrCreateDevToolsLoader(); + + nsresult ImportInto(const nsACString& aResourceURI, + JS::HandleValue aTargetObj, JSContext* aCx, uint8_t aArgc, + JS::MutableHandleValue aRetval); + + // Load a JSM. + nsresult Import(JSContext* aCx, const nsACString& aResourceURI, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, + bool aIgnoreExports = false); + + // Load an ES6 module and all its dependencies. + nsresult ImportESModule( + JSContext* aCx, const nsACString& aResourceURI, + JS::MutableHandleObject aModuleNamespace, + mozilla::loader::SkipCheckForBrokenURLOrZeroSized aSkipCheck = + mozilla::loader::SkipCheckForBrokenURLOrZeroSized::No); + + // Fallback from Import to ImportESModule. + nsresult TryFallbackToImportESModule(JSContext* aCx, + const nsACString& aResourceURI, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, + bool aIgnoreExports); + + // If the request was handled by fallback before, fills the output and + // sets *aFound to true and returns NS_OK. + // If the request wasn't yet handled by fallback, sets *Found to false + // and returns NS_OK. + nsresult TryCachedFallbackToImportESModule( + JSContext* aCx, const nsACString& aResourceURI, + JS::MutableHandleObject aModuleGlobal, + JS::MutableHandleObject aModuleExports, bool aIgnoreExports, + bool* aFound); + +#ifdef STARTUP_RECORDER_ENABLED + void RecordImportStack(JSContext* aCx, const nsACString& aLocation); + void RecordImportStack(JSContext* aCx, + JS::loader::ModuleLoadRequest* aRequest); +#endif + + nsresult Unload(const nsACString& aResourceURI); + nsresult IsModuleLoaded(const nsACString& aResourceURI, bool* aRetval); + nsresult IsJSModuleLoaded(const nsACString& aResourceURI, bool* aRetval); + nsresult IsESModuleLoaded(const nsACString& aResourceURI, bool* aRetval); + bool IsLoaderGlobal(JSObject* aObj) { return mLoaderGlobal == aObj; } + bool IsDevToolsLoader() const { return this == sDevToolsLoader; } + + // Public methods for use from ComponentModuleLoader. + static bool IsTrustedScheme(nsIURI* aURI); + static nsresult LoadSingleModuleScript( + mozilla::loader::ComponentModuleLoader* aModuleLoader, JSContext* aCx, + JS::loader::ModuleLoadRequest* aRequest, + JS::MutableHandleScript aScriptOut); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); + + bool DefineJSServices(JSContext* aCx, JS::Handle<JSObject*> aGlobal); + + protected: + mozJSModuleLoader(); + ~mozJSModuleLoader(); + + friend class XPCJSRuntime; + + private: + static mozilla::StaticRefPtr<mozJSModuleLoader> sSelf; + static mozilla::StaticRefPtr<mozJSModuleLoader> sDevToolsLoader; + + void Unload(); + void UnloadModules(); + + void CreateLoaderGlobal(JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aGlobal); + void CreateDevToolsLoaderGlobal(JSContext* aCx, const nsACString& aLocation, + JS::MutableHandleObject aGlobal); + + bool CreateJSServices(JSContext* aCx); + + JSObject* GetSharedGlobal(JSContext* aCx); + + static nsresult GetSourceFile(nsIURI* aResolvedURI, nsIFile** aSourceFileOut); + + static bool LocationIsRealFile(nsIURI* aURI); + + JSObject* PrepareObjectForLocation(JSContext* aCx, nsIFile* aModuleFile, + nsIURI* aURI, bool aRealFile); + + nsresult ObjectForLocation(ModuleLoaderInfo& aInfo, nsIFile* aModuleFile, + JS::MutableHandleObject aObject, + JS::MutableHandleScript aTableScript, + char** aLocation, bool aCatchException, + JS::MutableHandleValue aException); + + // Get the script for a given location, either from a cached stencil or by + // compiling it from source. + static nsresult GetScriptForLocation(JSContext* aCx, ModuleLoaderInfo& aInfo, + nsIFile* aModuleFile, bool aUseMemMap, + JS::MutableHandleScript aScriptOut, + char** aLocationOut = nullptr); + + static already_AddRefed<JS::Stencil> CompileStencil( + JSContext* aCx, const JS::CompileOptions& aOptions, + JS::SourceText<mozilla::Utf8Unit>& aSource, bool aIsModule); + static JSScript* InstantiateStencil(JSContext* aCx, JS::Stencil* aStencil, + bool aIsModule); + + nsresult ImportInto(const nsACString& aLocation, JS::HandleObject targetObj, + JSContext* callercx, JS::MutableHandleObject vp); + + class ModuleEntry { + public: + explicit ModuleEntry(JS::RootingContext* aRootingCx) + : obj(aRootingCx), exports(aRootingCx), thisObjectKey(aRootingCx) { + location = nullptr; + } + + ~ModuleEntry() { Clear(); } + + void Clear() { + if (obj) { + if (JS_HasExtensibleLexicalEnvironment(obj)) { + JS::RootedObject lexicalEnv(mozilla::dom::RootingCx(), + JS_ExtensibleLexicalEnvironment(obj)); + JS_SetAllNonReservedSlotsToUndefined(lexicalEnv); + } + JS_SetAllNonReservedSlotsToUndefined(obj); + obj = nullptr; + thisObjectKey = nullptr; + } + + if (location) { + free(location); + } + + obj = nullptr; + thisObjectKey = nullptr; + location = nullptr; + } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + JS::PersistentRootedObject obj; + JS::PersistentRootedObject exports; + JS::PersistentRootedScript thisObjectKey; + char* location; + nsCString resolvedURL; + }; + + class FallbackModuleEntry { + public: + explicit FallbackModuleEntry(JS::RootingContext* aRootingCx) + : globalProxy(aRootingCx), moduleNamespace(aRootingCx) {} + + ~FallbackModuleEntry() { Clear(); } + + void Clear() { + globalProxy = nullptr; + moduleNamespace = nullptr; + } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this); + } + + JS::PersistentRootedObject globalProxy; + JS::PersistentRootedObject moduleNamespace; + }; + + nsresult ExtractExports(JSContext* aCx, ModuleLoaderInfo& aInfo, + ModuleEntry* aMod, JS::MutableHandleObject aExports); + + nsClassHashtable<nsCStringHashKey, ModuleEntry> mImports; + nsTHashMap<nsCStringHashKey, ModuleEntry*> mInProgressImports; + nsClassHashtable<nsCStringHashKey, FallbackModuleEntry> mFallbackImports; +#ifdef STARTUP_RECORDER_ENABLED + nsTHashMap<nsCStringHashKey, nsCString> mImportStacks; +#endif + + // A map of on-disk file locations which are loaded as modules to the + // pre-resolved URIs they were loaded from. Used to prevent the same file + // from being loaded separately, from multiple URLs. + nsClassHashtable<nsCStringHashKey, nsCString> mLocations; + + bool mInitialized; +#ifdef DEBUG + bool mIsInitializingLoaderGlobal = false; +#endif + JS::PersistentRooted<JSObject*> mLoaderGlobal; + JS::PersistentRooted<JSObject*> mServicesObj; + + RefPtr<mozilla::loader::ComponentModuleLoader> mModuleLoader; +}; + +#endif diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp new file mode 100644 index 0000000000..33192bff29 --- /dev/null +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -0,0 +1,476 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozJSSubScriptLoader.h" +#include "js/experimental/JSStencil.h" +#include "mozJSModuleLoader.h" +#include "mozJSLoaderUtils.h" + +#include "nsIURI.h" +#include "nsIIOService.h" +#include "nsIChannel.h" +#include "nsIInputStream.h" +#include "nsNetCID.h" +#include "nsNetUtil.h" + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "xpcprivate.h" // xpc::OptionsBase +#include "js/CompilationAndEvaluation.h" // JS::Compile +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions, JS::DecodeOptions +#include "js/friend/JSMEnvironment.h" // JS::ExecuteInJSMEnvironment, JS::IsJSMEnvironment +#include "js/SourceText.h" // JS::Source{Ownership,Text} +#include "js/Wrapper.h" + +#include "mozilla/ContentPrincipal.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/ProfilerLabels.h" +#include "mozilla/ProfilerMarkers.h" +#include "mozilla/ScriptPreloader.h" +#include "mozilla/SystemPrincipal.h" +#include "mozilla/scache/StartupCache.h" +#include "mozilla/scache/StartupCacheUtils.h" +#include "mozilla/Unused.h" +#include "mozilla/Utf8.h" // mozilla::Utf8Unit +#include "nsContentUtils.h" +#include "nsString.h" + +using namespace mozilla::scache; +using namespace JS; +using namespace xpc; +using namespace mozilla; +using namespace mozilla::dom; + +class MOZ_STACK_CLASS LoadSubScriptOptions : public OptionsBase { + public: + explicit LoadSubScriptOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), + target(cx), + ignoreCache(false), + wantReturnValue(false) {} + + virtual bool Parse() override { + return ParseObject("target", &target) && + ParseBoolean("ignoreCache", &ignoreCache) && + ParseBoolean("wantReturnValue", &wantReturnValue); + } + + RootedObject target; + bool ignoreCache; + bool wantReturnValue; +}; + +/* load() error msgs, XXX localize? */ +#define LOAD_ERROR_NOSERVICE "Error creating IO Service." +#define LOAD_ERROR_NOURI "Error creating URI (invalid URL scheme?)" +#define LOAD_ERROR_NOSCHEME "Failed to get URI scheme. This is bad." +#define LOAD_ERROR_URI_NOT_LOCAL "Trying to load a non-local URI." +#define LOAD_ERROR_NOSTREAM "Error opening input stream (invalid filename?)" +#define LOAD_ERROR_NOCONTENT "ContentLength not available (not a local URL?)" +#define LOAD_ERROR_BADCHARSET "Error converting to specified charset" +#define LOAD_ERROR_NOSPEC "Failed to get URI spec. This is bad." +#define LOAD_ERROR_CONTENTTOOBIG "ContentLength is too large" + +mozJSSubScriptLoader::mozJSSubScriptLoader() = default; + +mozJSSubScriptLoader::~mozJSSubScriptLoader() = default; + +NS_IMPL_ISUPPORTS(mozJSSubScriptLoader, mozIJSSubScriptLoader) + +#define JSSUB_CACHE_PREFIX(aScopeType, aCompilationTarget) \ + "jssubloader/" aScopeType "/" aCompilationTarget + +static void SubscriptCachePath(JSContext* cx, nsIURI* uri, + JS::HandleObject targetObj, + nsACString& cachePath) { + // StartupCache must distinguish between non-syntactic vs global when + // computing the cache key. + if (!JS_IsGlobalObject(targetObj)) { + PathifyURI(JSSUB_CACHE_PREFIX("non-syntactic", "script"), uri, cachePath); + } else { + PathifyURI(JSSUB_CACHE_PREFIX("global", "script"), uri, cachePath); + } +} + +static void ReportError(JSContext* cx, const nsACString& msg) { + NS_ConvertUTF8toUTF16 ucMsg(msg); + + RootedValue exn(cx); + if (xpc::NonVoidStringToJsval(cx, ucMsg, &exn)) { + JS_SetPendingException(cx, exn); + } +} + +static void ReportError(JSContext* cx, const char* origMsg, nsIURI* uri) { + if (!uri) { + ReportError(cx, nsDependentCString(origMsg)); + return; + } + + nsAutoCString spec; + nsresult rv = uri->GetSpec(spec); + if (NS_FAILED(rv)) { + spec.AssignLiteral("(unknown)"); + } + + nsAutoCString msg(origMsg); + msg.AppendLiteral(": "); + msg.Append(spec); + ReportError(cx, msg); +} + +static bool EvalStencil(JSContext* cx, HandleObject targetObj, + HandleObject loadScope, MutableHandleValue retval, + nsIURI* uri, bool storeIntoStartupCache, + bool storeIntoPreloadCache, JS::Stencil* stencil) { + MOZ_ASSERT(!js::IsWrapper(targetObj)); + + JS::InstantiateOptions options; + JS::RootedScript script(cx, + JS::InstantiateGlobalStencil(cx, options, stencil)); + if (!script) { + return false; + } + + if (JS_IsGlobalObject(targetObj)) { + if (!JS_ExecuteScript(cx, script, retval)) { + return false; + } + } else if (JS::IsJSMEnvironment(targetObj)) { + if (!JS::ExecuteInJSMEnvironment(cx, script, targetObj)) { + return false; + } + retval.setUndefined(); + } else { + JS::RootedObjectVector envChain(cx); + if (!envChain.append(targetObj)) { + return false; + } + if (!loadScope) { + // A null loadScope means we are cross-realm. In this case, we should + // check the target isn't in the JSM loader shared-global or we will + // contaminate all JSMs in the realm. + // + // NOTE: If loadScope is already a shared-global JSM, we can't + // determine which JSM the target belongs to and have to assume it + // is in our JSM. +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + JSObject* targetGlobal = JS::GetNonCCWObjectGlobal(targetObj); + MOZ_DIAGNOSTIC_ASSERT( + !mozJSModuleLoader::Get()->IsLoaderGlobal(targetGlobal), + "Don't load subscript into target in a shared-global JSM"); +#endif + if (!JS_ExecuteScript(cx, envChain, script, retval)) { + return false; + } + } else if (JS_IsGlobalObject(loadScope)) { + if (!JS_ExecuteScript(cx, envChain, script, retval)) { + return false; + } + } else { + MOZ_ASSERT(JS::IsJSMEnvironment(loadScope)); + if (!JS::ExecuteInJSMEnvironment(cx, script, loadScope, envChain)) { + return false; + } + retval.setUndefined(); + } + } + + JSAutoRealm rar(cx, targetObj); + if (!JS_WrapValue(cx, retval)) { + return false; + } + + if (script && (storeIntoStartupCache || storeIntoPreloadCache)) { + nsAutoCString cachePath; + SubscriptCachePath(cx, uri, targetObj, cachePath); + + nsCString uriStr; + if (storeIntoPreloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) { + ScriptPreloader::GetSingleton().NoteStencil(uriStr, cachePath, stencil); + } + + if (storeIntoStartupCache) { + JSAutoRealm ar(cx, script); + WriteCachedStencil(StartupCache::GetSingleton(), cachePath, cx, stencil); + } + } + + return true; +} + +bool mozJSSubScriptLoader::ReadStencil( + JS::Stencil** stencilOut, nsIURI* uri, JSContext* cx, + const JS::ReadOnlyCompileOptions& options, nsIIOService* serv, + bool useCompilationScope) { + // We create a channel and call SetContentType, to avoid expensive MIME type + // lookups (bug 632490). + nsCOMPtr<nsIChannel> chan; + nsCOMPtr<nsIInputStream> instream; + nsresult rv; + rv = NS_NewChannel(getter_AddRefs(chan), uri, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_OTHER, + nullptr, // nsICookieJarSettings + nullptr, // PerformanceStorage + nullptr, // aLoadGroup + nullptr, // aCallbacks + nsIRequest::LOAD_NORMAL, serv); + + if (NS_SUCCEEDED(rv)) { + chan->SetContentType("application/javascript"_ns); + rv = chan->Open(getter_AddRefs(instream)); + } + + if (NS_FAILED(rv)) { + ReportError(cx, LOAD_ERROR_NOSTREAM, uri); + return false; + } + + int64_t len = -1; + + rv = chan->GetContentLength(&len); + if (NS_FAILED(rv)) { + ReportError(cx, LOAD_ERROR_NOCONTENT, uri); + return false; + } + + if (len > INT32_MAX) { + ReportError(cx, LOAD_ERROR_CONTENTTOOBIG, uri); + return false; + } + + nsCString buf; + rv = NS_ReadInputStreamToString(instream, buf, len); + NS_ENSURE_SUCCESS(rv, false); + + if (len < 0) { + len = buf.Length(); + } + + Maybe<JSAutoRealm> ar; + + // Note that when using the ScriptPreloader cache with loadSubScript, there + // will be a side-effect of keeping the global that the script was compiled + // for alive. See note above in EvalScript(). + // + // This will compile the script in XPConnect compilation scope. When the + // script is evaluated, it will be cloned into the target scope to be + // executed, avoiding leaks on the first session when we don't have a + // startup cache. + if (useCompilationScope) { + ar.emplace(cx, xpc::CompilationScope()); + } + + JS::SourceText<Utf8Unit> srcBuf; + if (!srcBuf.init(cx, buf.get(), len, JS::SourceOwnership::Borrowed)) { + return false; + } + + RefPtr<JS::Stencil> stencil = + JS::CompileGlobalScriptToStencil(cx, options, srcBuf); + stencil.forget(stencilOut); + return *stencilOut; +} + +NS_IMETHODIMP +mozJSSubScriptLoader::LoadSubScript(const nsAString& url, HandleValue target, + JSContext* cx, MutableHandleValue retval) { + /* + * Loads a local url, referring to UTF-8-encoded data, and evals it into the + * current cx. Synchronous. ChromeUtils.compileScript() should be used for + * async loads. + * url: The url to load. Must be local so that it can be loaded + * synchronously. + * targetObj: Optional object to eval the script onto (defaults to context + * global) + * returns: Whatever jsval the script pointed to by the url returns. + * Should ONLY (O N L Y !) be called from JavaScript code. + */ + LoadSubScriptOptions options(cx); + options.target = target.isObject() ? &target.toObject() : nullptr; + return DoLoadSubScriptWithOptions(url, options, cx, retval); +} + +NS_IMETHODIMP +mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url, + HandleValue optionsVal, + JSContext* cx, + MutableHandleValue retval) { + if (!optionsVal.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + LoadSubScriptOptions options(cx, &optionsVal.toObject()); + if (!options.Parse()) { + return NS_ERROR_INVALID_ARG; + } + + return DoLoadSubScriptWithOptions(url, options, cx, retval); +} + +nsresult mozJSSubScriptLoader::DoLoadSubScriptWithOptions( + const nsAString& url, LoadSubScriptOptions& options, JSContext* cx, + MutableHandleValue retval) { + nsresult rv = NS_OK; + RootedObject targetObj(cx); + RootedObject loadScope(cx); + mozJSModuleLoader* loader = mozJSModuleLoader::Get(); + loader->FindTargetObject(cx, &loadScope); + + if (options.target) { + targetObj = options.target; + } else { + targetObj = loadScope; + } + + targetObj = JS_FindCompilationScope(cx, targetObj); + if (!targetObj || !loadScope) { + return NS_ERROR_FAILURE; + } + + MOZ_ASSERT(!js::IsWrapper(targetObj), "JS_FindCompilationScope must unwrap"); + + if (js::GetNonCCWObjectRealm(loadScope) != + js::GetNonCCWObjectRealm(targetObj)) { + loadScope = nullptr; + } + + /* load up the url. From here on, failures are reflected as ``custom'' + * js exceptions */ + nsCOMPtr<nsIURI> uri; + nsAutoCString uriStr; + nsAutoCString scheme; + + // Figure out who's calling us + JS::AutoFilename filename; + if (!JS::DescribeScriptedCaller(cx, &filename)) { + // No scripted frame means we don't know who's calling, bail. + return NS_ERROR_FAILURE; + } + + JSAutoRealm ar(cx, targetObj); + + nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID); + if (!serv) { + ReportError(cx, nsLiteralCString(LOAD_ERROR_NOSERVICE)); + return NS_OK; + } + + NS_LossyConvertUTF16toASCII asciiUrl(url); + const nsDependentCSubstring profilerUrl = + Substring(asciiUrl, 0, std::min(size_t(128), asciiUrl.Length())); + AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING_NONSENSITIVE( + "mozJSSubScriptLoader::DoLoadSubScriptWithOptions", OTHER, profilerUrl); + AUTO_PROFILER_MARKER_TEXT("SubScript", JS, + MarkerOptions(MarkerStack::Capture(), + MarkerInnerWindowIdFromJSContext(cx)), + profilerUrl); + + // Make sure to explicitly create the URI, since we'll need the + // canonicalized spec. + rv = NS_NewURI(getter_AddRefs(uri), asciiUrl); + if (NS_FAILED(rv)) { + ReportError(cx, nsLiteralCString(LOAD_ERROR_NOURI)); + return NS_OK; + } + + rv = uri->GetSpec(uriStr); + if (NS_FAILED(rv)) { + ReportError(cx, nsLiteralCString(LOAD_ERROR_NOSPEC)); + return NS_OK; + } + + rv = uri->GetScheme(scheme); + if (NS_FAILED(rv)) { + ReportError(cx, LOAD_ERROR_NOSCHEME, uri); + return NS_OK; + } + + // Suppress caching if we're compiling as content or if we're loading a + // blob: URI. + bool useCompilationScope = false; + auto* principal = BasePrincipal::Cast(GetObjectPrincipal(targetObj)); + bool isSystem = principal->Is<SystemPrincipal>(); + if (!isSystem && principal->Is<ContentPrincipal>()) { + nsAutoCString scheme; + principal->GetScheme(scheme); + + // We want to enable caching for scripts with Activity Stream's + // codebase URLs. + if (scheme.EqualsLiteral("about")) { + nsAutoCString filePath; + principal->GetFilePath(filePath); + + useCompilationScope = filePath.EqualsLiteral("home") || + filePath.EqualsLiteral("newtab") || + filePath.EqualsLiteral("welcome"); + isSystem = true; + } + } + bool ignoreCache = + options.ignoreCache || !isSystem || scheme.EqualsLiteral("blob"); + + StartupCache* cache = ignoreCache ? nullptr : StartupCache::GetSingleton(); + + nsAutoCString cachePath; + SubscriptCachePath(cx, uri, targetObj, cachePath); + + JS::DecodeOptions decodeOptions; + ScriptPreloader::FillDecodeOptionsForCachedStencil(decodeOptions); + + RefPtr<JS::Stencil> stencil; + if (!options.ignoreCache) { + if (!options.wantReturnValue) { + // NOTE: If we need the return value, we cannot use ScriptPreloader. + stencil = ScriptPreloader::GetSingleton().GetCachedStencil( + cx, decodeOptions, cachePath); + } + if (!stencil && cache) { + rv = ReadCachedStencil(cache, cachePath, cx, decodeOptions, + getter_AddRefs(stencil)); + if (NS_FAILED(rv) || !stencil) { + JS_ClearPendingException(cx); + } + } + } + + bool storeIntoStartupCache = false; + if (!stencil) { + // Store into startup cache only when the script isn't come from any cache. + storeIntoStartupCache = cache; + + JS::CompileOptions compileOptions(cx); + ScriptPreloader::FillCompileOptionsForCachedStencil(compileOptions); + compileOptions.setFileAndLine(uriStr.get(), 1); + compileOptions.setNonSyntacticScope(!JS_IsGlobalObject(targetObj)); + + if (options.wantReturnValue) { + compileOptions.setNoScriptRval(false); + } + + if (!ReadStencil(getter_AddRefs(stencil), uri, cx, compileOptions, serv, + useCompilationScope)) { + return NS_OK; + } + +#ifdef DEBUG + // The above shouldn't touch any options for instantiation. + JS::InstantiateOptions instantiateOptions(compileOptions); + instantiateOptions.assertDefault(); +#endif + } + + // As a policy choice, we don't store scripts that want return values + // into the preload cache. + bool storeIntoPreloadCache = !ignoreCache && !options.wantReturnValue; + + Unused << EvalStencil(cx, targetObj, loadScope, retval, uri, + storeIntoStartupCache, storeIntoPreloadCache, stencil); + return NS_OK; +} diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.h b/js/xpconnect/loader/mozJSSubScriptLoader.h new file mode 100644 index 0000000000..01909da10c --- /dev/null +++ b/js/xpconnect/loader/mozJSSubScriptLoader.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCOMPtr.h" +#include "mozIJSSubScriptLoader.h" + +#include "js/experimental/JSStencil.h" +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions + +class nsIPrincipal; +class nsIURI; +class LoadSubScriptOptions; + +#define MOZ_JSSUBSCRIPTLOADER_CID \ + { /* 829814d6-1dd2-11b2-8e08-82fa0a339b00 */ \ + 0x929814d6, 0x1dd2, 0x11b2, { \ + 0x8e, 0x08, 0x82, 0xfa, 0x0a, 0x33, 0x9b, 0x00 \ + } \ + } + +class nsIIOService; + +class mozJSSubScriptLoader : public mozIJSSubScriptLoader { + public: + mozJSSubScriptLoader(); + + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_MOZIJSSUBSCRIPTLOADER + + private: + virtual ~mozJSSubScriptLoader(); + + bool ReadStencil(JS::Stencil** stencilOut, nsIURI* uri, JSContext* cx, + const JS::ReadOnlyCompileOptions& options, + nsIIOService* serv, bool useCompilationScope); + + nsresult ReadScriptAsync(nsIURI* uri, JS::HandleObject targetObj, + JS::HandleObject loadScope, nsIIOService* serv, + bool wantReturnValue, bool cache, + JS::MutableHandleValue retval); + + nsresult DoLoadSubScriptWithOptions(const nsAString& url, + LoadSubScriptOptions& options, + JSContext* cx, + JS::MutableHandleValue retval); +}; diff --git a/js/xpconnect/loader/nsImportModule.cpp b/js/xpconnect/loader/nsImportModule.cpp new file mode 100644 index 0000000000..a313c44388 --- /dev/null +++ b/js/xpconnect/loader/nsImportModule.cpp @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsImportModule.h" + +#include "mozilla/dom/ScriptSettings.h" +#include "mozJSModuleLoader.h" +#include "nsContentUtils.h" +#include "nsExceptionHandler.h" +#include "nsPrintfCString.h" +#include "xpcpublic.h" +#include "xpcprivate.h" +#include "js/PropertyAndElement.h" // JS_GetProperty + +using mozilla::dom::AutoJSAPI; + +namespace mozilla { +namespace loader { + +static void AnnotateCrashReportWithJSException(JSContext* aCx, + const char* aURI) { + JS::RootedValue exn(aCx); + if (JS_GetPendingException(aCx, &exn)) { + JS_ClearPendingException(aCx); + + JSAutoRealm ar(aCx, xpc::PrivilegedJunkScope()); + JS_WrapValue(aCx, &exn); + + nsAutoCString file; + uint32_t line; + uint32_t column; + nsAutoString msg; + nsContentUtils::ExtractErrorValues(aCx, exn, file, &line, &column, msg); + + nsPrintfCString errorString("Failed to load module \"%s\": %s:%u:%u: %s", + aURI, file.get(), line, column, + NS_ConvertUTF16toUTF8(msg).get()); + + CrashReporter::AnnotateCrashReport( + CrashReporter::Annotation::JSModuleLoadError, errorString); + } +} + +nsresult ImportModule(const char* aURI, const char* aExportName, + const nsIID& aIID, void** aResult, bool aInfallible) { + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + + JS::RootedObject global(cx); + JS::RootedObject exports(cx); + nsresult rv = mozJSModuleLoader::Get()->Import(cx, nsDependentCString(aURI), + &global, &exports); + if (NS_WARN_IF(NS_FAILED(rv))) { + if (aInfallible) { + AnnotateCrashReportWithJSException(cx, aURI); + + MOZ_CRASH_UNSAFE_PRINTF("Failed to load critical module \"%s\"", aURI); + } + return rv; + } + + if (aExportName) { + JS::RootedValue namedExport(cx); + if (!JS_GetProperty(cx, exports, aExportName, &namedExport)) { + return NS_ERROR_FAILURE; + } + if (!namedExport.isObject()) { + return NS_ERROR_XPC_BAD_CONVERT_JS; + } + exports.set(&namedExport.toObject()); + } + + return nsXPConnect::XPConnect()->WrapJS(cx, exports, aIID, aResult); +} + +nsresult ImportESModule(const char* aURI, const char* aExportName, + const nsIID& aIID, void** aResult, bool aInfallible) { + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + + JS::RootedObject moduleNamespace(cx); + nsresult rv = mozJSModuleLoader::Get()->ImportESModule( + cx, nsDependentCString(aURI), &moduleNamespace); + if (NS_WARN_IF(NS_FAILED(rv))) { + if (aInfallible) { + AnnotateCrashReportWithJSException(cx, aURI); + + MOZ_CRASH_UNSAFE_PRINTF("Failed to load critical module \"%s\"", aURI); + } + return rv; + } + + if (aExportName) { + JS::RootedValue namedExport(cx); + if (!JS_GetProperty(cx, moduleNamespace, aExportName, &namedExport)) { + return NS_ERROR_FAILURE; + } + if (!namedExport.isObject()) { + return NS_ERROR_XPC_BAD_CONVERT_JS; + } + moduleNamespace.set(&namedExport.toObject()); + } + + return nsXPConnect::XPConnect()->WrapJS(cx, moduleNamespace, aIID, aResult); +} + +} // namespace loader +} // namespace mozilla diff --git a/js/xpconnect/loader/nsImportModule.h b/js/xpconnect/loader/nsImportModule.h new file mode 100644 index 0000000000..31f6f8c7c1 --- /dev/null +++ b/js/xpconnect/loader/nsImportModule.h @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsImportModule_h +#define nsImportModule_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" + +#include "nsCOMPtr.h" +#include "mozilla/RefPtr.h" + +namespace mozilla { +namespace loader { + +nsresult ImportModule(const char* aURI, const char* aExportName, + const nsIID& aIID, void** aResult, bool aInfallible); + +nsresult ImportESModule(const char* aURI, const char* aExportName, + const nsIID& aIID, void** aResult, bool aInfallible); + +} // namespace loader +} // namespace mozilla + +class MOZ_STACK_CLASS nsImportModule final : public nsCOMPtr_helper { + public: + nsImportModule(const char* aURI, const char* aExportName, nsresult* aErrorPtr, + bool aInfallible) + : mURI(aURI), + mExportName(aExportName), + mErrorPtr(aErrorPtr), + mInfallible(aInfallible) { + MOZ_ASSERT_IF(mErrorPtr, !mInfallible); + } + + virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, + void** aResult) const override { + nsresult rv = ::mozilla::loader::ImportModule(mURI, mExportName, aIID, + aResult, mInfallible); + if (mErrorPtr) { + *mErrorPtr = rv; + } + return rv; + } + + private: + const char* mURI; + const char* mExportName; + nsresult* mErrorPtr; + bool mInfallible; +}; + +/** + * These helpers make it considerably easier for C++ code to import a JS module + * and wrap it in an appropriately-defined XPIDL interface for its exports. + * Typical usage is something like: + * + * Foo.jsm: + * + * var EXPORTED_SYMBOLS = ["foo"]; + * + * function foo(bar) { + * return bar.toString(); + * } + * + * mozIFoo.idl: + * + * interface mozIFoo : nsISupports { + * AString foo(double meh); + * } + * + * Thing.cpp: + * + * nsCOMPtr<mozIFoo> foo = do_ImportModule( + * "resource://meh/Foo.jsm"); + * + * MOZ_TRY(foo->Foo(42)); + * + * For JS modules which export all fields within a single named object, a second + * argument can be passed naming that object. + * + * Foo.jsm: + * + * var EXPORTED_SYMBOLS = ["Foo"]; + * + * var Foo = { + * function foo(bar) { + * return bar.toString(); + * } + * }; + * + * Thing.cpp: + * + * nsCOMPtr<mozIFoo> foo = do_ImportModule( + * "resource:://meh/Foo.jsm", "Foo"); + */ + +template <size_t N> +inline nsImportModule do_ImportModule(const char (&aURI)[N]) { + return {aURI, nullptr, nullptr, /* infallible */ true}; +} + +template <size_t N> +inline nsImportModule do_ImportModule(const char (&aURI)[N], + const mozilla::fallible_t&) { + return {aURI, nullptr, nullptr, /* infallible */ false}; +} + +template <size_t N> +inline nsImportModule do_ImportModule(const char (&aURI)[N], nsresult* aRv) { + return {aURI, nullptr, aRv, /* infallible */ false}; +} + +template <size_t N, size_t N2> +inline nsImportModule do_ImportModule(const char (&aURI)[N], + const char (&aExportName)[N2]) { + return {aURI, aExportName, nullptr, /* infallible */ true}; +} + +template <size_t N, size_t N2> +inline nsImportModule do_ImportModule(const char (&aURI)[N], + const char (&aExportName)[N2], + const mozilla::fallible_t&) { + return {aURI, aExportName, nullptr, /* infallible */ false}; +} + +template <size_t N, size_t N2> +inline nsImportModule do_ImportModule(const char (&aURI)[N], + const char (&aExportName)[N2], + nsresult* aRv) { + return {aURI, aExportName, aRv, /* infallible */ false}; +} + +class MOZ_STACK_CLASS nsImportESModule final : public nsCOMPtr_helper { + public: + nsImportESModule(const char* aURI, const char* aExportName, + nsresult* aErrorPtr, bool aInfallible) + : mURI(aURI), + mExportName(aExportName), + mErrorPtr(aErrorPtr), + mInfallible(aInfallible) { + MOZ_ASSERT_IF(mErrorPtr, !mInfallible); + } + + virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, + void** aResult) const override { + nsresult rv = ::mozilla::loader::ImportESModule(mURI, mExportName, aIID, + aResult, mInfallible); + if (mErrorPtr) { + *mErrorPtr = rv; + } + return rv; + } + + private: + const char* mURI; + const char* mExportName; + nsresult* mErrorPtr; + bool mInfallible; +}; + +/** + * Usage with exported name: + * + * Foo.sys.mjs: + * + * export function foo(bar) { + * return bar.toString(); + * } + * + * mozIFoo.idl: + * + * interface mozIFoo : nsISupports { + * AString foo(double meh); + * } + * + * Thing.cpp: + * + * nsCOMPtr<mozIFoo> foo = do_ImportESModule( + * "resource://meh/Foo.sys.mjs"); + * + * MOZ_TRY(foo->Foo(42)); + * + * Usage with a single named object: + * + * Foo.sys.mjs: + * + * export var Foo = { + * function foo(bar) { + * return bar.toString(); + * } + * }; + * + * Thing.cpp: + * + * nsCOMPtr<mozIFoo> foo = do_ImportESModule( + * "resource:://meh/Foo.sys.mjs", "Foo"); + */ + +template <size_t N> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N]) { + return {aURI, nullptr, nullptr, /* infallible */ true}; +} + +template <size_t N> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N], + const mozilla::fallible_t&) { + return {aURI, nullptr, nullptr, /* infallible */ false}; +} + +template <size_t N> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N], + nsresult* aRv) { + return {aURI, nullptr, aRv, /* infallible */ false}; +} + +template <size_t N, size_t N2> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N], + const char (&aExportName)[N2]) { + return {aURI, aExportName, nullptr, /* infallible */ true}; +} + +template <size_t N, size_t N2> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N], + const char (&aExportName)[N2], + const mozilla::fallible_t&) { + return {aURI, aExportName, nullptr, /* infallible */ false}; +} + +template <size_t N, size_t N2> +inline nsImportESModule do_ImportESModule(const char (&aURI)[N], + const char (&aExportName)[N2], + nsresult* aRv) { + return {aURI, aExportName, aRv, /* infallible */ false}; +} + +#endif // defined nsImportModule_h diff --git a/js/xpconnect/loader/script_cache.py b/js/xpconnect/loader/script_cache.py new file mode 100755 index 0000000000..bd3a746fcf --- /dev/null +++ b/js/xpconnect/loader/script_cache.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import io +import os +import struct +import sys + +MAGIC = b"mozXDRcachev002\0" + + +def usage(): + print( + """Usage: script_cache.py <file.bin> ... + + Decodes and prints out the contents of a startup script cache file + (e.g., startupCache/scriptCache.bin) in human-readable form.""" + ) + + sys.exit(1) + + +class ProcessTypes: + Uninitialized = 0 + Parent = 1 + Web = 2 + Extension = 3 + Privileged = 4 + + def __init__(self, val): + self.val = val + + def __str__(self): + res = [] + if self.val & (1 << self.Uninitialized): + raise Exception("Uninitialized process type") + if self.val & (1 << self.Parent): + res.append("Parent") + if self.val & (1 << self.Web): + res.append("Web") + if self.val & (1 << self.Extension): + res.append("Extension") + if self.val & (1 << self.Privileged): + res.append("Privileged") + return "|".join(res) + + +class InputBuffer(object): + def __init__(self, data): + self.data = data + self.offset = 0 + + @property + def remaining(self): + return len(self.data) - self.offset + + def unpack(self, fmt): + res = struct.unpack_from(fmt, self.data, self.offset) + self.offset += struct.calcsize(fmt) + return res + + def unpack_str(self): + (size,) = self.unpack("<H") + res = self.data[self.offset : self.offset + size].decode("utf-8") + self.offset += size + return res + + +if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]): + usage() + +for filename in sys.argv[1:]: + with io.open(filename, "rb") as f: + magic = f.read(len(MAGIC)) + if magic != MAGIC: + raise Exception("Bad magic number") + + (hdrSize,) = struct.unpack("<I", f.read(4)) + + hdr = InputBuffer(f.read(hdrSize)) + + i = 0 + while hdr.remaining: + i += 1 + print("{}: {}".format(i, hdr.unpack_str())) + print(" Key: {}".format(hdr.unpack_str())) + print(" Offset: {:>9,}".format(*hdr.unpack("<I"))) + print(" Size: {:>9,}".format(*hdr.unpack("<I"))) + print(" Processes: {}".format(ProcessTypes(*hdr.unpack("B")))) + print("") diff --git a/js/xpconnect/mach_commands.py b/js/xpconnect/mach_commands.py new file mode 100644 index 0000000000..514bfcff69 --- /dev/null +++ b/js/xpconnect/mach_commands.py @@ -0,0 +1,40 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import argparse +import sys +from pathlib import Path + +from mach.decorators import Command, CommandArgument + + +@Command("xpcshell", category="misc", description="Run the xpcshell binary") +@CommandArgument( + "args", nargs=argparse.REMAINDER, help="Arguments to provide to xpcshell" +) +def xpcshell(command_context, args): + dist_bin = Path(command_context._topobjdir, "dist", "bin") + browser_dir = dist_bin / "browser" + + if sys.platform == "win32": + xpcshell = dist_bin / "xpcshell.exe" + else: + xpcshell = dist_bin / "xpcshell" + + command = [ + str(xpcshell), + "-g", + str(dist_bin), + "-a", + str(browser_dir), + ] + + if args: + command.extend(args) + + return command_context.run_process( + command, + pass_thru=True, + ensure_exit_code=False, + ) diff --git a/js/xpconnect/moz.build b/js/xpconnect/moz.build new file mode 100644 index 0000000000..529f2ee043 --- /dev/null +++ b/js/xpconnect/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +with Files("**"): + BUG_COMPONENT = ("Core", "XPConnect") + +DIRS += ["public", "idl", "wrappers", "loader", "src"] +DIRS += ["shell"] +TEST_DIRS += ["tests"] diff --git a/js/xpconnect/public/moz.build b/js/xpconnect/public/moz.build new file mode 100644 index 0000000000..29e24495b2 --- /dev/null +++ b/js/xpconnect/public/moz.build @@ -0,0 +1,10 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + "xpc_make_class.h", + "xpc_map_end.h", +] diff --git a/js/xpconnect/public/xpc_make_class.h b/js/xpconnect/public/xpc_make_class.h new file mode 100644 index 0000000000..d9c0c4064d --- /dev/null +++ b/js/xpconnect/public/xpc_make_class.h @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpc_make_class_h +#define xpc_make_class_h + +// This file should be used to create JSClass instances for nsIXPCScriptable +// instances. This includes any file that uses xpc_map_end.h. + +#include "xpcpublic.h" +#include "mozilla/dom/DOMJSClass.h" + +bool XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, JS::HandleObject obj, + JS::HandleId id, JS::HandleValue v); +bool XPC_WN_CannotModifyPropertyStub(JSContext* cx, JS::HandleObject obj, + JS::HandleId id, JS::HandleValue v); + +bool XPC_WN_MaybeResolvingDeletePropertyStub(JSContext* cx, + JS::HandleObject obj, + JS::HandleId id, + JS::ObjectOpResult& result); +bool XPC_WN_CannotDeletePropertyStub(JSContext* cx, JS::HandleObject obj, + JS::HandleId id, + JS::ObjectOpResult& result); + +bool XPC_WN_Shared_Enumerate(JSContext* cx, JS::HandleObject obj); + +bool XPC_WN_NewEnumerate(JSContext* cx, JS::HandleObject obj, + JS::MutableHandleIdVector properties, + bool enumerableOnly); + +bool XPC_WN_Helper_Resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, + bool* resolvedp); + +void XPC_WN_Helper_Finalize(JS::GCContext* gcx, JSObject* obj); +void XPC_WN_NoHelper_Finalize(JS::GCContext* gcx, JSObject* obj); + +bool XPC_WN_Helper_Call(JSContext* cx, unsigned argc, JS::Value* vp); + +bool XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, JS::Value* vp); + +void XPCWrappedNative_Trace(JSTracer* trc, JSObject* obj); + +extern const js::ClassExtension XPC_WN_JSClassExtension; + +#define XPC_MAKE_CLASS_OPS(_flags) \ + { \ + /* addProperty */ \ + ((_flags)&XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY) ? nullptr \ + : ((_flags)&XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) \ + ? XPC_WN_MaybeResolvingPropertyStub \ + : XPC_WN_CannotModifyPropertyStub, \ + \ + /* delProperty */ \ + ((_flags)&XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY) ? nullptr \ + : ((_flags)&XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) \ + ? XPC_WN_MaybeResolvingDeletePropertyStub \ + : XPC_WN_CannotDeletePropertyStub, \ + \ + /* enumerate */ \ + ((_flags)&XPC_SCRIPTABLE_WANT_NEWENUMERATE) \ + ? nullptr /* We will use newEnumerate set below in this case */ \ + : XPC_WN_Shared_Enumerate, \ + \ + /* newEnumerate */ \ + ((_flags)&XPC_SCRIPTABLE_WANT_NEWENUMERATE) ? XPC_WN_NewEnumerate \ + : nullptr, \ + \ + /* resolve */ /* We have to figure out resolve strategy at call time \ + */ \ + XPC_WN_Helper_Resolve, \ + \ + /* mayResolve */ \ + nullptr, \ + \ + /* finalize */ \ + ((_flags)&XPC_SCRIPTABLE_WANT_FINALIZE) ? XPC_WN_Helper_Finalize \ + : XPC_WN_NoHelper_Finalize, \ + \ + /* call */ \ + ((_flags)&XPC_SCRIPTABLE_WANT_CALL) ? XPC_WN_Helper_Call : nullptr, \ + \ + /* construct */ \ + ((_flags)&XPC_SCRIPTABLE_WANT_CONSTRUCT) ? XPC_WN_Helper_Construct \ + : nullptr, \ + \ + /* trace */ \ + ((_flags)&XPC_SCRIPTABLE_IS_GLOBAL_OBJECT) ? JS_GlobalObjectTraceHook \ + : XPCWrappedNative_Trace, \ + } + +#define XPC_MAKE_CLASS(_name, _flags, _classOps) \ + { \ + /* name */ \ + _name, \ + \ + /* flags */ \ + JSCLASS_SLOT0_IS_NSISUPPORTS | JSCLASS_IS_WRAPPED_NATIVE | \ + JSCLASS_FOREGROUND_FINALIZE | \ + (((_flags)&XPC_SCRIPTABLE_IS_GLOBAL_OBJECT) \ + ? XPCONNECT_GLOBAL_FLAGS \ + : JSCLASS_HAS_RESERVED_SLOTS(1)), \ + \ + /* cOps */ \ + _classOps, \ + \ + /* spec */ \ + nullptr, \ + \ + /* ext */ \ + &XPC_WN_JSClassExtension, \ + \ + /* oOps */ \ + nullptr, \ + } + +#endif diff --git a/js/xpconnect/public/xpc_map_end.h b/js/xpconnect/public/xpc_map_end.h new file mode 100644 index 0000000000..1a63fc779c --- /dev/null +++ b/js/xpconnect/public/xpc_map_end.h @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// If you include this file you must also include xpc_make_class.h at the top +// of the file doing the including. + +#ifndef XPC_MAP_CLASSNAME +# error "Must #define XPC_MAP_CLASSNAME before #including xpc_map_end.h" +#endif + +#ifndef XPC_MAP_QUOTED_CLASSNAME +# error "Must #define XPC_MAP_QUOTED_CLASSNAME before #including xpc_map_end.h" +#endif + +#ifndef XPC_MAP_FLAGS +# error "Must #define XPC_MAP_FLAGS before #including xpc_map_end.h" +#endif + +#include "js/Id.h" + +/**************************************************************/ + +NS_IMETHODIMP XPC_MAP_CLASSNAME::GetClassName(nsACString& aClassName) { + aClassName.AssignLiteral(XPC_MAP_QUOTED_CLASSNAME); + return NS_OK; +} + +/**************************************************************/ + +// virtual +uint32_t XPC_MAP_CLASSNAME::GetScriptableFlags() { return (XPC_MAP_FLAGS); } + +// virtual +const JSClass* XPC_MAP_CLASSNAME::GetJSClass() { + static const JSClassOps classOps = XPC_MAKE_CLASS_OPS(GetScriptableFlags()); + static const JSClass klass = + XPC_MAKE_CLASS(XPC_MAP_QUOTED_CLASSNAME, GetScriptableFlags(), &classOps); + return &klass; +} + +/**************************************************************/ + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_PRECREATE) +NS_IMETHODIMP XPC_MAP_CLASSNAME::PreCreate(nsISupports* nativeObj, + JSContext* cx, JSObject* globalObj, + JSObject** parentObj) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_NEWENUMERATE) +NS_IMETHODIMP XPC_MAP_CLASSNAME::NewEnumerate( + nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* obj, + JS::MutableHandleIdVector properties, bool enumerableOnly, bool* _retval) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_RESOLVE) +NS_IMETHODIMP XPC_MAP_CLASSNAME::Resolve(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, jsid id, + bool* resolvedp, bool* _retval) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_FINALIZE) +NS_IMETHODIMP XPC_MAP_CLASSNAME::Finalize(nsIXPConnectWrappedNative* wrapper, + JS::GCContext* gcx, JSObject* obj) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_CALL) +NS_IMETHODIMP XPC_MAP_CLASSNAME::Call(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + const JS::CallArgs& args, bool* _retval) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_CONSTRUCT) +NS_IMETHODIMP XPC_MAP_CLASSNAME::Construct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + const JS::CallArgs& args, + bool* _retval) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +#if !((XPC_MAP_FLAGS)&XPC_SCRIPTABLE_WANT_HASINSTANCE) +NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + JS::HandleValue val, bool* bp, + bool* _retval) { + NS_ERROR("never called"); + return NS_ERROR_NOT_IMPLEMENTED; +} +#endif + +/**************************************************************/ + +#undef XPC_MAP_CLASSNAME +#undef XPC_MAP_QUOTED_CLASSNAME +#undef XPC_MAP_FLAGS diff --git a/js/xpconnect/shell/moz.build b/js/xpconnect/shell/moz.build new file mode 100644 index 0000000000..de3b050b79 --- /dev/null +++ b/js/xpconnect/shell/moz.build @@ -0,0 +1,77 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +GeckoProgram("xpcshell", linkage="dependent") + +SOURCES += [ + "xpcshell.cpp", +] + +if CONFIG["LIBFUZZER"]: + USE_LIBS += ["fuzzer"] + +if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": + SOURCES += [ + "xpcshellMacUtils.mm", + ] + +include("/ipc/chromium/chromium-config.mozbuild") + +LOCAL_INCLUDES += [ + "/toolkit/xre", +] + +if CONFIG["CC_TYPE"] == "clang-cl": + # Always enter a Windows program through wmain, whether or not we're + # a console application. + WIN32_EXE_LDFLAGS += ["-ENTRY:wmainCRTStartup"] + +# DELAYLOAD_DLLS in this block ensure that the DLL blocklist initializes +if CONFIG["OS_ARCH"] == "WINNT": + if CONFIG["MOZ_SANDBOX"]: + # For sandbox includes and the include dependencies those have + LOCAL_INCLUDES += [ + "/security/sandbox/chromium", + "/security/sandbox/chromium-shim", + ] + + OS_LIBS += [ + "advapi32", + "user32", + "version", + "winmm", + ] + + USE_LIBS += [ + "sandbox_s", + ] + + DELAYLOAD_DLLS += [ + "winmm.dll", + "user32.dll", + ] + + OS_LIBS += [ + "ntdll", + ] + + DELAYLOAD_DLLS += [ + "xul.dll", + ] + + # Don't build xpcshell.exe with CETCOMPAT, because we need to be able to + # only enable it for processes that are not using JIT in xul.dll. + LINK_FLAGS["CETCOMPAT"] = [] + +if CONFIG["OS_TARGET"] == "Darwin": + OS_LIBS += [ + "-framework Foundation", + ] + +if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": + CFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] + CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] + OS_LIBS += CONFIG["MOZ_GTK3_LIBS"] diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp new file mode 100644 index 0000000000..5e44db3b34 --- /dev/null +++ b/js/xpconnect/shell/xpcshell.cpp @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* XPConnect JavaScript interactive shell. */ + +#include <stdio.h> + +#include "mozilla/Bootstrap.h" +#include "XREShellData.h" + +#ifdef XP_MACOSX +# include "xpcshellMacUtils.h" +#endif +#ifdef XP_WIN +# include "mozilla/WindowsDllBlocklist.h" + +# include <windows.h> +# include <shlobj.h> + +// we want a wmain entry point +# define XRE_WANT_ENVIRON +# include "nsWindowsWMain.cpp" +# ifdef MOZ_SANDBOX +# include "mozilla/sandboxing/SandboxInitialization.h" +# endif +#endif + +#ifdef MOZ_WIDGET_GTK +# include <gtk/gtk.h> +#endif + +#include "BaseProfiler.h" + +#ifdef LIBFUZZER +# include "FuzzerDefs.h" +#endif + +int main(int argc, char** argv, char** envp) { +#ifdef MOZ_WIDGET_GTK + // A default display may or may not be required for xpcshell tests, and so + // is not created here. Instead we set the command line args, which is a + // fairly cheap operation. + gtk_parse_args(&argc, &argv); +#endif + +#ifdef XP_MACOSX + InitAutoreleasePool(); +#endif + + // unbuffer stdout so that output is in the correct order; note that stderr + // is unbuffered by default + setbuf(stdout, nullptr); + +#ifdef HAS_DLL_BLOCKLIST + DllBlocklist_Initialize(); +#endif + + char aLocal; + mozilla::baseprofiler::profiler_init(&aLocal); + + XREShellData shellData; +#if defined(XP_WIN) && defined(MOZ_SANDBOX) + shellData.sandboxBrokerServices = + mozilla::sandboxing::GetInitializedBrokerServices(); +#endif + + auto bootstrapResult = mozilla::GetBootstrap(); + if (bootstrapResult.isErr()) { + return 2; + } + + mozilla::Bootstrap::UniquePtr bootstrap = bootstrapResult.unwrap(); + +#ifdef LIBFUZZER + shellData.fuzzerDriver = fuzzer::FuzzerDriver; +#endif + + int result = bootstrap->XRE_XPCShellMain(argc, argv, envp, &shellData); + + mozilla::baseprofiler::profiler_shutdown(); + +#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) + DllBlocklist_Shutdown(); +#endif + +#ifdef XP_MACOSX + FinishAutoreleasePool(); +#endif + + return result; +} diff --git a/js/xpconnect/shell/xpcshell.exe.manifest b/js/xpconnect/shell/xpcshell.exe.manifest new file mode 100644 index 0000000000..1c671f14ef --- /dev/null +++ b/js/xpconnect/shell/xpcshell.exe.manifest @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> + +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this file, + - You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="1.0.0.0" + processorArchitecture="*" + name="Mozilla.xpcshell" + type="win32" +/> +<description>XPConnect Shell</description> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="mozglue" + version="1.0.0.0" + language="*" + /> + </dependentAssembly> +</dependency> +<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> + <ms_asmv3:security> + <ms_asmv3:requestedPrivileges> + <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" /> + </ms_asmv3:requestedPrivileges> + </ms_asmv3:security> +</ms_asmv3:trustInfo> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + </application> + </compatibility> +</assembly> diff --git a/js/xpconnect/shell/xpcshellMacUtils.h b/js/xpconnect/shell/xpcshellMacUtils.h new file mode 100644 index 0000000000..61d9030a9f --- /dev/null +++ b/js/xpconnect/shell/xpcshellMacUtils.h @@ -0,0 +1,9 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Functions to setup and release the Mac memory pool +void InitAutoreleasePool(); +void FinishAutoreleasePool(); diff --git a/js/xpconnect/shell/xpcshellMacUtils.mm b/js/xpconnect/shell/xpcshellMacUtils.mm new file mode 100644 index 0000000000..d034895154 --- /dev/null +++ b/js/xpconnect/shell/xpcshellMacUtils.mm @@ -0,0 +1,13 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <Foundation/Foundation.h> + +static NSAutoreleasePool* pool = NULL; + +void InitAutoreleasePool() { pool = [[NSAutoreleasePool alloc] init]; } + +void FinishAutoreleasePool() { [pool release]; } diff --git a/js/xpconnect/src/BackstagePass.h b/js/xpconnect/src/BackstagePass.h new file mode 100644 index 0000000000..fd19348e86 --- /dev/null +++ b/js/xpconnect/src/BackstagePass.h @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BackstagePass_h__ +#define BackstagePass_h__ + +#include "js/loader/ModuleLoaderBase.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/StorageAccess.h" +#include "nsISupports.h" +#include "nsWeakReference.h" +#include "nsIGlobalObject.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsIXPCScriptable.h" + +#include "js/HeapAPI.h" + +class XPCWrappedNative; + +class BackstagePass final : public nsIGlobalObject, + public nsIScriptObjectPrincipal, + public nsIXPCScriptable, + public nsIClassInfo, + public nsSupportsWeakReference { + public: + BackstagePass(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + using ModuleLoaderBase = JS::loader::ModuleLoaderBase; + + nsIPrincipal* GetPrincipal() override { return mPrincipal; } + + nsIPrincipal* GetEffectiveCookiePrincipal() override { return mPrincipal; } + + nsIPrincipal* GetEffectiveStoragePrincipal() override { return mPrincipal; } + + nsIPrincipal* PartitionedPrincipal() override { return mPrincipal; } + + mozilla::OriginTrials Trials() const override { return {}; } + + JSObject* GetGlobalJSObject() override; + JSObject* GetGlobalJSObjectPreserveColor() const override; + + ModuleLoaderBase* GetModuleLoader(JSContext* aCx) override { + return mModuleLoader; + } + + mozilla::StorageAccess GetStorageAccess() final { + MOZ_ASSERT(NS_IsMainThread()); + return mozilla::StorageAccess::eAllow; + } + + mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> GetStorageKey() + override; + + void ForgetGlobalObject() { mWrapper = nullptr; } + + void SetGlobalObject(JSObject* global); + + void InitModuleLoader(ModuleLoaderBase* aModuleLoader) { + MOZ_ASSERT(!mModuleLoader); + mModuleLoader = aModuleLoader; + } + + bool ShouldResistFingerprinting( + RFPTarget aTarget = RFPTarget::Unknown) const override { + // BackstagePass is always the System Principal + MOZ_RELEASE_ASSERT(mPrincipal->IsSystemPrincipal()); + return false; + } + + private: + virtual ~BackstagePass() = default; + + nsCOMPtr<nsIPrincipal> mPrincipal; + XPCWrappedNative* mWrapper; + + RefPtr<JS::loader::ModuleLoaderBase> mModuleLoader; +}; + +#endif // BackstagePass_h__ diff --git a/js/xpconnect/src/ExportHelpers.cpp b/js/xpconnect/src/ExportHelpers.cpp new file mode 100644 index 0000000000..ee89547b4d --- /dev/null +++ b/js/xpconnect/src/ExportHelpers.cpp @@ -0,0 +1,598 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "WrapperFactory.h" +#include "AccessCheck.h" +#include "jsfriendapi.h" +#include "js/CallAndConstruct.h" // JS::Call, JS::Construct, JS::IsCallable +#include "js/Exception.h" +#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById +#include "js/Proxy.h" +#include "js/Wrapper.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/Unused.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/BlobBinding.h" +#include "mozilla/dom/BlobImpl.h" +#include "mozilla/dom/File.h" +#include "mozilla/dom/StructuredCloneHolder.h" +#include "nsContentUtils.h" +#include "nsGlobalWindow.h" +#include "nsJSUtils.h" +#include "js/Object.h" // JS::GetCompartment + +using namespace mozilla; +using namespace mozilla::dom; +using namespace JS; + +namespace xpc { + +bool IsReflector(JSObject* obj, JSContext* cx) { + obj = js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false); + if (!obj) { + return false; + } + return IsWrappedNativeReflector(obj) || dom::IsDOMObject(obj); +} + +enum StackScopedCloneTags : uint32_t { + SCTAG_BASE = JS_SCTAG_USER_MIN, + SCTAG_REFLECTOR, + SCTAG_BLOB, + SCTAG_FUNCTION, +}; + +class MOZ_STACK_CLASS StackScopedCloneData : public StructuredCloneHolderBase { + public: + StackScopedCloneData(JSContext* aCx, StackScopedCloneOptions* aOptions) + : mOptions(aOptions), mReflectors(aCx), mFunctions(aCx) {} + + ~StackScopedCloneData() { Clear(); } + + JSObject* CustomReadHandler(JSContext* aCx, JSStructuredCloneReader* aReader, + const JS::CloneDataPolicy& aCloneDataPolicy, + uint32_t aTag, uint32_t aData) override { + if (aTag == SCTAG_REFLECTOR) { + MOZ_ASSERT(!aData); + + size_t idx; + if (!JS_ReadBytes(aReader, &idx, sizeof(size_t))) { + return nullptr; + } + + RootedObject reflector(aCx, mReflectors[idx]); + MOZ_ASSERT(reflector, "No object pointer?"); + MOZ_ASSERT(IsReflector(reflector, aCx), + "Object pointer must be a reflector!"); + + if (!JS_WrapObject(aCx, &reflector)) { + return nullptr; + } + + return reflector; + } + + if (aTag == SCTAG_FUNCTION) { + MOZ_ASSERT(aData < mFunctions.length()); + + RootedValue functionValue(aCx); + RootedObject obj(aCx, mFunctions[aData]); + + if (!JS_WrapObject(aCx, &obj)) { + return nullptr; + } + + FunctionForwarderOptions forwarderOptions; + if (!xpc::NewFunctionForwarder(aCx, JS::VoidHandlePropertyKey, obj, + forwarderOptions, &functionValue)) { + return nullptr; + } + + return &functionValue.toObject(); + } + + if (aTag == SCTAG_BLOB) { + MOZ_ASSERT(!aData); + + size_t idx; + if (!JS_ReadBytes(aReader, &idx, sizeof(size_t))) { + return nullptr; + } + + nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx); + MOZ_ASSERT(global); + + // RefPtr<File> needs to go out of scope before toObjectOrNull() is called + // because otherwise the static analysis thinks it can gc the JSObject via + // the stack. + JS::Rooted<JS::Value> val(aCx); + { + RefPtr<Blob> blob = Blob::Create(global, mBlobImpls[idx]); + if (NS_WARN_IF(!blob)) { + return nullptr; + } + + if (!ToJSValue(aCx, blob, &val)) { + return nullptr; + } + } + + return val.toObjectOrNull(); + } + + MOZ_ASSERT_UNREACHABLE("Encountered garbage in the clone stream!"); + return nullptr; + } + + bool CustomWriteHandler(JSContext* aCx, JSStructuredCloneWriter* aWriter, + JS::Handle<JSObject*> aObj, + bool* aSameProcessScopeRequired) override { + { + JS::Rooted<JSObject*> obj(aCx, aObj); + Blob* blob = nullptr; + if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) { + BlobImpl* blobImpl = blob->Impl(); + MOZ_ASSERT(blobImpl); + + // XXX(Bug 1631371) Check if this should use a fallible operation as it + // pretended earlier. + mBlobImpls.AppendElement(blobImpl); + + size_t idx = mBlobImpls.Length() - 1; + return JS_WriteUint32Pair(aWriter, SCTAG_BLOB, 0) && + JS_WriteBytes(aWriter, &idx, sizeof(size_t)); + } + } + + if (mOptions->wrapReflectors && IsReflector(aObj, aCx)) { + if (!mReflectors.append(aObj)) { + return false; + } + + size_t idx = mReflectors.length() - 1; + if (!JS_WriteUint32Pair(aWriter, SCTAG_REFLECTOR, 0)) { + return false; + } + if (!JS_WriteBytes(aWriter, &idx, sizeof(size_t))) { + return false; + } + return true; + } + + if (JS::IsCallable(aObj)) { + if (mOptions->cloneFunctions) { + if (!mFunctions.append(aObj)) { + return false; + } + return JS_WriteUint32Pair(aWriter, SCTAG_FUNCTION, + mFunctions.length() - 1); + } else { + JS_ReportErrorASCII( + aCx, "Permission denied to pass a Function via structured clone"); + return false; + } + } + + JS_ReportErrorASCII(aCx, + "Encountered unsupported value type writing " + "stack-scoped structured clone"); + return false; + } + + StackScopedCloneOptions* mOptions; + RootedObjectVector mReflectors; + RootedObjectVector mFunctions; + nsTArray<RefPtr<BlobImpl>> mBlobImpls; +}; + +/* + * General-purpose structured-cloning utility for cases where the structured + * clone buffer is only used in stack-scope (that is to say, the buffer does + * not escape from this function). The stack-scoping allows us to pass + * references to various JSObjects directly in certain situations without + * worrying about lifetime issues. + * + * This function assumes that |cx| is already entered the compartment we want + * to clone to, and that |val| may not be same-compartment with cx. When the + * function returns, |val| is set to the result of the clone. + */ +bool StackScopedClone(JSContext* cx, StackScopedCloneOptions& options, + HandleObject sourceScope, MutableHandleValue val) { + StackScopedCloneData data(cx, &options); + { + // For parsing val we have to enter (a realm in) its compartment. + JSAutoRealm ar(cx, sourceScope); + if (!data.Write(cx, val)) { + return false; + } + } + + // Now recreate the clones in the target realm. + if (!data.Read(cx, val)) { + return false; + } + + // Deep-freeze if requested. + if (options.deepFreeze && val.isObject()) { + RootedObject obj(cx, &val.toObject()); + if (!JS_DeepFreezeObject(cx, obj)) { + return false; + } + } + + return true; +} + +// Note - This function mirrors the logic of CheckPassToChrome in +// ChromeObjectWrapper.cpp. +static bool CheckSameOriginArg(JSContext* cx, FunctionForwarderOptions& options, + HandleValue v) { + // Consumers can explicitly opt out of this security check. This is used in + // the web console to allow the utility functions to accept cross-origin + // Windows. + if (options.allowCrossOriginArguments) { + return true; + } + + // Primitives are fine. + if (!v.isObject()) { + return true; + } + RootedObject obj(cx, &v.toObject()); + MOZ_ASSERT(JS::GetCompartment(obj) != js::GetContextCompartment(cx), + "This should be invoked after entering the compartment but before " + "wrapping the values"); + + // Non-wrappers are fine. + if (!js::IsWrapper(obj)) { + return true; + } + + // Wrappers leading back to the scope of the exported function are fine. + if (JS::GetCompartment(js::UncheckedUnwrap(obj)) == + js::GetContextCompartment(cx)) { + return true; + } + + // Same-origin wrappers are fine. + if (AccessCheck::wrapperSubsumes(obj)) { + return true; + } + + // Badness. + JS_ReportErrorASCII(cx, + "Permission denied to pass object to exported function"); + return false; +} + +// Sanitize the exception on cx (which comes from calling unwrappedFun), if the +// current Realm of cx shouldn't have access to it. unwrappedFun is generally +// _not_ in the current Realm of cx here. +static void MaybeSanitizeException(JSContext* cx, + JS::Handle<JSObject*> unwrappedFun) { + // Ensure that we are not propagating more-privileged exceptions + // to less-privileged code. + nsIPrincipal* callerPrincipal = nsContentUtils::SubjectPrincipal(cx); + + // No need to sanitize uncatchable exceptions, just return. + if (!JS_IsExceptionPending(cx)) { + return; + } + + // Re-enter the unwrappedFun Realm to do get the current exception, so we + // don't end up unnecessarily wrapping exceptions. + { // Scope for JSAutoRealm + JSAutoRealm ar(cx, unwrappedFun); + + JS::ExceptionStack exnStack(cx); + + // If JS::GetPendingExceptionStack returns false, we somehow failed to wrap + // the exception into our compartment. It seems fine to treat this as an + // uncatchable exception by returning without setting any exception on the + // JS context. + if (!JS::GetPendingExceptionStack(cx, &exnStack)) { + JS_ClearPendingException(cx); + return; + } + + // Let through non-objects as-is, because some APIs rely on + // that and accidental exceptions are never non-objects. + if (!exnStack.exception().isObject() || + callerPrincipal->Subsumes(nsContentUtils::ObjectPrincipal( + js::UncheckedUnwrap(&exnStack.exception().toObject())))) { + // Just leave exn as-is. + return; + } + + // Whoever we are throwing the exception to should not have access to + // the exception. Sanitize it. First clear the existing exception. + JS_ClearPendingException(cx); + { // Scope for AutoJSAPI + AutoJSAPI jsapi; + if (jsapi.Init(unwrappedFun)) { + JS::SetPendingExceptionStack(cx, exnStack); + } + // If Init() fails, we can't report the exception, but oh, well. + + // Now just let the AutoJSAPI go out of scope and it will report the + // exception in its destructor. + } + } + + // Now back in our original Realm again, throw a sanitized exception. + ErrorResult rv; + rv.ThrowInvalidStateError("An exception was thrown"); + // Can we provide a better context here? + Unused << rv.MaybeSetPendingException(cx); +} + +static bool FunctionForwarder(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + // Grab the options from the reserved slot. + RootedObject optionsObj( + cx, &js::GetFunctionNativeReserved(&args.callee(), 1).toObject()); + FunctionForwarderOptions options(cx, optionsObj); + if (!options.Parse()) { + return false; + } + + // Grab and unwrap the underlying callable. + RootedValue v(cx, js::GetFunctionNativeReserved(&args.callee(), 0)); + RootedObject unwrappedFun(cx, js::UncheckedUnwrap(&v.toObject())); + + RootedValue thisVal(cx, NullValue()); + if (!args.isConstructing()) { + RootedObject thisObject(cx); + if (!args.computeThis(cx, &thisObject)) { + return false; + } + thisVal.setObject(*thisObject); + } + + bool ok = true; + { + // We manually implement the contents of CrossCompartmentWrapper::call + // here, because certain function wrappers (notably content->nsEP) are + // not callable. + JSAutoRealm ar(cx, unwrappedFun); + bool crossCompartment = + JS::GetCompartment(unwrappedFun) != JS::GetCompartment(&args.callee()); + if (crossCompartment) { + if (!CheckSameOriginArg(cx, options, thisVal) || + !JS_WrapValue(cx, &thisVal)) { + return false; + } + + for (size_t n = 0; n < args.length(); ++n) { + if (!CheckSameOriginArg(cx, options, args[n]) || + !JS_WrapValue(cx, args[n])) { + return false; + } + } + } + + RootedValue fval(cx, ObjectValue(*unwrappedFun)); + if (args.isConstructing()) { + RootedObject obj(cx); + ok = JS::Construct(cx, fval, args, &obj); + if (ok) { + args.rval().setObject(*obj); + } + } else { + ok = JS::Call(cx, thisVal, fval, args, args.rval()); + } + } + + // Now that we are back in our original Realm, we can check whether to + // sanitize the exception. + if (!ok) { + MaybeSanitizeException(cx, unwrappedFun); + return false; + } + + // Rewrap the return value into our compartment. + return JS_WrapValue(cx, args.rval()); +} + +bool NewFunctionForwarder(JSContext* cx, HandleId idArg, HandleObject callable, + FunctionForwarderOptions& options, + MutableHandleValue vp) { + RootedId id(cx, idArg); + if (id.isVoid()) { + id = GetJSIDByIndex(cx, XPCJSContext::IDX_EMPTYSTRING); + } + + // If our callable is a (possibly wrapped) function, we can give + // the exported thing the right number of args. + unsigned nargs = 0; + RootedObject unwrapped(cx, js::UncheckedUnwrap(callable)); + if (unwrapped) { + if (JSFunction* fun = JS_GetObjectFunction(unwrapped)) { + nargs = JS_GetFunctionArity(fun); + } + } + + // We have no way of knowing whether the underlying function wants to be a + // constructor or not, so we just mark all forwarders as constructors, and + // let the underlying function throw for construct calls if it wants. + JSFunction* fun = js::NewFunctionByIdWithReserved( + cx, FunctionForwarder, nargs, JSFUN_CONSTRUCTOR, id); + if (!fun) { + return false; + } + + // Stash the callable in slot 0. + AssertSameCompartment(cx, callable); + RootedObject funobj(cx, JS_GetFunctionObject(fun)); + js::SetFunctionNativeReserved(funobj, 0, ObjectValue(*callable)); + + // Stash the options in slot 1. + RootedObject optionsObj(cx, options.ToJSObject(cx)); + if (!optionsObj) { + return false; + } + js::SetFunctionNativeReserved(funobj, 1, ObjectValue(*optionsObj)); + + vp.setObject(*funobj); + return true; +} + +bool ExportFunction(JSContext* cx, HandleValue vfunction, HandleValue vscope, + HandleValue voptions, MutableHandleValue rval) { + bool hasOptions = !voptions.isUndefined(); + if (!vscope.isObject() || !vfunction.isObject() || + (hasOptions && !voptions.isObject())) { + JS_ReportErrorASCII(cx, "Invalid argument"); + return false; + } + + RootedObject funObj(cx, &vfunction.toObject()); + RootedObject targetScope(cx, &vscope.toObject()); + ExportFunctionOptions options(cx, + hasOptions ? &voptions.toObject() : nullptr); + if (hasOptions && !options.Parse()) { + return false; + } + + // Restrictions: + // * We must subsume the scope we are exporting to. + // * We must subsume the function being exported, because the function + // forwarder manually circumvents security wrapper CALL restrictions. + targetScope = js::CheckedUnwrapDynamic(targetScope, cx); + // For the function we can just CheckedUnwrapStatic, because if it's + // not callable we're going to fail out anyway. + funObj = js::CheckedUnwrapStatic(funObj); + if (!targetScope || !funObj) { + JS_ReportErrorASCII(cx, "Permission denied to export function into scope"); + return false; + } + + if (js::IsScriptedProxy(targetScope)) { + JS_ReportErrorASCII(cx, "Defining property on proxy object is not allowed"); + return false; + } + + { + // We need to operate in the target scope from here on, let's enter + // its realm. + JSAutoRealm ar(cx, targetScope); + + // Unwrapping to see if we have a callable. + funObj = UncheckedUnwrap(funObj); + if (!JS::IsCallable(funObj)) { + JS_ReportErrorASCII(cx, "First argument must be a function"); + return false; + } + + RootedId id(cx, options.defineAs); + if (id.isVoid()) { + // If there wasn't any function name specified, copy the name from the + // function being imported. But be careful in case the callable we have + // is not actually a JSFunction. + RootedString funName(cx); + JSFunction* fun = JS_GetObjectFunction(funObj); + if (fun) { + funName = JS_GetFunctionId(fun); + } + if (!funName) { + funName = JS_AtomizeAndPinString(cx, ""); + } + JS_MarkCrossZoneIdValue(cx, StringValue(funName)); + + if (!JS_StringToId(cx, funName, &id)) { + return false; + } + } else { + JS_MarkCrossZoneId(cx, id); + } + MOZ_ASSERT(id.isString()); + + // The function forwarder will live in the target compartment. Since + // this function will be referenced from its private slot, to avoid a + // GC hazard, we must wrap it to the same compartment. + if (!JS_WrapObject(cx, &funObj)) { + return false; + } + + // And now, let's create the forwarder function in the target compartment + // for the function the be exported. + FunctionForwarderOptions forwarderOptions; + forwarderOptions.allowCrossOriginArguments = + options.allowCrossOriginArguments; + if (!NewFunctionForwarder(cx, id, funObj, forwarderOptions, rval)) { + JS_ReportErrorASCII(cx, "Exporting function failed"); + return false; + } + + // We have the forwarder function in the target compartment. If + // defineAs was set, we also need to define it as a property on + // the target. + if (!options.defineAs.isVoid()) { + if (!JS_DefinePropertyById(cx, targetScope, id, rval, JSPROP_ENUMERATE)) { + return false; + } + } + } + + // Finally we have to re-wrap the exported function back to the caller + // compartment. + if (!JS_WrapValue(cx, rval)) { + return false; + } + + return true; +} + +bool CreateObjectIn(JSContext* cx, HandleValue vobj, + CreateObjectInOptions& options, MutableHandleValue rval) { + if (!vobj.isObject()) { + JS_ReportErrorASCII(cx, "Expected an object as the target scope"); + return false; + } + + // cx represents the caller Realm. + RootedObject scope(cx, js::CheckedUnwrapDynamic(&vobj.toObject(), cx)); + if (!scope) { + JS_ReportErrorASCII( + cx, "Permission denied to create object in the target scope"); + return false; + } + + bool define = !options.defineAs.isVoid(); + + if (define && js::IsScriptedProxy(scope)) { + JS_ReportErrorASCII(cx, "Defining property on proxy object is not allowed"); + return false; + } + + RootedObject obj(cx); + { + JSAutoRealm ar(cx, scope); + JS_MarkCrossZoneId(cx, options.defineAs); + + obj = JS_NewPlainObject(cx); + if (!obj) { + return false; + } + + if (define) { + if (!JS_DefinePropertyById(cx, scope, options.defineAs, obj, + JSPROP_ENUMERATE)) + return false; + } + } + + rval.setObject(*obj); + if (!WrapperFactory::WaiveXrayAndWrap(cx, rval)) { + return false; + } + + return true; +} + +} /* namespace xpc */ diff --git a/js/xpconnect/src/JSServices.cpp b/js/xpconnect/src/JSServices.cpp new file mode 100644 index 0000000000..cb8fe6cdca --- /dev/null +++ b/js/xpconnect/src/JSServices.cpp @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "StaticComponents.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/ProfilerLabels.h" +#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById +#include "js/String.h" // JS::LinearStringHasLatin1Chars +#include "nsJSUtils.h" + +using namespace mozilla; +using namespace JS; + +namespace xpc { + +static bool Services_NewEnumerate(JSContext* cx, HandleObject obj, + MutableHandleIdVector properties, + bool enumerableOnly); +static bool Services_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp); +static bool Services_MayResolve(const JSAtomState& names, jsid id, + JSObject* maybeObj); + +static const JSClassOps sServices_ClassOps = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + Services_NewEnumerate, // newEnumerate + Services_Resolve, // resolve + Services_MayResolve, // mayResolve + nullptr, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +static const JSClass sServices_Class = {"JSServices", 0, &sServices_ClassOps}; + +JSObject* NewJSServices(JSContext* cx) { + return JS_NewObject(cx, &sServices_Class); +} + +static bool Services_NewEnumerate(JSContext* cx, HandleObject obj, + MutableHandleIdVector properties, + bool enumerableOnly) { + auto services = xpcom::StaticComponents::GetJSServices(); + + if (!properties.reserve(services.Length())) { + JS_ReportOutOfMemory(cx); + return false; + } + + RootedId id(cx); + RootedString name(cx); + for (const auto& service : services) { + name = JS_AtomizeString(cx, service.Name().get()); + if (!name || !JS_StringToId(cx, name, &id)) { + return false; + } + properties.infallibleAppend(id); + } + + return true; +} + +static JSLinearString* GetNameIfLatin1(jsid id) { + if (id.isString()) { + JSLinearString* name = id.toLinearString(); + if (JS::LinearStringHasLatin1Chars(name)) { + return name; + } + } + return nullptr; +} + +static bool GetServiceImpl(JSContext* cx, const xpcom::JSServiceEntry& service, + JS::MutableHandleObject aObj, ErrorResult& aRv) { + nsresult rv; + nsCOMPtr<nsISupports> inst = service.Module().GetService(&rv); + if (!inst) { + aRv.Throw(rv); + return false; + } + + auto ifaces = service.Interfaces(); + + if (ifaces.Length() == 0) { + // If we weren't given any interfaces, we're expecting either a WebIDL + // object or a wrapped JS object. In the former case, the object will handle + // its own wrapping, and there's nothing to do. In the latter case, we want + // to unwrap the underlying JS object. + if (nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(inst)) { + aObj.set(wrappedJS->GetJSObject()); + return !!aObj; + } + } + + JS::RootedValue val(cx); + + const nsIID* iid = ifaces.Length() ? ifaces[0] : nullptr; + xpcObjectHelper helper(inst); + if (!XPCConvert::NativeInterface2JSObject(cx, &val, helper, iid, + /* allowNativeWrapper */ true, + &rv)) { + aRv.Throw(rv); + return false; + } + + if (ifaces.Length() > 1) { + auto* wn = XPCWrappedNative::Get(&val.toObject()); + for (const nsIID* iid : Span(ifaces).From(1)) { + // Ignore any supplemental interfaces that aren't implemented. Tests do + // weird things with some services, and JS can generally handle the + // interfaces being absent. + Unused << wn->FindTearOff(cx, *iid); + } + } + + aObj.set(&val.toObject()); + return true; +} + +static JSObject* GetService(JSContext* cx, const xpcom::JSServiceEntry& service, + ErrorResult& aRv) { + JS::RootedObject obj(cx); + if (!GetServiceImpl(cx, service, &obj, aRv)) { + return nullptr; + } + return obj; +} + +static bool Services_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + *resolvedp = false; + JSLinearString* name = GetNameIfLatin1(id); + if (!name) { + return true; + } + + nsAutoJSLinearCString nameStr(name); + if (const auto* service = xpcom::JSServiceEntry::Lookup(nameStr)) { + AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING_NONSENSITIVE("Services_Resolve", + OTHER, service->Name()); + *resolvedp = true; + + ErrorResult rv; + JS::RootedValue val(cx); + + val.setObjectOrNull(GetService(cx, *service, rv)); + if (rv.MaybeSetPendingException(cx)) { + return false; + } + + return JS_DefinePropertyById(cx, obj, id, val, JSPROP_ENUMERATE); + } + return true; +} + +static bool Services_MayResolve(const JSAtomState& names, jsid id, + JSObject* maybeObj) { + if (JSLinearString* name = GetNameIfLatin1(id)) { + nsAutoJSLinearCString nameStr(name); + return xpcom::JSServiceEntry::Lookup(nameStr); + } + return false; +} + +} // namespace xpc diff --git a/js/xpconnect/src/JSServices.h b/js/xpconnect/src/JSServices.h new file mode 100644 index 0000000000..9dcfd15fdb --- /dev/null +++ b/js/xpconnect/src/JSServices.h @@ -0,0 +1,18 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef JSServices_h +#define JSServices_h + +#include "jstypes.h" + +namespace xpc { + +JSObject* NewJSServices(JSContext* cx); + +} + +#endif // ifndef JSServices_h diff --git a/js/xpconnect/src/README b/js/xpconnect/src/README new file mode 100644 index 0000000000..260eed6bcd --- /dev/null +++ b/js/xpconnect/src/README @@ -0,0 +1,3 @@ + +see http://www.mozilla.org/scriptable + diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp new file mode 100644 index 0000000000..b75bebc6f1 --- /dev/null +++ b/js/xpconnect/src/Sandbox.cpp @@ -0,0 +1,2256 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * The Components.Sandbox object. + */ + +#include "AccessCheck.h" +#include "jsfriendapi.h" +#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject +#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable +#include "js/CharacterEncoding.h" +#include "js/CompilationAndEvaluation.h" +#include "js/Object.h" // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot +#include "js/PropertyAndElement.h" // JS_DefineFunction, JS_DefineFunctions, JS_DefineProperty, JS_GetElement, JS_GetProperty, JS_HasProperty, JS_SetProperty, JS_SetPropertyById +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById, JS_GetPropertyDescriptorById +#include "js/PropertySpec.h" +#include "js/Proxy.h" +#include "js/SourceText.h" +#include "js/StructuredClone.h" +#include "nsContentUtils.h" +#include "nsGlobalWindow.h" +#include "nsIException.h" // for nsIStackFrame +#include "nsIScriptContext.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsIURI.h" +#include "nsJSUtils.h" +#include "nsNetUtil.h" +#include "ExpandedPrincipal.h" +#include "WrapperFactory.h" +#include "xpcprivate.h" +#include "xpc_make_class.h" +#include "XPCWrapper.h" +#include "Crypto.h" +#include "mozilla/Result.h" +#include "mozilla/dom/AbortControllerBinding.h" +#include "mozilla/dom/AutoEntryScript.h" +#include "mozilla/dom/BindingCallContext.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/BlobBinding.h" +#include "mozilla/dom/cache/CacheStorage.h" +#include "mozilla/dom/CSSBinding.h" +#include "mozilla/dom/CSSRuleBinding.h" +#include "mozilla/dom/DirectoryBinding.h" +#include "mozilla/dom/DocumentBinding.h" +#include "mozilla/dom/DOMExceptionBinding.h" +#include "mozilla/dom/DOMParserBinding.h" +#include "mozilla/dom/DOMTokenListBinding.h" +#include "mozilla/dom/ElementBinding.h" +#include "mozilla/dom/EventBinding.h" +#include "mozilla/dom/Exceptions.h" +#include "mozilla/dom/IndexedDatabaseManager.h" +#include "mozilla/dom/Fetch.h" +#include "mozilla/dom/FileBinding.h" +#include "mozilla/dom/HeadersBinding.h" +#include "mozilla/dom/IOUtilsBinding.h" +#include "mozilla/dom/InspectorUtilsBinding.h" +#include "mozilla/dom/MessageChannelBinding.h" +#include "mozilla/dom/MessagePortBinding.h" +#include "mozilla/dom/MIDIInputMapBinding.h" +#include "mozilla/dom/MIDIOutputMapBinding.h" +#include "mozilla/dom/ModuleLoader.h" +#include "mozilla/dom/NodeBinding.h" +#include "mozilla/dom/NodeFilterBinding.h" +#include "mozilla/dom/PathUtilsBinding.h" +#include "mozilla/dom/PerformanceBinding.h" +#include "mozilla/dom/PromiseBinding.h" +#include "mozilla/dom/PromiseDebuggingBinding.h" +#include "mozilla/dom/RangeBinding.h" +#include "mozilla/dom/RequestBinding.h" +#include "mozilla/dom/ReadableStreamBinding.h" +#include "mozilla/dom/ResponseBinding.h" +#ifdef MOZ_WEBRTC +# include "mozilla/dom/RTCIdentityProviderRegistrar.h" +#endif +#include "mozilla/dom/FileReaderBinding.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/SelectionBinding.h" +#include "mozilla/dom/StorageManager.h" +#include "mozilla/dom/TextDecoderBinding.h" +#include "mozilla/dom/TextEncoderBinding.h" +#include "mozilla/dom/URLBinding.h" +#include "mozilla/dom/URLSearchParamsBinding.h" +#include "mozilla/dom/XMLHttpRequest.h" +#include "mozilla/dom/WebSocketBinding.h" +#include "mozilla/dom/WindowBinding.h" +#include "mozilla/dom/XMLSerializerBinding.h" +#include "mozilla/dom/FormDataBinding.h" +#include "mozilla/dom/nsCSPContext.h" +#include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/DeferredFinalize.h" +#include "mozilla/ExtensionPolicyService.h" +#include "mozilla/Maybe.h" +#include "mozilla/NullPrincipal.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/StaticPrefs_extensions.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace JS; +using namespace JS::loader; +using namespace xpc; + +using mozilla::dom::DestroyProtoAndIfaceCache; +using mozilla::dom::IndexedDatabaseManager; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(SandboxPrivate) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SandboxPrivate) + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE + NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_PTR + NS_IMPL_CYCLE_COLLECTION_UNLINK(mModuleLoader) + tmp->UnlinkObjectsInGlobal(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SandboxPrivate) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mModuleLoader) + tmp->TraverseObjectsInGlobal(cb); +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(SandboxPrivate) +NS_IMPL_CYCLE_COLLECTING_RELEASE(SandboxPrivate) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SandboxPrivate) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptObjectPrincipal) + NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal) + NS_INTERFACE_MAP_ENTRY(nsIGlobalObject) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +NS_INTERFACE_MAP_END + +class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox, + public nsIXPCScriptable { + public: + // Aren't macros nice? + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_UTILS_SANDBOX + NS_DECL_NSIXPCSCRIPTABLE + + public: + nsXPCComponents_utils_Sandbox(); + + private: + virtual ~nsXPCComponents_utils_Sandbox(); + + static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval); +}; + +already_AddRefed<nsIXPCComponents_utils_Sandbox> xpc::NewSandboxConstructor() { + nsCOMPtr<nsIXPCComponents_utils_Sandbox> sbConstructor = + new nsXPCComponents_utils_Sandbox(); + return sbConstructor.forget(); +} + +static bool SandboxDump(JSContext* cx, unsigned argc, Value* vp) { + if (!nsJSUtils::DumpEnabled()) { + return true; + } + + CallArgs args = CallArgsFromVp(argc, vp); + + if (args.length() == 0) { + return true; + } + + RootedString str(cx, ToString(cx, args[0])); + if (!str) { + return false; + } + + JS::UniqueChars utf8str = JS_EncodeStringToUTF8(cx, str); + char* cstr = utf8str.get(); + if (!cstr) { + return false; + } + +#if defined(XP_MACOSX) + // Be nice and convert all \r to \n. + char* c = cstr; + char* cEnd = cstr + strlen(cstr); + while (c < cEnd) { + if (*c == '\r') { + *c = '\n'; + } + c++; + } +#endif + MOZ_LOG(nsContentUtils::DOMDumpLog(), mozilla::LogLevel::Debug, + ("[Sandbox.Dump] %s", cstr)); +#ifdef ANDROID + __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr); +#endif + fputs(cstr, stdout); + fflush(stdout); + args.rval().setBoolean(true); + return true; +} + +static bool SandboxDebug(JSContext* cx, unsigned argc, Value* vp) { +#ifdef DEBUG + return SandboxDump(cx, argc, vp); +#else + return true; +#endif +} + +static bool SandboxImport(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + if (args.length() < 1 || args[0].isPrimitive()) { + XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx); + return false; + } + + RootedString funname(cx); + if (args.length() > 1) { + // Use the second parameter as the function name. + funname = ToString(cx, args[1]); + if (!funname) { + return false; + } + } else { + // NB: funobj must only be used to get the JSFunction out. + RootedObject funobj(cx, &args[0].toObject()); + if (js::IsProxy(funobj)) { + funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj); + } + + JSAutoRealm ar(cx, funobj); + + RootedValue funval(cx, ObjectValue(*funobj)); + JSFunction* fun = JS_ValueToFunction(cx, funval); + if (!fun) { + XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx); + return false; + } + + // Use the actual function name as the name. + funname = JS_GetFunctionId(fun); + if (!funname) { + XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx); + return false; + } + } + JS_MarkCrossZoneIdValue(cx, StringValue(funname)); + + RootedId id(cx); + if (!JS_StringToId(cx, funname, &id)) { + return false; + } + + // We need to resolve the this object, because this function is used + // unbound and should still work and act on the original sandbox. + + RootedObject thisObject(cx); + if (!args.computeThis(cx, &thisObject)) { + return false; + } + + if (!JS_SetPropertyById(cx, thisObject, id, args[0])) { + return false; + } + + args.rval().setUndefined(); + return true; +} + +bool xpc::SandboxCreateCrypto(JSContext* cx, JS::Handle<JSObject*> obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + nsIGlobalObject* native = xpc::NativeGlobal(obj); + MOZ_ASSERT(native); + + dom::Crypto* crypto = new dom::Crypto(native); + JS::RootedObject wrapped(cx, crypto->WrapObject(cx, nullptr)); + return JS_DefineProperty(cx, obj, "crypto", wrapped, JSPROP_ENUMERATE); +} + +#ifdef MOZ_WEBRTC +static bool SandboxCreateRTCIdentityProvider(JSContext* cx, + JS::HandleObject obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + nsCOMPtr<nsIGlobalObject> nativeGlobal = xpc::NativeGlobal(obj); + MOZ_ASSERT(nativeGlobal); + + dom::RTCIdentityProviderRegistrar* registrar = + new dom::RTCIdentityProviderRegistrar(nativeGlobal); + JS::RootedObject wrapped(cx, registrar->WrapObject(cx, nullptr)); + return JS_DefineProperty(cx, obj, "rtcIdentityProvider", wrapped, + JSPROP_ENUMERATE); +} +#endif + +static bool SandboxFetch(JSContext* cx, JS::HandleObject scope, + const CallArgs& args) { + if (args.length() < 1) { + JS_ReportErrorASCII(cx, "fetch requires at least 1 argument"); + return false; + } + + BindingCallContext callCx(cx, "fetch"); + RequestOrUSVString request; + if (!request.Init(callCx, args[0], "Argument 1")) { + return false; + } + RootedDictionary<dom::RequestInit> options(cx); + if (!options.Init(callCx, args.hasDefined(1) ? args[1] : JS::NullHandleValue, + "Argument 2", false)) { + return false; + } + nsCOMPtr<nsIGlobalObject> global = xpc::NativeGlobal(scope); + if (!global) { + return false; + } + dom::CallerType callerType = nsContentUtils::IsSystemCaller(cx) + ? dom::CallerType::System + : dom::CallerType::NonSystem; + ErrorResult rv; + RefPtr<dom::Promise> response = FetchRequest( + global, Constify(request), Constify(options), callerType, rv); + if (rv.MaybeSetPendingException(cx)) { + return false; + } + + args.rval().setObject(*response->PromiseObj()); + return true; +} + +static bool SandboxFetchPromise(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + RootedObject scope(cx, JS::CurrentGlobalOrNull(cx)); + if (SandboxFetch(cx, scope, args)) { + return true; + } + return ConvertExceptionToPromise(cx, args.rval()); +} + +bool xpc::SandboxCreateFetch(JSContext* cx, JS::Handle<JSObject*> obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + return JS_DefineFunction(cx, obj, "fetch", SandboxFetchPromise, 2, 0) && + dom::Request_Binding::GetConstructorObject(cx) && + dom::Response_Binding::GetConstructorObject(cx) && + dom::Headers_Binding::GetConstructorObject(cx); +} + +static bool SandboxCreateStorage(JSContext* cx, JS::HandleObject obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + nsIGlobalObject* native = xpc::NativeGlobal(obj); + MOZ_ASSERT(native); + + dom::StorageManager* storageManager = new dom::StorageManager(native); + JS::RootedObject wrapped(cx, storageManager->WrapObject(cx, nullptr)); + return JS_DefineProperty(cx, obj, "storage", wrapped, JSPROP_ENUMERATE); +} + +static bool SandboxStructuredClone(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + if (!args.requireAtLeast(cx, "structuredClone", 1)) { + return false; + } + + RootedDictionary<dom::StructuredSerializeOptions> options(cx); + BindingCallContext callCx(cx, "structuredClone"); + if (!options.Init(cx, args.hasDefined(1) ? args[1] : JS::NullHandleValue, + "Argument 2", false)) { + return false; + } + + nsIGlobalObject* global = CurrentNativeGlobal(cx); + if (!global) { + JS_ReportErrorASCII(cx, "structuredClone: Missing global"); + return false; + } + + JS::Rooted<JS::Value> result(cx); + ErrorResult rv; + nsContentUtils::StructuredClone(cx, global, args[0], options, &result, rv); + if (rv.MaybeSetPendingException(cx)) { + return false; + } + + MOZ_ASSERT_IF(result.isGCThing(), + !JS::GCThingIsMarkedGray(result.toGCCellPtr())); + args.rval().set(result); + return true; +} + +bool xpc::SandboxCreateStructuredClone(JSContext* cx, HandleObject obj) { + MOZ_ASSERT(JS_IsGlobalObject(obj)); + + return JS_DefineFunction(cx, obj, "structuredClone", SandboxStructuredClone, + 1, 0); +} + +static bool SandboxIsProxy(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() < 1) { + JS_ReportErrorASCII(cx, "Function requires at least 1 argument"); + return false; + } + if (!args[0].isObject()) { + args.rval().setBoolean(false); + return true; + } + + RootedObject obj(cx, &args[0].toObject()); + // CheckedUnwrapStatic is OK here, since we only care about whether + // it's a scripted proxy and the things CheckedUnwrapStatic fails on + // are not. + obj = js::CheckedUnwrapStatic(obj); + if (!obj) { + args.rval().setBoolean(false); + return true; + } + + args.rval().setBoolean(js::IsScriptedProxy(obj)); + return true; +} + +/* + * Expected type of the arguments and the return value: + * function exportFunction(function funToExport, + * object targetScope, + * [optional] object options) + */ +static bool SandboxExportFunction(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() < 2) { + JS_ReportErrorASCII(cx, "Function requires at least 2 arguments"); + return false; + } + + RootedValue options(cx, args.length() > 2 ? args[2] : UndefinedValue()); + return ExportFunction(cx, args[0], args[1], options, args.rval()); +} + +static bool SandboxCreateObjectIn(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() < 1) { + JS_ReportErrorASCII(cx, "Function requires at least 1 argument"); + return false; + } + + RootedObject optionsObj(cx); + bool calledWithOptions = args.length() > 1; + if (calledWithOptions) { + if (!args[1].isObject()) { + JS_ReportErrorASCII( + cx, "Expected the 2nd argument (options) to be an object"); + return false; + } + optionsObj = &args[1].toObject(); + } + + CreateObjectInOptions options(cx, optionsObj); + if (calledWithOptions && !options.Parse()) { + return false; + } + + return xpc::CreateObjectIn(cx, args[0], options, args.rval()); +} + +static bool SandboxCloneInto(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() < 2) { + JS_ReportErrorASCII(cx, "Function requires at least 2 arguments"); + return false; + } + + RootedValue options(cx, args.length() > 2 ? args[2] : UndefinedValue()); + return xpc::CloneInto(cx, args[0], args[1], options, args.rval()); +} + +static void sandbox_finalize(JS::GCContext* gcx, JSObject* obj) { + SandboxPrivate* priv = SandboxPrivate::GetPrivate(obj); + if (!priv) { + // priv can be null if CreateSandboxObject fails in the middle. + return; + } + + priv->ForgetGlobalObject(obj); + DestroyProtoAndIfaceCache(obj); + DeferredFinalize(static_cast<nsIScriptObjectPrincipal*>(priv)); +} + +static size_t sandbox_moved(JSObject* obj, JSObject* old) { + // Note that this hook can be called before the private pointer is set. In + // this case the SandboxPrivate will not exist yet, so there is nothing to + // do. + SandboxPrivate* priv = SandboxPrivate::GetPrivate(obj); + if (!priv) { + return 0; + } + + return priv->ObjectMoved(obj, old); +} + +#define XPCONNECT_SANDBOX_CLASS_METADATA_SLOT \ + (XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET) + +static const JSClassOps SandboxClassOps = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + JS_NewEnumerateStandardClasses, // newEnumerate + JS_ResolveStandardClass, // resolve + JS_MayResolveStandardClass, // mayResolve + sandbox_finalize, // finalize + nullptr, // call + nullptr, // construct + JS_GlobalObjectTraceHook, // trace +}; + +static const js::ClassExtension SandboxClassExtension = { + sandbox_moved, // objectMovedOp +}; + +static const JSClass SandboxClass = { + "Sandbox", + XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE, + &SandboxClassOps, + JS_NULL_CLASS_SPEC, + &SandboxClassExtension, + JS_NULL_OBJECT_OPS}; + +static const JSFunctionSpec SandboxFunctions[] = { + JS_FN("dump", SandboxDump, 1, 0), JS_FN("debug", SandboxDebug, 1, 0), + JS_FN("importFunction", SandboxImport, 1, 0), JS_FS_END}; + +bool xpc::IsSandbox(JSObject* obj) { + const JSClass* clasp = JS::GetClass(obj); + return clasp == &SandboxClass; +} + +/***************************************************************************/ +nsXPCComponents_utils_Sandbox::nsXPCComponents_utils_Sandbox() = default; + +nsXPCComponents_utils_Sandbox::~nsXPCComponents_utils_Sandbox() = default; + +NS_IMPL_QUERY_INTERFACE(nsXPCComponents_utils_Sandbox, + nsIXPCComponents_utils_Sandbox, nsIXPCScriptable) + +NS_IMPL_ADDREF(nsXPCComponents_utils_Sandbox) +NS_IMPL_RELEASE(nsXPCComponents_utils_Sandbox) + +// We use the nsIXPScriptable macros to generate lots of stuff for us. +#define XPC_MAP_CLASSNAME nsXPCComponents_utils_Sandbox +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_utils_Sandbox" +#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | XPC_SCRIPTABLE_WANT_CONSTRUCT) +#include "xpc_map_end.h" /* This #undef's the above. */ + +class SandboxProxyHandler : public js::Wrapper { + public: + constexpr SandboxProxyHandler() : js::Wrapper(0) {} + + virtual bool getOwnPropertyDescriptor( + JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, + JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const override; + + // We just forward the high-level methods to the BaseProxyHandler versions + // which implement them in terms of lower-level methods. + virtual bool has(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, bool* bp) const override; + virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::HandleValue receiver, JS::Handle<jsid> id, + JS::MutableHandle<JS::Value> vp) const override; + virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, JS::Handle<JS::Value> v, + JS::Handle<JS::Value> receiver, + JS::ObjectOpResult& result) const override; + + virtual bool hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, bool* bp) const override; + virtual bool getOwnEnumerablePropertyKeys( + JSContext* cx, JS::Handle<JSObject*> proxy, + JS::MutableHandleIdVector props) const override; + virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::MutableHandleIdVector props) const override; + + private: + // Implements the custom getPropertyDescriptor behavior. If the getOwn + // argument is true we only look for "own" properties. + bool getPropertyDescriptorImpl( + JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, + bool getOwn, JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const; +}; + +static const SandboxProxyHandler sandboxProxyHandler; + +namespace xpc { + +bool IsSandboxPrototypeProxy(JSObject* obj) { + return js::IsProxy(obj) && js::GetProxyHandler(obj) == &sandboxProxyHandler; +} + +bool IsWebExtensionContentScriptSandbox(JSObject* obj) { + return IsSandbox(obj) && + CompartmentPrivate::Get(obj)->isWebExtensionContentScript; +} + +} // namespace xpc + +// A proxy handler that lets us wrap callables and invoke them with +// the correct this object, while forwarding all other operations down +// to them directly. +class SandboxCallableProxyHandler : public js::Wrapper { + public: + constexpr SandboxCallableProxyHandler() : js::Wrapper(0) {} + + virtual bool call(JSContext* cx, JS::Handle<JSObject*> proxy, + const JS::CallArgs& args) const override; + + static const size_t SandboxProxySlot = 0; + + static inline JSObject* getSandboxProxy(JS::Handle<JSObject*> proxy) { + return &js::GetProxyReservedSlot(proxy, SandboxProxySlot).toObject(); + } +}; + +static const SandboxCallableProxyHandler sandboxCallableProxyHandler; + +bool SandboxCallableProxyHandler::call(JSContext* cx, + JS::Handle<JSObject*> proxy, + const JS::CallArgs& args) const { + // We forward the call to our underlying callable. + + // Get our SandboxProxyHandler proxy. + RootedObject sandboxProxy(cx, getSandboxProxy(proxy)); + MOZ_ASSERT(js::IsProxy(sandboxProxy) && + js::GetProxyHandler(sandboxProxy) == &sandboxProxyHandler); + + // The global of the sandboxProxy is the sandbox global, and the + // target object is the original proto. + RootedObject sandboxGlobal(cx, JS::GetNonCCWObjectGlobal(sandboxProxy)); + MOZ_ASSERT(IsSandbox(sandboxGlobal)); + + // If our this object is the sandbox global, we call with this set to the + // original proto instead. + // + // There are two different ways we can compute |this|. If we use + // JS_THIS_VALUE, we'll get the bonafide |this| value as passed by the + // caller, which may be undefined if a global function was invoked without + // an explicit invocant. If we use JS_THIS or JS_THIS_OBJECT, the |this| + // in |vp| will be coerced to the global, which is not the correct + // behavior in ES5 strict mode. And we have no way to compute strictness + // here. + // + // The naive approach is simply to use JS_THIS_VALUE here. If |this| was + // explicit, we can remap it appropriately. If it was implicit, then we + // leave it as undefined, and let the callee sort it out. Since the callee + // is generally in the same compartment as its global (eg the Window's + // compartment, not the Sandbox's), the callee will generally compute the + // correct |this|. + // + // However, this breaks down in the Xray case. If the sandboxPrototype + // is an Xray wrapper, then we'll end up reifying the native methods in + // the Sandbox's scope, which means that they'll compute |this| to be the + // Sandbox, breaking old-style XPC_WN_CallMethod methods. + // + // Luckily, the intent of Xrays is to provide a vanilla view of a foreign + // DOM interface, which means that we don't care about script-enacted + // strictness in the prototype's home compartment. Indeed, since DOM + // methods are always non-strict, we can just assume non-strict semantics + // if the sandboxPrototype is an Xray Wrapper, which lets us appropriately + // remap |this|. + bool isXray = WrapperFactory::IsXrayWrapper(sandboxProxy); + RootedValue thisVal(cx, args.thisv()); + if (isXray) { + RootedObject thisObject(cx); + if (!args.computeThis(cx, &thisObject)) { + return false; + } + thisVal.setObject(*thisObject); + } + + if (thisVal == ObjectValue(*sandboxGlobal)) { + thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy)); + } + + RootedValue func(cx, js::GetProxyPrivate(proxy)); + return JS::Call(cx, thisVal, func, args, args.rval()); +} + +/* + * Wrap a callable such that if we're called with oldThisObj as the + * "this" we will instead call it with newThisObj as the this. + */ +static JSObject* WrapCallable(JSContext* cx, HandleObject callable, + HandleObject sandboxProtoProxy) { + MOZ_ASSERT(JS::IsCallable(callable)); + // Our proxy is wrapping the callable. So we need to use the + // callable as the private. We put the given sandboxProtoProxy in + // an extra slot, and our call() hook depends on that. + MOZ_ASSERT(js::IsProxy(sandboxProtoProxy) && + js::GetProxyHandler(sandboxProtoProxy) == &sandboxProxyHandler); + + RootedValue priv(cx, ObjectValue(*callable)); + // We want to claim to have the same proto as our wrapped callable, so set + // ourselves up with a lazy proto. + js::ProxyOptions options; + options.setLazyProto(true); + JSObject* obj = js::NewProxyObject(cx, &sandboxCallableProxyHandler, priv, + nullptr, options); + if (obj) { + js::SetProxyReservedSlot(obj, SandboxCallableProxyHandler::SandboxProxySlot, + ObjectValue(*sandboxProtoProxy)); + } + + return obj; +} + +bool WrapAccessorFunction(JSContext* cx, MutableHandleObject accessor, + HandleObject sandboxProtoProxy) { + if (!accessor) { + return true; + } + + accessor.set(WrapCallable(cx, accessor, sandboxProtoProxy)); + return !!accessor; +} + +static bool IsMaybeWrappedDOMConstructor(JSObject* obj) { + // We really care about the underlying object here, which might be wrapped in + // cross-compartment wrappers. CheckedUnwrapStatic is fine, since we just + // care whether it's a DOM constructor. + obj = js::CheckedUnwrapStatic(obj); + if (!obj) { + return false; + } + + return dom::IsDOMConstructor(obj); +} + +bool SandboxProxyHandler::getPropertyDescriptorImpl( + JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, + bool getOwn, MutableHandle<Maybe<PropertyDescriptor>> desc_) const { + JS::RootedObject obj(cx, wrappedObject(proxy)); + + MOZ_ASSERT(JS::GetCompartment(obj) == JS::GetCompartment(proxy)); + + if (getOwn) { + if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, desc_)) { + return false; + } + } else { + Rooted<JSObject*> holder(cx); + if (!JS_GetPropertyDescriptorById(cx, obj, id, desc_, &holder)) { + return false; + } + } + + if (desc_.isNothing()) { + return true; + } + + Rooted<PropertyDescriptor> desc(cx, *desc_); + + // Now fix up the getter/setter/value as needed. + if (desc.hasGetter() && !WrapAccessorFunction(cx, desc.getter(), proxy)) { + return false; + } + if (desc.hasSetter() && !WrapAccessorFunction(cx, desc.setter(), proxy)) { + return false; + } + if (desc.hasValue() && desc.value().isObject()) { + RootedObject val(cx, &desc.value().toObject()); + if (JS::IsCallable(val) && + // Don't wrap DOM constructors: they don't care about the "this" + // they're invoked with anyway, being constructors. And if we wrap + // them here we break invariants like Node == Node and whatnot. + !IsMaybeWrappedDOMConstructor(val)) { + val = WrapCallable(cx, val, proxy); + if (!val) { + return false; + } + desc.value().setObject(*val); + } + } + + desc_.set(Some(desc.get())); + return true; +} + +bool SandboxProxyHandler::getOwnPropertyDescriptor( + JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, + MutableHandle<Maybe<PropertyDescriptor>> desc) const { + return getPropertyDescriptorImpl(cx, proxy, id, /* getOwn = */ true, desc); +} + +/* + * Reuse the BaseProxyHandler versions of the derived traps that are implemented + * in terms of the fundamental traps. + */ + +bool SandboxProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, bool* bp) const { + // This uses JS_GetPropertyDescriptorById for backward compatibility. + Rooted<Maybe<PropertyDescriptor>> desc(cx); + if (!getPropertyDescriptorImpl(cx, proxy, id, /* getOwn = */ false, &desc)) { + return false; + } + + *bp = desc.isSome(); + return true; +} +bool SandboxProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, bool* bp) const { + return BaseProxyHandler::hasOwn(cx, proxy, id, bp); +} + +bool SandboxProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<JS::Value> receiver, + JS::Handle<jsid> id, + JS::MutableHandle<Value> vp) const { + // This uses JS_GetPropertyDescriptorById for backward compatibility. + Rooted<Maybe<PropertyDescriptor>> desc(cx); + if (!getPropertyDescriptorImpl(cx, proxy, id, /* getOwn = */ false, &desc)) { + return false; + } + + if (desc.isNothing()) { + vp.setUndefined(); + return true; + } else { + desc->assertComplete(); + } + + // Everything after here follows [[Get]] for ordinary objects. + if (desc->isDataDescriptor()) { + vp.set(desc->value()); + return true; + } + + MOZ_ASSERT(desc->isAccessorDescriptor()); + RootedObject getter(cx, desc->getter()); + + if (!getter) { + vp.setUndefined(); + return true; + } + + return Call(cx, receiver, getter, HandleValueArray::empty(), vp); +} + +bool SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::Handle<jsid> id, JS::Handle<Value> v, + JS::Handle<Value> receiver, + JS::ObjectOpResult& result) const { + return BaseProxyHandler::set(cx, proxy, id, v, receiver, result); +} + +bool SandboxProxyHandler::getOwnEnumerablePropertyKeys( + JSContext* cx, JS::Handle<JSObject*> proxy, + MutableHandleIdVector props) const { + return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props); +} + +bool SandboxProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy, + JS::MutableHandleIdVector props) const { + return BaseProxyHandler::enumerate(cx, proxy, props); +} + +bool xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj) { + uint32_t length; + bool ok = JS::GetArrayLength(cx, obj, &length); + NS_ENSURE_TRUE(ok, false); + for (uint32_t i = 0; i < length; i++) { + RootedValue nameValue(cx); + ok = JS_GetElement(cx, obj, i, &nameValue); + NS_ENSURE_TRUE(ok, false); + if (!nameValue.isString()) { + JS_ReportErrorASCII(cx, "Property names must be strings"); + return false; + } + JSLinearString* nameStr = JS_EnsureLinearString(cx, nameValue.toString()); + if (!nameStr) { + return false; + } + + if (JS_LinearStringEqualsLiteral(nameStr, "AbortController")) { + AbortController = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Blob")) { + Blob = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "ChromeUtils")) { + ChromeUtils = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "CSS")) { + CSS = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "CSSRule")) { + CSSRule = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Document")) { + Document = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Directory")) { + Directory = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "DOMException")) { + DOMException = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "DOMParser")) { + DOMParser = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "DOMTokenList")) { + DOMTokenList = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Element")) { + Element = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Event")) { + Event = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "File")) { + File = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "FileReader")) { + FileReader = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "FormData")) { + FormData = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Headers")) { + Headers = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "IOUtils")) { + IOUtils = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "InspectorUtils")) { + InspectorUtils = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "MessageChannel")) { + MessageChannel = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "MIDIInputMap")) { + MIDIInputMap = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "MIDIOutputMap")) { + MIDIOutputMap = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Node")) { + Node = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "NodeFilter")) { + NodeFilter = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "PathUtils")) { + PathUtils = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Performance")) { + Performance = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "PromiseDebugging")) { + PromiseDebugging = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Range")) { + Range = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Selection")) { + Selection = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "TextDecoder")) { + TextDecoder = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "TextEncoder")) { + TextEncoder = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "URL")) { + URL = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "URLSearchParams")) { + URLSearchParams = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "XMLHttpRequest")) { + XMLHttpRequest = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "WebSocket")) { + WebSocket = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "Window")) { + Window = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "XMLSerializer")) { + XMLSerializer = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "ReadableStream")) { + ReadableStream = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "atob")) { + atob = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "btoa")) { + btoa = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "caches")) { + caches = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "crypto")) { + crypto = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "fetch")) { + fetch = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "storage")) { + storage = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "structuredClone")) { + structuredClone = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "indexedDB")) { + indexedDB = true; + } else if (JS_LinearStringEqualsLiteral(nameStr, "isSecureContext")) { + isSecureContext = true; +#ifdef MOZ_WEBRTC + } else if (JS_LinearStringEqualsLiteral(nameStr, "rtcIdentityProvider")) { + rtcIdentityProvider = true; +#endif + } else { + RootedString nameStr(cx, nameValue.toString()); + JS::UniqueChars name = JS_EncodeStringToUTF8(cx, nameStr); + if (!name) { + return false; + } + + JS_ReportErrorUTF8(cx, "Unknown property name: %s", name.get()); + return false; + } + } + return true; +} + +bool xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj) { + MOZ_ASSERT(js::GetContextCompartment(cx) == JS::GetCompartment(obj)); + // Properties will be exposed to System automatically but not to Sandboxes + // if |[Exposed=System]| is specified. + // This function holds common properties not exposed automatically but able + // to be requested either in |Cu.importGlobalProperties| or + // |wantGlobalProperties| of a sandbox. + if (AbortController && + !dom::AbortController_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Blob && !dom::Blob_Binding::GetConstructorObject(cx)) return false; + + if (ChromeUtils && !dom::ChromeUtils_Binding::GetConstructorObject(cx)) { + return false; + } + + if (CSS && !dom::CSS_Binding::GetConstructorObject(cx)) { + return false; + } + + if (CSSRule && !dom::CSSRule_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Directory && !dom::Directory_Binding::GetConstructorObject(cx)) + return false; + + if (Document && !dom::Document_Binding::GetConstructorObject(cx)) { + return false; + } + + if (DOMException && !dom::DOMException_Binding::GetConstructorObject(cx)) { + return false; + } + + if (DOMParser && !dom::DOMParser_Binding::GetConstructorObject(cx)) { + return false; + } + + if (DOMTokenList && !dom::DOMTokenList_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Element && !dom::Element_Binding::GetConstructorObject(cx)) return false; + + if (Event && !dom::Event_Binding::GetConstructorObject(cx)) return false; + + if (File && !dom::File_Binding::GetConstructorObject(cx)) return false; + + if (FileReader && !dom::FileReader_Binding::GetConstructorObject(cx)) { + return false; + } + + if (FormData && !dom::FormData_Binding::GetConstructorObject(cx)) + return false; + + if (Headers && !dom::Headers_Binding::GetConstructorObject(cx)) { + return false; + } + + if (IOUtils && !dom::IOUtils_Binding::GetConstructorObject(cx)) { + return false; + } + + if (InspectorUtils && !dom::InspectorUtils_Binding::GetConstructorObject(cx)) + return false; + + if (MessageChannel && + (!dom::MessageChannel_Binding::GetConstructorObject(cx) || + !dom::MessagePort_Binding::GetConstructorObject(cx))) + return false; + + if (MIDIInputMap && !dom::MIDIInputMap_Binding::GetConstructorObject(cx)) { + return false; + } + + if (MIDIOutputMap && !dom::MIDIOutputMap_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Node && !dom::Node_Binding::GetConstructorObject(cx)) { + return false; + } + + if (NodeFilter && !dom::NodeFilter_Binding::GetConstructorObject(cx)) { + return false; + } + + if (PathUtils && !dom::PathUtils_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Performance && !dom::Performance_Binding::GetConstructorObject(cx)) { + return false; + } + + if (PromiseDebugging && + !dom::PromiseDebugging_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Range && !dom::Range_Binding::GetConstructorObject(cx)) { + return false; + } + + if (Selection && !dom::Selection_Binding::GetConstructorObject(cx)) { + return false; + } + + if (TextDecoder && !dom::TextDecoder_Binding::GetConstructorObject(cx)) + return false; + + if (TextEncoder && !dom::TextEncoder_Binding::GetConstructorObject(cx)) + return false; + + if (URL && !dom::URL_Binding::GetConstructorObject(cx)) return false; + + if (URLSearchParams && + !dom::URLSearchParams_Binding::GetConstructorObject(cx)) + return false; + + if (XMLHttpRequest && !dom::XMLHttpRequest_Binding::GetConstructorObject(cx)) + return false; + + if (WebSocket && !dom::WebSocket_Binding::GetConstructorObject(cx)) + return false; + + if (Window && !dom::Window_Binding::GetConstructorObject(cx)) return false; + + if (XMLSerializer && !dom::XMLSerializer_Binding::GetConstructorObject(cx)) + return false; + + if (ReadableStream && !dom::ReadableStream_Binding::GetConstructorObject(cx)) + return false; + + if (atob && !JS_DefineFunction(cx, obj, "atob", Atob, 1, 0)) return false; + + if (btoa && !JS_DefineFunction(cx, obj, "btoa", Btoa, 1, 0)) return false; + + if (caches && !dom::cache::CacheStorage::DefineCaches(cx, obj)) { + return false; + } + + if (crypto && !SandboxCreateCrypto(cx, obj)) { + return false; + } + + if (fetch && !SandboxCreateFetch(cx, obj)) { + return false; + } + + if (storage && !SandboxCreateStorage(cx, obj)) { + return false; + } + + if (structuredClone && !SandboxCreateStructuredClone(cx, obj)) { + return false; + } + + // Note that isSecureContext here doesn't mean the context is actually secure + // - just that the caller wants the property defined + if (isSecureContext) { + bool hasSecureContext = IsSecureContextOrObjectIsFromSecureContext(cx, obj); + JS::Rooted<JS::Value> secureJsValue(cx, JS::BooleanValue(hasSecureContext)); + return JS_DefineProperty(cx, obj, "isSecureContext", secureJsValue, + JSPROP_ENUMERATE); + } + +#ifdef MOZ_WEBRTC + if (rtcIdentityProvider && !SandboxCreateRTCIdentityProvider(cx, obj)) { + return false; + } +#endif + + return true; +} + +bool xpc::GlobalProperties::DefineInXPCComponents(JSContext* cx, + JS::HandleObject obj) { + if (indexedDB && !IndexedDatabaseManager::DefineIndexedDB(cx, obj)) + return false; + + return Define(cx, obj); +} + +bool xpc::GlobalProperties::DefineInSandbox(JSContext* cx, + JS::HandleObject obj) { + MOZ_ASSERT(IsSandbox(obj)); + MOZ_ASSERT(js::GetContextCompartment(cx) == JS::GetCompartment(obj)); + + if (indexedDB && !(IndexedDatabaseManager::ResolveSandboxBinding(cx) && + IndexedDatabaseManager::DefineIndexedDB(cx, obj))) + return false; + + return Define(cx, obj); +} + +/** + * If enabled, apply the extension base CSP, then apply the + * content script CSP which will either be a default or one + * provided by the extension in its manifest. + */ +nsresult ApplyAddonContentScriptCSP(nsISupports* prinOrSop) { + nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(prinOrSop); + if (!principal) { + return NS_OK; + } + + auto* basePrin = BasePrincipal::Cast(principal); + // We only get an addonPolicy if the principal is an + // expanded principal with an extension principal in it. + auto* addonPolicy = basePrin->ContentScriptAddonPolicy(); + if (!addonPolicy) { + return NS_OK; + } + // For backwards compatibility, content scripts have no CSP + // in manifest v2. Only apply content script CSP to V3 or later. + if (addonPolicy->ManifestVersion() < 3) { + return NS_OK; + } + + nsString url; + MOZ_TRY_VAR(url, addonPolicy->GetURL(u""_ns)); + + nsCOMPtr<nsIURI> selfURI; + MOZ_TRY(NS_NewURI(getter_AddRefs(selfURI), url)); + + const nsAString& baseCSP = addonPolicy->BaseCSP(); + + // If we got here, we're definitly an expanded principal. + auto expanded = basePrin->As<ExpandedPrincipal>(); + nsCOMPtr<nsIContentSecurityPolicy> csp; + +#ifdef MOZ_DEBUG + // Bug 1548468: Move CSP off ExpandedPrincipal + expanded->GetCsp(getter_AddRefs(csp)); + if (csp) { + uint32_t count = 0; + csp->GetPolicyCount(&count); + if (count > 0) { + // Ensure that the policy was not already added. + nsAutoString parsedPolicyStr; + for (uint32_t i = 0; i < count; i++) { + csp->GetPolicyString(i, parsedPolicyStr); + MOZ_ASSERT(!parsedPolicyStr.Equals(baseCSP)); + } + } + } +#endif + + // Create a clone of the expanded principal to be used for the call to + // SetRequestContextWithPrincipal (to prevent the CSP and expanded + // principal instances to keep each other alive indefinitely, see + // Bug 1741600). + // + // This may not be necessary anymore once Bug 1548468 will move CSP + // off ExpandedPrincipal. + RefPtr<ExpandedPrincipal> clonedPrincipal = ExpandedPrincipal::Create( + expanded->AllowList(), expanded->OriginAttributesRef()); + MOZ_ASSERT(clonedPrincipal); + + csp = new nsCSPContext(); + MOZ_TRY( + csp->SetRequestContextWithPrincipal(clonedPrincipal, selfURI, u""_ns, 0)); + + MOZ_TRY(csp->AppendPolicy(baseCSP, false, false)); + + expanded->SetCsp(csp); + return NS_OK; +} + +nsresult xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, + nsISupports* prinOrSop, + SandboxOptions& options) { + // Create the sandbox global object + nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(prinOrSop); + nsCOMPtr<nsIGlobalObject> obj = do_QueryInterface(prinOrSop); + if (obj) { + nsGlobalWindowInner* window = + WindowOrNull(js::UncheckedUnwrap(obj->GetGlobalJSObject(), false)); + // If we have a secure context window inherit from it's parent + if (window && window->IsSecureContext()) { + options.forceSecureContext = true; + } + } + if (!principal) { + nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(prinOrSop); + if (sop) { + principal = sop->GetPrincipal(); + } else { + RefPtr<NullPrincipal> nullPrin = + NullPrincipal::CreateWithoutOriginAttributes(); + principal = nullPrin; + } + } + MOZ_ASSERT(principal); + + JS::RealmOptions realmOptions; + + auto& creationOptions = realmOptions.creationOptions(); + + bool isSystemPrincipal = principal->IsSystemPrincipal(); + + if (isSystemPrincipal) { + options.forceSecureContext = true; + } + + // If we are able to see [SecureContext] API code + if (options.forceSecureContext) { + creationOptions.setSecureContext(true); + } + + xpc::SetPrefableRealmOptions(realmOptions); + if (options.sameZoneAs) { + creationOptions.setNewCompartmentInExistingZone( + js::UncheckedUnwrap(options.sameZoneAs)); + } else if (options.freshZone) { + creationOptions.setNewCompartmentAndZone(); + } else if (isSystemPrincipal && !options.invisibleToDebugger && + !options.freshCompartment) { + // Use a shared system compartment for system-principal sandboxes that don't + // require invisibleToDebugger (this is a compartment property, see bug + // 1482215). + creationOptions.setExistingCompartment(xpc::PrivilegedJunkScope()); + } else { + creationOptions.setNewCompartmentInSystemZone(); + } + + creationOptions.setInvisibleToDebugger(options.invisibleToDebugger) + .setTrace(TraceXPCGlobal); + + realmOptions.behaviors().setDiscardSource(options.discardSource); + + if (isSystemPrincipal) { + realmOptions.behaviors().setClampAndJitterTime(false); + } + + const JSClass* clasp = &SandboxClass; + + RootedObject sandbox( + cx, xpc::CreateGlobalObject(cx, clasp, principal, realmOptions)); + if (!sandbox) { + return NS_ERROR_FAILURE; + } + + // Use exclusive expandos for non-system-principal sandboxes. + bool hasExclusiveExpandos = !isSystemPrincipal; + + // Set up the wantXrays flag, which indicates whether xrays are desired even + // for same-origin access. + // + // This flag has historically been ignored for chrome sandboxes due to + // quirks in the wrapping implementation that have now been removed. Indeed, + // same-origin Xrays for chrome->chrome access seems a bit superfluous. + // Arguably we should just flip the default for chrome and still honor the + // flag, but such a change would break code in subtle ways for minimal + // benefit. So we just switch it off here. + bool wantXrays = AccessCheck::isChrome(sandbox) ? false : options.wantXrays; + + if (creationOptions.compartmentSpecifier() == + JS::CompartmentSpecifier::ExistingCompartment) { + // Make sure the compartment we're reusing has flags that match what we + // would set on a new compartment. + CompartmentPrivate* priv = CompartmentPrivate::Get(sandbox); + MOZ_RELEASE_ASSERT(priv->allowWaivers == options.allowWaivers); + MOZ_RELEASE_ASSERT(priv->isWebExtensionContentScript == + options.isWebExtensionContentScript); + MOZ_RELEASE_ASSERT(priv->isUAWidgetCompartment == options.isUAWidgetScope); + MOZ_RELEASE_ASSERT(priv->hasExclusiveExpandos == hasExclusiveExpandos); + MOZ_RELEASE_ASSERT(priv->wantXrays == wantXrays); + } else { + CompartmentPrivate* priv = CompartmentPrivate::Get(sandbox); + priv->allowWaivers = options.allowWaivers; + priv->isWebExtensionContentScript = options.isWebExtensionContentScript; + priv->isUAWidgetCompartment = options.isUAWidgetScope; + priv->hasExclusiveExpandos = hasExclusiveExpandos; + priv->wantXrays = wantXrays; + } + + { + JSAutoRealm ar(cx, sandbox); + + // This creates a SandboxPrivate and passes ownership of it to |sandbox|. + SandboxPrivate::Create(principal, sandbox); + + // Ensure |Object.prototype| is instantiated before prototype- + // splicing below. + if (!JS::GetRealmObjectPrototype(cx)) { + return NS_ERROR_XPC_UNEXPECTED; + } + + if (options.proto) { + bool ok = JS_WrapObject(cx, &options.proto); + if (!ok) { + return NS_ERROR_XPC_UNEXPECTED; + } + + // Now check what sort of thing we've got in |proto|, and figure out + // if we need a SandboxProxyHandler. + // + // Note that, in the case of a window, we can't require that the + // Sandbox subsumes the prototype, because we have to hold our + // reference to it via an outer window, and the window may navigate + // at any time. So we have to handle that case separately. + bool useSandboxProxy = + !!WindowOrNull(js::UncheckedUnwrap(options.proto, false)); + if (!useSandboxProxy) { + // We just wrapped options.proto into the compartment of whatever Realm + // is on the cx, so use that same realm for the CheckedUnwrapDynamic + // call. + JSObject* unwrappedProto = + js::CheckedUnwrapDynamic(options.proto, cx, false); + if (!unwrappedProto) { + JS_ReportErrorASCII(cx, "Sandbox must subsume sandboxPrototype"); + return NS_ERROR_INVALID_ARG; + } + const JSClass* unwrappedClass = JS::GetClass(unwrappedProto); + useSandboxProxy = unwrappedClass->isWrappedNative() || + mozilla::dom::IsDOMClass(unwrappedClass); + } + + if (useSandboxProxy) { + // Wrap it up in a proxy that will do the right thing in terms + // of this-binding for methods. + RootedValue priv(cx, ObjectValue(*options.proto)); + options.proto = + js::NewProxyObject(cx, &sandboxProxyHandler, priv, nullptr); + if (!options.proto) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + ok = JS_SetPrototype(cx, sandbox, options.proto); + if (!ok) { + return NS_ERROR_XPC_UNEXPECTED; + } + } + + bool allowComponents = principal->IsSystemPrincipal(); + if (options.wantComponents && allowComponents) { + if (!ObjectScope(sandbox)->AttachComponentsObject(cx)) { + return NS_ERROR_XPC_UNEXPECTED; + } + + if (!ObjectScope(sandbox)->AttachJSServices(cx)) { + return NS_ERROR_XPC_UNEXPECTED; + } + } + + if (!XPCNativeWrapper::AttachNewConstructorObject(cx, sandbox)) { + return NS_ERROR_XPC_UNEXPECTED; + } + + if (!JS_DefineFunctions(cx, sandbox, SandboxFunctions)) { + return NS_ERROR_XPC_UNEXPECTED; + } + + if (options.wantExportHelpers && + (!JS_DefineFunction(cx, sandbox, "exportFunction", + SandboxExportFunction, 3, 0) || + !JS_DefineFunction(cx, sandbox, "createObjectIn", + SandboxCreateObjectIn, 2, 0) || + !JS_DefineFunction(cx, sandbox, "cloneInto", SandboxCloneInto, 3, 0) || + !JS_DefineFunction(cx, sandbox, "isProxy", SandboxIsProxy, 1, 0))) + return NS_ERROR_XPC_UNEXPECTED; + + if (!options.globalProperties.DefineInSandbox(cx, sandbox)) { + return NS_ERROR_XPC_UNEXPECTED; + } + } + + // We handle the case where the context isn't in a compartment for the + // benefit of UnprivilegedJunkScope(). + vp.setObject(*sandbox); + if (js::GetContextCompartment(cx) && !JS_WrapValue(cx, vp)) { + return NS_ERROR_UNEXPECTED; + } + + // Set the location information for the new global, so that tools like + // about:memory may use that information + xpc::SetLocationForGlobal(sandbox, options.sandboxName); + + xpc::SetSandboxMetadata(cx, sandbox, options.metadata); + + JSAutoRealm ar(cx, sandbox); + JS_FireOnNewGlobalObject(cx, sandbox); + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_utils_Sandbox::Call(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +NS_IMETHODIMP +nsXPCComponents_utils_Sandbox::Construct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +/* + * For sandbox constructor the first argument can be a URI string in which case + * we use the related Content Principal for the sandbox. + */ +bool ParsePrincipal(JSContext* cx, HandleString contentUrl, + const OriginAttributes& aAttrs, nsIPrincipal** principal) { + MOZ_ASSERT(principal); + MOZ_ASSERT(contentUrl); + nsCOMPtr<nsIURI> uri; + nsAutoJSString contentStr; + NS_ENSURE_TRUE(contentStr.init(cx, contentUrl), false); + nsresult rv = NS_NewURI(getter_AddRefs(uri), contentStr); + if (NS_FAILED(rv)) { + JS_ReportErrorASCII(cx, "Creating URI from string failed"); + return false; + } + + // We could allow passing in the app-id and browser-element info to the + // sandbox constructor. But creating a sandbox based on a string is a + // deprecated API so no need to add features to it. + nsCOMPtr<nsIPrincipal> prin = + BasePrincipal::CreateContentPrincipal(uri, aAttrs); + prin.forget(principal); + + if (!*principal) { + JS_ReportErrorASCII(cx, "Creating Principal from URI failed"); + return false; + } + return true; +} + +/* + * For sandbox constructor the first argument can be a principal object or + * a script object principal (Document, Window). + */ +static bool GetPrincipalOrSOP(JSContext* cx, HandleObject from, + nsISupports** out) { + MOZ_ASSERT(out); + *out = nullptr; + + // We might have a Window here, so need ReflectorToISupportsDynamic + nsCOMPtr<nsISupports> native = ReflectorToISupportsDynamic(from, cx); + + if (nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(native)) { + sop.forget(out); + return true; + } + + nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(native); + principal.forget(out); + NS_ENSURE_TRUE(*out, false); + + return true; +} + +/* + * The first parameter of the sandbox constructor might be an array of + * principals, either in string format or actual objects (see GetPrincipalOrSOP) + */ +static bool GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, + const SandboxOptions& options, + nsIExpandedPrincipal** out) { + MOZ_ASSERT(out); + uint32_t length; + + if (!JS::GetArrayLength(cx, arrayObj, &length)) { + return false; + } + if (!length) { + // We need a whitelist of principals or uri strings to create an + // expanded principal, if we got an empty array or something else + // report error. + JS_ReportErrorASCII(cx, "Expected an array of URI strings"); + return false; + } + + nsTArray<nsCOMPtr<nsIPrincipal>> allowedDomains(length); + allowedDomains.SetLength(length); + + // If an originAttributes option has been specified, we will use that as the + // OriginAttribute of all of the string arguments passed to this function. + // Otherwise, we will use the OriginAttributes of a principal or SOP object + // in the array, if any. If no such object is present, and all we have are + // strings, then we will use a default OriginAttribute. + // Otherwise, we will use the origin attributes of the passed object(s). If + // more than one object is specified, we ensure that the OAs match. + Maybe<OriginAttributes> attrs; + if (options.originAttributes) { + attrs.emplace(); + JS::RootedValue val(cx, JS::ObjectValue(*options.originAttributes)); + if (!attrs->Init(cx, val)) { + // The originAttributes option, if specified, must be valid! + JS_ReportErrorASCII(cx, "Expected a valid OriginAttributes object"); + return false; + } + } + + // Now we go over the array in two passes. In the first pass, we ignore + // strings, and only process objects. Assuming that no originAttributes + // option has been passed, if we encounter a principal or SOP object, we + // grab its OA and save it if it's the first OA encountered, otherwise + // check to make sure that it is the same as the OA found before. + // In the second pass, we ignore objects, and use the OA found in pass 0 + // (or the previously computed OA if we have obtained it from the options) + // to construct content principals. + // + // The effective OA selected above will also be set as the OA of the + // expanded principal object. + + // First pass: + for (uint32_t i = 0; i < length; ++i) { + RootedValue allowed(cx); + if (!JS_GetElement(cx, arrayObj, i, &allowed)) { + return false; + } + + nsCOMPtr<nsIPrincipal> principal; + if (allowed.isObject()) { + // In case of object let's see if it's a Principal or a + // ScriptObjectPrincipal. + nsCOMPtr<nsISupports> prinOrSop; + RootedObject obj(cx, &allowed.toObject()); + if (!GetPrincipalOrSOP(cx, obj, getter_AddRefs(prinOrSop))) { + return false; + } + + nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(prinOrSop)); + principal = do_QueryInterface(prinOrSop); + if (sop) { + principal = sop->GetPrincipal(); + } + NS_ENSURE_TRUE(principal, false); + + if (!options.originAttributes) { + const OriginAttributes prinAttrs = principal->OriginAttributesRef(); + if (attrs.isNothing()) { + attrs.emplace(prinAttrs); + } else if (prinAttrs != attrs.ref()) { + // If attrs is from a previously encountered principal in the + // array, we need to ensure that it matches the OA of the + // principal we have here. + // If attrs comes from OriginAttributes, we don't need + // this check. + return false; + } + } + + // We do not allow ExpandedPrincipals to contain any system principals. + bool isSystem = principal->IsSystemPrincipal(); + if (isSystem) { + JS_ReportErrorASCII( + cx, "System principal is not allowed in an expanded principal"); + return false; + } + allowedDomains[i] = principal; + } else if (allowed.isString()) { + // Skip any string arguments - we handle them in the next pass. + } else { + // Don't know what this is. + return false; + } + } + + if (attrs.isNothing()) { + // If no OriginAttributes was found in the first pass, fall back to a + // default one. + attrs.emplace(); + } + + // Second pass: + for (uint32_t i = 0; i < length; ++i) { + RootedValue allowed(cx); + if (!JS_GetElement(cx, arrayObj, i, &allowed)) { + return false; + } + + nsCOMPtr<nsIPrincipal> principal; + if (allowed.isString()) { + // In case of string let's try to fetch a content principal from it. + RootedString str(cx, allowed.toString()); + + // attrs here is either a default OriginAttributes in case the + // originAttributes option isn't specified, and no object in the array + // provides a principal. Otherwise it's either the forced principal, or + // the principal found before, so we can use it here. + if (!ParsePrincipal(cx, str, attrs.ref(), getter_AddRefs(principal))) { + return false; + } + NS_ENSURE_TRUE(principal, false); + allowedDomains[i] = principal; + } else { + MOZ_ASSERT(allowed.isObject()); + } + } + + RefPtr<ExpandedPrincipal> result = + ExpandedPrincipal::Create(allowedDomains, attrs.ref()); + result.forget(out); + return true; +} + +/* + * Helper that tries to get a property from the options object. + */ +bool OptionsBase::ParseValue(const char* name, MutableHandleValue prop, + bool* aFound) { + bool found; + bool ok = JS_HasProperty(mCx, mObject, name, &found); + NS_ENSURE_TRUE(ok, false); + + if (aFound) { + *aFound = found; + } + + if (!found) { + return true; + } + + return JS_GetProperty(mCx, mObject, name, prop); +} + +/* + * Helper that tries to get a boolean property from the options object. + */ +bool OptionsBase::ParseBoolean(const char* name, bool* prop) { + MOZ_ASSERT(prop); + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!value.isBoolean()) { + JS_ReportErrorASCII(mCx, "Expected a boolean value for property %s", name); + return false; + } + + *prop = value.toBoolean(); + return true; +} + +/* + * Helper that tries to get an object property from the options object. + */ +bool OptionsBase::ParseObject(const char* name, MutableHandleObject prop) { + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!value.isObject()) { + JS_ReportErrorASCII(mCx, "Expected an object value for property %s", name); + return false; + } + prop.set(&value.toObject()); + return true; +} + +/* + * Helper that tries to get an object property from the options object. + */ +bool OptionsBase::ParseJSString(const char* name, MutableHandleString prop) { + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!value.isString()) { + JS_ReportErrorASCII(mCx, "Expected a string value for property %s", name); + return false; + } + prop.set(value.toString()); + return true; +} + +/* + * Helper that tries to get a string property from the options object. + */ +bool OptionsBase::ParseString(const char* name, nsCString& prop) { + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!value.isString()) { + JS_ReportErrorASCII(mCx, "Expected a string value for property %s", name); + return false; + } + + JS::UniqueChars tmp = JS_EncodeStringToLatin1(mCx, value.toString()); + NS_ENSURE_TRUE(tmp, false); + prop.Assign(tmp.get(), strlen(tmp.get())); + return true; +} + +/* + * Helper that tries to get a string property from the options object. + */ +bool OptionsBase::ParseString(const char* name, nsString& prop) { + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!value.isString()) { + JS_ReportErrorASCII(mCx, "Expected a string value for property %s", name); + return false; + } + + nsAutoJSString strVal; + if (!strVal.init(mCx, value.toString())) { + return false; + } + + prop = strVal; + return true; +} + +/* + * Helper that tries to get jsid property from the options object. + */ +bool OptionsBase::ParseId(const char* name, MutableHandleId prop) { + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + return JS_ValueToId(mCx, value, prop); +} + +/* + * Helper that tries to get a uint32_t property from the options object. + */ +bool OptionsBase::ParseUInt32(const char* name, uint32_t* prop) { + MOZ_ASSERT(prop); + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) { + return true; + } + + if (!JS::ToUint32(mCx, value, prop)) { + JS_ReportErrorASCII(mCx, "Expected a uint32_t value for property %s", name); + return false; + } + + return true; +} + +/* + * Helper that tries to get a list of DOM constructors and other helpers from + * the options object. + */ +bool SandboxOptions::ParseGlobalProperties() { + RootedValue value(mCx); + bool found; + bool ok = ParseValue("wantGlobalProperties", &value, &found); + NS_ENSURE_TRUE(ok, false); + if (!found) { + return true; + } + + if (!value.isObject()) { + JS_ReportErrorASCII(mCx, + "Expected an array value for wantGlobalProperties"); + return false; + } + + RootedObject ctors(mCx, &value.toObject()); + bool isArray; + if (!JS::IsArrayObject(mCx, ctors, &isArray)) { + return false; + } + if (!isArray) { + JS_ReportErrorASCII(mCx, + "Expected an array value for wantGlobalProperties"); + return false; + } + + return globalProperties.Parse(mCx, ctors); +} + +/* + * Helper that parsing the sandbox options object (from) and sets the fields of + * the incoming options struct (options). + */ +bool SandboxOptions::Parse() { + /* All option names must be ASCII-only. */ + bool ok = ParseObject("sandboxPrototype", &proto) && + ParseBoolean("wantXrays", &wantXrays) && + ParseBoolean("allowWaivers", &allowWaivers) && + ParseBoolean("wantComponents", &wantComponents) && + ParseBoolean("wantExportHelpers", &wantExportHelpers) && + ParseBoolean("isWebExtensionContentScript", + &isWebExtensionContentScript) && + ParseBoolean("forceSecureContext", &forceSecureContext) && + ParseString("sandboxName", sandboxName) && + ParseObject("sameZoneAs", &sameZoneAs) && + ParseBoolean("freshCompartment", &freshCompartment) && + ParseBoolean("freshZone", &freshZone) && + ParseBoolean("invisibleToDebugger", &invisibleToDebugger) && + ParseBoolean("discardSource", &discardSource) && + ParseGlobalProperties() && ParseValue("metadata", &metadata) && + ParseUInt32("userContextId", &userContextId) && + ParseObject("originAttributes", &originAttributes); + if (!ok) { + return false; + } + + if (freshZone && sameZoneAs) { + JS_ReportErrorASCII(mCx, "Cannot use both sameZoneAs and freshZone"); + return false; + } + + return true; +} + +static nsresult AssembleSandboxMemoryReporterName(JSContext* cx, + nsCString& sandboxName) { + // Use a default name when the caller did not provide a sandboxName. + if (sandboxName.IsEmpty()) { + sandboxName = "[anonymous sandbox]"_ns; + } else { +#ifndef DEBUG + // Adding the caller location is fairly expensive, so in non-debug + // builds, only add it if we don't have an explicit sandbox name. + return NS_OK; +#endif + } + + // Get the xpconnect native call context. + XPCCallContext* cc = XPCJSContext::Get()->GetCallContext(); + NS_ENSURE_TRUE(cc, NS_ERROR_INVALID_ARG); + + // Get the current source info from xpc. + nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack(); + + // Append the caller's location information. + if (frame) { + nsString location; + frame->GetFilename(cx, location); + int32_t lineNumber = frame->GetLineNumber(cx); + + sandboxName.AppendLiteral(" (from: "); + sandboxName.Append(NS_ConvertUTF16toUTF8(location)); + sandboxName.Append(':'); + sandboxName.AppendInt(lineNumber); + sandboxName.Append(')'); + } + + return NS_OK; +} + +// static +nsresult nsXPCComponents_utils_Sandbox::CallOrConstruct( + nsIXPConnectWrappedNative* wrapper, JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval) { + if (args.length() < 1) { + return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval); + } + + nsresult rv; + bool ok = false; + bool calledWithOptions = args.length() > 1; + if (calledWithOptions && !args[1].isObject()) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + RootedObject optionsObject(cx, + calledWithOptions ? &args[1].toObject() : nullptr); + + SandboxOptions options(cx, optionsObject); + if (calledWithOptions && !options.Parse()) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + // Make sure to set up principals on the sandbox before initing classes. + nsCOMPtr<nsIPrincipal> principal; + nsCOMPtr<nsIExpandedPrincipal> expanded; + nsCOMPtr<nsISupports> prinOrSop; + + if (args[0].isString()) { + RootedString str(cx, args[0].toString()); + OriginAttributes attrs; + if (options.originAttributes) { + JS::RootedValue val(cx, JS::ObjectValue(*options.originAttributes)); + if (!attrs.Init(cx, val)) { + // The originAttributes option, if specified, must be valid! + JS_ReportErrorASCII(cx, "Expected a valid OriginAttributes object"); + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + } + attrs.mUserContextId = options.userContextId; + ok = ParsePrincipal(cx, str, attrs, getter_AddRefs(principal)); + prinOrSop = principal; + } else if (args[0].isObject()) { + RootedObject obj(cx, &args[0].toObject()); + bool isArray; + if (!JS::IsArrayObject(cx, obj, &isArray)) { + ok = false; + } else if (isArray) { + if (options.userContextId != 0) { + // We don't support passing a userContextId with an array. + ok = false; + } else { + ok = GetExpandedPrincipal(cx, obj, options, getter_AddRefs(expanded)); + prinOrSop = expanded; + // If this is an addon content script we need to apply the csp. + MOZ_TRY(ApplyAddonContentScriptCSP(prinOrSop)); + } + } else { + ok = GetPrincipalOrSOP(cx, obj, getter_AddRefs(prinOrSop)); + } + } else if (args[0].isNull()) { + // Null means that we just pass prinOrSop = nullptr, and get an + // NullPrincipal. + ok = true; + } + + if (!ok) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + if (NS_FAILED(AssembleSandboxMemoryReporterName(cx, options.sandboxName))) { + return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval); + } + + if (options.metadata.isNullOrUndefined()) { + // If the caller is running in a sandbox, inherit. + RootedObject callerGlobal(cx, JS::GetScriptedCallerGlobal(cx)); + if (IsSandbox(callerGlobal)) { + rv = GetSandboxMetadata(cx, callerGlobal, &options.metadata); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + } + + rv = CreateSandboxObject(cx, args.rval(), prinOrSop, options); + + if (NS_FAILED(rv)) { + return ThrowAndFail(rv, cx, _retval); + } + + *_retval = true; + return NS_OK; +} + +nsresult xpc::EvalInSandbox(JSContext* cx, HandleObject sandboxArg, + const nsAString& source, const nsACString& filename, + int32_t lineNo, bool enforceFilenameRestrictions, + MutableHandleValue rval) { + JS_AbortIfWrongThread(cx); + rval.set(UndefinedValue()); + + bool waiveXray = xpc::WrapperFactory::HasWaiveXrayFlag(sandboxArg); + // CheckedUnwrapStatic is fine here, since we're checking for "is it a + // sandbox". + RootedObject sandbox(cx, js::CheckedUnwrapStatic(sandboxArg)); + if (!sandbox || !IsSandbox(sandbox)) { + return NS_ERROR_INVALID_ARG; + } + + SandboxPrivate* priv = SandboxPrivate::GetPrivate(sandbox); + nsIScriptObjectPrincipal* sop = priv; + MOZ_ASSERT(sop, "Invalid sandbox passed"); + nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal(); + NS_ENSURE_TRUE(prin, NS_ERROR_FAILURE); + + nsAutoCString filenameBuf; + if (!filename.IsVoid() && filename.Length() != 0) { + filenameBuf.Assign(filename); + } else { + // Default to the spec of the principal. + nsresult rv = nsJSPrincipals::get(prin)->GetScriptLocation(filenameBuf); + NS_ENSURE_SUCCESS(rv, rv); + lineNo = 1; + } + + // We create a separate cx to do the sandbox evaluation. Scope it. + RootedValue v(cx, UndefinedValue()); + RootedValue exn(cx, UndefinedValue()); + bool ok = true; + { + // We're about to evaluate script, so make an AutoEntryScript. + // This is clearly Gecko-specific and not in any spec. + mozilla::dom::AutoEntryScript aes(priv, "XPConnect sandbox evaluation"); + JSContext* sandcx = aes.cx(); + JSAutoRealm ar(sandcx, sandbox); + + JS::CompileOptions options(sandcx); + options.setFileAndLine(filenameBuf.get(), lineNo); + options.setSkipFilenameValidation(!enforceFilenameRestrictions); + MOZ_ASSERT(JS_IsGlobalObject(sandbox)); + + const nsPromiseFlatString& flat = PromiseFlatString(source); + + JS::SourceText<char16_t> buffer; + ok = buffer.init(sandcx, flat.get(), flat.Length(), + JS::SourceOwnership::Borrowed) && + JS::Evaluate(sandcx, options, buffer, &v); + + // If the sandbox threw an exception, grab it off the context. + if (aes.HasException()) { + if (!aes.StealException(&exn)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + } + + // + // Alright, we're back on the caller's cx. If an error occured, try to + // wrap and set the exception. Otherwise, wrap the return value. + // + + if (!ok) { + // If we end up without an exception, it was probably due to OOM along + // the way, in which case we thow. Otherwise, wrap it. + if (exn.isUndefined() || !JS_WrapValue(cx, &exn)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // Set the exception on our caller's cx. + JS_SetPendingException(cx, exn); + return NS_ERROR_FAILURE; + } + + // Transitively apply Xray waivers if |sb| was waived. + if (waiveXray) { + ok = xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v); + } else { + ok = JS_WrapValue(cx, &v); + } + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); + + // Whew! + rval.set(v); + return NS_OK; +} + +nsresult xpc::GetSandboxMetadata(JSContext* cx, HandleObject sandbox, + MutableHandleValue rval) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(IsSandbox(sandbox)); + + RootedValue metadata(cx); + { + JSAutoRealm ar(cx, sandbox); + metadata = + JS::GetReservedSlot(sandbox, XPCONNECT_SANDBOX_CLASS_METADATA_SLOT); + } + + if (!JS_WrapValue(cx, &metadata)) { + return NS_ERROR_UNEXPECTED; + } + + rval.set(metadata); + return NS_OK; +} + +nsresult xpc::SetSandboxMetadata(JSContext* cx, HandleObject sandbox, + HandleValue metadataArg) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(IsSandbox(sandbox)); + + RootedValue metadata(cx); + + JSAutoRealm ar(cx, sandbox); + if (!JS_StructuredClone(cx, metadataArg, &metadata, nullptr, nullptr)) { + return NS_ERROR_UNEXPECTED; + } + + JS_SetReservedSlot(sandbox, XPCONNECT_SANDBOX_CLASS_METADATA_SLOT, metadata); + + return NS_OK; +} + +ModuleLoaderBase* SandboxPrivate::GetModuleLoader(JSContext* aCx) { + if (mModuleLoader) { + return mModuleLoader; + } + + JSObject* object = GetGlobalJSObject(); + nsGlobalWindowInner* sandboxWindow = xpc::SandboxWindowOrNull(object, aCx); + if (!sandboxWindow) { + return nullptr; + } + + ModuleLoader* mainModuleLoader = + static_cast<ModuleLoader*>(sandboxWindow->GetModuleLoader(aCx)); + + ScriptLoader* scriptLoader = mainModuleLoader->GetScriptLoader(); + + ModuleLoader* moduleLoader = + new ModuleLoader(scriptLoader, this, ModuleLoader::WebExtension); + scriptLoader->RegisterContentScriptModuleLoader(moduleLoader); + mModuleLoader = moduleLoader; + + return moduleLoader; +} + +mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> +SandboxPrivate::GetStorageKey() { + MOZ_ASSERT(NS_IsMainThread()); + + mozilla::ipc::PrincipalInfo principalInfo; + nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &principalInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { + return mozilla::Err(rv); + } + + // Block expanded and null principals, let content and system through. + if (principalInfo.type() != + mozilla::ipc::PrincipalInfo::TContentPrincipalInfo && + principalInfo.type() != + mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) { + return Err(NS_ERROR_DOM_SECURITY_ERR); + } + + return std::move(principalInfo); +} diff --git a/js/xpconnect/src/SandboxPrivate.h b/js/xpconnect/src/SandboxPrivate.h new file mode 100644 index 0000000000..345893864d --- /dev/null +++ b/js/xpconnect/src/SandboxPrivate.h @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __SANDBOXPRIVATE_H__ +#define __SANDBOXPRIVATE_H__ + +#include "mozilla/WeakPtr.h" +#include "mozilla/StaticPrefs_dom.h" +#include "mozilla/StorageAccess.h" +#include "mozilla/net/CookieJarSettings.h" +#include "nsContentUtils.h" +#include "nsIGlobalObject.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsIPrincipal.h" +#include "nsGlobalWindowInner.h" +#include "nsWeakReference.h" +#include "nsWrapperCache.h" + +#include "js/loader/ModuleLoaderBase.h" + +#include "js/Object.h" // JS::GetPrivate, JS::SetPrivate +#include "js/RootingAPI.h" + +class SandboxPrivate : public nsIGlobalObject, + public nsIScriptObjectPrincipal, + public nsSupportsWeakReference, + public mozilla::SupportsWeakPtr, + public nsWrapperCache { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(SandboxPrivate, + nsIGlobalObject) + + static void Create(nsIPrincipal* principal, JS::Handle<JSObject*> global) { + RefPtr<SandboxPrivate> sbp = new SandboxPrivate(principal); + sbp->SetWrapper(global); + sbp->PreserveWrapper(ToSupports(sbp.get())); + + // Pass on ownership of sbp to |global|. + // The type used to cast to void needs to match the one in GetPrivate. + nsIScriptObjectPrincipal* sop = + static_cast<nsIScriptObjectPrincipal*>(sbp.forget().take()); + JS::SetObjectISupports(global, sop); + } + + static SandboxPrivate* GetPrivate(JSObject* obj) { + // The type used to cast to void needs to match the one in Create. + nsIScriptObjectPrincipal* sop = + JS::GetObjectISupports<nsIScriptObjectPrincipal>(obj); + return static_cast<SandboxPrivate*>(sop); + } + + mozilla::OriginTrials Trials() const final { return {}; } + + nsIPrincipal* GetPrincipal() override { return mPrincipal; } + + nsIPrincipal* GetEffectiveCookiePrincipal() override { return mPrincipal; } + + nsIPrincipal* GetEffectiveStoragePrincipal() override { return mPrincipal; } + + nsIPrincipal* PartitionedPrincipal() override { return mPrincipal; } + + JSObject* GetGlobalJSObject() override { return GetWrapper(); } + JSObject* GetGlobalJSObjectPreserveColor() const override { + return GetWrapperPreserveColor(); + } + + mozilla::StorageAccess GetStorageAccess() final { + MOZ_ASSERT(NS_IsMainThread()); + if (mozilla::StaticPrefs::dom_serviceWorkers_testing_enabled()) { + // XXX: This is a hack to workaround bug 1732159 and is not intended + return mozilla::StorageAccess::eAllow; + } + nsCOMPtr<nsICookieJarSettings> cookieJarSettings = + mozilla::net::CookieJarSettings::Create(mPrincipal); + return mozilla::StorageAllowedForServiceWorker(mPrincipal, + cookieJarSettings); + } + + void ForgetGlobalObject(JSObject* obj) { ClearWrapper(obj); } + + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle<JSObject*> aGivenProto) override { + MOZ_CRASH("SandboxPrivate doesn't use DOM bindings!"); + } + + JS::loader::ModuleLoaderBase* GetModuleLoader(JSContext* aCx) override; + + mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> GetStorageKey() + override; + + size_t ObjectMoved(JSObject* obj, JSObject* old) { + UpdateWrapper(obj, old); + return 0; + } + + bool ShouldResistFingerprinting( + RFPTarget aTarget = RFPTarget::Unknown) const override { + return nsContentUtils::ShouldResistFingerprinting( + "Presently we don't have enough context to make an informed decision" + "on JS Sandboxes. See 1782853", + aTarget); + } + + private: + explicit SandboxPrivate(nsIPrincipal* principal) : mPrincipal(principal) {} + + virtual ~SandboxPrivate() = default; + + nsCOMPtr<nsIPrincipal> mPrincipal; + + RefPtr<JS::loader::ModuleLoaderBase> mModuleLoader; +}; + +#endif // __SANDBOXPRIVATE_H__ diff --git a/js/xpconnect/src/XPCCallContext.cpp b/js/xpconnect/src/XPCCallContext.cpp new file mode 100644 index 0000000000..b7da79ba9a --- /dev/null +++ b/js/xpconnect/src/XPCCallContext.cpp @@ -0,0 +1,218 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Call context. */ + +#include "xpcprivate.h" +#include "jsfriendapi.h" +#include "js/Object.h" // JS::GetClass, JS::GetReservedSlot +#include "js/Wrapper.h" +#include "nsContentUtils.h" + +using namespace mozilla; +using namespace xpc; +using namespace JS; + +static inline bool IsTearoffClass(const JSClass* clazz) { + return clazz == &XPC_WN_Tearoff_JSClass; +} + +XPCCallContext::XPCCallContext( + JSContext* cx, HandleObject obj /* = nullptr */, + HandleObject funobj /* = nullptr */, + HandleId name /* = JSID_VOID */, unsigned argc /* = NO_ARGS */, + Value* argv /* = nullptr */, Value* rval /* = nullptr */) + : mState(INIT_FAILED), + mXPC(nsXPConnect::XPConnect()), + mXPCJSContext(nullptr), + mJSContext(cx), + mWrapper(nullptr), + mTearOff(nullptr), + mMember(nullptr), + mName(cx), + mStaticMemberIsLocal(false), + mArgc(0), + mArgv(nullptr), + mRetVal(nullptr) { + MOZ_ASSERT(cx); + MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext()); + + if (!mXPC) { + return; + } + + mXPCJSContext = XPCJSContext::Get(); + + // hook into call context chain. + mPrevCallContext = mXPCJSContext->SetCallContext(this); + + mState = HAVE_CONTEXT; + + if (!obj) { + return; + } + + mMethodIndex = 0xDEAD; + + mState = HAVE_OBJECT; + + mTearOff = nullptr; + + JSObject* unwrapped = + js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false); + if (!unwrapped) { + JS_ReportErrorASCII(mJSContext, + "Permission denied to call method on |this|"); + mState = INIT_FAILED; + return; + } + const JSClass* clasp = JS::GetClass(unwrapped); + if (clasp->isWrappedNative()) { + mWrapper = XPCWrappedNative::Get(unwrapped); + } else if (IsTearoffClass(clasp)) { + mTearOff = XPCWrappedNativeTearOff::Get(unwrapped); + mWrapper = XPCWrappedNative::Get( + &JS::GetReservedSlot(unwrapped, XPCWrappedNativeTearOff::FlatObjectSlot) + .toObject()); + } + if (mWrapper && !mTearOff) { + mScriptable = mWrapper->GetScriptable(); + } + + if (!name.isVoid()) { + SetName(name); + } + + if (argc != NO_ARGS) { + SetArgsAndResultPtr(argc, argv, rval); + } + + CHECK_STATE(HAVE_OBJECT); +} + +void XPCCallContext::SetName(jsid name) { + CHECK_STATE(HAVE_OBJECT); + + mName = name; + + if (mTearOff) { + mSet = nullptr; + mInterface = mTearOff->GetInterface(); + mMember = mInterface->FindMember(mName); + mStaticMemberIsLocal = true; + if (mMember && !mMember->IsConstant()) { + mMethodIndex = mMember->GetIndex(); + } + } else { + mSet = mWrapper ? mWrapper->GetSet() : nullptr; + + if (mSet && + mSet->FindMember( + mName, &mMember, &mInterface, + mWrapper->HasProto() ? mWrapper->GetProto()->GetSet() : nullptr, + &mStaticMemberIsLocal)) { + if (mMember && !mMember->IsConstant()) { + mMethodIndex = mMember->GetIndex(); + } + } else { + mMember = nullptr; + mInterface = nullptr; + mStaticMemberIsLocal = false; + } + } + + mState = HAVE_NAME; +} + +void XPCCallContext::SetCallInfo(XPCNativeInterface* iface, + XPCNativeMember* member, bool isSetter) { + CHECK_STATE(HAVE_CONTEXT); + + // We are going straight to the method info and need not do a lookup + // by id. + + // don't be tricked if method is called with wrong 'this' + if (mTearOff && mTearOff->GetInterface() != iface) { + mTearOff = nullptr; + } + + mSet = nullptr; + mInterface = iface; + mMember = member; + mMethodIndex = mMember->GetIndex() + (isSetter ? 1 : 0); + mName = mMember->GetName(); + + if (mState < HAVE_NAME) { + mState = HAVE_NAME; + } +} + +void XPCCallContext::SetArgsAndResultPtr(unsigned argc, Value* argv, + Value* rval) { + CHECK_STATE(HAVE_OBJECT); + + if (mState < HAVE_NAME) { + mSet = nullptr; + mInterface = nullptr; + mMember = nullptr; + mStaticMemberIsLocal = false; + } + + mArgc = argc; + mArgv = argv; + mRetVal = rval; + + mState = HAVE_ARGS; +} + +nsresult XPCCallContext::CanCallNow() { + nsresult rv; + + if (!HasInterfaceAndMember()) { + return NS_ERROR_UNEXPECTED; + } + if (mState < HAVE_ARGS) { + return NS_ERROR_UNEXPECTED; + } + + if (!mTearOff) { + mTearOff = mWrapper->FindTearOff(mJSContext, mInterface, false, &rv); + if (!mTearOff || mTearOff->GetInterface() != mInterface) { + mTearOff = nullptr; + return NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED; + } + } + + // Refresh in case FindTearOff extended the set + mSet = mWrapper->GetSet(); + + mState = READY_TO_CALL; + return NS_OK; +} + +void XPCCallContext::SystemIsBeingShutDown() { + // XXX This is pretty questionable since the per thread cleanup stuff + // can be making this call on one thread for call contexts on another + // thread. + NS_WARNING( + "Shutting Down XPConnect even through there is a live XPCCallContext"); + mXPCJSContext = nullptr; + mState = SYSTEM_SHUTDOWN; + mSet = nullptr; + mInterface = nullptr; + + if (mPrevCallContext) { + mPrevCallContext->SystemIsBeingShutDown(); + } +} + +XPCCallContext::~XPCCallContext() { + if (mXPCJSContext) { + DebugOnly<XPCCallContext*> old = + mXPCJSContext->SetCallContext(mPrevCallContext); + MOZ_ASSERT(old == this, "bad pop from per thread data"); + } +} diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp new file mode 100644 index 0000000000..77df85b5f8 --- /dev/null +++ b/js/xpconnect/src/XPCComponents.cpp @@ -0,0 +1,2665 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* The "Components" xpcom objects for JavaScript. */ + +#include "xpcprivate.h" +#include "xpc_make_class.h" +#include "JSServices.h" +#include "XPCJSWeakReference.h" +#include "AccessCheck.h" +#include "WrapperFactory.h" +#include "nsJSUtils.h" +#include "mozJSModuleLoader.h" +#include "nsContentUtils.h" +#include "nsCycleCollector.h" +#include "jsfriendapi.h" +#include "js/Array.h" // JS::IsArrayObject +#include "js/CallAndConstruct.h" // JS::IsCallable, JS_CallFunctionName, JS_CallFunctionValue +#include "js/CharacterEncoding.h" +#include "js/ContextOptions.h" +#include "js/friend/WindowProxy.h" // js::ToWindowProxyIfWindow +#include "js/Object.h" // JS::GetClass, JS::GetCompartment +#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_SetProperty, JS_SetPropertyById +#include "js/SavedFrameAPI.h" +#include "js/StructuredClone.h" +#include "mozilla/AppShutdown.h" +#include "mozilla/Attributes.h" +#include "mozilla/LoadContext.h" +#include "mozilla/Preferences.h" +#include "nsJSEnvironment.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/URLPreloader.h" +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/DOMExceptionBinding.h" +#include "mozilla/dom/Exceptions.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/RemoteObjectProxy.h" +#include "mozilla/dom/StructuredCloneTags.h" +#include "mozilla/dom/WindowBinding.h" +#include "nsZipArchive.h" +#include "nsWindowMemoryReporter.h" +#include "nsICycleCollectorListener.h" +#include "nsIException.h" +#include "nsIScriptError.h" +#include "nsPIDOMWindow.h" +#include "nsGlobalWindow.h" +#include "nsScriptError.h" +#include "GeckoProfiler.h" +#include "ProfilerControl.h" +#include "mozilla/EditorSpellCheck.h" +#include "nsCommandLine.h" +#include "nsCommandParams.h" +#include "nsPersistentProperties.h" +#include "nsIDocumentEncoder.h" + +using namespace mozilla; +using namespace JS; +using namespace js; +using namespace xpc; +using mozilla::dom::Exception; + +/***************************************************************************/ +// stuff used by all + +nsresult xpc::ThrowAndFail(nsresult errNum, JSContext* cx, bool* retval) { + XPCThrower::Throw(errNum, cx); + *retval = false; + return NS_OK; +} + +static bool JSValIsInterfaceOfType(JSContext* cx, HandleValue v, REFNSIID iid) { + nsCOMPtr<nsIXPConnectWrappedNative> wn; + nsCOMPtr<nsISupports> iface; + + if (v.isPrimitive()) { + return false; + } + + nsIXPConnect* xpc = nsIXPConnect::XPConnect(); + RootedObject obj(cx, &v.toObject()); + return NS_SUCCEEDED( + xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && + wn && + NS_SUCCEEDED( + wn->Native()->QueryInterface(iid, getter_AddRefs(iface))) && + iface; +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +class nsXPCComponents_Interfaces final : public nsIXPCComponents_Interfaces, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_INTERFACES + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_Interfaces(); + + private: + virtual ~nsXPCComponents_Interfaces(); +}; + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Interfaces), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_Interfaces"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_Interfaces::nsXPCComponents_Interfaces() = default; + +nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_Interfaces, nsIXPCComponents_Interfaces, + nsIXPCScriptable, nsIClassInfo); + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Interfaces +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Interfaces" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + JS::MutableHandleIdVector properties, + bool enumerableOnly, bool* _retval) { + if (!properties.reserve(nsXPTInterfaceInfo::InterfaceCount())) { + *_retval = false; + return NS_OK; + } + + for (uint32_t index = 0; index < nsXPTInterfaceInfo::InterfaceCount(); + index++) { + const nsXPTInterfaceInfo* interface = nsXPTInterfaceInfo::ByIndex(index); + if (!interface) { + continue; + } + + const char* name = interface->Name(); + if (!name) { + continue; + } + + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); + if (!idstr) { + *_retval = false; + return NS_OK; + } + + RootedId id(cx); + if (!JS_StringToId(cx, idstr, &id)) { + *_retval = false; + return NS_OK; + } + + properties.infallibleAppend(id); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Interfaces::Resolve(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, jsid idArg, + bool* resolvedp, bool* _retval) { + RootedObject obj(cx, objArg); + RootedId id(cx, idArg); + + if (!id.isString()) { + return NS_OK; + } + + RootedString str(cx, id.toString()); + JS::UniqueChars name = JS_EncodeStringToLatin1(cx, str); + + // we only allow interfaces by name here + if (name && name[0] != '{') { + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name.get()); + if (!info) { + return NS_OK; + } + + RootedValue iidv(cx); + if (xpc::IfaceID2JSValue(cx, *info, &iidv)) { + *resolvedp = true; + *_retval = JS_DefinePropertyById(cx, obj, id, iidv, + JSPROP_ENUMERATE | JSPROP_READONLY | + JSPROP_PERMANENT | JSPROP_RESOLVING); + } + } + return NS_OK; +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +class nsXPCComponents_Classes final : public nsIXPCComponents_Classes, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_CLASSES + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_Classes(); + + private: + virtual ~nsXPCComponents_Classes(); +}; + +/***************************************************************************/ +NS_IMETHODIMP +nsXPCComponents_Classes::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Classes), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_Classes"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_Classes::nsXPCComponents_Classes() = default; + +nsXPCComponents_Classes::~nsXPCComponents_Classes() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_Classes, nsIXPCComponents_Classes, + nsIXPCScriptable, nsIClassInfo) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Classes +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Classes" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + JS::MutableHandleIdVector properties, + bool enumerableOnly, bool* _retval) { + nsCOMPtr<nsIComponentRegistrar> compMgr; + if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || + !compMgr) { + return NS_ERROR_UNEXPECTED; + } + + nsTArray<nsCString> contractIDs; + if (NS_FAILED(compMgr->GetContractIDs(contractIDs))) { + return NS_ERROR_UNEXPECTED; + } + + for (const auto& name : contractIDs) { + RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length())); + if (!idstr) { + *_retval = false; + return NS_OK; + } + + RootedId id(cx); + if (!JS_StringToId(cx, idstr, &id)) { + *_retval = false; + return NS_OK; + } + + if (!properties.append(id)) { + *_retval = false; + return NS_OK; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Classes::Resolve(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, jsid idArg, + bool* resolvedp, bool* _retval) + +{ + RootedId id(cx, idArg); + RootedObject obj(cx, objArg); + + RootedValue cidv(cx); + if (id.isString() && xpc::ContractID2JSValue(cx, id.toString(), &cidv)) { + *resolvedp = true; + *_retval = JS_DefinePropertyById(cx, obj, id, cidv, + JSPROP_ENUMERATE | JSPROP_READONLY | + JSPROP_PERMANENT | JSPROP_RESOLVING); + } + return NS_OK; +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +// Currently the possible results do not change at runtime, so they are only +// cached once (unlike ContractIDs, CLSIDs, and IIDs) + +class nsXPCComponents_Results final : public nsIXPCComponents_Results, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_RESULTS + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_Results(); + + private: + virtual ~nsXPCComponents_Results(); +}; + +/***************************************************************************/ +NS_IMETHODIMP +nsXPCComponents_Results::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Results), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_Results"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_Results::nsXPCComponents_Results() = default; + +nsXPCComponents_Results::~nsXPCComponents_Results() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_Results, nsIXPCComponents_Results, + nsIXPCScriptable, nsIClassInfo) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Results +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Results" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + JS::MutableHandleIdVector properties, + bool enumerableOnly, bool* _retval) { + const char* name; + const void* iter = nullptr; + while (nsXPCException::IterateNSResults(nullptr, &name, nullptr, &iter)) { + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); + if (!idstr) { + *_retval = false; + return NS_OK; + } + + RootedId id(cx); + if (!JS_StringToId(cx, idstr, &id)) { + *_retval = false; + return NS_OK; + } + + if (!properties.append(id)) { + *_retval = false; + return NS_OK; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Results::Resolve(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, jsid idArg, + bool* resolvedp, bool* _retval) { + RootedObject obj(cx, objArg); + RootedId id(cx, idArg); + if (!id.isString()) { + return NS_OK; + } + + JS::UniqueChars name = JS_EncodeStringToLatin1(cx, id.toString()); + if (name) { + const char* rv_name; + const void* iter = nullptr; + nsresult rv; + while (nsXPCException::IterateNSResults(&rv, &rv_name, nullptr, &iter)) { + if (!strcmp(name.get(), rv_name)) { + *resolvedp = true; + if (!JS_DefinePropertyById(cx, obj, id, (uint32_t)rv, + JSPROP_ENUMERATE | JSPROP_READONLY | + JSPROP_PERMANENT | JSPROP_RESOLVING)) { + return NS_ERROR_UNEXPECTED; + } + } + } + } + return NS_OK; +} + +/***************************************************************************/ +// JavaScript Constructor for nsIJSID objects (Components.ID) + +class nsXPCComponents_ID final : public nsIXPCComponents_ID, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_ID + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_ID(); + + private: + virtual ~nsXPCComponents_ID(); + static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval); +}; + +/***************************************************************************/ +NS_IMETHODIMP +nsXPCComponents_ID::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_ID), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_ID"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_ID::nsXPCComponents_ID() = default; + +nsXPCComponents_ID::~nsXPCComponents_ID() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_ID, nsIXPCComponents_ID, nsIXPCScriptable, + nsIClassInfo) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_ID +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ID" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_CALL | XPC_SCRIPTABLE_WANT_CONSTRUCT | \ + XPC_SCRIPTABLE_WANT_HASINSTANCE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_ID::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, + JSObject* objArg, const CallArgs& args, + bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +NS_IMETHODIMP +nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, + JSObject* objArg, const CallArgs& args, + bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +// static +nsresult nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, HandleObject obj, + const CallArgs& args, + bool* _retval) { + // make sure we have at least one arg + + if (args.length() < 1) { + return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval); + } + + // Prevent non-chrome code from creating ID objects. + if (!nsContentUtils::IsCallerChrome()) { + return ThrowAndFail(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, cx, _retval); + } + + // convert the first argument into a string and see if it looks like an id + + JSString* jsstr = ToString(cx, args[0]); + if (!jsstr) { + return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval); + } + + JS::UniqueChars bytes = JS_EncodeStringToLatin1(cx, jsstr); + if (!bytes) { + return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval); + } + + nsID id; + if (!id.Parse(bytes.get())) { + return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval); + } + + // make the new object and return it. + + if (!xpc::ID2JSValue(cx, id, args.rval())) { + return NS_ERROR_UNEXPECTED; + } + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, HandleValue val, + bool* bp, bool* _retval) { + if (bp) { + *bp = xpc::JSValue2ID(cx, val).isSome(); + } + return NS_OK; +} + +/***************************************************************************/ +// JavaScript Constructor for Exception objects (Components.Exception) + +class nsXPCComponents_Exception final : public nsIXPCComponents_Exception, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_EXCEPTION + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_Exception(); + + private: + virtual ~nsXPCComponents_Exception(); + static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval); +}; + +/***************************************************************************/ +NS_IMETHODIMP +nsXPCComponents_Exception::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Exception), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_Exception"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_Exception::nsXPCComponents_Exception() = default; + +nsXPCComponents_Exception::~nsXPCComponents_Exception() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_Exception, nsIXPCComponents_Exception, + nsIXPCScriptable, nsIClassInfo) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Exception +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Exception" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_CALL | XPC_SCRIPTABLE_WANT_CONSTRUCT | \ + XPC_SCRIPTABLE_WANT_HASINSTANCE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +NS_IMETHODIMP +nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +struct MOZ_STACK_CLASS ExceptionArgParser { + ExceptionArgParser(JSContext* context, nsIXPConnect* xpconnect) + : eMsg("exception"), + eResult(NS_ERROR_FAILURE), + cx(context), + xpc(xpconnect) {} + + // Public exception parameter values. During construction, these are + // initialized to the appropriate defaults. + const char* eMsg; + nsresult eResult; + nsCOMPtr<nsIStackFrame> eStack; + nsCOMPtr<nsISupports> eData; + + // Parse the constructor arguments into the above |eFoo| parameter values. + bool parse(const CallArgs& args) { + /* + * The Components.Exception takes a series of arguments, all of them + * optional: + * + * Argument 0: Exception message (defaults to 'exception'). + * Argument 1: Result code (defaults to NS_ERROR_FAILURE) _or_ options + * object (see below). + * Argument 2: Stack (defaults to the current stack, which we trigger + * by leaving this nullptr in the parser). + * Argument 3: Optional user data (defaults to nullptr). + * + * To dig our way out of this clunky API, we now support passing an + * options object as the second parameter (as opposed to a result code). + * If this is the case, all subsequent arguments are ignored, and the + * following properties are parsed out of the object (using the + * associated default if the property does not exist): + * + * result: Result code (see argument 1). + * stack: Call stack (see argument 2). + * data: User data (see argument 3). + */ + if (args.length() > 0 && !parseMessage(args[0])) { + return false; + } + if (args.length() > 1) { + if (args[1].isObject()) { + RootedObject obj(cx, &args[1].toObject()); + return parseOptionsObject(obj); + } + if (!parseResult(args[1])) { + return false; + } + } + if (args.length() > 2) { + if (!parseStack(args[2])) { + return false; + } + } + if (args.length() > 3) { + if (!parseData(args[3])) { + return false; + } + } + return true; + } + + protected: + /* + * Parsing helpers. + */ + + bool parseMessage(HandleValue v) { + JSString* str = ToString(cx, v); + if (!str) { + return false; + } + messageBytes = JS_EncodeStringToLatin1(cx, str); + eMsg = messageBytes.get(); + return !!eMsg; + } + + bool parseResult(HandleValue v) { + return JS::ToUint32(cx, v, (uint32_t*)&eResult); + } + + bool parseStack(HandleValue v) { + if (!v.isObject()) { + // eStack has already been initialized to null, which is what we want + // for any non-object values (including null). + return true; + } + + RootedObject stackObj(cx, &v.toObject()); + return NS_SUCCEEDED(xpc->WrapJS(cx, stackObj, NS_GET_IID(nsIStackFrame), + getter_AddRefs(eStack))); + } + + bool parseData(HandleValue v) { + if (!v.isObject()) { + // eData has already been initialized to null, which is what we want + // for any non-object values (including null). + return true; + } + + RootedObject obj(cx, &v.toObject()); + return NS_SUCCEEDED( + xpc->WrapJS(cx, obj, NS_GET_IID(nsISupports), getter_AddRefs(eData))); + } + + bool parseOptionsObject(HandleObject obj) { + RootedValue v(cx); + + if (!getOption(obj, "result", &v) || (!v.isUndefined() && !parseResult(v))) + return false; + + if (!getOption(obj, "stack", &v) || (!v.isUndefined() && !parseStack(v))) + return false; + + if (!getOption(obj, "data", &v) || (!v.isUndefined() && !parseData(v))) + return false; + + return true; + } + + bool getOption(HandleObject obj, const char* name, MutableHandleValue rv) { + // Look for the property. + bool found; + if (!JS_HasProperty(cx, obj, name, &found)) { + return false; + } + + // If it wasn't found, indicate with undefined. + if (!found) { + rv.setUndefined(); + return true; + } + + // Get the property. + return JS_GetProperty(cx, obj, name, rv); + } + + /* + * Internal data members. + */ + + // If there's a non-default exception string, hold onto the allocated bytes. + JS::UniqueChars messageBytes; + + // Various bits and pieces that are helpful to have around. + JSContext* cx; + nsIXPConnect* xpc; +}; + +// static +nsresult nsXPCComponents_Exception::CallOrConstruct( + nsIXPConnectWrappedNative* wrapper, JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval) { + nsIXPConnect* xpc = nsIXPConnect::XPConnect(); + + MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::IsCallerChrome()); + + // Parse the arguments to the Exception constructor. + ExceptionArgParser parser(cx, xpc); + if (!parser.parse(args)) { + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); + } + + RefPtr<Exception> e = new Exception(nsCString(parser.eMsg), parser.eResult, + ""_ns, parser.eStack, parser.eData); + + RootedObject newObj(cx); + if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIException), + newObj.address())) || + !newObj) { + return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval); + } + + args.rval().setObject(*newObj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + HandleValue val, bool* bp, + bool* _retval) { + using namespace mozilla::dom; + + if (bp) { + *bp = (val.isObject() && IS_INSTANCE_OF(Exception, &val.toObject())) || + JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException)); + } + return NS_OK; +} + +/*******************************************************/ +// JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor) + +class nsXPCComponents_Constructor final : public nsIXPCComponents_Constructor, + public nsIXPCScriptable, + public nsIClassInfo { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO + + public: + nsXPCComponents_Constructor(); + + private: + virtual ~nsXPCComponents_Constructor(); + static bool InnerConstructor(JSContext* cx, unsigned argc, JS::Value* vp); + static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval); +}; + +/***************************************************************************/ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCComponents_Constructor), + NS_GET_IID(nsIXPCScriptable)}; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetScriptableHelper(nsIXPCScriptable** retval) { + *retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassDescription( + nsACString& aClassDescription) { + aClassDescription.AssignLiteral("XPCComponents_Constructor"); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +nsXPCComponents_Constructor::nsXPCComponents_Constructor() = default; + +nsXPCComponents_Constructor::~nsXPCComponents_Constructor() { + // empty +} + +NS_IMPL_ISUPPORTS(nsXPCComponents_Constructor, nsIXPCComponents_Constructor, + nsIXPCScriptable, nsIClassInfo) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Constructor +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Constructor" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_CALL | XPC_SCRIPTABLE_WANT_CONSTRUCT | \ + XPC_SCRIPTABLE_WANT_HASINSTANCE | \ + XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE) +#include "xpc_map_end.h" /* This will #undef the above */ + +// static +bool nsXPCComponents_Constructor::InnerConstructor(JSContext* cx, unsigned argc, + JS::Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + RootedObject callee(cx, &args.callee()); + + // Fetch the property name ids, so we can look them up. + XPCJSRuntime* runtime = XPCJSRuntime::Get(); + HandleId classIDProp = runtime->GetStringID(XPCJSContext::IDX_CLASS_ID); + HandleId interfaceIDProp = + runtime->GetStringID(XPCJSContext::IDX_INTERFACE_ID); + HandleId initializerProp = + runtime->GetStringID(XPCJSContext::IDX_INITIALIZER); + + // Get properties ('classID', 'interfaceID', and 'initializer') off the + // constructor object. + RootedValue classIDv(cx); + RootedValue interfaceID(cx); + RootedValue initializer(cx); + if (!JS_GetPropertyById(cx, callee, classIDProp, &classIDv) || + !JS_GetPropertyById(cx, callee, interfaceIDProp, &interfaceID) || + !JS_GetPropertyById(cx, callee, initializerProp, &initializer)) { + return false; + } + if (!classIDv.isObject() || !interfaceID.isObject()) { + XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx); + return false; + } + + // Call 'createInstance' on the 'classID' object to create the object. + RootedValue instancev(cx); + RootedObject classID(cx, &classIDv.toObject()); + if (!JS_CallFunctionName(cx, classID, "createInstance", + HandleValueArray(interfaceID), &instancev)) { + return false; + } + if (!instancev.isObject()) { + XPCThrower::Throw(NS_ERROR_FAILURE, cx); + return false; + } + + // Call the method 'initializer' on the instance, passing in our parameters. + if (!initializer.isUndefined()) { + RootedValue dummy(cx); + RootedValue initfunc(cx); + RootedId initid(cx); + RootedObject instance(cx, &instancev.toObject()); + if (!JS_ValueToId(cx, initializer, &initid) || + !JS_GetPropertyById(cx, instance, initid, &initfunc) || + !JS_CallFunctionValue(cx, instance, initfunc, args, &dummy)) { + return false; + } + } + + args.rval().set(instancev); + return true; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* objArg, + const CallArgs& args, bool* _retval) { + RootedObject obj(cx, objArg); + return CallOrConstruct(wrapper, cx, obj, args, _retval); +} + +// static +nsresult nsXPCComponents_Constructor::CallOrConstruct( + nsIXPConnectWrappedNative* wrapper, JSContext* cx, HandleObject obj, + const CallArgs& args, bool* _retval) { + // make sure we have at least one arg + + if (args.length() < 1) { + return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval); + } + + // Fetch the property name ids, so we can look them up. + XPCJSRuntime* runtime = XPCJSRuntime::Get(); + HandleId classIDProp = runtime->GetStringID(XPCJSContext::IDX_CLASS_ID); + HandleId interfaceIDProp = + runtime->GetStringID(XPCJSContext::IDX_INTERFACE_ID); + HandleId initializerProp = + runtime->GetStringID(XPCJSContext::IDX_INITIALIZER); + + // get the various other object pointers we need + + nsIXPConnect* xpc = nsIXPConnect::XPConnect(); + XPCWrappedNativeScope* scope = ObjectScope(obj); + nsCOMPtr<nsIXPCComponents> comp; + + if (!xpc || !scope || !(comp = scope->GetComponents())) { + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); + } + + // Prevent non-chrome code from creating constructor objects. + if (!nsContentUtils::IsCallerChrome()) { + return ThrowAndFail(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, cx, _retval); + } + + JSFunction* ctorfn = JS_NewFunction(cx, InnerConstructor, 0, + JSFUN_CONSTRUCTOR, "XPCOM_Constructor"); + if (!ctorfn) { + return ThrowAndFail(NS_ERROR_OUT_OF_MEMORY, cx, _retval); + } + + JS::RootedObject ctor(cx, JS_GetFunctionObject(ctorfn)); + + if (args.length() >= 3) { + // args[2] is an initializer function or property name + RootedString str(cx, ToString(cx, args[2])); + if (!JS_DefinePropertyById( + cx, ctor, initializerProp, str, + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { + return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval); + } + } + + RootedString ifaceName(cx); + if (args.length() >= 2) { + ifaceName = ToString(cx, args[1]); + } else { + ifaceName = JS_NewStringCopyZ(cx, "nsISupports"); + } + + if (!ifaceName) { + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); + } + + // a new scope to avoid warnings about shadowed names + { + nsCOMPtr<nsIXPCComponents_Interfaces> ifaces; + RootedObject ifacesObj(cx); + + // we do the lookup by asking the Components.interfaces object + // for the property with this name - i.e. we let its caching of these + // nsIJSIID objects work for us. + + if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) || + NS_FAILED(xpc->WrapNative(cx, obj, ifaces, + NS_GET_IID(nsIXPCComponents_Interfaces), + ifacesObj.address())) || + !ifacesObj) { + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); + } + + RootedId id(cx); + if (!JS_StringToId(cx, ifaceName, &id)) { + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); + } + + RootedValue val(cx); + if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || val.isPrimitive()) { + return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval); + } + + if (!JS_DefinePropertyById( + cx, ctor, interfaceIDProp, val, + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { + return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval); + } + } + + // a new scope to avoid warnings about shadowed names + { + // argv[0] is a contractid name string + + // we do the lookup by asking the Components.classes object + // for the property with this name - i.e. we let its caching of these + // nsIJSCID objects work for us. + + nsCOMPtr<nsIXPCComponents_Classes> classes; + RootedObject classesObj(cx); + + if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) || + NS_FAILED(xpc->WrapNative(cx, obj, classes, + NS_GET_IID(nsIXPCComponents_Classes), + classesObj.address())) || + !classesObj) { + return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval); + } + + RootedString str(cx, ToString(cx, args[0])); + RootedId id(cx); + if (!str || !JS_StringToId(cx, str, &id)) { + return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); + } + + RootedValue val(cx); + if (!JS_GetPropertyById(cx, classesObj, id, &val) || val.isPrimitive()) { + return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval); + } + + if (!JS_DefinePropertyById( + cx, ctor, classIDProp, val, + JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { + return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval); + } + } + + args.rval().setObject(*ctor); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative* wrapper, + JSContext* cx, JSObject* obj, + HandleValue val, bool* isa, + bool* _retval) { + *isa = + val.isObject() && JS_IsNativeFunction(&val.toObject(), InnerConstructor); + return NS_OK; +} + +class nsXPCComponents_Utils final : public nsIXPCComponents_Utils, + public nsIXPCScriptable { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSIXPCCOMPONENTS_UTILS + + public: + nsXPCComponents_Utils() = default; + + private: + virtual ~nsXPCComponents_Utils() = default; + nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox; +}; + +NS_IMPL_ISUPPORTS(nsXPCComponents_Utils, nsIXPCComponents_Utils, + nsIXPCScriptable) + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME nsXPCComponents_Utils +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Utils" +#define XPC_MAP_FLAGS XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox** aSandbox) { + NS_ENSURE_ARG_POINTER(aSandbox); + if (!mSandbox) { + mSandbox = NewSandboxConstructor(); + } + + nsCOMPtr<nsIXPCComponents_utils_Sandbox> rval = mSandbox; + rval.forget(aSandbox); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateServicesCache(JSContext* aCx, + MutableHandleValue aServices) { + if (JSObject* services = NewJSServices(aCx)) { + aServices.setObject(*services); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::PrintStderr(const nsACString& message) { + printf_stderr("%s", PromiseFlatUTF8String(message).get()); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ReportError(HandleValue error, HandleValue stack, + JSContext* cx) { + // This function shall never fail! Silently eat any failure conditions. + + nsCOMPtr<nsIConsoleService> console( + do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + if (!console) { + return NS_OK; + } + + nsGlobalWindowInner* win = CurrentWindowOrNull(cx); + const uint64_t innerWindowID = win ? win->WindowID() : 0; + + Rooted<Maybe<Value>> exception(cx, Some(error)); + if (!innerWindowID) { + // Leak mitigation: nsConsoleService::ClearMessagesForWindowID needs + // a WindowID for cleanup and exception values could hold arbitrary + // objects alive. + exception = Nothing(); + } + + nsCOMPtr<nsIScriptError> scripterr; + RootedObject errorObj(cx, error.isObject() ? &error.toObject() : nullptr); + if (errorObj) { + JS::RootedObject stackVal(cx); + JS::RootedObject stackGlobal(cx); + FindExceptionStackForConsoleReport(win, error, nullptr, &stackVal, + &stackGlobal); + if (stackVal) { + scripterr = CreateScriptError(win, exception, stackVal, stackGlobal); + } + } + + nsString fileName; + uint32_t lineNo = 0; + + if (!scripterr) { + RootedObject stackObj(cx); + RootedObject stackGlobal(cx); + if (stack.isObject()) { + if (!JS::IsMaybeWrappedSavedFrame(&stack.toObject())) { + return NS_ERROR_INVALID_ARG; + } + + // |stack| might be a wrapper, but it must be same-compartment with + // the current global. + stackObj = &stack.toObject(); + stackGlobal = JS::CurrentGlobalOrNull(cx); + js::AssertSameCompartment(stackObj, stackGlobal); + + JSPrincipals* principals = + JS::GetRealmPrincipals(js::GetContextRealm(cx)); + + if (GetSavedFrameLine(cx, principals, stackObj, &lineNo) != + SavedFrameResult::Ok) { + JS_ClearPendingException(cx); + } + + RootedString source(cx); + nsAutoJSString str; + if (GetSavedFrameSource(cx, principals, stackObj, &source) == + SavedFrameResult::Ok && + str.init(cx, source)) { + fileName = str; + } else { + JS_ClearPendingException(cx); + } + } else { + nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack(); + if (frame) { + frame->GetFilename(cx, fileName); + lineNo = frame->GetLineNumber(cx); + JS::Rooted<JS::Value> stack(cx); + nsresult rv = frame->GetNativeSavedFrame(&stack); + if (NS_SUCCEEDED(rv) && stack.isObject()) { + stackObj = &stack.toObject(); + MOZ_ASSERT(JS::IsUnwrappedSavedFrame(stackObj)); + stackGlobal = JS::GetNonCCWObjectGlobal(stackObj); + } + } + } + + if (stackObj) { + scripterr = CreateScriptError(win, exception, stackObj, stackGlobal); + } + } + + if (!scripterr) { + scripterr = CreateScriptError(win, exception, nullptr, nullptr); + } + + JSErrorReport* err = errorObj ? JS_ErrorFromException(cx, errorObj) : nullptr; + if (err) { + // It's a proper JS Error + nsAutoString fileUni; + CopyUTF8toUTF16(mozilla::MakeStringSpan(err->filename), fileUni); + + uint32_t column = err->tokenOffset(); + + const char16_t* linebuf = err->linebuf(); + uint32_t flags = err->isWarning() ? nsIScriptError::warningFlag + : nsIScriptError::errorFlag; + + nsresult rv = scripterr->InitWithWindowID( + err->message() ? NS_ConvertUTF8toUTF16(err->message().c_str()) + : EmptyString(), + fileUni, + linebuf ? nsDependentString(linebuf, err->linebufLength()) + : EmptyString(), + err->lineno, column, flags, "XPConnect JavaScript", innerWindowID, + innerWindowID == 0 ? true : false); + NS_ENSURE_SUCCESS(rv, NS_OK); + + console->LogMessage(scripterr); + return NS_OK; + } + + // It's not a JS Error object, so we synthesize as best we're able. + RootedString msgstr(cx, ToString(cx, error)); + if (!msgstr) { + return NS_OK; + } + + nsAutoJSString msg; + if (!msg.init(cx, msgstr)) { + return NS_OK; + } + + nsresult rv = scripterr->InitWithWindowID( + msg, fileName, u""_ns, lineNo, 0, 0, "XPConnect JavaScript", + innerWindowID, innerWindowID == 0 ? true : false); + NS_ENSURE_SUCCESS(rv, NS_OK); + + console->LogMessage(scripterr); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::EvalInSandbox( + const nsAString& source, HandleValue sandboxVal, HandleValue version, + const nsACString& filenameArg, int32_t lineNumber, + bool enforceFilenameRestrictions, JSContext* cx, uint8_t optionalArgc, + MutableHandleValue retval) { + RootedObject sandbox(cx); + if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox) { + return NS_ERROR_INVALID_ARG; + } + + // Optional third argument: JS version, as a string, is unused. + + // Optional fourth and fifth arguments: filename and line number. + int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1; + nsCString filename; + if (!filenameArg.IsVoid()) { + filename.Assign(filenameArg); + } else { + // Get the current source info. + nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack(); + if (frame) { + nsString frameFile; + frame->GetFilename(cx, frameFile); + CopyUTF16toUTF8(frameFile, filename); + lineNo = frame->GetLineNumber(cx); + } + } + enforceFilenameRestrictions = + (optionalArgc >= 4) ? enforceFilenameRestrictions : true; + + return xpc::EvalInSandbox(cx, sandbox, source, filename, lineNo, + enforceFilenameRestrictions, retval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetUAWidgetScope(nsIPrincipal* principal, JSContext* cx, + MutableHandleValue rval) { + rval.set(UndefinedValue()); + + JSObject* scope = xpc::GetUAWidgetScope(cx, principal); + + rval.set(JS::ObjectValue(*scope)); + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal, JSContext* cx, + MutableHandleValue rval) { + if (!sandboxVal.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + RootedObject sandbox(cx, &sandboxVal.toObject()); + // We only care about sandboxes here, so CheckedUnwrapStatic is fine. + sandbox = js::CheckedUnwrapStatic(sandbox); + if (!sandbox || !xpc::IsSandbox(sandbox)) { + return NS_ERROR_INVALID_ARG; + } + + return xpc::GetSandboxMetadata(cx, sandbox, rval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal, + HandleValue metadataVal, + JSContext* cx) { + if (!sandboxVal.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + RootedObject sandbox(cx, &sandboxVal.toObject()); + // We only care about sandboxes here, so CheckedUnwrapStatic is fine. + sandbox = js::CheckedUnwrapStatic(sandbox); + if (!sandbox || !xpc::IsSandbox(sandbox)) { + return NS_ERROR_INVALID_ARG; + } + + nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::Import(const nsACString& registryLocation, + HandleValue targetObj, JSContext* cx, + uint8_t optionalArgc, MutableHandleValue retval) { + RefPtr moduleloader = mozJSModuleLoader::Get(); + MOZ_ASSERT(moduleloader); + + AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("nsXPCComponents_Utils::Import", OTHER, + registryLocation); + + return moduleloader->ImportInto(registryLocation, targetObj, cx, optionalArgc, + retval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsModuleLoaded(const nsACString& aResourceURI, + bool* retval) { + RefPtr moduleloader = mozJSModuleLoader::Get(); + MOZ_ASSERT(moduleloader); + return moduleloader->IsModuleLoaded(aResourceURI, retval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsJSModuleLoaded(const nsACString& aResourceURI, + bool* retval) { + RefPtr moduleloader = mozJSModuleLoader::Get(); + MOZ_ASSERT(moduleloader); + return moduleloader->IsJSModuleLoaded(aResourceURI, retval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsESModuleLoaded(const nsACString& aResourceURI, + bool* retval) { + RefPtr moduleloader = mozJSModuleLoader::Get(); + MOZ_ASSERT(moduleloader); + return moduleloader->IsESModuleLoaded(aResourceURI, retval); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::Unload(const nsACString& registryLocation) { + RefPtr moduleloader = mozJSModuleLoader::Get(); + MOZ_ASSERT(moduleloader); + return moduleloader->Unload(registryLocation); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList, + JSContext* cx) { + // Ensure we're working in the scripted caller's realm. This is not guaranteed + // to be the current realm because we switch realms when calling cross-realm + // functions. + RootedObject global(cx, JS::GetScriptedCallerGlobal(cx)); + MOZ_ASSERT(global); + js::AssertSameCompartment(cx, global); + JSAutoRealm ar(cx, global); + + // Don't allow doing this if the global is a Window. + nsGlobalWindowInner* win; + if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, win))) { + return NS_ERROR_NOT_AVAILABLE; + } + + GlobalProperties options; + NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG); + + RootedObject propertyList(cx, &aPropertyList.toObject()); + bool isArray; + if (NS_WARN_IF(!JS::IsArrayObject(cx, propertyList, &isArray))) { + return NS_ERROR_FAILURE; + } + if (NS_WARN_IF(!isArray)) { + return NS_ERROR_INVALID_ARG; + } + + if (!options.Parse(cx, propertyList) || + !options.DefineInXPCComponents(cx, global)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext* cx, + xpcIJSWeakReference** _retval) { + RefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference(); + nsresult rv = ref->Init(cx, object); + NS_ENSURE_SUCCESS(rv, rv); + ref.forget(_retval); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ForceGC(JSContext* aCx) { + PrepareForFullGC(aCx); + NonIncrementalGC(aCx, GCOptions::Normal, GCReason::COMPONENT_UTILS); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ForceCC(nsICycleCollectorListener* listener) { + nsJSContext::CycleCollectNow(CCReason::API, listener); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateCCLogger(nsICycleCollectorListener** aListener) { + NS_ENSURE_ARG_POINTER(aListener); + nsCOMPtr<nsICycleCollectorListener> logger = nsCycleCollector_createLogger(); + logger.forget(aListener); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::FinishCC() { + nsCycleCollector_finishAnyCurrentCollection(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CcSlice(int64_t budget) { + nsJSContext::RunCycleCollectorWorkSlice(budget); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetMaxCCSliceTimeSinceClear(int32_t* out) { + *out = nsJSContext::GetMaxCCSliceTimeSinceClear(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ClearMaxCCTime() { + nsJSContext::ClearMaxCCSliceTime(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ForceShrinkingGC(JSContext* aCx) { + PrepareForFullGC(aCx); + NonIncrementalGC(aCx, GCOptions::Shrink, GCReason::COMPONENT_UTILS); + return NS_OK; +} + +class PreciseGCRunnable : public Runnable { + public: + PreciseGCRunnable(nsIScheduledGCCallback* aCallback, bool aShrinking) + : mozilla::Runnable("PreciseGCRunnable"), + mCallback(aCallback), + mShrinking(aShrinking) {} + + NS_IMETHOD Run() override { + nsJSContext::GarbageCollectNow( + GCReason::COMPONENT_UTILS, + mShrinking ? nsJSContext::ShrinkingGC : nsJSContext::NonShrinkingGC); + + mCallback->Callback(); + return NS_OK; + } + + private: + nsCOMPtr<nsIScheduledGCCallback> mCallback; + bool mShrinking; +}; + +NS_IMETHODIMP +nsXPCComponents_Utils::SchedulePreciseGC(nsIScheduledGCCallback* aCallback) { + RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, false); + return NS_DispatchToMainThread(event); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::SchedulePreciseShrinkingGC( + nsIScheduledGCCallback* aCallback) { + RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true); + return NS_DispatchToMainThread(event); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::UnlinkGhostWindows() { +#ifdef DEBUG + nsWindowMemoryReporter::UnlinkGhostWindows(); + + if (XRE_IsParentProcess()) { + nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService(); + if (obsvc) { + obsvc->NotifyObservers(nullptr, "child-ghost-request", nullptr); + } + } + + return NS_OK; +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + +#ifdef NS_FREE_PERMANENT_DATA +struct IntentionallyLeakedObject { + MOZ_COUNTED_DEFAULT_CTOR(IntentionallyLeakedObject) + + MOZ_COUNTED_DTOR(IntentionallyLeakedObject) +}; +#endif + +NS_IMETHODIMP +nsXPCComponents_Utils::IntentionallyLeak() { +#ifdef NS_FREE_PERMANENT_DATA + Unused << new IntentionallyLeakedObject(); + return NS_OK; +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetJSTestingFunctions(JSContext* cx, + MutableHandleValue retval) { + JSObject* obj = js::GetTestingFunctions(cx); + if (!obj) { + return NS_ERROR_XPC_JAVASCRIPT_ERROR; + } + retval.setObject(*obj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetFunctionSourceLocation(HandleValue funcValue, + JSContext* cx, + MutableHandleValue retval) { + NS_ENSURE_TRUE(funcValue.isObject(), NS_ERROR_INVALID_ARG); + + nsAutoString filename; + uint32_t lineNumber; + { + RootedObject funcObj(cx, UncheckedUnwrap(&funcValue.toObject())); + JSAutoRealm ar(cx, funcObj); + + Rooted<JSFunction*> func(cx, JS_GetObjectFunction(funcObj)); + NS_ENSURE_TRUE(func, NS_ERROR_INVALID_ARG); + + RootedScript script(cx, JS_GetFunctionScript(cx, func)); + NS_ENSURE_TRUE(func, NS_ERROR_FAILURE); + + AppendUTF8toUTF16(nsDependentCString(JS_GetScriptFilename(script)), + filename); + lineNumber = JS_GetScriptBaseLineNumber(cx, script) + 1; + } + + RootedObject res(cx, JS_NewPlainObject(cx)); + NS_ENSURE_TRUE(res, NS_ERROR_OUT_OF_MEMORY); + + RootedValue filenameVal(cx); + if (!xpc::NonVoidStringToJsval(cx, filename, &filenameVal) || + !JS_DefineProperty(cx, res, "filename", filenameVal, JSPROP_ENUMERATE)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (!JS_DefineProperty(cx, res, "lineNumber", lineNumber, JSPROP_ENUMERATE)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + retval.setObject(*res); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CallFunctionWithAsyncStack(HandleValue function, + nsIStackFrame* stack, + const nsAString& asyncCause, + JSContext* cx, + MutableHandleValue retval) { + nsresult rv; + + if (!stack || asyncCause.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + JS::Rooted<JS::Value> asyncStack(cx); + rv = stack->GetNativeSavedFrame(&asyncStack); + if (NS_FAILED(rv)) { + return rv; + } + if (!asyncStack.isObject()) { + JS_ReportErrorASCII(cx, "Must use a native JavaScript stack frame"); + return NS_ERROR_INVALID_ARG; + } + + JS::Rooted<JSObject*> asyncStackObj(cx, &asyncStack.toObject()); + + NS_ConvertUTF16toUTF8 utf8Cause(asyncCause); + JS::AutoSetAsyncStackForNewCalls sas( + cx, asyncStackObj, utf8Cause.get(), + JS::AutoSetAsyncStackForNewCalls::AsyncCallKind::EXPLICIT); + + if (!JS_CallFunctionValue(cx, nullptr, function, + JS::HandleValueArray::empty(), retval)) { + return NS_ERROR_XPC_JAVASCRIPT_ERROR; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetGlobalForObject(HandleValue object, JSContext* cx, + MutableHandleValue retval) { + // First argument must be an object. + if (object.isPrimitive()) { + return NS_ERROR_XPC_BAD_CONVERT_JS; + } + + // When getting the global for a cross-compartment wrapper, we really want + // a wrapper for the foreign global. So we need to unwrap before getting the + // global and then wrap the result. + Rooted<JSObject*> obj(cx, &object.toObject()); + obj = JS::GetNonCCWObjectGlobal(js::UncheckedUnwrap(obj)); + + if (!JS_WrapObject(cx, &obj)) { + return NS_ERROR_FAILURE; + } + + // Get the WindowProxy if necessary. + obj = js::ToWindowProxyIfWindow(obj); + + retval.setObject(*obj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext* cx, bool* rval) { + if (!vobj.isObject()) { + *rval = false; + return NS_OK; + } + + RootedObject obj(cx, &vobj.toObject()); + // We need to do a dynamic unwrap, because we apparently want to treat + // "failure to unwrap" differently from "not a proxy" (throw for the former, + // return false for the latter). + obj = js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false); + NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE); + + *rval = js::IsScriptedProxy(obj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope, + HandleValue voptions, JSContext* cx, + MutableHandleValue rval) { + if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions, + JSContext* cx, MutableHandleValue rval) { + RootedObject optionsObject( + cx, voptions.isObject() ? &voptions.toObject() : nullptr); + CreateObjectInOptions options(cx, optionsObject); + if (voptions.isObject() && !options.Parse()) { + return NS_ERROR_FAILURE; + } + + if (!xpc::CreateObjectIn(cx, vobj, options, rval)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext* cx) { + if (!cx) { + return NS_ERROR_FAILURE; + } + + // first argument must be an object + if (vobj.isPrimitive()) { + return NS_ERROR_XPC_BAD_CONVERT_JS; + } + + RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject())); + JSAutoRealm ar(cx, obj); + Rooted<IdVector> ida(cx, IdVector(cx)); + if (!JS_Enumerate(cx, obj, &ida)) { + return NS_ERROR_FAILURE; + } + + RootedId id(cx); + RootedValue v(cx); + for (size_t i = 0; i < ida.length(); ++i) { + id = ida[i]; + + if (!JS_GetPropertyById(cx, obj, id, &v)) { + return NS_ERROR_FAILURE; + } + + if (v.isPrimitive()) { + continue; + } + + RootedObject propobj(cx, &v.toObject()); + // TODO Deal with non-functions. + if (!js::IsWrapper(propobj) || !JS::IsCallable(propobj)) { + continue; + } + + FunctionForwarderOptions forwarderOptions; + if (!NewFunctionForwarder(cx, id, propobj, forwarderOptions, &v) || + !JS_SetPropertyById(cx, obj, id, v)) + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool* out) { + *out = false; + if (obj.isPrimitive()) { + return NS_ERROR_INVALID_ARG; + } + + // We should never have cross-compartment wrappers for dead wrappers. + MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(&obj.toObject()), + !JS_IsDeadWrapper(js::UncheckedUnwrap(&obj.toObject()))); + + *out = JS_IsDeadWrapper(&obj.toObject()); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsRemoteProxy(HandleValue val, bool* out) { + if (val.isObject()) { + *out = dom::IsRemoteObjectProxy(UncheckedUnwrap(&val.toObject())); + ; + } else { + *out = false; + } + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext* cx) { + // Determine the compartment of the given object, if any. + JS::Compartment* c = + vobj.isObject() + ? JS::GetCompartment(js::UncheckedUnwrap(&vobj.toObject())) + : nullptr; + + // If no compartment was given, recompute all. + if (!c) { + js::RecomputeWrappers(cx, js::AllCompartments(), js::AllCompartments()); + // Otherwise, recompute wrappers for the given compartment. + } else { + js::RecomputeWrappers(cx, js::SingleCompartment(c), + js::AllCompartments()) && + js::RecomputeWrappers(cx, js::AllCompartments(), + js::SingleCompartment(c)); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext* cx) { + if (!vscope.isObject()) { + return NS_ERROR_INVALID_ARG; + } + JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject()); + MOZ_RELEASE_ASSERT(!AccessCheck::isChrome(scopeObj), + "Don't call setWantXrays on system-principal scopes"); + JS::Compartment* compartment = JS::GetCompartment(scopeObj); + CompartmentPrivate::Get(scopeObj)->wantXrays = true; + bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment), + js::AllCompartments()); + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope, + JSContext* cx) { + RootedValue runnable(cx, runnableArg); + // Enter the given realm, if any, and rewrap runnable. + Maybe<JSAutoRealm> ar; + if (scope.isObject()) { + JSObject* scopeObj = js::UncheckedUnwrap(&scope.toObject()); + if (!scopeObj) { + return NS_ERROR_FAILURE; + } + ar.emplace(cx, scopeObj); + if (!JS_WrapValue(cx, &runnable)) { + return NS_ERROR_FAILURE; + } + } + + // Get an XPCWrappedJS for |runnable|. + if (!runnable.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + RootedObject runnableObj(cx, &runnable.toObject()); + nsCOMPtr<nsIRunnable> run; + nsresult rv = nsXPConnect::XPConnect()->WrapJS( + cx, runnableObj, NS_GET_IID(nsIRunnable), getter_AddRefs(run)); + NS_ENSURE_SUCCESS(rv, rv); + MOZ_ASSERT(run); + + // Dispatch. + return NS_DispatchToMainThread(run); +} + +#define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Get##_attr(JSContext* cx, bool* aValue) { \ + *aValue = ContextOptionsRef(cx)._getter(); \ + return NS_OK; \ + } \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Set##_attr(JSContext* cx, bool aValue) { \ + ContextOptionsRef(cx)._setter(aValue); \ + return NS_OK; \ + } + +GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) + +#undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER + +NS_IMETHODIMP +nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx) { +#ifdef JS_GC_ZEAL + JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ); +#endif + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetIsInAutomation(bool* aResult) { + NS_ENSURE_ARG_POINTER(aResult); + + *aResult = xpc::IsInAutomation(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ExitIfInAutomation() { + NS_ENSURE_TRUE(xpc::IsInAutomation(), NS_ERROR_FAILURE); + + profiler_shutdown(IsFastShutdown::Yes); + + mozilla::AppShutdown::DoImmediateExit(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CrashIfNotInAutomation() { + xpc::CrashIfNotInAutomation(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx) { + AUTO_PROFILER_LABEL("nsXPCComponents_Utils::NukeSandbox", OTHER); + NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG); + JSObject* wrapper = &obj.toObject(); + NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG); + RootedObject sb(cx, UncheckedUnwrap(wrapper)); + NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG); + + xpc::NukeAllWrappersForRealm(cx, GetNonCCWObjectRealm(sb)); + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg, + JSContext* cx) { + NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG); + RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(), + /* stopAtWindowProxy = */ false)); + NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG); + if (xpc::GetObjectPrincipal(global)->IsSystemPrincipal()) { + JS_ReportErrorASCII(cx, "Script may not be disabled for system globals"); + return NS_ERROR_FAILURE; + } + Scriptability::Get(global).Block(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg, + JSContext* cx) { + NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG); + RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(), + /* stopAtWindowProxy = */ false)); + NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG); + if (xpc::GetObjectPrincipal(global)->IsSystemPrincipal()) { + JS_ReportErrorASCII(cx, "Script may not be disabled for system globals"); + return NS_ERROR_FAILURE; + } + Scriptability::Get(global).Unblock(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsOpaqueWrapper(HandleValue obj, bool* aRetval) { + *aRetval = + obj.isObject() && xpc::WrapperFactory::IsOpaqueWrapper(&obj.toObject()); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval) { + *aRetval = + obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject()); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext* aCx, + MutableHandleValue aRetval) { + RootedValue value(aCx, aVal); + if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value)) { + return NS_ERROR_FAILURE; + } + aRetval.set(value); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext* aCx, + MutableHandleValue aRetval) { + if (!aVal.isObject()) { + aRetval.set(aVal); + return NS_OK; + } + + RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject())); + if (!JS_WrapObject(aCx, &obj)) { + return NS_ERROR_FAILURE; + } + aRetval.setObject(*obj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, + JSContext* aCx, char** aRv) { + if (!aObj.isObject()) { + return NS_ERROR_INVALID_ARG; + } + RootedObject obj(aCx, &aObj.toObject()); + if (aUnwrap) { + obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false); + } + *aRv = NS_xstrdup(JS::GetClass(obj)->name); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName, + nsIClassInfo** aClassInfo) { + *aClassInfo = nullptr; + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback, JSContext* aCx, + MutableHandleValue aOut) { + nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal(); + RootedValue globalVal(aCx); + + if (!global) { + globalVal = NullValue(); + } else { + // Note: We rely on the wrap call for outerization. + globalVal = ObjectValue(*global->GetGlobalJSObject()); + if (!JS_WrapValue(aCx, &globalVal)) { + return NS_ERROR_FAILURE; + } + } + + // Invoke the callback, if passed. + if (aCallback.isObject()) { + RootedValue ignored(aCx); + if (!JS_CallFunctionValue(aCx, nullptr, aCallback, + JS::HandleValueArray(globalVal), &ignored)) { + return NS_ERROR_FAILURE; + } + } + + aOut.set(globalVal); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetDebugName(HandleValue aObj, JSContext* aCx, + nsACString& aOut) { + if (!aObj.isObject()) { + return NS_ERROR_INVALID_ARG; + } + + RootedObject obj(aCx, &aObj.toObject()); + aOut = xpc::GetFunctionName(aCx, obj); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, + PRTime* aOut) { + WatchdogTimestampCategory category; + if (aCategory.EqualsLiteral("ContextStateChange")) { + category = TimestampContextStateChange; + } else if (aCategory.EqualsLiteral("WatchdogWakeup")) { + category = TimestampWatchdogWakeup; + } else if (aCategory.EqualsLiteral("WatchdogHibernateStart")) { + category = TimestampWatchdogHibernateStart; + } else if (aCategory.EqualsLiteral("WatchdogHibernateStop")) { + category = TimestampWatchdogHibernateStop; + } else { + return NS_ERROR_INVALID_ARG; + } + *aOut = XPCJSContext::Get()->GetWatchdogTimestamp(category); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext* cx, + MutableHandleValue rval) { + RootedObject obj(cx, JS_NewPlainObject(cx)); + if (!obj) { + return NS_ERROR_OUT_OF_MEMORY; + } + + // No JS engine telemetry in use at the moment. + + rval.setObject(*obj); + return NS_OK; +} + +bool xpc::CloneInto(JSContext* aCx, HandleValue aValue, HandleValue aScope, + HandleValue aOptions, MutableHandleValue aCloned) { + if (!aScope.isObject()) { + return false; + } + + RootedObject scope(aCx, &aScope.toObject()); + // The scope could be a Window, so we need to CheckedUnwrapDynamic. + scope = js::CheckedUnwrapDynamic(scope, aCx); + if (!scope) { + JS_ReportErrorASCII(aCx, "Permission denied to clone object into scope"); + return false; + } + + if (!aOptions.isUndefined() && !aOptions.isObject()) { + JS_ReportErrorASCII(aCx, "Invalid argument"); + return false; + } + + RootedObject optionsObject( + aCx, aOptions.isObject() ? &aOptions.toObject() : nullptr); + StackScopedCloneOptions options(aCx, optionsObject); + if (aOptions.isObject() && !options.Parse()) { + return false; + } + + js::AssertSameCompartment(aCx, aValue); + RootedObject sourceScope(aCx, JS::CurrentGlobalOrNull(aCx)); + + { + JSAutoRealm ar(aCx, scope); + aCloned.set(aValue); + if (!StackScopedClone(aCx, options, sourceScope, aCloned)) { + return false; + } + } + + return JS_WrapValue(aCx, aCloned); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CloneInto(HandleValue aValue, HandleValue aScope, + HandleValue aOptions, JSContext* aCx, + MutableHandleValue aCloned) { + return xpc::CloneInto(aCx, aValue, aScope, aOptions, aCloned) + ? NS_OK + : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetWebIDLCallerPrincipal(nsIPrincipal** aResult) { + // This API may only be when the Entry Settings Object corresponds to a + // JS-implemented WebIDL call. In all other cases, the value will be null, + // and we throw. + nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal(); + if (!callerPrin) { + return NS_ERROR_NOT_AVAILABLE; + } + callerPrin.forget(aResult); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetObjectPrincipal(HandleValue val, JSContext* cx, + nsIPrincipal** result) { + if (!val.isObject()) { + return NS_ERROR_INVALID_ARG; + } + RootedObject obj(cx, &val.toObject()); + // We need to be able to unwrap to WindowProxy or Location here, so + // use CheckedUnwrapDynamic. + obj = js::CheckedUnwrapDynamic(obj, cx); + MOZ_ASSERT(obj); + + nsCOMPtr<nsIPrincipal> prin = nsContentUtils::ObjectPrincipal(obj); + prin.forget(result); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetRealmLocation(HandleValue val, JSContext* cx, + nsACString& result) { + if (!val.isObject()) { + return NS_ERROR_INVALID_ARG; + } + RootedObject obj(cx, &val.toObject()); + // We need to be able to unwrap to WindowProxy or Location here, so + // use CheckedUnwrapDynamic. + obj = js::CheckedUnwrapDynamic(obj, cx); + MOZ_ASSERT(obj); + + result = xpc::RealmPrivate::Get(obj)->GetLocation(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ReadUTF8File(nsIFile* aFile, nsACString& aResult) { + NS_ENSURE_TRUE(aFile, NS_ERROR_INVALID_ARG); + + MOZ_TRY_VAR(aResult, URLPreloader::ReadFile(aFile)); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::ReadUTF8URI(nsIURI* aURI, nsACString& aResult) { + NS_ENSURE_TRUE(aURI, NS_ERROR_INVALID_ARG); + + MOZ_TRY_VAR(aResult, URLPreloader::ReadURI(aURI)); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::Now(double* aRetval) { + TimeStamp start = TimeStamp::ProcessCreation(); + *aRetval = (TimeStamp::Now() - start).ToMilliseconds(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateSpellChecker(nsIEditorSpellCheck** aSpellChecker) { + NS_ENSURE_ARG_POINTER(aSpellChecker); + nsCOMPtr<nsIEditorSpellCheck> spellChecker = new mozilla::EditorSpellCheck(); + spellChecker.forget(aSpellChecker); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateCommandLine(const nsTArray<nsCString>& aArgs, + nsIFile* aWorkingDir, uint32_t aState, + nsISupports** aCommandLine) { + NS_ENSURE_ARG_MAX(aState, nsICommandLine::STATE_REMOTE_EXPLICIT); + NS_ENSURE_ARG_POINTER(aCommandLine); + + nsCOMPtr<nsISupports> commandLine = new nsCommandLine(); + nsCOMPtr<nsICommandLineRunner> runner = do_QueryInterface(commandLine); + + nsTArray<const char*> fakeArgv(aArgs.Length() + 2); + + // Prepend a dummy argument for the program name, which will be ignored. + fakeArgv.AppendElement(nullptr); + for (const nsCString& arg : aArgs) { + fakeArgv.AppendElement(arg.get()); + } + // Append a null terminator. + fakeArgv.AppendElement(nullptr); + + nsresult rv = runner->Init(fakeArgv.Length() - 1, fakeArgv.Elements(), + aWorkingDir, aState); + NS_ENSURE_SUCCESS(rv, rv); + + commandLine.forget(aCommandLine); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateCommandParams(nsICommandParams** aCommandParams) { + NS_ENSURE_ARG_POINTER(aCommandParams); + nsCOMPtr<nsICommandParams> commandParams = new nsCommandParams(); + commandParams.forget(aCommandParams); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateLoadContext(nsILoadContext** aLoadContext) { + NS_ENSURE_ARG_POINTER(aLoadContext); + nsCOMPtr<nsILoadContext> loadContext = ::CreateLoadContext(); + loadContext.forget(aLoadContext); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreatePrivateLoadContext(nsILoadContext** aLoadContext) { + NS_ENSURE_ARG_POINTER(aLoadContext); + nsCOMPtr<nsILoadContext> loadContext = ::CreatePrivateLoadContext(); + loadContext.forget(aLoadContext); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreatePersistentProperties( + nsIPersistentProperties** aPersistentProperties) { + NS_ENSURE_ARG_POINTER(aPersistentProperties); + nsCOMPtr<nsIPersistentProperties> props = new nsPersistentProperties(); + props.forget(aPersistentProperties); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateDocumentEncoder( + const char* aContentType, nsIDocumentEncoder** aDocumentEncoder) { + NS_ENSURE_ARG_POINTER(aDocumentEncoder); + nsCOMPtr<nsIDocumentEncoder> encoder = do_createDocumentEncoder(aContentType); + encoder.forget(aDocumentEncoder); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::CreateHTMLCopyEncoder( + nsIDocumentEncoder** aDocumentEncoder) { + NS_ENSURE_ARG_POINTER(aDocumentEncoder); + nsCOMPtr<nsIDocumentEncoder> encoder = do_createHTMLCopyEncoder(); + encoder.forget(aDocumentEncoder); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetLoadedModules(nsTArray<nsCString>& aLoadedModules) { + return mozJSModuleLoader::Get()->GetLoadedJSAndESModules(aLoadedModules); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetLoadedJSModules( + nsTArray<nsCString>& aLoadedJSModules) { + mozJSModuleLoader::Get()->GetLoadedModules(aLoadedJSModules); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetLoadedESModules( + nsTArray<nsCString>& aLoadedESModules) { + return mozJSModuleLoader::Get()->GetLoadedESModules(aLoadedESModules); +} + +NS_IMETHODIMP +nsXPCComponents_Utils::GetModuleImportStack(const nsACString& aLocation, + nsACString& aRetval) { + nsresult rv = + mozJSModuleLoader::Get()->GetModuleImportStack(aLocation, aRetval); + // Fallback the query to the DevTools loader if not found in the shared loader + if (rv == NS_ERROR_FAILURE && mozJSModuleLoader::GetDevToolsLoader()) { + return mozJSModuleLoader::GetDevToolsLoader()->GetModuleImportStack( + aLocation, aRetval); + } + return rv; +} + +/***************************************************************************/ +/***************************************************************************/ +/***************************************************************************/ + +nsXPCComponents::nsXPCComponents(XPCWrappedNativeScope* aScope) + : mScope(aScope) { + MOZ_ASSERT(aScope, "aScope must not be null"); +} + +nsXPCComponents::~nsXPCComponents() = default; + +void nsXPCComponents::ClearMembers() { + mInterfaces = nullptr; + mResults = nullptr; + mClasses = nullptr; + mID = nullptr; + mException = nullptr; + mConstructor = nullptr; + mUtils = nullptr; +} + +/*******************************************/ +#define XPC_IMPL_GET_OBJ_METHOD(_class, _n) \ + NS_IMETHODIMP _class::Get##_n(nsIXPCComponents_##_n** a##_n) { \ + NS_ENSURE_ARG_POINTER(a##_n); \ + if (!m##_n) m##_n = new nsXPCComponents_##_n(); \ + RefPtr<nsXPCComponents_##_n> ret = m##_n; \ + ret.forget(a##_n); \ + return NS_OK; \ + } + +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Interfaces) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Classes) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Results) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ID) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Exception) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Constructor) +XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Utils) + +#undef XPC_IMPL_GET_OBJ_METHOD +/*******************************************/ + +NS_IMETHODIMP +nsXPCComponents::IsSuccessCode(nsresult result, bool* out) { + *out = NS_SUCCEEDED(result); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents::GetStack(nsIStackFrame** aStack) { + nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack(); + frame.forget(aStack); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents::GetManager(nsIComponentManager** aManager) { + MOZ_ASSERT(aManager, "bad param"); + return NS_GetComponentManager(aManager); +} + +NS_IMETHODIMP +nsXPCComponents::GetReturnCode(JSContext* aCx, MutableHandleValue aOut) { + nsresult res = XPCJSContext::Get()->GetPendingResult(); + aOut.setNumber(static_cast<uint32_t>(res)); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCComponents::SetReturnCode(JSContext* aCx, HandleValue aCode) { + nsresult rv; + if (!ToUint32(aCx, aCode, (uint32_t*)&rv)) { + return NS_ERROR_FAILURE; + } + XPCJSContext::Get()->SetPendingResult(rv); + return NS_OK; +} + +/**********************************************/ + +class ComponentsSH : public nsIXPCScriptable { + public: + explicit constexpr ComponentsSH(unsigned dummy) {} + + // We don't actually inherit any ref counting infrastructure, but we don't + // need an nsAutoRefCnt member, so the _INHERITED macro is a hack to avoid + // having one. + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIXPCSCRIPTABLE + static nsresult Get(nsIXPCScriptable** helper) { + *helper = &singleton; + return NS_OK; + } + + private: + static ComponentsSH singleton; +}; + +ComponentsSH ComponentsSH::singleton(0); + +// Singleton refcounting. +NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::AddRef(void) { return 1; } +NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::Release(void) { + return 1; +} + +NS_IMPL_QUERY_INTERFACE(ComponentsSH, nsIXPCScriptable) + +#define NSXPCCOMPONENTS_CID \ + { \ + 0x3649f405, 0xf0ec, 0x4c28, { \ + 0xae, 0xb0, 0xaf, 0x9a, 0x51, 0xe4, 0x4c, 0x81 \ + } \ + } + +NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, 0, NSXPCCOMPONENTS_CID) +NS_IMPL_ISUPPORTS_CI(nsXPCComponents, nsIXPCComponents) + +// The nsIXPCScriptable map declaration that will generate stubs for us +#define XPC_MAP_CLASSNAME ComponentsSH +#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents" +#define XPC_MAP_FLAGS XPC_SCRIPTABLE_WANT_PRECREATE +#include "xpc_map_end.h" /* This will #undef the above */ + +NS_IMETHODIMP +ComponentsSH::PreCreate(nsISupports* nativeObj, JSContext* cx, + JSObject* globalObj, JSObject** parentObj) { + nsXPCComponents* self = static_cast<nsXPCComponents*>(nativeObj); + // this should never happen + if (!self->GetScope()) { + NS_WARNING( + "mScope must not be null when nsXPCComponents::PreCreate is called"); + return NS_ERROR_FAILURE; + } + *parentObj = self->GetScope()->GetGlobalForWrappedNatives(); + return NS_OK; +} diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp new file mode 100644 index 0000000000..9c6fd75eec --- /dev/null +++ b/js/xpconnect/src/XPCConvert.cpp @@ -0,0 +1,1649 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Data conversion between native and JavaScript types. */ + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Range.h" +#include "mozilla/Sprintf.h" + +#include "xpcprivate.h" +#include "nsIScriptError.h" +#include "nsISimpleEnumerator.h" +#include "nsWrapperCache.h" +#include "nsJSUtils.h" +#include "nsQueryObject.h" +#include "nsScriptError.h" +#include "WrapperFactory.h" + +#include "nsWrapperCacheInlines.h" + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject +#include "js/CharacterEncoding.h" +#include "js/experimental/TypedData.h" // JS_GetArrayBufferViewType, JS_GetArrayBufferViewData, JS_GetTypedArrayLength, JS_IsTypedArrayObject +#include "js/MemoryFunctions.h" +#include "js/Object.h" // JS::GetClass +#include "js/PropertyAndElement.h" // JS_DefineElement, JS_GetElement +#include "js/String.h" // JS::StringHasLatin1Chars + +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/PrimitiveConversions.h" +#include "mozilla/dom/Promise.h" + +using namespace xpc; +using namespace mozilla; +using namespace mozilla::dom; +using namespace JS; + +// #define STRICT_CHECK_OF_UNICODE +#ifdef STRICT_CHECK_OF_UNICODE +# define ILLEGAL_RANGE(c) (0 != ((c)&0xFF80)) +#else // STRICT_CHECK_OF_UNICODE +# define ILLEGAL_RANGE(c) (0 != ((c)&0xFF00)) +#endif // STRICT_CHECK_OF_UNICODE + +#define ILLEGAL_CHAR_RANGE(c) (0 != ((c)&0x80)) + +/***************************************************************************/ + +// static +bool XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface) { + if (JS::GetClass(obj)->slot0IsISupports()) { + *iface = JS::GetObjectISupports<nsISupports>(obj); + return true; + } + *iface = UnwrapDOMObjectToISupports(obj); + return !!*iface; +} + +/***************************************************************************/ + +// static +bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d, + const void* s, const nsXPTType& type, + const nsID* iid, uint32_t arrlen, + nsresult* pErr) { + MOZ_ASSERT(s, "bad param"); + + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE; + } + + switch (type.Tag()) { + case nsXPTType::T_I8: + d.setInt32(*static_cast<const int8_t*>(s)); + return true; + case nsXPTType::T_I16: + d.setInt32(*static_cast<const int16_t*>(s)); + return true; + case nsXPTType::T_I32: + d.setInt32(*static_cast<const int32_t*>(s)); + return true; + case nsXPTType::T_I64: + d.setNumber(static_cast<double>(*static_cast<const int64_t*>(s))); + return true; + case nsXPTType::T_U8: + d.setInt32(*static_cast<const uint8_t*>(s)); + return true; + case nsXPTType::T_U16: + d.setInt32(*static_cast<const uint16_t*>(s)); + return true; + case nsXPTType::T_U32: + d.setNumber(*static_cast<const uint32_t*>(s)); + return true; + case nsXPTType::T_U64: + d.setNumber(static_cast<double>(*static_cast<const uint64_t*>(s))); + return true; + case nsXPTType::T_FLOAT: + d.setNumber(*static_cast<const float*>(s)); + return true; + case nsXPTType::T_DOUBLE: + d.set(JS_NumberValue(*static_cast<const double*>(s))); + return true; + case nsXPTType::T_BOOL: + d.setBoolean(*static_cast<const bool*>(s)); + return true; + case nsXPTType::T_CHAR: { + char p = *static_cast<const char*>(s); + +#ifdef STRICT_CHECK_OF_UNICODE + MOZ_ASSERT(!ILLEGAL_CHAR_RANGE(p), "passing non ASCII data"); +#endif // STRICT_CHECK_OF_UNICODE + + JSString* str = JS_NewStringCopyN(cx, &p, 1); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + case nsXPTType::T_WCHAR: { + char16_t p = *static_cast<const char16_t*>(s); + + JSString* str = JS_NewUCStringCopyN(cx, &p, 1); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + + case nsXPTType::T_JSVAL: { + d.set(*static_cast<const Value*>(s)); + return JS_WrapValue(cx, d); + } + + case nsXPTType::T_VOID: + XPC_LOG_ERROR(("XPCConvert::NativeData2JS : void* params not supported")); + return false; + + case nsXPTType::T_NSIDPTR: { + nsID* iid2 = *static_cast<nsID* const*>(s); + if (!iid2) { + d.setNull(); + return true; + } + + return xpc::ID2JSValue(cx, *iid2, d); + } + + case nsXPTType::T_NSID: + return xpc::ID2JSValue(cx, *static_cast<const nsID*>(s), d); + + case nsXPTType::T_ASTRING: { + const nsAString* p = static_cast<const nsAString*>(s); + if (!p || p->IsVoid()) { + d.setNull(); + return true; + } + + nsStringBuffer* buf; + if (!XPCStringConvert::ReadableToJSVal(cx, *p, &buf, d)) { + return false; + } + if (buf) { + buf->AddRef(); + } + return true; + } + + case nsXPTType::T_CHAR_STR: { + const char* p = *static_cast<const char* const*>(s); + arrlen = p ? strlen(p) : 0; + [[fallthrough]]; + } + case nsXPTType::T_PSTRING_SIZE_IS: { + const char* p = *static_cast<const char* const*>(s); + if (!p) { + d.setNull(); + return true; + } + +#ifdef STRICT_CHECK_OF_UNICODE + bool isAscii = true; + for (uint32_t i = 0; i < arrlen; i++) { + if (ILLEGAL_CHAR_RANGE(p[i])) { + isAscii = false; + } + } + MOZ_ASSERT(isAscii, "passing non ASCII data"); +#endif // STRICT_CHECK_OF_UNICODE + + JSString* str = JS_NewStringCopyN(cx, p, arrlen); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + + case nsXPTType::T_WCHAR_STR: { + const char16_t* p = *static_cast<const char16_t* const*>(s); + arrlen = p ? nsCharTraits<char16_t>::length(p) : 0; + [[fallthrough]]; + } + case nsXPTType::T_PWSTRING_SIZE_IS: { + const char16_t* p = *static_cast<const char16_t* const*>(s); + if (!p) { + d.setNull(); + return true; + } + + JSString* str = JS_NewUCStringCopyN(cx, p, arrlen); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + + case nsXPTType::T_UTF8STRING: { + const nsACString* utf8String = static_cast<const nsACString*>(s); + + if (!utf8String || utf8String->IsVoid()) { + d.setNull(); + return true; + } + + if (utf8String->IsEmpty()) { + d.set(JS_GetEmptyStringValue(cx)); + return true; + } + + uint32_t len = utf8String->Length(); + auto allocLen = CheckedUint32(len) + 1; + if (!allocLen.isValid()) { + return false; + } + + // Usage of UTF-8 in XPConnect is mostly for things that are + // almost always ASCII, so the inexact allocations below + // should be fine. + + if (IsUtf8Latin1(*utf8String)) { + using UniqueLatin1Chars = + js::UniquePtr<JS::Latin1Char[], JS::FreePolicy>; + + UniqueLatin1Chars buffer(static_cast<JS::Latin1Char*>( + JS_string_malloc(cx, allocLen.value()))); + if (!buffer) { + return false; + } + + size_t written = LossyConvertUtf8toLatin1( + *utf8String, Span(reinterpret_cast<char*>(buffer.get()), len)); + buffer[written] = 0; + + // written can never exceed len, so the truncation is OK. + JSString* str = JS_NewLatin1String(cx, std::move(buffer), written); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + + // 1-byte sequences decode to 1 UTF-16 code unit + // 2-byte sequences decode to 1 UTF-16 code unit + // 3-byte sequences decode to 1 UTF-16 code unit + // 4-byte sequences decode to 2 UTF-16 code units + // So the number of output code units never exceeds + // the number of input code units (but see the comment + // below). allocLen already takes the zero terminator + // into account. + allocLen *= sizeof(char16_t); + if (!allocLen.isValid()) { + return false; + } + + JS::UniqueTwoByteChars buffer( + static_cast<char16_t*>(JS_string_malloc(cx, allocLen.value()))); + if (!buffer) { + return false; + } + + // For its internal simplicity, ConvertUTF8toUTF16 requires the + // destination to be one code unit longer than the source, but + // it never actually writes more code units than the number of + // code units in the source. That's why it's OK to claim the + // output buffer has len + 1 space but then still expect to + // have space for the zero terminator. + size_t written = + ConvertUtf8toUtf16(*utf8String, Span(buffer.get(), allocLen.value())); + MOZ_RELEASE_ASSERT(written <= len); + buffer[written] = 0; + + JSString* str = JS_NewUCStringDontDeflate(cx, std::move(buffer), written); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + case nsXPTType::T_CSTRING: { + const nsACString* cString = static_cast<const nsACString*>(s); + + if (!cString || cString->IsVoid()) { + d.setNull(); + return true; + } + + // c-strings (binary blobs) are deliberately not converted from + // UTF-8 to UTF-16. T_UTF8Sting is for UTF-8 encoded strings + // with automatic conversion. + JSString* str = JS_NewStringCopyN(cx, cString->Data(), cString->Length()); + if (!str) { + return false; + } + + d.setString(str); + return true; + } + + case nsXPTType::T_INTERFACE: + case nsXPTType::T_INTERFACE_IS: { + nsISupports* iface = *static_cast<nsISupports* const*>(s); + if (!iface) { + d.setNull(); + return true; + } + + if (iid->Equals(NS_GET_IID(nsIVariant))) { + nsCOMPtr<nsIVariant> variant = do_QueryInterface(iface); + if (!variant) { + return false; + } + + return XPCVariant::VariantDataToJS(cx, variant, pErr, d); + } + + xpcObjectHelper helper(iface); + return NativeInterface2JSObject(cx, d, helper, iid, true, pErr); + } + + case nsXPTType::T_DOMOBJECT: { + void* ptr = *static_cast<void* const*>(s); + if (!ptr) { + d.setNull(); + return true; + } + + return type.GetDOMObjectInfo().Wrap(cx, ptr, d); + } + + case nsXPTType::T_PROMISE: { + Promise* promise = *static_cast<Promise* const*>(s); + if (!promise) { + d.setNull(); + return true; + } + + RootedObject jsobj(cx, promise->PromiseObj()); + if (!JS_WrapObject(cx, &jsobj)) { + return false; + } + d.setObject(*jsobj); + return true; + } + + case nsXPTType::T_LEGACY_ARRAY: + return NativeArray2JS(cx, d, *static_cast<const void* const*>(s), + type.ArrayElementType(), iid, arrlen, pErr); + + case nsXPTType::T_ARRAY: { + auto* array = static_cast<const xpt::detail::UntypedTArray*>(s); + return NativeArray2JS(cx, d, array->Elements(), type.ArrayElementType(), + iid, array->Length(), pErr); + } + + default: + NS_ERROR("bad type"); + return false; + } +} + +/***************************************************************************/ + +#ifdef DEBUG +static bool CheckChar16InCharRange(char16_t c) { + if (ILLEGAL_RANGE(c)) { + /* U+0080/U+0100 - U+FFFF data lost. */ + static const size_t MSG_BUF_SIZE = 64; + char msg[MSG_BUF_SIZE]; + SprintfLiteral(msg, + "char16_t out of char range; high bits of data lost: 0x%x", + int(c)); + NS_WARNING(msg); + return false; + } + + return true; +} + +template <typename CharT> +static void CheckCharsInCharRange(const CharT* chars, size_t len) { + for (size_t i = 0; i < len; i++) { + if (!CheckChar16InCharRange(chars[i])) { + break; + } + } +} +#endif + +template <typename T> +bool ConvertToPrimitive(JSContext* cx, HandleValue v, T* retval) { + return ValueToPrimitive<T, eDefault>(cx, v, "Value", retval); +} + +// static +bool XPCConvert::JSData2Native(JSContext* cx, void* d, HandleValue s, + const nsXPTType& type, const nsID* iid, + uint32_t arrlen, nsresult* pErr) { + MOZ_ASSERT(d, "bad param"); + + js::AssertSameCompartment(cx, s); + + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_JS; + } + + bool sizeis = + type.Tag() == TD_PSTRING_SIZE_IS || type.Tag() == TD_PWSTRING_SIZE_IS; + + switch (type.Tag()) { + case nsXPTType::T_I8: + return ConvertToPrimitive(cx, s, static_cast<int8_t*>(d)); + case nsXPTType::T_I16: + return ConvertToPrimitive(cx, s, static_cast<int16_t*>(d)); + case nsXPTType::T_I32: + return ConvertToPrimitive(cx, s, static_cast<int32_t*>(d)); + case nsXPTType::T_I64: + return ConvertToPrimitive(cx, s, static_cast<int64_t*>(d)); + case nsXPTType::T_U8: + return ConvertToPrimitive(cx, s, static_cast<uint8_t*>(d)); + case nsXPTType::T_U16: + return ConvertToPrimitive(cx, s, static_cast<uint16_t*>(d)); + case nsXPTType::T_U32: + return ConvertToPrimitive(cx, s, static_cast<uint32_t*>(d)); + case nsXPTType::T_U64: + return ConvertToPrimitive(cx, s, static_cast<uint64_t*>(d)); + case nsXPTType::T_FLOAT: + return ConvertToPrimitive(cx, s, static_cast<float*>(d)); + case nsXPTType::T_DOUBLE: + return ConvertToPrimitive(cx, s, static_cast<double*>(d)); + case nsXPTType::T_BOOL: + return ConvertToPrimitive(cx, s, static_cast<bool*>(d)); + case nsXPTType::T_CHAR: { + JSString* str = ToString(cx, s); + if (!str) { + return false; + } + + char16_t ch; + if (JS_GetStringLength(str) == 0) { + ch = 0; + } else { + if (!JS_GetStringCharAt(cx, str, 0, &ch)) { + return false; + } + } +#ifdef DEBUG + CheckChar16InCharRange(ch); +#endif + *((char*)d) = char(ch); + break; + } + case nsXPTType::T_WCHAR: { + JSString* str; + if (!(str = ToString(cx, s))) { + return false; + } + size_t length = JS_GetStringLength(str); + if (length == 0) { + *((uint16_t*)d) = 0; + break; + } + + char16_t ch; + if (!JS_GetStringCharAt(cx, str, 0, &ch)) { + return false; + } + + *((uint16_t*)d) = uint16_t(ch); + break; + } + case nsXPTType::T_JSVAL: + *((Value*)d) = s; + break; + case nsXPTType::T_VOID: + XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported")); + NS_ERROR("void* params not supported"); + return false; + + case nsXPTType::T_NSIDPTR: + if (Maybe<nsID> id = xpc::JSValue2ID(cx, s)) { + *((const nsID**)d) = id.ref().Clone(); + return true; + } + return false; + + case nsXPTType::T_NSID: + if (Maybe<nsID> id = xpc::JSValue2ID(cx, s)) { + *((nsID*)d) = id.ref(); + return true; + } + return false; + + case nsXPTType::T_ASTRING: { + nsAString* ws = (nsAString*)d; + if (s.isUndefined() || s.isNull()) { + ws->SetIsVoid(true); + return true; + } + size_t length = 0; + JSString* str = ToString(cx, s); + if (!str) { + return false; + } + + length = JS_GetStringLength(str); + if (!length) { + ws->Truncate(); + return true; + } + + return AssignJSString(cx, *ws, str); + } + + case nsXPTType::T_CHAR_STR: + case nsXPTType::T_PSTRING_SIZE_IS: { + if (s.isUndefined() || s.isNull()) { + if (sizeis && 0 != arrlen) { + if (pErr) { + *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING; + } + return false; + } + *((char**)d) = nullptr; + return true; + } + + JSString* str = ToString(cx, s); + if (!str) { + return false; + } + +#ifdef DEBUG + if (JS::StringHasLatin1Chars(str)) { + size_t len; + AutoCheckCannotGC nogc; + const Latin1Char* chars = + JS_GetLatin1StringCharsAndLength(cx, nogc, str, &len); + if (chars) { + CheckCharsInCharRange(chars, len); + } + } else { + size_t len; + AutoCheckCannotGC nogc; + const char16_t* chars = + JS_GetTwoByteStringCharsAndLength(cx, nogc, str, &len); + if (chars) { + CheckCharsInCharRange(chars, len); + } + } +#endif // DEBUG + + size_t length = JS_GetStringEncodingLength(cx, str); + if (length == size_t(-1)) { + return false; + } + if (sizeis) { + if (length > arrlen) { + if (pErr) { + *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING; + } + return false; + } + if (length < arrlen) { + length = arrlen; + } + } + char* buffer = static_cast<char*>(moz_xmalloc(length + 1)); + if (!JS_EncodeStringToBuffer(cx, str, buffer, length)) { + free(buffer); + return false; + } + buffer[length] = '\0'; + *((void**)d) = buffer; + return true; + } + + case nsXPTType::T_WCHAR_STR: + case nsXPTType::T_PWSTRING_SIZE_IS: { + JSString* str; + + if (s.isUndefined() || s.isNull()) { + if (sizeis && 0 != arrlen) { + if (pErr) { + *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING; + } + return false; + } + *((char16_t**)d) = nullptr; + return true; + } + + if (!(str = ToString(cx, s))) { + return false; + } + size_t len = JS_GetStringLength(str); + if (sizeis) { + if (len > arrlen) { + if (pErr) { + *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING; + } + return false; + } + if (len < arrlen) { + len = arrlen; + } + } + + size_t byte_len = (len + 1) * sizeof(char16_t); + *((void**)d) = moz_xmalloc(byte_len); + mozilla::Range<char16_t> destChars(*((char16_t**)d), len + 1); + if (!JS_CopyStringChars(cx, destChars, str)) { + return false; + } + destChars[len] = 0; + + return true; + } + + case nsXPTType::T_UTF8STRING: { + nsACString* rs = (nsACString*)d; + if (s.isNull() || s.isUndefined()) { + rs->SetIsVoid(true); + return true; + } + + // The JS val is neither null nor void... + JSString* str = ToString(cx, s); + if (!str) { + return false; + } + + size_t length = JS_GetStringLength(str); + if (!length) { + rs->Truncate(); + return true; + } + + JSLinearString* linear = JS_EnsureLinearString(cx, str); + if (!linear) { + return false; + } + + size_t utf8Length = JS::GetDeflatedUTF8StringLength(linear); + if (!rs->SetLength(utf8Length, fallible)) { + if (pErr) { + *pErr = NS_ERROR_OUT_OF_MEMORY; + } + return false; + } + + mozilla::DebugOnly<size_t> written = JS::DeflateStringToUTF8Buffer( + linear, mozilla::Span(rs->BeginWriting(), utf8Length)); + MOZ_ASSERT(written == utf8Length); + + return true; + } + + case nsXPTType::T_CSTRING: { + nsACString* rs = (nsACString*)d; + if (s.isNull() || s.isUndefined()) { + rs->SetIsVoid(true); + return true; + } + + // The JS val is neither null nor void... + JSString* str = ToString(cx, s); + if (!str) { + return false; + } + + size_t length = JS_GetStringEncodingLength(cx, str); + if (length == size_t(-1)) { + return false; + } + + if (!length) { + rs->Truncate(); + return true; + } + + if (!rs->SetLength(uint32_t(length), fallible)) { + if (pErr) { + *pErr = NS_ERROR_OUT_OF_MEMORY; + } + return false; + } + if (rs->Length() != uint32_t(length)) { + return false; + } + if (!JS_EncodeStringToBuffer(cx, str, rs->BeginWriting(), length)) { + return false; + } + + return true; + } + + case nsXPTType::T_INTERFACE: + case nsXPTType::T_INTERFACE_IS: { + MOZ_ASSERT(iid, "can't do interface conversions without iid"); + + if (iid->Equals(NS_GET_IID(nsIVariant))) { + nsCOMPtr<nsIVariant> variant = XPCVariant::newVariant(cx, s); + if (!variant) { + return false; + } + + variant.forget(static_cast<nsISupports**>(d)); + return true; + } + + if (s.isNullOrUndefined()) { + *((nsISupports**)d) = nullptr; + return true; + } + + // only wrap JSObjects + if (!s.isObject()) { + if (pErr && s.isInt32() && 0 == s.toInt32()) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL; + } + return false; + } + + RootedObject src(cx, &s.toObject()); + return JSObject2NativeInterface(cx, (void**)d, src, iid, nullptr, pErr); + } + + case nsXPTType::T_DOMOBJECT: { + if (s.isNullOrUndefined()) { + *((void**)d) = nullptr; + return true; + } + + // Can't handle non-JSObjects + if (!s.isObject()) { + return false; + } + + nsresult err = type.GetDOMObjectInfo().Unwrap(s, (void**)d, cx); + if (pErr) { + *pErr = err; + } + return NS_SUCCEEDED(err); + } + + case nsXPTType::T_PROMISE: { + nsIGlobalObject* glob = CurrentNativeGlobal(cx); + if (!glob) { + if (pErr) { + *pErr = NS_ERROR_UNEXPECTED; + } + return false; + } + + // Call Promise::Resolve to create a Promise object. This allows us to + // support returning non-promise values from Promise-returning functions + // in JS. + IgnoredErrorResult err; + *(Promise**)d = Promise::Resolve(glob, cx, s, err).take(); + bool ok = !err.Failed(); + if (pErr) { + *pErr = err.StealNSResult(); + } + + return ok; + } + + case nsXPTType::T_LEGACY_ARRAY: { + void** dest = (void**)d; + const nsXPTType& elty = type.ArrayElementType(); + + *dest = nullptr; + + // FIXME: XPConnect historically has shortcut the JSArray2Native codepath + // in its caller if arrlen is 0, allowing arbitrary values to be passed as + // arrays and interpreted as the empty array (bug 1458987). + // + // NOTE: Once this is fixed, null/undefined should be allowed for arrays + // if arrlen is 0. + if (arrlen == 0) { + return true; + } + + bool ok = JSArray2Native( + cx, s, elty, iid, pErr, [&](uint32_t* aLength) -> void* { + // Check that we have enough elements in our array. + if (*aLength < arrlen) { + if (pErr) { + *pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY; + } + return nullptr; + } + *aLength = arrlen; + + // Allocate the backing buffer & return it. + *dest = moz_xmalloc(*aLength * elty.Stride()); + return *dest; + }); + + if (!ok && *dest) { + // An error occurred, free any allocated backing buffer. + free(*dest); + *dest = nullptr; + } + return ok; + } + + case nsXPTType::T_ARRAY: { + auto* dest = (xpt::detail::UntypedTArray*)d; + const nsXPTType& elty = type.ArrayElementType(); + + bool ok = JSArray2Native(cx, s, elty, iid, pErr, + [&](uint32_t* aLength) -> void* { + if (!dest->SetLength(elty, *aLength)) { + if (pErr) { + *pErr = NS_ERROR_OUT_OF_MEMORY; + } + return nullptr; + } + return dest->Elements(); + }); + + if (!ok) { + // An error occurred, free any allocated backing buffer. + dest->Clear(); + } + return ok; + } + + default: + NS_ERROR("bad type"); + return false; + } + return true; +} + +/***************************************************************************/ +// static +bool XPCConvert::NativeInterface2JSObject(JSContext* cx, MutableHandleValue d, + xpcObjectHelper& aHelper, + const nsID* iid, + bool allowNativeWrapper, + nsresult* pErr) { + if (!iid) { + iid = &NS_GET_IID(nsISupports); + } + + d.setNull(); + if (!aHelper.Object()) { + return true; + } + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE; + } + + // We used to have code here that unwrapped and simply exposed the + // underlying JSObject. That caused anomolies when JSComponents were + // accessed from other JS code - they didn't act like other xpconnect + // wrapped components. So, instead, we create "double wrapped" objects + // (that means an XPCWrappedNative around an nsXPCWrappedJS). This isn't + // optimal -- we could detect this and roll the functionality into a + // single wrapper, but the current solution is good enough for now. + XPCWrappedNativeScope* xpcscope = ObjectScope(JS::CurrentGlobalOrNull(cx)); + if (!xpcscope) { + return false; + } + + JSAutoRealm ar(cx, xpcscope->GetGlobalForWrappedNatives()); + + // First, see if this object supports the wrapper cache. In that case, the + // object to use is found as cache->GetWrapper(). If that is null, then the + // object will create (and fill the cache) from its WrapObject call. + nsWrapperCache* cache = aHelper.GetWrapperCache(); + + RootedObject flat(cx, cache ? cache->GetWrapper() : nullptr); + if (!flat && cache) { + RootedObject global(cx, CurrentGlobalOrNull(cx)); + flat = cache->WrapObject(cx, nullptr); + if (!flat) { + return false; + } + } + if (flat) { + if (allowNativeWrapper && !JS_WrapObject(cx, &flat)) { + return false; + } + d.setObjectOrNull(flat); + return true; + } + + // Go ahead and create an XPCWrappedNative for this object. + RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, iid); + if (!iface) { + return false; + } + + RefPtr<XPCWrappedNative> wrapper; + nsresult rv = XPCWrappedNative::GetNewOrUsed(cx, aHelper, xpcscope, iface, + getter_AddRefs(wrapper)); + if (NS_FAILED(rv) && pErr) { + *pErr = rv; + } + + // If creating the wrapped native failed, then return early. + if (NS_FAILED(rv) || !wrapper) { + return false; + } + + // If we're not creating security wrappers, we can return the + // XPCWrappedNative as-is here. + flat = wrapper->GetFlatJSObject(); + if (!allowNativeWrapper) { + d.setObjectOrNull(flat); + if (pErr) { + *pErr = NS_OK; + } + return true; + } + + // The call to wrap here handles both cross-compartment and same-compartment + // security wrappers. + RootedObject original(cx, flat); + if (!JS_WrapObject(cx, &flat)) { + return false; + } + + d.setObjectOrNull(flat); + + if (pErr) { + *pErr = NS_OK; + } + + return true; +} + +/***************************************************************************/ + +// static +bool XPCConvert::JSObject2NativeInterface(JSContext* cx, void** dest, + HandleObject src, const nsID* iid, + nsISupports* aOuter, nsresult* pErr) { + MOZ_ASSERT(dest, "bad param"); + MOZ_ASSERT(src, "bad param"); + MOZ_ASSERT(iid, "bad param"); + + js::AssertSameCompartment(cx, src); + + *dest = nullptr; + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_JS; + } + + nsISupports* iface; + + if (!aOuter) { + // Note that if we have a non-null aOuter then it means that we are + // forcing the creation of a wrapper even if the object *is* a + // wrappedNative or other wise has 'nsISupportness'. + // This allows wrapJSAggregatedToNative to work. + + // If we're looking at a security wrapper, see now if we're allowed to + // pass it to C++. If we are, then fall through to the code below. If + // we aren't, throw an exception eagerly. + // + // NB: It's very important that we _don't_ unwrap in the aOuter case, + // because the caller may explicitly want to create the XPCWrappedJS + // around a security wrapper. XBL does this with Xrays from the XBL + // scope - see nsBindingManager::GetBindingImplementation. + // + // It's also very important that "inner" be rooted here. + RootedObject inner( + cx, js::CheckedUnwrapDynamic(src, cx, + /* stopAtWindowProxy = */ false)); + if (!inner) { + if (pErr) { + *pErr = NS_ERROR_XPC_SECURITY_MANAGER_VETO; + } + return false; + } + + // Is this really a native xpcom object with a wrapper? + XPCWrappedNative* wrappedNative = nullptr; + if (IsWrappedNativeReflector(inner)) { + wrappedNative = XPCWrappedNative::Get(inner); + } + if (wrappedNative) { + iface = wrappedNative->GetIdentityObject(); + return NS_SUCCEEDED(iface->QueryInterface(*iid, dest)); + } + // else... + + // Deal with slim wrappers here. + if (GetISupportsFromJSObject(inner ? inner : src, &iface)) { + if (iface && NS_SUCCEEDED(iface->QueryInterface(*iid, dest))) { + return true; + } + + // If that failed, and iid is for mozIDOMWindowProxy, we actually + // want the outer! + if (iid->Equals(NS_GET_IID(mozIDOMWindowProxy))) { + if (nsCOMPtr<mozIDOMWindow> inner = do_QueryInterface(iface)) { + iface = nsPIDOMWindowInner::From(inner)->GetOuterWindow(); + return NS_SUCCEEDED(iface->QueryInterface(*iid, dest)); + } + } + + return false; + } + } + + RefPtr<nsXPCWrappedJS> wrapper; + nsresult rv = + nsXPCWrappedJS::GetNewOrUsed(cx, src, *iid, getter_AddRefs(wrapper)); + if (pErr) { + *pErr = rv; + } + + if (NS_FAILED(rv) || !wrapper) { + return false; + } + + // If the caller wanted to aggregate this JS object to a native, + // attach it to the wrapper. Note that we allow a maximum of one + // aggregated native for a given XPCWrappedJS. + if (aOuter) { + wrapper->SetAggregatedNativeObject(aOuter); + } + + // We need to go through the QueryInterface logic to make this return + // the right thing for the various 'special' interfaces; e.g. + // nsISimpleEnumerator. We must use AggregatedQueryInterface in cases where + // there is an outer to avoid nasty recursion. + rv = aOuter ? wrapper->AggregatedQueryInterface(*iid, dest) + : wrapper->QueryInterface(*iid, dest); + if (pErr) { + *pErr = rv; + } + return NS_SUCCEEDED(rv); +} + +/***************************************************************************/ +/***************************************************************************/ + +// static +nsresult XPCConvert::ConstructException(nsresult rv, const char* message, + const char* ifaceName, + const char* methodName, + nsISupports* data, Exception** exceptn, + JSContext* cx, Value* jsExceptionPtr) { + MOZ_ASSERT(!cx == !jsExceptionPtr, + "Expected cx and jsExceptionPtr to cooccur."); + + static const char format[] = "\'%s\' when calling method: [%s::%s]"; + const char* msg = message; + nsAutoCString sxmsg; // must have the same lifetime as msg + + nsCOMPtr<nsIScriptError> errorObject = do_QueryInterface(data); + if (errorObject) { + nsString xmsg; + if (NS_SUCCEEDED(errorObject->GetMessageMoz(xmsg))) { + CopyUTF16toUTF8(xmsg, sxmsg); + msg = sxmsg.get(); + } + } + if (!msg) { + if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &msg) || !msg) { + msg = "<error>"; + } + } + + nsCString msgStr(msg); + if (ifaceName && methodName) { + msgStr.AppendPrintf(format, msg, ifaceName, methodName); + } + + RefPtr<Exception> e = new Exception(msgStr, rv, ""_ns, nullptr, data); + + if (cx && jsExceptionPtr) { + e->StowJSVal(*jsExceptionPtr); + } + + e.forget(exceptn); + return NS_OK; +} + +/********************************/ + +class MOZ_STACK_CLASS AutoExceptionRestorer { + public: + AutoExceptionRestorer(JSContext* cx, const Value& v) + : mContext(cx), tvr(cx, v) { + JS_ClearPendingException(mContext); + } + + ~AutoExceptionRestorer() { JS_SetPendingException(mContext, tvr); } + + private: + JSContext* const mContext; + RootedValue tvr; +}; + +static nsresult JSErrorToXPCException(JSContext* cx, const char* toStringResult, + const char* ifaceName, + const char* methodName, + const JSErrorReport* report, + Exception** exceptn) { + nsresult rv = NS_ERROR_FAILURE; + RefPtr<nsScriptError> data; + if (report) { + nsAutoString bestMessage; + if (report->message()) { + CopyUTF8toUTF16(mozilla::MakeStringSpan(report->message().c_str()), + bestMessage); + } else if (toStringResult) { + CopyUTF8toUTF16(mozilla::MakeStringSpan(toStringResult), bestMessage); + } else { + bestMessage.AssignLiteral("JavaScript Error"); + } + + const char16_t* linebuf = report->linebuf(); + uint32_t flags = report->isWarning() ? nsIScriptError::warningFlag + : nsIScriptError::errorFlag; + + data = new nsScriptError(); + data->nsIScriptError::InitWithWindowID( + bestMessage, NS_ConvertUTF8toUTF16(report->filename), + linebuf ? nsDependentString(linebuf, report->linebufLength()) + : EmptyString(), + report->lineno, report->tokenOffset(), flags, "XPConnect JavaScript"_ns, + nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx)); + } + + if (data) { + // Pass nullptr for the message: ConstructException will get a message + // from the nsIScriptError. + rv = XPCConvert::ConstructException( + NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS, nullptr, ifaceName, + methodName, static_cast<nsIScriptError*>(data.get()), exceptn, nullptr, + nullptr); + } else { + rv = XPCConvert::ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR, nullptr, + ifaceName, methodName, nullptr, exceptn, + nullptr, nullptr); + } + return rv; +} + +// static +nsresult XPCConvert::JSValToXPCException(JSContext* cx, MutableHandleValue s, + const char* ifaceName, + const char* methodName, + Exception** exceptn) { + AutoExceptionRestorer aer(cx, s); + + if (!s.isPrimitive()) { + // we have a JSObject + RootedObject obj(cx, s.toObjectOrNull()); + + if (!obj) { + NS_ERROR("when is an object not an object?"); + return NS_ERROR_FAILURE; + } + + // is this really a native xpcom object with a wrapper? + JSObject* unwrapped = + js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false); + if (!unwrapped) { + return NS_ERROR_XPC_SECURITY_MANAGER_VETO; + } + // It's OK to use ReflectorToISupportsStatic, because we have already + // stripped off wrappers. + if (nsCOMPtr<nsISupports> supports = + ReflectorToISupportsStatic(unwrapped)) { + nsCOMPtr<Exception> iface = do_QueryInterface(supports); + if (iface) { + // just pass through the exception (with extra ref and all) + iface.forget(exceptn); + return NS_OK; + } + + // it is a wrapped native, but not an exception! + return ConstructException(NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT, nullptr, + ifaceName, methodName, supports, exceptn, + nullptr, nullptr); + } else { + // It is a JSObject, but not a wrapped native... + + // If it is an engine Error with an error report then let's + // extract the report and build an xpcexception from that + const JSErrorReport* report; + if (nullptr != (report = JS_ErrorFromException(cx, obj))) { + JS::UniqueChars toStringResult; + RootedString str(cx, ToString(cx, s)); + if (str) { + toStringResult = JS_EncodeStringToUTF8(cx, str); + } + return JSErrorToXPCException(cx, toStringResult.get(), ifaceName, + methodName, report, exceptn); + } + + // XXX we should do a check against 'js_ErrorClass' here and + // do the right thing - even though it has no JSErrorReport, + // The fact that it is a JSError exceptions means we can extract + // particular info and our 'result' should reflect that. + + // otherwise we'll just try to convert it to a string + + JSString* str = ToString(cx, s); + if (!str) { + return NS_ERROR_FAILURE; + } + + JS::UniqueChars strBytes = JS_EncodeStringToLatin1(cx, str); + if (!strBytes) { + return NS_ERROR_FAILURE; + } + + return ConstructException(NS_ERROR_XPC_JS_THREW_JS_OBJECT, strBytes.get(), + ifaceName, methodName, nullptr, exceptn, cx, + s.address()); + } + } + + if (s.isUndefined() || s.isNull()) { + return ConstructException(NS_ERROR_XPC_JS_THREW_NULL, nullptr, ifaceName, + methodName, nullptr, exceptn, cx, s.address()); + } + + if (s.isNumber()) { + // lets see if it looks like an nsresult + nsresult rv; + double number; + bool isResult = false; + + if (s.isInt32()) { + rv = (nsresult)s.toInt32(); + if (NS_FAILED(rv)) { + isResult = true; + } else { + number = (double)s.toInt32(); + } + } else { + number = s.toDouble(); + if (number > 0.0 && number < (double)0xffffffff && + 0.0 == fmod(number, 1)) { + // Visual Studio 9 doesn't allow casting directly from a + // double to an enumeration type, contrary to 5.2.9(10) of + // C++11, so add an intermediate cast. + rv = (nsresult)(uint32_t)number; + if (NS_FAILED(rv)) { + isResult = true; + } + } + } + + if (isResult) { + return ConstructException(rv, nullptr, ifaceName, methodName, nullptr, + exceptn, cx, s.address()); + } else { + // XXX all this nsISupportsDouble code seems a little redundant + // now that we're storing the Value in the exception... + nsCOMPtr<nsISupportsDouble> data; + nsCOMPtr<nsIComponentManager> cm; + if (NS_FAILED(NS_GetComponentManager(getter_AddRefs(cm))) || !cm || + NS_FAILED(cm->CreateInstanceByContractID( + NS_SUPPORTS_DOUBLE_CONTRACTID, NS_GET_IID(nsISupportsDouble), + getter_AddRefs(data)))) { + return NS_ERROR_FAILURE; + } + data->SetData(number); + rv = ConstructException(NS_ERROR_XPC_JS_THREW_NUMBER, nullptr, ifaceName, + methodName, data, exceptn, cx, s.address()); + return rv; + } + } + + // otherwise we'll just try to convert it to a string + // Note: e.g., bools get converted to JSStrings by this code. + + JSString* str = ToString(cx, s); + if (str) { + if (JS::UniqueChars strBytes = JS_EncodeStringToLatin1(cx, str)) { + return ConstructException(NS_ERROR_XPC_JS_THREW_STRING, strBytes.get(), + ifaceName, methodName, nullptr, exceptn, cx, + s.address()); + } + } + return NS_ERROR_FAILURE; +} + +/***************************************************************************/ + +// array fun... + +// static +bool XPCConvert::NativeArray2JS(JSContext* cx, MutableHandleValue d, + const void* buf, const nsXPTType& type, + const nsID* iid, uint32_t count, + nsresult* pErr) { + MOZ_ASSERT(buf || count == 0, "Must have buf or 0 elements"); + + RootedObject array(cx, JS::NewArrayObject(cx, count)); + if (!array) { + return false; + } + + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE; + } + + RootedValue current(cx, JS::NullValue()); + for (uint32_t i = 0; i < count; ++i) { + if (!NativeData2JS(cx, ¤t, type.ElementPtr(buf, i), type, iid, 0, + pErr) || + !JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) + return false; + } + + if (pErr) { + *pErr = NS_OK; + } + d.setObject(*array); + return true; +} + +// static +bool XPCConvert::JSArray2Native(JSContext* cx, JS::HandleValue aJSVal, + const nsXPTType& aEltType, const nsIID* aIID, + nsresult* pErr, + const ArrayAllocFixupLen& aAllocFixupLen) { + // Wrap aAllocFixupLen to check length is within bounds & initialize the + // allocated memory if needed. + auto allocFixupLen = [&](uint32_t* aLength) -> void* { + if (*aLength > (UINT32_MAX / aEltType.Stride())) { + return nullptr; // Byte length doesn't fit in uint32_t + } + + void* buf = aAllocFixupLen(aLength); + + // Ensure the buffer has valid values for each element. We can skip this + // for arithmetic types, as they do not require initialization. + if (buf && !aEltType.IsArithmetic()) { + for (uint32_t i = 0; i < *aLength; ++i) { + InitializeValue(aEltType, aEltType.ElementPtr(buf, i)); + } + } + return buf; + }; + + // JSArray2Native only accepts objects (Array and TypedArray). + if (!aJSVal.isObject()) { + if (pErr) { + *pErr = NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY; + } + return false; + } + RootedObject jsarray(cx, &aJSVal.toObject()); + + if (pErr) { + *pErr = NS_ERROR_XPC_BAD_CONVERT_JS; + } + + if (JS_IsTypedArrayObject(jsarray)) { + // Fast conversion of typed arrays to native using memcpy. No float or + // double canonicalization is done. ArrayBuffers are not accepted; + // create a properly typed array view on them first. The element type of + // array must match the XPCOM type in size, type and signedness exactly. + // As an exception, Uint8ClampedArray is allowed for arrays of uint8_t. + // DataViews are not supported. + + nsXPTTypeTag tag; + switch (JS_GetArrayBufferViewType(jsarray)) { + case js::Scalar::Int8: + tag = TD_INT8; + break; + case js::Scalar::Uint8: + tag = TD_UINT8; + break; + case js::Scalar::Uint8Clamped: + tag = TD_UINT8; + break; + case js::Scalar::Int16: + tag = TD_INT16; + break; + case js::Scalar::Uint16: + tag = TD_UINT16; + break; + case js::Scalar::Int32: + tag = TD_INT32; + break; + case js::Scalar::Uint32: + tag = TD_UINT32; + break; + case js::Scalar::Float32: + tag = TD_FLOAT; + break; + case js::Scalar::Float64: + tag = TD_DOUBLE; + break; + default: + return false; + } + if (aEltType.Tag() != tag) { + return false; + } + + // Allocate the backing buffer before getting the view data in case + // allocFixupLen can cause GCs. + uint32_t length; + { + // nsTArray and code below uses uint32_t lengths, so reject large typed + // arrays. + size_t fullLength = JS_GetTypedArrayLength(jsarray); + if (fullLength > UINT32_MAX) { + return false; + } + length = uint32_t(fullLength); + } + void* buf = allocFixupLen(&length); + if (!buf) { + return false; + } + + // Get the backing memory buffer to copy out of. + JS::AutoCheckCannotGC nogc; + bool isShared = false; + const void* data = JS_GetArrayBufferViewData(jsarray, &isShared, nogc); + + // Require opting in to shared memory - a future project. + if (isShared) { + return false; + } + + // Directly copy data into the allocated target buffer. + memcpy(buf, data, length * aEltType.Stride()); + return true; + } + + // If jsarray is not a TypedArrayObject, check for an Array object. + uint32_t length = 0; + bool isArray = false; + if (!JS::IsArrayObject(cx, jsarray, &isArray) || !isArray || + !JS::GetArrayLength(cx, jsarray, &length)) { + if (pErr) { + *pErr = NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY; + } + return false; + } + + void* buf = allocFixupLen(&length); + if (!buf) { + return false; + } + + // Translate each array element separately. + RootedValue current(cx); + for (uint32_t i = 0; i < length; ++i) { + if (!JS_GetElement(cx, jsarray, i, ¤t) || + !JSData2Native(cx, aEltType.ElementPtr(buf, i), current, aEltType, aIID, + 0, pErr)) { + // Array element conversion failed. Clean up all elements converted + // before the error. Caller handles freeing 'buf'. + for (uint32_t j = 0; j < i; ++j) { + DestructValue(aEltType, aEltType.ElementPtr(buf, j)); + } + return false; + } + } + + return true; +} + +/***************************************************************************/ + +// Internal implementation details for xpc::CleanupValue. + +void xpc::InnerCleanupValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen) { + MOZ_ASSERT(!aType.IsArithmetic(), + "Arithmetic types should not get to InnerCleanupValue!"); + MOZ_ASSERT(aArrayLen == 0 || aType.Tag() == nsXPTType::T_PSTRING_SIZE_IS || + aType.Tag() == nsXPTType::T_PWSTRING_SIZE_IS || + aType.Tag() == nsXPTType::T_LEGACY_ARRAY, + "Array lengths may only appear for certain types!"); + + switch (aType.Tag()) { + // Pointer types + case nsXPTType::T_DOMOBJECT: + aType.GetDOMObjectInfo().Cleanup(*(void**)aValue); + break; + + case nsXPTType::T_PROMISE: + (*(mozilla::dom::Promise**)aValue)->Release(); + break; + + case nsXPTType::T_INTERFACE: + case nsXPTType::T_INTERFACE_IS: + (*(nsISupports**)aValue)->Release(); + break; + + // String types + case nsXPTType::T_ASTRING: + ((nsAString*)aValue)->Truncate(); + break; + case nsXPTType::T_UTF8STRING: + case nsXPTType::T_CSTRING: + ((nsACString*)aValue)->Truncate(); + break; + + // Pointer Types + case nsXPTType::T_NSIDPTR: + case nsXPTType::T_CHAR_STR: + case nsXPTType::T_WCHAR_STR: + case nsXPTType::T_PSTRING_SIZE_IS: + case nsXPTType::T_PWSTRING_SIZE_IS: + free(*(void**)aValue); + break; + + // Legacy Array Type + case nsXPTType::T_LEGACY_ARRAY: { + const nsXPTType& elty = aType.ArrayElementType(); + void* elements = *(void**)aValue; + + for (uint32_t i = 0; i < aArrayLen; ++i) { + DestructValue(elty, elty.ElementPtr(elements, i)); + } + free(elements); + break; + } + + // Array Type + case nsXPTType::T_ARRAY: { + const nsXPTType& elty = aType.ArrayElementType(); + auto* array = (xpt::detail::UntypedTArray*)aValue; + + for (uint32_t i = 0; i < array->Length(); ++i) { + DestructValue(elty, elty.ElementPtr(array->Elements(), i)); + } + array->Clear(); + break; + } + + // Clear nsID& parameters to `0` + case nsXPTType::T_NSID: + ((nsID*)aValue)->Clear(); + break; + + // Clear the JS::Value to `undefined` + case nsXPTType::T_JSVAL: + ((JS::Value*)aValue)->setUndefined(); + break; + + // Non-arithmetic types requiring no cleanup + case nsXPTType::T_VOID: + break; + + default: + MOZ_CRASH("Unknown Type!"); + } + + // Clear any non-complex values to the valid '0' state. + if (!aType.IsComplex()) { + aType.ZeroValue(aValue); + } +} + +/***************************************************************************/ + +// Implementation of xpc::InitializeValue. + +void xpc::InitializeValue(const nsXPTType& aType, void* aValue) { + switch (aType.Tag()) { + // Use placement-new to initialize complex values +#define XPT_INIT_TYPE(tag, type) \ + case tag: \ + new (aValue) type(); \ + break; + XPT_FOR_EACH_COMPLEX_TYPE(XPT_INIT_TYPE) +#undef XPT_INIT_TYPE + + // The remaining types have valid states where all bytes are '0'. + default: + aType.ZeroValue(aValue); + break; + } +} + +// In XPT_FOR_EACH_COMPLEX_TYPE, typenames may be namespaced (such as +// xpt::UntypedTArray). Namespaced typenames cannot be used to explicitly invoke +// destructors, so this method acts as a helper to let us call the destructor of +// these objects. +template <typename T> +static void _DestructValueHelper(void* aValue) { + static_cast<T*>(aValue)->~T(); +} + +void xpc::DestructValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen) { + // Get aValue into an clean, empty state. + xpc::CleanupValue(aType, aValue, aArrayLen); + + // Run destructors on complex types. + switch (aType.Tag()) { +#define XPT_RUN_DESTRUCTOR(tag, type) \ + case tag: \ + _DestructValueHelper<type>(aValue); \ + break; + XPT_FOR_EACH_COMPLEX_TYPE(XPT_RUN_DESTRUCTOR) +#undef XPT_RUN_DESTRUCTOR + default: + break; // dtor is a no-op on other types. + } +} diff --git a/js/xpconnect/src/XPCDebug.cpp b/js/xpconnect/src/XPCDebug.cpp new file mode 100644 index 0000000000..25cf8758b2 --- /dev/null +++ b/js/xpconnect/src/XPCDebug.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "js/friend/DumpFunctions.h" // JS::FormatStackDump +#include "nsThreadUtils.h" +#include "nsContentUtils.h" + +#include "mozilla/Sprintf.h" + +#ifdef XP_WIN +# include <windows.h> +# include "nsPrintfCString.h" +#endif + +#ifdef ANDROID +# include <android/log.h> +#endif + +static void DebugDump(const char* str) { +#ifdef XP_WIN + if (IsDebuggerPresent()) { + nsPrintfCString output("%s\n", str); + OutputDebugStringA(output.get()); + } +#elif defined(ANDROID) + __android_log_print(ANDROID_LOG_DEBUG, "Gecko", "%s\n", str); +#endif + printf("%s\n", str); +} + +bool xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps) { + JSContext* cx = nsContentUtils::GetCurrentJSContext(); + if (!cx) { + printf("there is no JSContext on the stack!\n"); + } else if (JS::UniqueChars buf = + xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps)) { + DebugDump(buf.get()); + } + return true; +} + +JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, + bool showThisProps) { + JS::AutoSaveExceptionState state(cx); + + JS::UniqueChars buf = + JS::FormatStackDump(cx, showArgs, showLocals, showThisProps); + if (!buf) { + DebugDump("Failed to format JavaScript stack for dump"); + } + + state.restore(); + return buf; +} diff --git a/js/xpconnect/src/XPCException.cpp b/js/xpconnect/src/XPCException.cpp new file mode 100644 index 0000000000..64a83e3b31 --- /dev/null +++ b/js/xpconnect/src/XPCException.cpp @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* An implementaion of nsIException. */ + +#include "xpcprivate.h" +#include "nsError.h" + +#include <iterator> + +/***************************************************************************/ +/* Quick and dirty mapping of well known result codes to strings. We only + * call this when building an exception object, so iterating the short array + * is not too bad. + * + * It sure would be nice to have exceptions declared in idl and available + * in some more global way at runtime. + */ + +static const struct ResultMap { + nsresult rv; + const char* name; + const char* format; +} map[] = { +#define XPC_MSG_DEF(val, format) {(val), #val, format}, +#include "xpc.msg" +#undef XPC_MSG_DEF + {NS_OK, 0, 0} // sentinel to mark end of array +}; + +#define RESULT_COUNT (std::size(map) - 1) + +// static +bool nsXPCException::NameAndFormatForNSResult(nsresult rv, const char** name, + const char** format) { + for (const ResultMap* p = map; p->name; p++) { + if (rv == p->rv) { + if (name) *name = p->name; + if (format) *format = p->format; + return true; + } + } + return false; +} + +// static +const void* nsXPCException::IterateNSResults(nsresult* rv, const char** name, + const char** format, + const void** iterp) { + const ResultMap* p = (const ResultMap*)*iterp; + if (!p) { + p = map; + } else { + p++; + } + if (!p->name) { + p = nullptr; + } else { + if (rv) { + *rv = p->rv; + } + if (name) { + *name = p->name; + } + if (format) { + *format = p->format; + } + } + *iterp = p; + return p; +} + +// static +uint32_t nsXPCException::GetNSResultCount() { return RESULT_COUNT; } diff --git a/js/xpconnect/src/XPCForwards.h b/js/xpconnect/src/XPCForwards.h new file mode 100644 index 0000000000..56ad984025 --- /dev/null +++ b/js/xpconnect/src/XPCForwards.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Private forward declarations. */ + +#ifndef xpcforwards_h___ +#define xpcforwards_h___ + +// forward declarations of internally used classes... + +class nsXPConnect; +class XPCJSContext; +class XPCJSRuntime; +class XPCContext; +class XPCCallContext; + +class XPCJSThrower; + +class nsXPCWrappedJS; + +class XPCNativeMember; +class XPCNativeInterface; +class XPCNativeSet; + +class XPCWrappedNative; +class XPCWrappedNativeProto; +class XPCWrappedNativeTearOff; + +class JSObject2WrappedJSMap; +class Native2WrappedNativeMap; +class IID2NativeInterfaceMap; +class ClassInfo2NativeSetMap; +class ClassInfo2WrappedNativeProtoMap; +class NativeSetMap; +class JSObject2JSObjectMap; + +class nsXPCComponents; +class nsXPCComponents_Interfaces; +class nsXPCComponents_Classes; +class nsXPCComponents_Results; +class nsXPCComponents_ID; +class nsXPCComponents_Exception; +class nsXPCComponents_Constructor; +class nsXPCComponents_Utils; + +class AutoMarkingPtr; + +#endif /* xpcforwards_h___ */ diff --git a/js/xpconnect/src/XPCInlines.h b/js/xpconnect/src/XPCInlines.h new file mode 100644 index 0000000000..bc29c23ff8 --- /dev/null +++ b/js/xpconnect/src/XPCInlines.h @@ -0,0 +1,367 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* private inline methods (#include'd by xpcprivate.h). */ + +#ifndef xpcinlines_h___ +#define xpcinlines_h___ + +#include <algorithm> + +#include "js/PropertyAndElement.h" // JS_HasProperty, JS_HasPropertyById + +/***************************************************************************/ + +inline void XPCJSRuntime::AddSubjectToFinalizationWJS( + nsXPCWrappedJS* wrappedJS) { + mSubjectToFinalizationWJS.insertBack(wrappedJS); +} + +/***************************************************************************/ + +inline bool XPCCallContext::IsValid() const { return mState != INIT_FAILED; } + +inline XPCJSContext* XPCCallContext::GetContext() const { + CHECK_STATE(HAVE_CONTEXT); + return mXPCJSContext; +} + +inline JSContext* XPCCallContext::GetJSContext() const { + CHECK_STATE(HAVE_CONTEXT); + return mJSContext; +} + +inline XPCCallContext* XPCCallContext::GetPrevCallContext() const { + CHECK_STATE(HAVE_CONTEXT); + return mPrevCallContext; +} + +inline XPCWrappedNative* XPCCallContext::GetWrapper() const { + if (mState == INIT_FAILED) { + return nullptr; + } + + CHECK_STATE(HAVE_OBJECT); + return mWrapper; +} + +inline bool XPCCallContext::CanGetTearOff() const { + return mState >= HAVE_OBJECT; +} + +inline XPCWrappedNativeTearOff* XPCCallContext::GetTearOff() const { + CHECK_STATE(HAVE_OBJECT); + return mTearOff; +} + +inline nsIXPCScriptable* XPCCallContext::GetScriptable() const { + CHECK_STATE(HAVE_OBJECT); + return mScriptable; +} + +inline XPCNativeSet* XPCCallContext::GetSet() const { + CHECK_STATE(HAVE_NAME); + return mSet; +} + +inline XPCNativeInterface* XPCCallContext::GetInterface() const { + CHECK_STATE(HAVE_NAME); + return mInterface; +} + +inline XPCNativeMember* XPCCallContext::GetMember() const { + CHECK_STATE(HAVE_NAME); + return mMember; +} + +inline bool XPCCallContext::HasInterfaceAndMember() const { + return mState >= HAVE_NAME && mInterface && mMember; +} + +inline bool XPCCallContext::GetStaticMemberIsLocal() const { + CHECK_STATE(HAVE_NAME); + return mStaticMemberIsLocal; +} + +inline unsigned XPCCallContext::GetArgc() const { + CHECK_STATE(READY_TO_CALL); + return mArgc; +} + +inline JS::Value* XPCCallContext::GetArgv() const { + CHECK_STATE(READY_TO_CALL); + return mArgv; +} + +inline void XPCCallContext::SetRetVal(const JS::Value& val) { + CHECK_STATE(HAVE_ARGS); + if (mRetVal) { + *mRetVal = val; + } +} + +inline jsid XPCCallContext::GetResolveName() const { + CHECK_STATE(HAVE_CONTEXT); + return GetContext()->GetResolveName(); +} + +inline jsid XPCCallContext::SetResolveName(JS::HandleId name) { + CHECK_STATE(HAVE_CONTEXT); + return GetContext()->SetResolveName(name); +} + +inline XPCWrappedNative* XPCCallContext::GetResolvingWrapper() const { + CHECK_STATE(HAVE_OBJECT); + return GetContext()->GetResolvingWrapper(); +} + +inline XPCWrappedNative* XPCCallContext::SetResolvingWrapper( + XPCWrappedNative* w) { + CHECK_STATE(HAVE_OBJECT); + return GetContext()->SetResolvingWrapper(w); +} + +inline uint16_t XPCCallContext::GetMethodIndex() const { + CHECK_STATE(HAVE_OBJECT); + return mMethodIndex; +} + +/***************************************************************************/ +inline XPCNativeInterface* XPCNativeMember::GetInterface() const { + XPCNativeMember* arrayStart = + const_cast<XPCNativeMember*>(this - mIndexInInterface); + size_t arrayStartOffset = XPCNativeInterface::OffsetOfMembers(); + char* xpcNativeInterfaceStart = + reinterpret_cast<char*>(arrayStart) - arrayStartOffset; + return reinterpret_cast<XPCNativeInterface*>(xpcNativeInterfaceStart); +} + +/***************************************************************************/ + +inline const nsIID* XPCNativeInterface::GetIID() const { return &mInfo->IID(); } + +inline const char* XPCNativeInterface::GetNameString() const { + return mInfo->Name(); +} + +inline XPCNativeMember* XPCNativeInterface::FindMember(jsid name) const { + const XPCNativeMember* member = mMembers; + for (int i = (int)mMemberCount; i > 0; i--, member++) { + if (member->GetName() == name) { + return const_cast<XPCNativeMember*>(member); + } + } + return nullptr; +} + +/* static */ +inline size_t XPCNativeInterface::OffsetOfMembers() { + return offsetof(XPCNativeInterface, mMembers); +} + +/***************************************************************************/ + +inline XPCNativeSetKey::XPCNativeSetKey(XPCNativeSet* baseSet, + XPCNativeInterface* addition) + : mCx(nullptr), mBaseSet(baseSet), mAddition(addition) { + MOZ_ASSERT(mBaseSet); + MOZ_ASSERT(mAddition); + MOZ_ASSERT(!mBaseSet->HasInterface(mAddition)); +} + +/***************************************************************************/ + +inline bool XPCNativeSet::FindMember(jsid name, XPCNativeMember** pMember, + uint16_t* pInterfaceIndex) const { + XPCNativeInterface* const* iface; + int count = (int)mInterfaceCount; + int i; + + // look for interface names first + + for (i = 0, iface = mInterfaces; i < count; i++, iface++) { + if (name == (*iface)->GetName()) { + if (pMember) { + *pMember = nullptr; + } + if (pInterfaceIndex) { + *pInterfaceIndex = (uint16_t)i; + } + return true; + } + } + + // look for method names + for (i = 0, iface = mInterfaces; i < count; i++, iface++) { + XPCNativeMember* member = (*iface)->FindMember(name); + if (member) { + if (pMember) { + *pMember = member; + } + if (pInterfaceIndex) { + *pInterfaceIndex = (uint16_t)i; + } + return true; + } + } + return false; +} + +inline bool XPCNativeSet::FindMember( + jsid name, XPCNativeMember** pMember, + RefPtr<XPCNativeInterface>* pInterface) const { + uint16_t index; + if (!FindMember(name, pMember, &index)) { + return false; + } + *pInterface = mInterfaces[index]; + return true; +} + +inline bool XPCNativeSet::FindMember(JS::HandleId name, + XPCNativeMember** pMember, + RefPtr<XPCNativeInterface>* pInterface, + XPCNativeSet* protoSet, + bool* pIsLocal) const { + XPCNativeMember* Member; + RefPtr<XPCNativeInterface> Interface; + XPCNativeMember* protoMember; + + if (!FindMember(name, &Member, &Interface)) { + return false; + } + + *pMember = Member; + + *pIsLocal = !Member || !protoSet || + (protoSet != this && + !protoSet->MatchesSetUpToInterface(this, Interface) && + (!protoSet->FindMember(name, &protoMember, (uint16_t*)nullptr) || + protoMember != Member)); + + *pInterface = std::move(Interface); + + return true; +} + +inline bool XPCNativeSet::HasInterface(XPCNativeInterface* aInterface) const { + XPCNativeInterface* const* pp = mInterfaces; + + for (int i = (int)mInterfaceCount; i > 0; i--, pp++) { + if (aInterface == *pp) { + return true; + } + } + return false; +} + +inline bool XPCNativeSet::MatchesSetUpToInterface( + const XPCNativeSet* other, XPCNativeInterface* iface) const { + int count = std::min(int(mInterfaceCount), int(other->mInterfaceCount)); + + XPCNativeInterface* const* pp1 = mInterfaces; + XPCNativeInterface* const* pp2 = other->mInterfaces; + + for (int i = (int)count; i > 0; i--, pp1++, pp2++) { + XPCNativeInterface* cur = (*pp1); + if (cur != (*pp2)) { + return false; + } + if (cur == iface) { + return true; + } + } + return false; +} + +/***************************************************************************/ + +inline JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const { + return mJSObject.unbarrieredGetPtr(); +} + +inline JSObject* XPCWrappedNativeTearOff::GetJSObject() { return mJSObject; } + +inline void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj) { + MOZ_ASSERT(!IsMarked()); + mJSObject = JSObj; +} + +inline void XPCWrappedNativeTearOff::JSObjectMoved(JSObject* obj, + const JSObject* old) { + MOZ_ASSERT(!IsMarked()); + MOZ_ASSERT(mJSObject == old); + mJSObject = obj; +} + +inline XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff() { + MOZ_COUNT_DTOR(XPCWrappedNativeTearOff); + MOZ_ASSERT(!(GetInterface() || GetNative() || GetJSObjectPreserveColor()), + "tearoff not empty in dtor"); +} + +/***************************************************************************/ + +inline void XPCWrappedNative::SweepTearOffs() { + for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; + to = to->GetNextTearOff()) { + bool marked = to->IsMarked(); + to->Unmark(); + if (marked) { + continue; + } + + // If this tearoff does not have a live dedicated JSObject, + // then let's recycle it. + if (!to->GetJSObjectPreserveColor()) { + to->SetNative(nullptr); + to->SetInterface(nullptr); + } + } +} + +/***************************************************************************/ + +inline bool xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, + jsid idArg) { + JS::RootedId id(cx, idArg); + bool dummy; + return JS_HasPropertyById(cx, obj, id, &dummy); +} + +inline jsid GetJSIDByIndex(JSContext* cx, unsigned index) { + XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance(); + return xpcrt->GetStringID(index); +} + +inline bool ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx) { + XPCThrower::ThrowBadParam(rv, paramNum, ccx); + return false; +} + +inline void ThrowBadResult(nsresult result, XPCCallContext& ccx) { + XPCThrower::ThrowBadResult(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE, result, ccx); +} + +/***************************************************************************/ + +inline void xpc::CleanupValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen) { + // Check if we can do a cheap early return, and only perform the inner call + // if we can't. We never have to clean up null pointer types or arithmetic + // types. + // + // NOTE: We can skip zeroing arithmetic types in CleanupValue, as they are + // already in a valid state. + if (aType.IsArithmetic() || (aType.IsPointer() && !*(void**)aValue)) { + return; + } + xpc::InnerCleanupValue(aType, aValue, aArrayLen); +} + +/***************************************************************************/ + +#endif /* xpcinlines_h___ */ diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp new file mode 100644 index 0000000000..0f54e00cd5 --- /dev/null +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -0,0 +1,1500 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Per JSContext object */ + +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +#include "xpcprivate.h" +#include "xpcpublic.h" +#include "XPCWrapper.h" +#include "XPCJSMemoryReporter.h" +#include "XPCSelfHostedShmem.h" +#include "WrapperFactory.h" +#include "mozJSModuleLoader.h" +#include "nsNetUtil.h" +#include "nsThreadUtils.h" + +#include "nsIObserverService.h" +#include "nsIDebug2.h" +#include "nsPIDOMWindow.h" +#include "nsPrintfCString.h" +#include "mozilla/Preferences.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Services.h" +#ifdef FUZZING +# include "mozilla/StaticPrefs_fuzzing.h" +#endif +#include "mozilla/StaticPrefs_dom.h" +#include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_javascript.h" +#include "mozilla/dom/ScriptSettings.h" + +#include "nsContentUtils.h" +#include "nsCCUncollectableMarker.h" +#include "nsCycleCollectionNoteRootCallback.h" +#include "nsCycleCollector.h" +#include "nsJSEnvironment.h" +#include "jsapi.h" +#include "js/ArrayBuffer.h" +#include "js/ContextOptions.h" +#include "js/HelperThreadAPI.h" +#include "js/Initialization.h" +#include "js/MemoryMetrics.h" +#include "js/OffThreadScriptCompilation.h" +#include "js/WasmFeatures.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/dom/WindowBinding.h" +#include "mozilla/extensions/WebExtensionPolicy.h" +#include "mozilla/Atomics.h" +#include "mozilla/Attributes.h" +#include "mozilla/ProcessHangMonitor.h" +#include "mozilla/Sprintf.h" +#include "mozilla/SystemPrincipal.h" +#include "mozilla/TaskController.h" +#include "mozilla/ThreadLocal.h" +#include "mozilla/UniquePtrExtensions.h" +#include "mozilla/Unused.h" +#include "AccessCheck.h" +#include "nsGlobalWindow.h" +#include "nsAboutProtocolUtils.h" + +#include "GeckoProfiler.h" +#include "nsIXULRuntime.h" +#include "nsJSPrincipals.h" +#include "ExpandedPrincipal.h" + +#if defined(XP_LINUX) && !defined(ANDROID) +// For getrlimit and min/max. +# include <algorithm> +# include <sys/resource.h> +#endif + +#ifdef XP_WIN +// For min. +# include <algorithm> +# include <windows.h> +#endif + +using namespace mozilla; +using namespace mozilla::dom; +using namespace xpc; +using namespace JS; + +// We will clamp to reasonable values if this isn't set. +#if !defined(PTHREAD_STACK_MIN) +# define PTHREAD_STACK_MIN 0 +#endif + +static void WatchdogMain(void* arg); +class Watchdog; +class WatchdogManager; +class MOZ_RAII AutoLockWatchdog final { + Watchdog* const mWatchdog; + + public: + explicit AutoLockWatchdog(Watchdog* aWatchdog); + ~AutoLockWatchdog(); +}; + +class Watchdog { + public: + explicit Watchdog(WatchdogManager* aManager) + : mManager(aManager), + mLock(nullptr), + mWakeup(nullptr), + mThread(nullptr), + mHibernating(false), + mInitialized(false), + mShuttingDown(false), + mMinScriptRunTimeSeconds(1) {} + ~Watchdog() { MOZ_ASSERT(!Initialized()); } + + WatchdogManager* Manager() { return mManager; } + bool Initialized() { return mInitialized; } + bool ShuttingDown() { return mShuttingDown; } + PRLock* GetLock() { return mLock; } + bool Hibernating() { return mHibernating; } + void WakeUp() { + MOZ_ASSERT(Initialized()); + MOZ_ASSERT(Hibernating()); + mHibernating = false; + PR_NotifyCondVar(mWakeup); + } + + // + // Invoked by the main thread only. + // + + void Init() { + MOZ_ASSERT(NS_IsMainThread()); + mLock = PR_NewLock(); + if (!mLock) { + MOZ_CRASH("PR_NewLock failed."); + } + + mWakeup = PR_NewCondVar(mLock); + if (!mWakeup) { + MOZ_CRASH("PR_NewCondVar failed."); + } + + { + // Make sure the debug service is instantiated before we create the + // watchdog thread, since we intentionally try to keep the thread's stack + // segment as small as possible. It isn't always large enough to + // instantiate a new service, and even when it is, we don't want fault in + // extra pages if we can avoid it. + nsCOMPtr<nsIDebug2> dbg = do_GetService("@mozilla.org/xpcom/debug;1"); + Unused << dbg; + } + + { + AutoLockWatchdog lock(this); + + // The watchdog thread loop is pretty trivial, and should not + // require much stack space to do its job. So only give it 32KiB + // or the platform minimum. On modern Linux libc this might resolve to + // a runtime call. + size_t watchdogStackSize = PTHREAD_STACK_MIN; + watchdogStackSize = std::max<size_t>(32 * 1024, watchdogStackSize); + + // Gecko uses thread private for accounting and has to clean up at thread + // exit. Therefore, even though we don't have a return value from the + // watchdog, we need to join it on shutdown. + mThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, watchdogStackSize); + if (!mThread) { + MOZ_CRASH("PR_CreateThread failed!"); + } + + // WatchdogMain acquires the lock and then asserts mInitialized. So + // make sure to set mInitialized before releasing the lock here so + // that it's atomic with the creation of the thread. + mInitialized = true; + } + } + + void Shutdown() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(Initialized()); + { // Scoped lock. + AutoLockWatchdog lock(this); + + // Signal to the watchdog thread that it's time to shut down. + mShuttingDown = true; + + // Wake up the watchdog, and wait for it to call us back. + PR_NotifyCondVar(mWakeup); + } + + PR_JoinThread(mThread); + + // The thread sets mShuttingDown to false as it exits. + MOZ_ASSERT(!mShuttingDown); + + // Destroy state. + mThread = nullptr; + PR_DestroyCondVar(mWakeup); + mWakeup = nullptr; + PR_DestroyLock(mLock); + mLock = nullptr; + + // All done. + mInitialized = false; + } + + void SetMinScriptRunTimeSeconds(int32_t seconds) { + // This variable is atomic, and is set from the main thread without + // locking. + MOZ_ASSERT(seconds > 0); + mMinScriptRunTimeSeconds = seconds; + } + + // + // Invoked by the watchdog thread only. + // + + void Hibernate() { + MOZ_ASSERT(!NS_IsMainThread()); + mHibernating = true; + Sleep(PR_INTERVAL_NO_TIMEOUT); + } + void Sleep(PRIntervalTime timeout) { + MOZ_ASSERT(!NS_IsMainThread()); + AUTO_PROFILER_THREAD_SLEEP; + MOZ_ALWAYS_TRUE(PR_WaitCondVar(mWakeup, timeout) == PR_SUCCESS); + } + void Finished() { + MOZ_ASSERT(!NS_IsMainThread()); + mShuttingDown = false; + } + + int32_t MinScriptRunTimeSeconds() { return mMinScriptRunTimeSeconds; } + + private: + WatchdogManager* mManager; + + PRLock* mLock; + PRCondVar* mWakeup; + PRThread* mThread; + bool mHibernating; + bool mInitialized; + bool mShuttingDown; + mozilla::Atomic<int32_t> mMinScriptRunTimeSeconds; +}; + +#define PREF_MAX_SCRIPT_RUN_TIME_CONTENT "dom.max_script_run_time" +#define PREF_MAX_SCRIPT_RUN_TIME_CHROME "dom.max_chrome_script_run_time" +#define PREF_MAX_SCRIPT_RUN_TIME_EXT_CONTENT \ + "dom.max_ext_content_script_run_time" + +static const char* gCallbackPrefs[] = { + "dom.use_watchdog", + PREF_MAX_SCRIPT_RUN_TIME_CONTENT, + PREF_MAX_SCRIPT_RUN_TIME_CHROME, + PREF_MAX_SCRIPT_RUN_TIME_EXT_CONTENT, + nullptr, +}; + +class WatchdogManager { + public: + explicit WatchdogManager() { + // All the timestamps start at zero. + PodArrayZero(mTimestamps); + + // Register ourselves as an observer to get updates on the pref. + Preferences::RegisterCallbacks(PrefsChanged, gCallbackPrefs, this); + } + + virtual ~WatchdogManager() { + // Shutting down the watchdog requires context-switching to the watchdog + // thread, which isn't great to do in a destructor. So we require + // consumers to shut it down manually before releasing it. + MOZ_ASSERT(!mWatchdog); + } + + private: + static void PrefsChanged(const char* aPref, void* aSelf) { + static_cast<WatchdogManager*>(aSelf)->RefreshWatchdog(); + } + + public: + void Shutdown() { + Preferences::UnregisterCallbacks(PrefsChanged, gCallbackPrefs, this); + } + + void RegisterContext(XPCJSContext* aContext) { + MOZ_ASSERT(NS_IsMainThread()); + AutoLockWatchdog lock(mWatchdog.get()); + + if (aContext->mActive == XPCJSContext::CONTEXT_ACTIVE) { + mActiveContexts.insertBack(aContext); + } else { + mInactiveContexts.insertBack(aContext); + } + + // Enable the watchdog, if appropriate. + RefreshWatchdog(); + } + + void UnregisterContext(XPCJSContext* aContext) { + MOZ_ASSERT(NS_IsMainThread()); + AutoLockWatchdog lock(mWatchdog.get()); + + // aContext must be in one of our two lists, simply remove it. + aContext->LinkedListElement<XPCJSContext>::remove(); + +#ifdef DEBUG + // If this was the last context, we should have already shut down + // the watchdog. + if (mActiveContexts.isEmpty() && mInactiveContexts.isEmpty()) { + MOZ_ASSERT(!mWatchdog); + } +#endif + } + + // Context statistics. These live on the watchdog manager, are written + // from the main thread, and are read from the watchdog thread (holding + // the lock in each case). + void RecordContextActivity(XPCJSContext* aContext, bool active) { + // The watchdog reads this state, so acquire the lock before writing it. + MOZ_ASSERT(NS_IsMainThread()); + AutoLockWatchdog lock(mWatchdog.get()); + + // Write state. + aContext->mLastStateChange = PR_Now(); + aContext->mActive = + active ? XPCJSContext::CONTEXT_ACTIVE : XPCJSContext::CONTEXT_INACTIVE; + UpdateContextLists(aContext); + + // The watchdog may be hibernating, waiting for the context to go + // active. Wake it up if necessary. + if (active && mWatchdog && mWatchdog->Hibernating()) { + mWatchdog->WakeUp(); + } + } + + bool IsAnyContextActive() { return !mActiveContexts.isEmpty(); } + PRTime TimeSinceLastActiveContext() { + // Must be called on the watchdog thread with the lock held. + MOZ_ASSERT(!NS_IsMainThread()); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mWatchdog->GetLock()); + MOZ_ASSERT(mActiveContexts.isEmpty()); + MOZ_ASSERT(!mInactiveContexts.isEmpty()); + + // We store inactive contexts with the most recently added inactive + // context at the end of the list. + return PR_Now() - mInactiveContexts.getLast()->mLastStateChange; + } + + void RecordTimestamp(WatchdogTimestampCategory aCategory) { + // Must be called on the watchdog thread with the lock held. + MOZ_ASSERT(!NS_IsMainThread()); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mWatchdog->GetLock()); + MOZ_ASSERT(aCategory != TimestampContextStateChange, + "Use RecordContextActivity to update this"); + + mTimestamps[aCategory] = PR_Now(); + } + + PRTime GetContextTimestamp(XPCJSContext* aContext, + const AutoLockWatchdog& aProofOfLock) { + return aContext->mLastStateChange; + } + + PRTime GetTimestamp(WatchdogTimestampCategory aCategory, + const AutoLockWatchdog& aProofOfLock) { + MOZ_ASSERT(aCategory != TimestampContextStateChange, + "Use GetContextTimestamp to retrieve this"); + return mTimestamps[aCategory]; + } + + Watchdog* GetWatchdog() { return mWatchdog.get(); } + + void RefreshWatchdog() { + bool wantWatchdog = Preferences::GetBool("dom.use_watchdog", true); + if (wantWatchdog != !!mWatchdog) { + if (wantWatchdog) { + StartWatchdog(); + } else { + StopWatchdog(); + } + } + + if (mWatchdog) { + int32_t contentTime = StaticPrefs::dom_max_script_run_time(); + if (contentTime <= 0) { + contentTime = INT32_MAX; + } + int32_t chromeTime = StaticPrefs::dom_max_chrome_script_run_time(); + if (chromeTime <= 0) { + chromeTime = INT32_MAX; + } + int32_t extTime = StaticPrefs::dom_max_ext_content_script_run_time(); + if (extTime <= 0) { + extTime = INT32_MAX; + } + mWatchdog->SetMinScriptRunTimeSeconds( + std::min({contentTime, chromeTime, extTime})); + } + } + + void StartWatchdog() { + MOZ_ASSERT(!mWatchdog); + mWatchdog = mozilla::MakeUnique<Watchdog>(this); + mWatchdog->Init(); + } + + void StopWatchdog() { + MOZ_ASSERT(mWatchdog); + mWatchdog->Shutdown(); + mWatchdog = nullptr; + } + + template <class Callback> + void ForAllActiveContexts(Callback&& aCallback) { + // This function must be called on the watchdog thread with the lock held. + MOZ_ASSERT(!NS_IsMainThread()); + PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mWatchdog->GetLock()); + + for (auto* context = mActiveContexts.getFirst(); context; + context = context->LinkedListElement<XPCJSContext>::getNext()) { + if (!aCallback(context)) { + return; + } + } + } + + private: + void UpdateContextLists(XPCJSContext* aContext) { + // Given aContext whose activity state or timestamp has just changed, + // put it back in the proper position in the proper list. + aContext->LinkedListElement<XPCJSContext>::remove(); + auto& list = aContext->mActive == XPCJSContext::CONTEXT_ACTIVE + ? mActiveContexts + : mInactiveContexts; + + // Either the new list is empty or aContext must be more recent than + // the existing last element. + MOZ_ASSERT_IF(!list.isEmpty(), list.getLast()->mLastStateChange < + aContext->mLastStateChange); + list.insertBack(aContext); + } + + LinkedList<XPCJSContext> mActiveContexts; + LinkedList<XPCJSContext> mInactiveContexts; + mozilla::UniquePtr<Watchdog> mWatchdog; + + // We store ContextStateChange on the contexts themselves. + PRTime mTimestamps[kWatchdogTimestampCategoryCount - 1]; +}; + +AutoLockWatchdog::AutoLockWatchdog(Watchdog* aWatchdog) : mWatchdog(aWatchdog) { + if (mWatchdog) { + PR_Lock(mWatchdog->GetLock()); + } +} + +AutoLockWatchdog::~AutoLockWatchdog() { + if (mWatchdog) { + PR_Unlock(mWatchdog->GetLock()); + } +} + +static void WatchdogMain(void* arg) { + AUTO_PROFILER_REGISTER_THREAD("JS Watchdog"); + // Create an nsThread wrapper for the thread and register it with the thread + // manager. + Unused << NS_GetCurrentThread(); + NS_SetCurrentThreadName("JS Watchdog"); + + Watchdog* self = static_cast<Watchdog*>(arg); + WatchdogManager* manager = self->Manager(); + + // Lock lasts until we return + AutoLockWatchdog lock(self); + + MOZ_ASSERT(self->Initialized()); + while (!self->ShuttingDown()) { + // Sleep only 1 second if recently (or currently) active; otherwise, + // hibernate + if (manager->IsAnyContextActive() || + manager->TimeSinceLastActiveContext() <= PRTime(2 * PR_USEC_PER_SEC)) { + self->Sleep(PR_TicksPerSecond()); + } else { + manager->RecordTimestamp(TimestampWatchdogHibernateStart); + self->Hibernate(); + manager->RecordTimestamp(TimestampWatchdogHibernateStop); + } + + // Rise and shine. + manager->RecordTimestamp(TimestampWatchdogWakeup); + + // Don't request an interrupt callback unless the current script has + // been running long enough that we might show the slow script dialog. + // Triggering the callback from off the main thread can be expensive. + + // We want to avoid showing the slow script dialog if the user's laptop + // goes to sleep in the middle of running a script. To ensure this, we + // invoke the interrupt callback after only half the timeout has + // elapsed. The callback simply records the fact that it was called in + // the mSlowScriptSecondHalf flag. Then we wait another (timeout/2) + // seconds and invoke the callback again. This time around it sees + // mSlowScriptSecondHalf is set and so it shows the slow script + // dialog. If the computer is put to sleep during one of the (timeout/2) + // periods, the script still has the other (timeout/2) seconds to + // finish. + if (!self->ShuttingDown() && manager->IsAnyContextActive()) { + bool debuggerAttached = false; + nsCOMPtr<nsIDebug2> dbg = do_GetService("@mozilla.org/xpcom/debug;1"); + if (dbg) { + dbg->GetIsDebuggerAttached(&debuggerAttached); + } + if (debuggerAttached) { + // We won't be interrupting these scripts anyway. + continue; + } + + PRTime usecs = self->MinScriptRunTimeSeconds() * PR_USEC_PER_SEC / 2; + manager->ForAllActiveContexts([usecs, manager, + &lock](XPCJSContext* aContext) -> bool { + auto timediff = PR_Now() - manager->GetContextTimestamp(aContext, lock); + if (timediff > usecs) { + JS_RequestInterruptCallback(aContext->Context()); + return true; + } + return false; + }); + } + } + + // Tell the manager that we've shut down. + self->Finished(); +} + +PRTime XPCJSContext::GetWatchdogTimestamp(WatchdogTimestampCategory aCategory) { + AutoLockWatchdog lock(mWatchdogManager->GetWatchdog()); + return aCategory == TimestampContextStateChange + ? mWatchdogManager->GetContextTimestamp(this, lock) + : mWatchdogManager->GetTimestamp(aCategory, lock); +} + +// static +bool XPCJSContext::RecordScriptActivity(bool aActive) { + MOZ_ASSERT(NS_IsMainThread()); + + XPCJSContext* xpccx = XPCJSContext::Get(); + if (!xpccx) { + // mozilla::SpinEventLoopUntil may use AutoScriptActivity(false) after + // we destroyed the XPCJSContext. + MOZ_ASSERT(!aActive); + return false; + } + + bool oldValue = xpccx->SetHasScriptActivity(aActive); + if (aActive == oldValue) { + // Nothing to do. + return oldValue; + } + + if (!aActive) { + ProcessHangMonitor::ClearHang(); + } + xpccx->mWatchdogManager->RecordContextActivity(xpccx, aActive); + + return oldValue; +} + +AutoScriptActivity::AutoScriptActivity(bool aActive) + : mActive(aActive), + mOldValue(XPCJSContext::RecordScriptActivity(aActive)) {} + +AutoScriptActivity::~AutoScriptActivity() { + MOZ_ALWAYS_TRUE(mActive == XPCJSContext::RecordScriptActivity(mOldValue)); +} + +static const double sChromeSlowScriptTelemetryCutoff(10.0); +static bool sTelemetryEventEnabled(false); + +// static +bool XPCJSContext::InterruptCallback(JSContext* cx) { + XPCJSContext* self = XPCJSContext::Get(); + + // Now is a good time to turn on profiling if it's pending. + PROFILER_JS_INTERRUPT_CALLBACK(); + + if (profiler_thread_is_being_profiled_for_markers()) { + nsDependentCString filename("unknown file"); + JS::AutoFilename scriptFilename; + // Computing the line number can be very expensive (see bug 1330231 for + // example), so don't request it here. + if (JS::DescribeScriptedCaller(cx, &scriptFilename)) { + if (const char* file = scriptFilename.get()) { + filename.Assign(file, strlen(file)); + } + PROFILER_MARKER_TEXT("JS::InterruptCallback", JS, {}, filename); + } + } + + // Normally we record mSlowScriptCheckpoint when we start to process an + // event. However, we can run JS outside of event handlers. This code takes + // care of that case. + if (self->mSlowScriptCheckpoint.IsNull()) { + self->mSlowScriptCheckpoint = TimeStamp::NowLoRes(); + self->mSlowScriptSecondHalf = false; + self->mSlowScriptActualWait = mozilla::TimeDuration(); + self->mTimeoutAccumulated = false; + self->mExecutedChromeScript = false; + return true; + } + + // Sometimes we get called back during XPConnect initialization, before Gecko + // has finished bootstrapping. Avoid crashing in nsContentUtils below. + if (!nsContentUtils::IsInitialized()) { + return true; + } + + // This is at least the second interrupt callback we've received since + // returning to the event loop. See how long it's been, and what the limit + // is. + TimeStamp now = TimeStamp::NowLoRes(); + TimeDuration duration = now - self->mSlowScriptCheckpoint; + int32_t limit; + + nsString addonId; + const char* prefName; + auto principal = BasePrincipal::Cast(nsContentUtils::SubjectPrincipal(cx)); + bool chrome = principal->Is<SystemPrincipal>(); + if (chrome) { + prefName = PREF_MAX_SCRIPT_RUN_TIME_CHROME; + limit = StaticPrefs::dom_max_chrome_script_run_time(); + self->mExecutedChromeScript = true; + } else if (auto policy = principal->ContentScriptAddonPolicy()) { + policy->GetId(addonId); + prefName = PREF_MAX_SCRIPT_RUN_TIME_EXT_CONTENT; + limit = StaticPrefs::dom_max_ext_content_script_run_time(); + } else { + prefName = PREF_MAX_SCRIPT_RUN_TIME_CONTENT; + limit = StaticPrefs::dom_max_script_run_time(); + } + + // When the parent process slow script dialog is disabled, we still want + // to be able to track things for telemetry, so set `mSlowScriptSecondHalf` + // to true in that case: + if (limit == 0 && chrome && + duration.ToSeconds() > sChromeSlowScriptTelemetryCutoff / 2.0) { + self->mSlowScriptSecondHalf = true; + return true; + } + // If there's no limit, or we're within the limit, let it go. + if (limit == 0 || duration.ToSeconds() < limit / 2.0) { + return true; + } + + self->mSlowScriptCheckpoint = now; + self->mSlowScriptActualWait += duration; + + // In order to guard against time changes or laptops going to sleep, we + // don't trigger the slow script warning until (limit/2) seconds have + // elapsed twice. + if (!self->mSlowScriptSecondHalf) { + self->mSlowScriptSecondHalf = true; + return true; + } + + // For scripts in content processes, we only want to show the slow script + // dialogue if the user is actually trying to perform an important + // interaction. In theory this could be a chrome script running in the + // content process, which we probably don't want to give the user the ability + // to terminate. However, if this is the case we won't be able to map the + // script global to a window and we'll bail out below. + if (XRE_IsContentProcess() && + StaticPrefs::dom_max_script_run_time_require_critical_input()) { + // Call possibly slow PeekMessages after the other common early returns in + // this method. + ContentChild* contentChild = ContentChild::GetSingleton(); + mozilla::ipc::MessageChannel* channel = + contentChild ? contentChild->GetIPCChannel() : nullptr; + if (channel) { + bool foundInputEvent = false; + channel->PeekMessages( + [&foundInputEvent](const IPC::Message& aMsg) -> bool { + if (nsContentUtils::IsMessageCriticalInputEvent(aMsg)) { + foundInputEvent = true; + return false; + } + return true; + }); + if (!foundInputEvent) { + return true; + } + } + } + + // We use a fixed value of 2 from browser_parent_process_hang_telemetry.js + // to check if the telemetry events work. Do not interrupt it with a dialog. + if (chrome && limit == 2 && xpc::IsInAutomation()) { + return true; + } + + // + // This has gone on long enough! Time to take action. ;-) + // + + // Get the DOM window associated with the running script. If the script is + // running in a non-DOM scope, we have to just let it keep running. + RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); + RefPtr<nsGlobalWindowInner> win = WindowOrNull(global); + if (!win) { + // If this is a sandbox associated with a DOMWindow via a + // sandboxPrototype, use that DOMWindow. This supports WebExtension + // content scripts. + win = SandboxWindowOrNull(global, cx); + } + + if (!win) { + NS_WARNING("No active window"); + return true; + } + + if (win->IsDying()) { + // The window is being torn down. When that happens we try to prevent + // the dispatch of new runnables, so it also makes sense to kill any + // long-running script. The user is primarily interested in this page + // going away. + return false; + } + + // Accumulate slow script invokation delay. + if (!chrome && !self->mTimeoutAccumulated) { + uint32_t delay = uint32_t(self->mSlowScriptActualWait.ToMilliseconds() - + (limit * 1000.0)); + Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_NOTIFY_DELAY, delay); + self->mTimeoutAccumulated = true; + } + + // Show the prompt to the user, and kill if requested. + nsGlobalWindowInner::SlowScriptResponse response = win->ShowSlowScriptDialog( + cx, addonId, self->mSlowScriptActualWait.ToMilliseconds()); + if (response == nsGlobalWindowInner::KillSlowScript) { + if (Preferences::GetBool("dom.global_stop_script", true)) { + xpc::Scriptability::Get(global).Block(); + } + return false; + } + + // The user chose to continue the script. Reset the timer, and disable this + // machinery with a pref if the user opted out of future slow-script dialogs. + if (response != nsGlobalWindowInner::ContinueSlowScriptAndKeepNotifying) { + self->mSlowScriptCheckpoint = TimeStamp::NowLoRes(); + } + + if (response == nsGlobalWindowInner::AlwaysContinueSlowScript) { + Preferences::SetInt(prefName, 0); + } + + return true; +} + +#define JS_OPTIONS_DOT_STR "javascript.options." + +static mozilla::Atomic<bool> sDiscardSystemSource(false); + +bool xpc::ShouldDiscardSystemSource() { return sDiscardSystemSource; } + +static mozilla::Atomic<bool> sSharedMemoryEnabled(false); +static mozilla::Atomic<bool> sStreamsEnabled(false); + +static mozilla::Atomic<bool> sPropertyErrorMessageFixEnabled(false); +static mozilla::Atomic<bool> sWeakRefsEnabled(false); +static mozilla::Atomic<bool> sWeakRefsExposeCleanupSome(false); +static mozilla::Atomic<bool> sIteratorHelpersEnabled(false); +static mozilla::Atomic<bool> sShadowRealmsEnabled(false); +#ifdef NIGHTLY_BUILD +static mozilla::Atomic<bool> sArrayGroupingEnabled(false); +static mozilla::Atomic<bool> sWellFormedUnicodeStringsEnabled(false); +#endif +static mozilla::Atomic<bool> sChangeArrayByCopyEnabled(false); +static mozilla::Atomic<bool> sArrayFromAsyncEnabled(true); +#ifdef ENABLE_NEW_SET_METHODS +static mozilla::Atomic<bool> sEnableNewSetMethods(false); +#endif + +static JS::WeakRefSpecifier GetWeakRefsEnabled() { + if (!sWeakRefsEnabled) { + return JS::WeakRefSpecifier::Disabled; + } + + if (sWeakRefsExposeCleanupSome) { + return JS::WeakRefSpecifier::EnabledWithCleanupSome; + } + + return JS::WeakRefSpecifier::EnabledWithoutCleanupSome; +} + +void xpc::SetPrefableRealmOptions(JS::RealmOptions& options) { + options.creationOptions() + .setSharedMemoryAndAtomicsEnabled(sSharedMemoryEnabled) + .setCoopAndCoepEnabled( + StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy() && + StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) + .setPropertyErrorMessageFixEnabled(sPropertyErrorMessageFixEnabled) + .setWeakRefsEnabled(GetWeakRefsEnabled()) + .setIteratorHelpersEnabled(sIteratorHelpersEnabled) + .setShadowRealmsEnabled(sShadowRealmsEnabled) +#ifdef NIGHTLY_BUILD + .setArrayGroupingEnabled(sArrayGroupingEnabled) + .setWellFormedUnicodeStringsEnabled(sWellFormedUnicodeStringsEnabled) +#endif + .setChangeArrayByCopyEnabled(sChangeArrayByCopyEnabled) + .setArrayFromAsyncEnabled(sArrayFromAsyncEnabled) +#ifdef ENABLE_NEW_SET_METHODS + .setNewSetMethodsEnabled(sEnableNewSetMethods) +#endif + ; +} + +void xpc::SetPrefableContextOptions(JS::ContextOptions& options) { + options + .setAsmJS(Preferences::GetBool(JS_OPTIONS_DOT_STR "asmjs")) +#ifdef FUZZING + .setFuzzing(Preferences::GetBool(JS_OPTIONS_DOT_STR "fuzzing.enabled")) +#endif + .setWasm(Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm")) + .setWasmForTrustedPrinciples( + Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_trustedprincipals")) + .setWasmIon(Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_optimizingjit")) + .setWasmBaseline( + Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_baselinejit")) +#define WASM_FEATURE(NAME, LOWER_NAME, COMPILE_PRED, COMPILER_PRED, FLAG_PRED, \ + SHELL, PREF) \ + .setWasm##NAME(Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_" PREF)) + JS_FOR_WASM_FEATURES(WASM_FEATURE, WASM_FEATURE, WASM_FEATURE) +#undef WASM_FEATURE + .setWasmVerbose(Preferences::GetBool(JS_OPTIONS_DOT_STR "wasm_verbose")) + .setThrowOnAsmJSValidationFailure(Preferences::GetBool( + JS_OPTIONS_DOT_STR "throw_on_asmjs_validation_failure")) + .setSourcePragmas( + Preferences::GetBool(JS_OPTIONS_DOT_STR "source_pragmas")) + .setAsyncStack(Preferences::GetBool(JS_OPTIONS_DOT_STR "asyncstack")) + .setAsyncStackCaptureDebuggeeOnly(Preferences::GetBool( + JS_OPTIONS_DOT_STR "asyncstack_capture_debuggee_only")) +#ifdef NIGHTLY_BUILD + .setImportAssertions(Preferences::GetBool( + JS_OPTIONS_DOT_STR "experimental.import_assertions")) +#endif + ; +} + +// Mirrored value of javascript.options.self_hosted.use_shared_memory. +static bool sSelfHostedUseSharedMemory = false; + +static void LoadStartupJSPrefs(XPCJSContext* xpccx) { + // Prefs that require a restart are handled here. This includes the + // process-wide JIT options because toggling these at runtime can easily cause + // races or get us into an inconsistent state. + // + // 'Live' prefs are handled by ReloadPrefsCallback below. + + JSContext* cx = xpccx->Context(); + + // Some prefs are unlisted in all.js / StaticPrefs (and thus are invisible in + // about:config). Make sure we use explicit defaults here. + bool useJitForTrustedPrincipals = + Preferences::GetBool(JS_OPTIONS_DOT_STR "jit_trustedprincipals", false); + bool disableWasmHugeMemory = Preferences::GetBool( + JS_OPTIONS_DOT_STR "wasm_disable_huge_memory", false); + + bool safeMode = false; + nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1"); + if (xr) { + xr->GetInSafeMode(&safeMode); + } + + // NOTE: Baseline Interpreter is still used in safe-mode. This gives a big + // perf gain and is our simplest JIT so we make a tradeoff. + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_BASELINE_INTERPRETER_ENABLE, + StaticPrefs::javascript_options_blinterp_DoNotUseDirectly()); + + // Disable most JITs in Safe-Mode. + if (safeMode) { + JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_ENABLE, false); + JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_ENABLE, false); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_JIT_TRUSTEDPRINCIPALS_ENABLE, false); + JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_NATIVE_REGEXP_ENABLE, + false); + JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_JIT_HINTS_ENABLE, false); + sSelfHostedUseSharedMemory = false; + } else { + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_BASELINE_ENABLE, + StaticPrefs::javascript_options_baselinejit_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_ION_ENABLE, + StaticPrefs::javascript_options_ion_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption(cx, + JSJITCOMPILER_JIT_TRUSTEDPRINCIPALS_ENABLE, + useJitForTrustedPrincipals); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_NATIVE_REGEXP_ENABLE, + StaticPrefs::javascript_options_native_regexp_DoNotUseDirectly()); + // Only enable the jit hints cache for the content process to avoid + // any possible jank or delays on the parent process. + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_JIT_HINTS_ENABLE, + XRE_IsContentProcess() + ? StaticPrefs::javascript_options_jithints_DoNotUseDirectly() + : false); + sSelfHostedUseSharedMemory = StaticPrefs:: + javascript_options_self_hosted_use_shared_memory_DoNotUseDirectly(); + } + + JS_SetOffthreadIonCompilationEnabled( + cx, StaticPrefs:: + javascript_options_ion_offthread_compilation_DoNotUseDirectly()); + + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_BASELINE_INTERPRETER_WARMUP_TRIGGER, + StaticPrefs::javascript_options_blinterp_threshold_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_BASELINE_WARMUP_TRIGGER, + StaticPrefs::javascript_options_baselinejit_threshold_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_ION_NORMAL_WARMUP_TRIGGER, + StaticPrefs::javascript_options_ion_threshold_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_ION_FREQUENT_BAILOUT_THRESHOLD, + StaticPrefs:: + javascript_options_ion_frequent_bailout_threshold_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_INLINING_BYTECODE_MAX_LENGTH, + StaticPrefs:: + javascript_options_inlining_bytecode_max_length_DoNotUseDirectly()); + +#ifdef DEBUG + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_FULL_DEBUG_CHECKS, + StaticPrefs::javascript_options_jit_full_debug_checks_DoNotUseDirectly()); +#endif + +#if !defined(JS_CODEGEN_MIPS32) && !defined(JS_CODEGEN_MIPS64) && \ + !defined(JS_CODEGEN_RISCV64) && !defined(JS_CODEGEN_LOONG64) + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_SPECTRE_INDEX_MASKING, + StaticPrefs::javascript_options_spectre_index_masking_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_SPECTRE_OBJECT_MITIGATIONS, + StaticPrefs:: + javascript_options_spectre_object_mitigations_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_SPECTRE_STRING_MITIGATIONS, + StaticPrefs:: + javascript_options_spectre_string_mitigations_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_SPECTRE_VALUE_MASKING, + StaticPrefs::javascript_options_spectre_value_masking_DoNotUseDirectly()); + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_SPECTRE_JIT_TO_CXX_CALLS, + StaticPrefs:: + javascript_options_spectre_jit_to_cxx_calls_DoNotUseDirectly()); +#endif + + JS_SetGlobalJitCompilerOption( + cx, JSJITCOMPILER_WATCHTOWER_MEGAMORPHIC, + StaticPrefs:: + javascript_options_watchtower_megamorphic_DoNotUseDirectly()); + + if (disableWasmHugeMemory) { + bool disabledHugeMemory = JS::DisableWasmHugeMemory(); + MOZ_RELEASE_ASSERT(disabledHugeMemory); + } + + JS::SetSiteBasedPretenuringEnabled( + StaticPrefs:: + javascript_options_site_based_pretenuring_DoNotUseDirectly()); +} + +static void ReloadPrefsCallback(const char* pref, void* aXpccx) { + // Note: Prefs that require a restart are handled in LoadStartupJSPrefs above. + + auto xpccx = static_cast<XPCJSContext*>(aXpccx); + JSContext* cx = xpccx->Context(); + + sDiscardSystemSource = + Preferences::GetBool(JS_OPTIONS_DOT_STR "discardSystemSource"); + sSharedMemoryEnabled = + Preferences::GetBool(JS_OPTIONS_DOT_STR "shared_memory"); + sStreamsEnabled = Preferences::GetBool(JS_OPTIONS_DOT_STR "streams"); + sPropertyErrorMessageFixEnabled = + Preferences::GetBool(JS_OPTIONS_DOT_STR "property_error_message_fix"); + sWeakRefsEnabled = Preferences::GetBool(JS_OPTIONS_DOT_STR "weakrefs"); + sWeakRefsExposeCleanupSome = Preferences::GetBool( + JS_OPTIONS_DOT_STR "experimental.weakrefs.expose_cleanupSome"); + sShadowRealmsEnabled = + Preferences::GetBool(JS_OPTIONS_DOT_STR "experimental.shadow_realms"); +#ifdef NIGHTLY_BUILD + sIteratorHelpersEnabled = + Preferences::GetBool(JS_OPTIONS_DOT_STR "experimental.iterator_helpers"); + sArrayGroupingEnabled = + Preferences::GetBool(JS_OPTIONS_DOT_STR "experimental.array_grouping"); + sWellFormedUnicodeStringsEnabled = Preferences::GetBool( + JS_OPTIONS_DOT_STR "experimental.well_formed_unicode_strings"); +#endif + sChangeArrayByCopyEnabled = Preferences::GetBool( + JS_OPTIONS_DOT_STR "experimental.enable_change_array_by_copy"); + sArrayFromAsyncEnabled = Preferences::GetBool( + JS_OPTIONS_DOT_STR "experimental.enable_array_from_async"); +#ifdef ENABLE_NEW_SET_METHODS + sEnableNewSetMethods = + Preferences::GetBool(JS_OPTIONS_DOT_STR "experimental.new_set_methods"); +#endif + +#ifdef JS_GC_ZEAL + int32_t zeal = Preferences::GetInt(JS_OPTIONS_DOT_STR "gczeal", -1); + int32_t zeal_frequency = Preferences::GetInt( + JS_OPTIONS_DOT_STR "gczeal.frequency", JS_DEFAULT_ZEAL_FREQ); + if (zeal >= 0) { + JS_SetGCZeal(cx, (uint8_t)zeal, zeal_frequency); + } +#endif // JS_GC_ZEAL + + auto& contextOptions = JS::ContextOptionsRef(cx); + SetPrefableContextOptions(contextOptions); + + // Set options not shared with workers. + contextOptions + .setThrowOnDebuggeeWouldRun(Preferences::GetBool( + JS_OPTIONS_DOT_STR "throw_on_debuggee_would_run")) + .setDumpStackOnDebuggeeWouldRun(Preferences::GetBool( + JS_OPTIONS_DOT_STR "dump_stack_on_debuggee_would_run")); + + JS::SetUseFdlibmForSinCosTan( + Preferences::GetBool(JS_OPTIONS_DOT_STR "use_fdlibm_for_sin_cos_tan")); + + nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1"); + if (xr) { + bool safeMode = false; + xr->GetInSafeMode(&safeMode); + if (safeMode) { + contextOptions.disableOptionsForSafeMode(); + } + } + + JS_SetParallelParsingEnabled( + cx, Preferences::GetBool(JS_OPTIONS_DOT_STR "parallel_parsing")); +} + +XPCJSContext::~XPCJSContext() { + MOZ_COUNT_DTOR_INHERITED(XPCJSContext, CycleCollectedJSContext); + // Elsewhere we abort immediately if XPCJSContext initialization fails. + // Therefore the context must be non-null. + MOZ_ASSERT(MaybeContext()); + + Preferences::UnregisterPrefixCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, + this); + +#ifdef FUZZING + Preferences::UnregisterCallback(ReloadPrefsCallback, "fuzzing.enabled", this); +#endif + + // Clear any pending exception. It might be an XPCWrappedJS, and if we try + // to destroy it later we will crash. + SetPendingException(nullptr); + + // If we're the last XPCJSContext around, clean up the watchdog manager. + if (--sInstanceCount == 0) { + if (mWatchdogManager->GetWatchdog()) { + mWatchdogManager->StopWatchdog(); + } + + mWatchdogManager->UnregisterContext(this); + mWatchdogManager->Shutdown(); + sWatchdogInstance = nullptr; + } else { + // Otherwise, simply remove ourselves from the list. + mWatchdogManager->UnregisterContext(this); + } + + if (mCallContext) { + mCallContext->SystemIsBeingShutDown(); + } + + PROFILER_CLEAR_JS_CONTEXT(); +} + +XPCJSContext::XPCJSContext() + : mCallContext(nullptr), + mAutoRoots(nullptr), + mResolveName(JS::PropertyKey::Void()), + mResolvingWrapper(nullptr), + mWatchdogManager(GetWatchdogManager()), + mSlowScriptSecondHalf(false), + mTimeoutAccumulated(false), + mExecutedChromeScript(false), + mHasScriptActivity(false), + mPendingResult(NS_OK), + mActive(CONTEXT_INACTIVE), + mLastStateChange(PR_Now()) { + MOZ_COUNT_CTOR_INHERITED(XPCJSContext, CycleCollectedJSContext); + MOZ_ASSERT(mWatchdogManager); + ++sInstanceCount; + mWatchdogManager->RegisterContext(this); +} + +/* static */ +XPCJSContext* XPCJSContext::Get() { + // Do an explicit null check, because this can get called from a process that + // does not run JS. + nsXPConnect* xpc = static_cast<nsXPConnect*>(nsXPConnect::XPConnect()); + return xpc ? xpc->GetContext() : nullptr; +} + +#ifdef XP_WIN +static size_t GetWindowsStackSize() { + // First, get the stack base. Because the stack grows down, this is the top + // of the stack. + const uint8_t* stackTop; +# ifdef _WIN64 + PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb()); + stackTop = reinterpret_cast<const uint8_t*>(pTib->StackBase); +# else + PNT_TIB pTib = reinterpret_cast<PNT_TIB>(NtCurrentTeb()); + stackTop = reinterpret_cast<const uint8_t*>(pTib->StackBase); +# endif + + // Now determine the stack bottom. Note that we can't use tib->StackLimit, + // because that's the size of the committed area and we're also interested + // in the reserved pages below that. + MEMORY_BASIC_INFORMATION mbi; + if (!VirtualQuery(&mbi, &mbi, sizeof(mbi))) { + MOZ_CRASH("VirtualQuery failed"); + } + + const uint8_t* stackBottom = + reinterpret_cast<const uint8_t*>(mbi.AllocationBase); + + // Do some sanity checks. + size_t stackSize = size_t(stackTop - stackBottom); + MOZ_RELEASE_ASSERT(stackSize >= 1 * 1024 * 1024); + MOZ_RELEASE_ASSERT(stackSize <= 32 * 1024 * 1024); + + // Subtract 40 KB (Win32) or 80 KB (Win64) to account for things like + // the guard page and large PGO stack frames. + return stackSize - 10 * sizeof(uintptr_t) * 1024; +} +#endif + +XPCJSRuntime* XPCJSContext::Runtime() const { + return static_cast<XPCJSRuntime*>(CycleCollectedJSContext::Runtime()); +} + +CycleCollectedJSRuntime* XPCJSContext::CreateRuntime(JSContext* aCx) { + return new XPCJSRuntime(aCx); +} + +class HelperThreadTaskHandler : public Task { + public: + bool Run() override { + JS::RunHelperThreadTask(); + return true; + } + explicit HelperThreadTaskHandler() : Task(false, EventQueuePriority::Normal) { + // Bug 1703185: Currently all tasks are run at the same priority. + } + +#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY + bool GetName(nsACString& aName) override { + aName.AssignLiteral("HelperThreadTask"); + return true; + } +#endif + + private: + ~HelperThreadTaskHandler() = default; +}; + +static void DispatchOffThreadTask(JS::DispatchReason) { + TaskController::Get()->AddTask(MakeAndAddRef<HelperThreadTaskHandler>()); +} + +static bool CreateSelfHostedSharedMemory(JSContext* aCx, + JS::SelfHostedCache aBuf) { + auto& shm = xpc::SelfHostedShmem::GetSingleton(); + MOZ_RELEASE_ASSERT(shm.Content().IsEmpty()); + // Failures within InitFromParent output warnings but do not cause + // unrecoverable failures. + shm.InitFromParent(aBuf); + return true; +} + +nsresult XPCJSContext::Initialize() { + if (StaticPrefs::javascript_options_external_thread_pool_DoNotUseDirectly()) { + size_t threadCount = TaskController::GetPoolThreadCount(); + size_t stackSize = TaskController::GetThreadStackSize(); + SetHelperThreadTaskCallback(&DispatchOffThreadTask, threadCount, stackSize); + } + + nsresult rv = + CycleCollectedJSContext::Initialize(nullptr, JS::DefaultHeapMaxBytes); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(Context()); + JSContext* cx = Context(); + + // The JS engine permits us to set different stack limits for system code, + // trusted script, and untrusted script. We have tests that ensure that + // we can always execute 10 "heavy" (eval+with) stack frames deeper in + // privileged code. Our stack sizes vary greatly in different configurations, + // so satisfying those tests requires some care. Manual measurements of the + // number of heavy stack frames achievable gives us the following rough data, + // ordered by the effective categories in which they are grouped in the + // JS_SetNativeStackQuota call (which predates this analysis). + // + // The following "Stack Frames" numbers come from `chromeLimit` in + // js/xpconnect/tests/chrome/test_bug732665.xul + // + // Platform | Build | Stack Quota | Stack Frames | Stack Frame Size + // ------------+-------+-------------+--------------+------------------ + // OSX 64 | Opt | 7MB | 1331 | ~5.4k + // OSX 64 | Debug | 7MB | 1202 | ~6.0k + // ------------+-------+-------------+--------------+------------------ + // Linux 32 | Opt | 7.875MB | 2513 | ~3.2k + // Linux 32 | Debug | 7.875MB | 2146 | ~3.8k + // ------------+-------+-------------+--------------+------------------ + // Linux 64 | Opt | 7.875MB | 1360 | ~5.9k + // Linux 64 | Debug | 7.875MB | 1180 | ~6.8k + // Linux 64 | ASan | 7.875MB | 473 | ~17.0k + // ------------+-------+-------------+--------------+------------------ + // Windows 32 | Opt | 984k | 188 | ~5.2k + // Windows 32 | Debug | 984k | 208 | ~4.7k + // ------------+-------+-------------+--------------+------------------ + // Windows 64 | Opt | 1.922MB | 189 | ~10.4k + // Windows 64 | Debug | 1.922MB | 175 | ~11.2k + // + // We tune the trusted/untrusted quotas for each configuration to achieve our + // invariants while attempting to minimize overhead. In contrast, our buffer + // between system code and trusted script is a very unscientific 10k. + const size_t kSystemCodeBuffer = 10 * 1024; + + // Our "default" stack is what we use in configurations where we don't have + // a compelling reason to do things differently. This is effectively 512KB + // on 32-bit platforms and 1MB on 64-bit platforms. + const size_t kDefaultStackQuota = 128 * sizeof(size_t) * 1024; + + // Set maximum stack size for different configurations. This value is then + // capped below because huge stacks are not web-compatible. + +#if defined(XP_MACOSX) || defined(DARWIN) + // MacOS has a gargantuan default stack size of 8MB. Go wild with 7MB, + // and give trusted script 180k extra. The stack is huge on mac anyway. + const size_t kUncappedStackQuota = 7 * 1024 * 1024; + const size_t kTrustedScriptBuffer = 180 * 1024; +#elif defined(XP_LINUX) && !defined(ANDROID) + // Most Linux distributions set default stack size to 8MB. Use it as the + // maximum value. + const size_t kStackQuotaMax = 8 * 1024 * 1024; +# if defined(MOZ_ASAN) || defined(DEBUG) + // Bug 803182: account for the 4x difference in the size of js::Interpret + // between optimized and debug builds. We use 2x since the JIT part + // doesn't increase much. + // See the standalone MOZ_ASAN branch below for the ASan case. + const size_t kStackQuotaMin = 2 * kDefaultStackQuota; +# else + const size_t kStackQuotaMin = kDefaultStackQuota; +# endif + // Allocate 128kB margin for the safe space. + const size_t kStackSafeMargin = 128 * 1024; + + struct rlimit rlim; + const size_t kUncappedStackQuota = + getrlimit(RLIMIT_STACK, &rlim) == 0 + ? std::max(std::min(size_t(rlim.rlim_cur - kStackSafeMargin), + kStackQuotaMax - kStackSafeMargin), + kStackQuotaMin) + : kStackQuotaMin; +# if defined(MOZ_ASAN) + // See the standalone MOZ_ASAN branch below for the ASan case. + const size_t kTrustedScriptBuffer = 450 * 1024; +# else + const size_t kTrustedScriptBuffer = 180 * 1024; +# endif +#elif defined(XP_WIN) + // 1MB is the default stack size on Windows. We use the -STACK linker flag + // (see WIN32_EXE_LDFLAGS in config/config.mk) to request a larger stack, so + // we determine the stack size at runtime. + const size_t kUncappedStackQuota = GetWindowsStackSize(); +# if defined(MOZ_ASAN) + // See the standalone MOZ_ASAN branch below for the ASan case. + const size_t kTrustedScriptBuffer = 450 * 1024; +# else + const size_t kTrustedScriptBuffer = (sizeof(size_t) == 8) + ? 180 * 1024 // win64 + : 120 * 1024; // win32 +# endif +#elif defined(MOZ_ASAN) + // ASan requires more stack space due to red-zones, so give it double the + // default (1MB on 32-bit, 2MB on 64-bit). ASAN stack frame measurements + // were not taken at the time of this writing, so we hazard a guess that + // ASAN builds have roughly thrice the stack overhead as normal builds. + // On normal builds, the largest stack frame size we might encounter is + // 9.0k (see above), so let's use a buffer of 9.0 * 5 * 10 = 450k. + // + // FIXME: Does this branch make sense for Windows and Android? + // (See bug 1415195) + const size_t kUncappedStackQuota = 2 * kDefaultStackQuota; + const size_t kTrustedScriptBuffer = 450 * 1024; +#elif defined(ANDROID) + // Android appears to have 1MB stacks. Allow the use of 3/4 of that size + // (768KB on 32-bit), since otherwise we can crash with a stack overflow + // when nearing the 1MB limit. + const size_t kUncappedStackQuota = + kDefaultStackQuota + kDefaultStackQuota / 2; + const size_t kTrustedScriptBuffer = sizeof(size_t) * 12800; +#else + // Catch-all configuration for other environments. +# if defined(DEBUG) + const size_t kUncappedStackQuota = 2 * kDefaultStackQuota; +# else + const size_t kUncappedStackQuota = kDefaultStackQuota; +# endif + // Given the numbers above, we use 50k and 100k trusted buffers on 32-bit + // and 64-bit respectively. + const size_t kTrustedScriptBuffer = sizeof(size_t) * 12800; +#endif + + // Avoid an unused variable warning on platforms where we don't use the + // default. + (void)kDefaultStackQuota; + + // Large stacks are not web-compatible so cap to a smaller value. + // See bug 1537609 and bug 1562700. + const size_t kStackQuotaCap = + StaticPrefs::javascript_options_main_thread_stack_quota_cap(); + const size_t kStackQuota = std::min(kUncappedStackQuota, kStackQuotaCap); + + JS_SetNativeStackQuota( + cx, kStackQuota, kStackQuota - kSystemCodeBuffer, + kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer); + + PROFILER_SET_JS_CONTEXT(cx); + + JS_AddInterruptCallback(cx, InterruptCallback); + + Runtime()->Initialize(cx); + + LoadStartupJSPrefs(this); + + // Watch for the JS boolean options. + ReloadPrefsCallback(nullptr, this); + Preferences::RegisterPrefixCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, + this); + +#ifdef FUZZING + Preferences::RegisterCallback(ReloadPrefsCallback, "fuzzing.enabled", this); +#endif + + // Initialize the MIME type used for the bytecode cache, after calling + // SetProcessBuildIdOp and loading JS prefs. + if (!nsContentUtils::InitJSBytecodeMimeType()) { + NS_ABORT_OOM(0); // Size is unknown. + } + + // When available, set the self-hosted shared memory to be read, so that we + // can decode the self-hosted content instead of parsing it. + auto& shm = xpc::SelfHostedShmem::GetSingleton(); + JS::SelfHostedCache selfHostedContent = shm.Content(); + JS::SelfHostedWriter writer = nullptr; + if (XRE_IsParentProcess() && sSelfHostedUseSharedMemory) { + // Only the Parent process has permissions to write to the self-hosted + // shared memory. + writer = CreateSelfHostedSharedMemory; + } + + if (!JS::InitSelfHostedCode(cx, selfHostedContent, writer)) { + // Note: If no exception is pending, failure is due to OOM. + if (!JS_IsExceptionPending(cx) || JS_IsThrowingOutOfMemory(cx)) { + NS_ABORT_OOM(0); // Size is unknown. + } + + // Failed to execute self-hosted JavaScript! Uh oh. + MOZ_CRASH("InitSelfHostedCode failed"); + } + + MOZ_RELEASE_ASSERT(Runtime()->InitializeStrings(cx), + "InitializeStrings failed"); + + return NS_OK; +} + +// static +uint32_t XPCJSContext::sInstanceCount; + +// static +StaticAutoPtr<WatchdogManager> XPCJSContext::sWatchdogInstance; + +// static +WatchdogManager* XPCJSContext::GetWatchdogManager() { + if (sWatchdogInstance) { + return sWatchdogInstance; + } + + MOZ_ASSERT(sInstanceCount == 0); + sWatchdogInstance = new WatchdogManager(); + return sWatchdogInstance; +} + +// static +XPCJSContext* XPCJSContext::NewXPCJSContext() { + XPCJSContext* self = new XPCJSContext(); + nsresult rv = self->Initialize(); + if (rv == NS_ERROR_OUT_OF_MEMORY) { + mozalloc_handle_oom(0); + } else if (NS_FAILED(rv)) { + MOZ_CRASH("new XPCJSContext failed to initialize."); + } + + if (self->Context()) { + return self; + } + + MOZ_CRASH("new XPCJSContext failed to initialize."); +} + +void XPCJSContext::BeforeProcessTask(bool aMightBlock) { + MOZ_ASSERT(NS_IsMainThread()); + + // Start the slow script timer. + mSlowScriptCheckpoint = mozilla::TimeStamp::NowLoRes(); + mSlowScriptSecondHalf = false; + mSlowScriptActualWait = mozilla::TimeDuration(); + mTimeoutAccumulated = false; + mExecutedChromeScript = false; + CycleCollectedJSContext::BeforeProcessTask(aMightBlock); +} + +void XPCJSContext::AfterProcessTask(uint32_t aNewRecursionDepth) { + // Record hangs in the parent process for telemetry. + if (mSlowScriptSecondHalf && XRE_IsE10sParentProcess()) { + double hangDuration = (mozilla::TimeStamp::NowLoRes() - + mSlowScriptCheckpoint + mSlowScriptActualWait) + .ToSeconds(); + // We use the pref to test this code. + double limit = sChromeSlowScriptTelemetryCutoff; + if (xpc::IsInAutomation()) { + double prefLimit = StaticPrefs::dom_max_chrome_script_run_time(); + if (prefLimit > 0) { + limit = std::min(prefLimit, sChromeSlowScriptTelemetryCutoff); + } + } + if (hangDuration > limit) { + if (!sTelemetryEventEnabled) { + sTelemetryEventEnabled = true; + Telemetry::SetEventRecordingEnabled("slow_script_warning"_ns, true); + } + + auto uriType = mExecutedChromeScript ? "browser"_ns : "content"_ns; + // Use AppendFloat to avoid printf-type APIs using locale-specific + // decimal separators, when we definitely want a `.`. + nsCString durationStr; + durationStr.AppendFloat(hangDuration); + auto extra = Some<nsTArray<Telemetry::EventExtraEntry>>( + {Telemetry::EventExtraEntry{"hang_duration"_ns, durationStr}, + Telemetry::EventExtraEntry{"uri_type"_ns, uriType}}); + Telemetry::RecordEvent( + Telemetry::EventID::Slow_script_warning_Shown_Browser, Nothing(), + extra); + } + } + + // Now that we're back to the event loop, reset the slow script checkpoint. + mSlowScriptCheckpoint = mozilla::TimeStamp(); + mSlowScriptSecondHalf = false; + + // Call cycle collector occasionally. + MOZ_ASSERT(NS_IsMainThread()); + nsJSContext::MaybePokeCC(); + CycleCollectedJSContext::AfterProcessTask(aNewRecursionDepth); + + // This exception might have been set if we called an XPCWrappedJS that threw, + // but now we're returning to the event loop, so nothing is going to look at + // this value again. Clear it to prevent leaks. + SetPendingException(nullptr); +} + +void XPCJSContext::MaybePokeGC() { nsJSContext::MaybePokeGC(); } + +bool XPCJSContext::IsSystemCaller() const { + return nsContentUtils::IsSystemCaller(Context()); +} diff --git a/js/xpconnect/src/XPCJSID.cpp b/js/xpconnect/src/XPCJSID.cpp new file mode 100644 index 0000000000..565dc99c86 --- /dev/null +++ b/js/xpconnect/src/XPCJSID.cpp @@ -0,0 +1,626 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* An xpcom implementation of the JavaScript nsIID and nsCID objects. */ + +#include "xpcprivate.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/Attributes.h" +#include "js/Object.h" // JS::GetClass, JS::GetReservedSlot +#include "js/PropertyAndElement.h" // JS_DefineFunction, JS_DefineFunctionById, JS_DefineProperty, JS_DefinePropertyById +#include "js/Symbol.h" +#include "nsContentUtils.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace JS; + +namespace xpc { + +/****************************************************************************** + * # Generic IDs # + * + * Generic IDs are the type of JS object created by most code which passes nsID + * objects to JavaScript code. They provide no special methods, and only store + * the raw nsID value. + * + * The nsID value is stored in 4 reserved slots, with 32 bits of the 128-bit + * value stored in each slot. Getter code extracts this data, and combines them + * back into the nsID value. + */ +static bool ID_Equals(JSContext* aCx, unsigned aArgc, Value* aVp); +static bool ID_GetNumber(JSContext* aCx, unsigned aArgc, Value* aVp); + +// Generic ID objects contain 4 reserved slots, each containing a uint32_t with +// 1/4 of the representation of the nsID value. This allows us to avoid an extra +// allocation for the nsID object, and eliminates the need for a finalizer. +enum { kID_Slot0, kID_Slot1, kID_Slot2, kID_Slot3, kID_SlotCount }; +static const JSClass sID_Class = { + "nsJSID", JSCLASS_HAS_RESERVED_SLOTS(kID_SlotCount), JS_NULL_CLASS_OPS}; + +/****************************************************************************** + * # Interface IDs # + * + * In addition to the properties exposed by Generic ID objects, IID supports + * 'instanceof', exposes constant properties defined on the class, and exposes + * the interface name as the 'name' and 'toString()' values. + */ +static bool IID_HasInstance(JSContext* aCx, unsigned aArgc, Value* aVp); +static bool IID_GetName(JSContext* aCx, unsigned aArgc, Value* aVp); + +static bool IID_NewEnumerate(JSContext* cx, HandleObject obj, + MutableHandleIdVector properties, + bool enumerableOnly); +static bool IID_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp); +static bool IID_MayResolve(const JSAtomState& names, jsid id, + JSObject* maybeObj); + +static const JSClassOps sIID_ClassOps = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + IID_NewEnumerate, // newEnumerate + IID_Resolve, // resolve + IID_MayResolve, // mayResolve + nullptr, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +// Interface ID objects use a single reserved slot containing a pointer to the +// nsXPTInterfaceInfo object for the interface in question. +enum { kIID_InfoSlot, kIID_SlotCount }; +static const JSClass sIID_Class = { + "nsJSIID", JSCLASS_HAS_RESERVED_SLOTS(kIID_SlotCount), &sIID_ClassOps}; + +/****************************************************************************** + * # Contract IDs # + * + * In addition to the properties exposed by Generic ID objects, Contract IDs + * expose 'getService' and 'createInstance' methods, and expose the contractID + * string as '.name' and '.toString()'. + */ +static bool CID_CreateInstance(JSContext* aCx, unsigned aArgc, Value* aVp); +static bool CID_GetService(JSContext* aCx, unsigned aArgc, Value* aVp); +static bool CID_GetName(JSContext* aCx, unsigned aArgc, Value* aVp); + +// ContractID objects use a single reserved slot, containing the ContractID. The +// nsCID value for this object is looked up when the object is being unwrapped. +enum { kCID_ContractSlot, kCID_SlotCount }; +static const JSClass sCID_Class = { + "nsJSCID", JSCLASS_HAS_RESERVED_SLOTS(kCID_SlotCount), JS_NULL_CLASS_OPS}; + +/** + * Ensure that the nsID prototype objects have been created for the current + * global, and extract the prototype values. + */ +static JSObject* GetIDPrototype(JSContext* aCx, const JSClass* aClass) { + XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(aCx)); + if (NS_WARN_IF(!scope)) { + return nullptr; + } + + // Create prototype objects for the JSID objects if they haven't been + // created for this scope yet. + if (!scope->mIDProto) { + MOZ_ASSERT(!scope->mIIDProto && !scope->mCIDProto); + + RootedObject idProto(aCx, JS_NewPlainObject(aCx)); + RootedObject iidProto(aCx, + JS_NewObjectWithGivenProto(aCx, nullptr, idProto)); + RootedObject cidProto(aCx, + JS_NewObjectWithGivenProto(aCx, nullptr, idProto)); + RootedId hasInstance(aCx, + GetWellKnownSymbolKey(aCx, SymbolCode::hasInstance)); + + const uint32_t kFlags = + JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT; + const uint32_t kNoEnum = JSPROP_READONLY | JSPROP_PERMANENT; + + bool ok = + idProto && iidProto && cidProto && + // Methods and properties on all ID Objects: + JS_DefineFunction(aCx, idProto, "equals", ID_Equals, 1, kFlags) && + JS_DefineProperty(aCx, idProto, "number", ID_GetNumber, nullptr, + kFlags) && + + // Methods for IfaceID objects, which also inherit ID properties: + JS_DefineFunctionById(aCx, iidProto, hasInstance, IID_HasInstance, 1, + kNoEnum) && + JS_DefineProperty(aCx, iidProto, "name", IID_GetName, nullptr, + kFlags) && + + // Methods for ContractID objects, which also inherit ID properties: + JS_DefineFunction(aCx, cidProto, "createInstance", CID_CreateInstance, + 1, kFlags) && + JS_DefineFunction(aCx, cidProto, "getService", CID_GetService, 1, + kFlags) && + JS_DefineProperty(aCx, cidProto, "name", CID_GetName, nullptr, + kFlags) && + + // ToString returns '.number' on generic IDs, while returning + // '.name' on other ID types. + JS_DefineFunction(aCx, idProto, "toString", ID_GetNumber, 0, kFlags) && + JS_DefineFunction(aCx, iidProto, "toString", IID_GetName, 0, kFlags) && + JS_DefineFunction(aCx, cidProto, "toString", CID_GetName, 0, kFlags); + if (!ok) { + return nullptr; + } + + scope->mIDProto = idProto; + scope->mIIDProto = iidProto; + scope->mCIDProto = cidProto; + } + + if (aClass == &sID_Class) { + return scope->mIDProto; + } else if (aClass == &sIID_Class) { + return scope->mIIDProto; + } else if (aClass == &sCID_Class) { + return scope->mCIDProto; + } + + MOZ_CRASH("Unrecognized ID Object Class"); +} + +// Unwrap the given value to an object with the correct class, or nullptr. +static JSObject* GetIDObject(HandleValue aVal, const JSClass* aClass) { + if (aVal.isObject()) { + // We care only about IID/CID objects here, so CheckedUnwrapStatic is fine. + JSObject* obj = js::CheckedUnwrapStatic(&aVal.toObject()); + if (obj && JS::GetClass(obj) == aClass) { + return obj; + } + } + return nullptr; +} + +static const nsXPTInterfaceInfo* GetInterfaceInfo(JSObject* obj) { + MOZ_ASSERT(JS::GetClass(obj) == &sIID_Class); + return static_cast<const nsXPTInterfaceInfo*>( + JS::GetReservedSlot(obj, kIID_InfoSlot).toPrivate()); +} + +/** + * Unwrap an nsID object from a JSValue. + * + * For Generic ID objects, this function will extract the nsID from reserved + * slots. For IfaceID objects, it will be extracted from the nsXPTInterfaceInfo, + * and for ContractID objects, the ContractID's corresponding CID will be looked + * up. + */ +Maybe<nsID> JSValue2ID(JSContext* aCx, HandleValue aVal) { + if (!aVal.isObject()) { + return Nothing(); + } + + // We only care about ID objects here, so CheckedUnwrapStatic is fine. + RootedObject obj(aCx, js::CheckedUnwrapStatic(&aVal.toObject())); + if (!obj) { + return Nothing(); + } + + mozilla::Maybe<nsID> id; + if (JS::GetClass(obj) == &sID_Class) { + // Extract the raw bytes of the nsID from reserved slots. + uint32_t rawid[] = {JS::GetReservedSlot(obj, kID_Slot0).toPrivateUint32(), + JS::GetReservedSlot(obj, kID_Slot1).toPrivateUint32(), + JS::GetReservedSlot(obj, kID_Slot2).toPrivateUint32(), + JS::GetReservedSlot(obj, kID_Slot3).toPrivateUint32()}; + + // Construct a nsID inside the Maybe, and copy the rawid into it. + id.emplace(); + memcpy(id.ptr(), &rawid, sizeof(nsID)); + } else if (JS::GetClass(obj) == &sIID_Class) { + // IfaceID objects store a nsXPTInterfaceInfo* pointer. + const nsXPTInterfaceInfo* info = GetInterfaceInfo(obj); + id.emplace(info->IID()); + } else if (JS::GetClass(obj) == &sCID_Class) { + // ContractID objects store a ContractID string. + JS::UniqueChars contractId = JS_EncodeStringToLatin1( + aCx, JS::GetReservedSlot(obj, kCID_ContractSlot).toString()); + + // NOTE(nika): If we directly access the nsComponentManager, we can do + // this with a more-basic pointer lookup: + // nsFactoryEntry* entry = nsComponentManagerImpl::gComponentManager-> + // GetFactoryEntry(contractId.ptr(), contractId.length()); + // if (entry) id.emplace(entry->mCIDEntry->cid); + + nsCOMPtr<nsIComponentRegistrar> registrar; + nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(registrar)); + if (NS_FAILED(rv) || !registrar) { + return Nothing(); + } + + nsCID* cid = nullptr; + if (NS_SUCCEEDED(registrar->ContractIDToCID(contractId.get(), &cid))) { + id.emplace(*cid); + free(cid); + } + } + return id; +} + +/** + * Public ID Object Constructor Methods + */ +static JSObject* NewIDObjectHelper(JSContext* aCx, const JSClass* aClass) { + RootedObject proto(aCx, GetIDPrototype(aCx, aClass)); + if (proto) { + return JS_NewObjectWithGivenProto(aCx, aClass, proto); + } + return nullptr; +} + +bool ID2JSValue(JSContext* aCx, const nsID& aId, MutableHandleValue aVal) { + RootedObject obj(aCx, NewIDObjectHelper(aCx, &sID_Class)); + if (!obj) { + return false; + } + + // Get the data in nsID as 4 uint32_ts, and store them in slots. + uint32_t rawid[4]; + memcpy(&rawid, &aId, sizeof(nsID)); + static_assert(sizeof(nsID) == sizeof(rawid), "Wrong size of nsID"); + JS::SetReservedSlot(obj, kID_Slot0, PrivateUint32Value(rawid[0])); + JS::SetReservedSlot(obj, kID_Slot1, PrivateUint32Value(rawid[1])); + JS::SetReservedSlot(obj, kID_Slot2, PrivateUint32Value(rawid[2])); + JS::SetReservedSlot(obj, kID_Slot3, PrivateUint32Value(rawid[3])); + + aVal.setObject(*obj); + return true; +} + +bool IfaceID2JSValue(JSContext* aCx, const nsXPTInterfaceInfo& aInfo, + MutableHandleValue aVal) { + RootedObject obj(aCx, NewIDObjectHelper(aCx, &sIID_Class)); + if (!obj) { + return false; + } + + // The InterfaceInfo is stored in a reserved slot. + JS::SetReservedSlot(obj, kIID_InfoSlot, PrivateValue((void*)&aInfo)); + aVal.setObject(*obj); + return true; +} + +bool ContractID2JSValue(JSContext* aCx, JSString* aContract, + MutableHandleValue aVal) { + RootedString jsContract(aCx, aContract); + + { + // It is perfectly safe to have a ContractID object with an invalid + // ContractID, but is usually a bug. + nsCOMPtr<nsIComponentRegistrar> registrar; + NS_GetComponentRegistrar(getter_AddRefs(registrar)); + if (!registrar) { + return false; + } + + bool registered = false; + JS::UniqueChars contract = JS_EncodeStringToLatin1(aCx, jsContract); + registrar->IsContractIDRegistered(contract.get(), ®istered); + if (!registered) { + return false; + } + } + + RootedObject obj(aCx, NewIDObjectHelper(aCx, &sCID_Class)); + if (!obj) { + return false; + } + + // The Contract is stored in a reserved slot. + JS::SetReservedSlot(obj, kCID_ContractSlot, StringValue(jsContract)); + aVal.setObject(*obj); + return true; +} + +/****************************************************************************** + * # Method & Property Getter Implementations # + */ + +// NOTE: This method is used both for 'get ID.prototype.number' and +// 'ID.prototype.toString'. +static bool ID_GetNumber(JSContext* aCx, unsigned aArgc, Value* aVp) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + + Maybe<nsID> id = JSValue2ID(aCx, args.thisv()); + if (!id) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + char buf[NSID_LENGTH]; + id->ToProvidedString(buf); + JSString* jsnum = JS_NewStringCopyZ(aCx, buf); + if (!jsnum) { + return Throw(aCx, NS_ERROR_OUT_OF_MEMORY); + } + + args.rval().setString(jsnum); + return true; +} + +static bool ID_Equals(JSContext* aCx, unsigned aArgc, Value* aVp) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + if (!args.requireAtLeast(aCx, "nsID.equals", 1)) { + return false; + } + + Maybe<nsID> id = JSValue2ID(aCx, args.thisv()); + Maybe<nsID> id2 = JSValue2ID(aCx, args[0]); + if (!id || !id2) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + args.rval().setBoolean(id->Equals(*id2)); + return true; +} + +/* + * HasInstance hooks need to find an appropriate reflector in order to function + * properly. There are two complexities that we need to handle: + * + * 1 - Cross-compartment wrappers. Chrome uses over 100 compartments, all with + * system principal. The success of an instanceof check should not depend + * on which compartment an object comes from. At the same time, we want to + * make sure we don't unwrap important security wrappers. + * CheckedUnwrap does the right thing here. + * + * 2 - Prototype chains. Suppose someone creates a vanilla JS object |a| and + * sets its __proto__ to some WN |b|. If |b instanceof nsIFoo| returns true, + * one would expect |a instanceof nsIFoo| to return true as well, since + * instanceof is transitive up the prototype chain in ECMAScript. Moreover, + * there's chrome code that relies on this. + * + * This static method handles both complexities, returning either an XPCWN, a + * DOM object, or null. The object may well be cross-compartment from |cx|. + */ +static nsresult FindObjectForHasInstance(JSContext* cx, HandleObject objArg, + MutableHandleObject target) { + RootedObject obj(cx, objArg), proto(cx); + while (true) { + // Try the object, or the wrappee if allowed. We want CheckedUnwrapDynamic + // here, because we might in fact be looking for a Window. "cx" represents + // our current global. + JSObject* o = + js::IsWrapper(obj) ? js::CheckedUnwrapDynamic(obj, cx, false) : obj; + if (o && (IsWrappedNativeReflector(o) || IsDOMObject(o))) { + target.set(o); + return NS_OK; + } + + // Walk the prototype chain from the perspective of the callee (i.e. + // respecting Xrays if they exist). + if (!js::GetObjectProto(cx, obj, &proto)) { + return NS_ERROR_FAILURE; + } + if (!proto) { + target.set(nullptr); + return NS_OK; + } + obj = proto; + } +} + +nsresult HasInstance(JSContext* cx, HandleObject objArg, const nsID* iid, + bool* bp) { + *bp = false; + + RootedObject obj(cx); + nsresult rv = FindObjectForHasInstance(cx, objArg, &obj); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (!obj) { + return NS_OK; + } + + // Need to unwrap Window correctly here, so use ReflectorToISupportsDynamic. + nsCOMPtr<nsISupports> identity = ReflectorToISupportsDynamic(obj, cx); + if (!identity) { + return NS_OK; + } + + nsCOMPtr<nsISupports> supp; + identity->QueryInterface(*iid, getter_AddRefs(supp)); + *bp = supp; + + // Our old HasInstance implementation operated by invoking FindTearOff on + // XPCWrappedNatives, and various bits of chrome JS came to depend on + // |instanceof| doing an implicit QI if it succeeds. Do a drive-by QI to + // preserve that behavior. This is just a compatibility hack, so we don't + // really care if it fails. + if (IsWrappedNativeReflector(obj)) { + (void)XPCWrappedNative::Get(obj)->FindTearOff(cx, *iid); + } + + return NS_OK; +} + +static bool IID_HasInstance(JSContext* aCx, unsigned aArgc, Value* aVp) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + if (!args.requireAtLeast(aCx, "nsIID[Symbol.hasInstance]", 1)) { + return false; + } + + Maybe<nsID> id = JSValue2ID(aCx, args.thisv()); + if (!id) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + bool hasInstance = false; + if (args[0].isObject()) { + RootedObject target(aCx, &args[0].toObject()); + nsresult rv = HasInstance(aCx, target, id.ptr(), &hasInstance); + if (NS_FAILED(rv)) { + return Throw(aCx, rv); + } + } + args.rval().setBoolean(hasInstance); + return true; +} + +// NOTE: This method is used both for 'get IID.prototype.name' and +// 'IID.prototype.toString'. +static bool IID_GetName(JSContext* aCx, unsigned aArgc, Value* aVp) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + + RootedObject obj(aCx, GetIDObject(args.thisv(), &sIID_Class)); + if (!obj) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + const nsXPTInterfaceInfo* info = GetInterfaceInfo(obj); + + // Name property is the name of the interface this nsIID was created from. + JSString* name = JS_NewStringCopyZ(aCx, info->Name()); + if (!name) { + return Throw(aCx, NS_ERROR_OUT_OF_MEMORY); + } + + args.rval().setString(name); + return true; +} + +static bool IID_NewEnumerate(JSContext* cx, HandleObject obj, + MutableHandleIdVector properties, + bool enumerableOnly) { + const nsXPTInterfaceInfo* info = GetInterfaceInfo(obj); + + if (!properties.reserve(info->ConstantCount())) { + JS_ReportOutOfMemory(cx); + return false; + } + + RootedId id(cx); + RootedString name(cx); + for (uint16_t i = 0; i < info->ConstantCount(); ++i) { + name = JS_AtomizeString(cx, info->Constant(i).Name()); + if (!name || !JS_StringToId(cx, name, &id)) { + return false; + } + properties.infallibleAppend(id); + } + + return true; +} + +static bool IID_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + *resolvedp = false; + if (!id.isString()) { + return true; + } + + JSLinearString* name = id.toLinearString(); + const nsXPTInterfaceInfo* info = GetInterfaceInfo(obj); + for (uint16_t i = 0; i < info->ConstantCount(); ++i) { + if (JS_LinearStringEqualsAscii(name, info->Constant(i).Name())) { + *resolvedp = true; + + RootedValue constant(cx, info->Constant(i).JSValue()); + return JS_DefinePropertyById( + cx, obj, id, constant, + JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT); + } + } + return true; +} + +static bool IID_MayResolve(const JSAtomState& names, jsid id, + JSObject* maybeObj) { + if (!id.isString()) { + return false; + } + + if (!maybeObj) { + // Each interface object has its own set of constants, so if we don't know + // the object, assume any string property may be resolved. + return true; + } + + JSLinearString* name = id.toLinearString(); + const nsXPTInterfaceInfo* info = GetInterfaceInfo(maybeObj); + for (uint16_t i = 0; i < info->ConstantCount(); ++i) { + if (JS_LinearStringEqualsAscii(name, info->Constant(i).Name())) { + return true; + } + } + return false; +} + +// Common code for CID_CreateInstance and CID_GetService +static bool CIGSHelper(JSContext* aCx, unsigned aArgc, Value* aVp, + bool aGetService) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + + // Extract the ContractID string from our reserved slot. Don't use + // JSValue2ID as this method should only be defined on Contract ID objects, + // and it allows us to avoid a duplicate hashtable lookup. + RootedObject obj(aCx, GetIDObject(args.thisv(), &sCID_Class)); + if (!obj) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + JS::UniqueChars contractID = JS_EncodeStringToLatin1( + aCx, JS::GetReservedSlot(obj, kCID_ContractSlot).toString()); + + // Extract the IID from the first argument, if passed. Default: nsISupports. + Maybe<nsIID> iid = args.length() >= 1 ? JSValue2ID(aCx, args[0]) + : Some(NS_GET_IID(nsISupports)); + if (!iid) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + // Invoke CreateInstance or GetService with our ContractID. + nsresult rv; + nsCOMPtr<nsISupports> result; + if (aGetService) { + rv = CallGetService(contractID.get(), *iid, getter_AddRefs(result)); + if (NS_FAILED(rv) || !result) { + return Throw(aCx, NS_ERROR_XPC_GS_RETURNED_FAILURE); + } + } else { + rv = CallCreateInstance(contractID.get(), *iid, getter_AddRefs(result)); + if (NS_FAILED(rv) || !result) { + return Throw(aCx, NS_ERROR_XPC_CI_RETURNED_FAILURE); + } + } + + // Wrap the created object and return it. + rv = nsContentUtils::WrapNative(aCx, result, iid.ptr(), args.rval()); + if (NS_FAILED(rv) || args.rval().isPrimitive()) { + return Throw(aCx, NS_ERROR_XPC_CANT_CREATE_WN); + } + return true; +} + +static bool CID_CreateInstance(JSContext* aCx, unsigned aArgc, Value* aVp) { + return CIGSHelper(aCx, aArgc, aVp, /* aGetService = */ false); +} + +static bool CID_GetService(JSContext* aCx, unsigned aArgc, Value* aVp) { + return CIGSHelper(aCx, aArgc, aVp, /* aGetService = */ true); +} + +// NOTE: This method is used both for 'get CID.prototype.name' and +// 'CID.prototype.toString'. +static bool CID_GetName(JSContext* aCx, unsigned aArgc, Value* aVp) { + CallArgs args = CallArgsFromVp(aArgc, aVp); + RootedObject obj(aCx, GetIDObject(args.thisv(), &sCID_Class)); + if (!obj) { + return Throw(aCx, NS_ERROR_XPC_BAD_CONVERT_JS); + } + + // Return the string stored in our reserved ContractID slot. + args.rval().set(JS::GetReservedSlot(obj, kCID_ContractSlot)); + return true; +} + +} // namespace xpc diff --git a/js/xpconnect/src/XPCJSMemoryReporter.h b/js/xpconnect/src/XPCJSMemoryReporter.h new file mode 100644 index 0000000000..aa9954ec15 --- /dev/null +++ b/js/xpconnect/src/XPCJSMemoryReporter.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef XPCJSMemoryReporter_h +#define XPCJSMemoryReporter_h + +class nsISupports; +class nsIHandleReportCallback; + +namespace xpc { + +// The key is the window ID. +typedef nsTHashMap<nsUint64HashKey, nsCString> WindowPaths; + +// This is very nearly an instance of nsIMemoryReporter, but it's not, +// because it's invoked by nsWindowMemoryReporter in order to get |windowPaths| +// in CollectReports. +class JSReporter { + public: + static void CollectReports(WindowPaths* windowPaths, + WindowPaths* topWindowPaths, + nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize); +}; + +} // namespace xpc + +#endif diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp new file mode 100644 index 0000000000..2424cf9dda --- /dev/null +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -0,0 +1,3174 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Per JSRuntime object */ + +#include "mozilla/ArrayUtils.h" +#include "mozilla/AutoRestore.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +#include "xpcprivate.h" +#include "xpcpublic.h" +#include "XPCMaps.h" +#include "XPCWrapper.h" +#include "XPCJSMemoryReporter.h" +#include "XrayWrapper.h" +#include "WrapperFactory.h" +#include "mozJSModuleLoader.h" +#include "nsNetUtil.h" +#include "nsContentSecurityUtils.h" + +#include "nsExceptionHandler.h" +#include "nsIMemoryInfoDumper.h" +#include "nsIMemoryReporter.h" +#include "nsIObserverService.h" +#include "mozilla/dom/Document.h" +#include "nsIRunnable.h" +#include "nsIPlatformInfo.h" +#include "nsPIDOMWindow.h" +#include "nsPrintfCString.h" +#include "nsScriptSecurityManager.h" +#include "nsThreadPool.h" +#include "nsWindowSizes.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/Preferences.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Services.h" +#include "mozilla/dom/ScriptLoader.h" +#include "mozilla/dom/ScriptSettings.h" + +#include "nsContentUtils.h" +#include "nsCCUncollectableMarker.h" +#include "nsCycleCollectionNoteRootCallback.h" +#include "nsCycleCollector.h" +#include "jsapi.h" +#include "js/BuildId.h" // JS::BuildIdCharVector, JS::SetProcessBuildIdOp +#include "js/experimental/SourceHook.h" // js::{,Set}SourceHook +#include "js/GCAPI.h" +#include "js/MemoryFunctions.h" +#include "js/MemoryMetrics.h" +#include "js/Object.h" // JS::GetClass +#include "js/RealmIterators.h" +#include "js/SliceBudget.h" +#include "js/UbiNode.h" +#include "js/UbiNodeUtils.h" +#include "js/friend/UsageStatistics.h" // JSMetric, JS_SetAccumulateTelemetryCallback +#include "js/friend/WindowProxy.h" // js::SetWindowProxyClass +#include "js/friend/XrayJitInfo.h" // JS::SetXrayJitInfo +#include "mozilla/dom/AbortSignalBinding.h" +#include "mozilla/dom/GeneratedAtomList.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/FetchUtil.h" +#include "mozilla/dom/WindowBinding.h" +#include "mozilla/Atomics.h" +#include "mozilla/Attributes.h" +#include "mozilla/ProcessHangMonitor.h" +#include "mozilla/ProfilerLabels.h" +#include "mozilla/Sprintf.h" +#include "mozilla/UniquePtrExtensions.h" +#include "mozilla/Unused.h" +#include "AccessCheck.h" +#include "nsGlobalWindow.h" +#include "nsAboutProtocolUtils.h" + +#include "NodeUbiReporting.h" +#include "ExpandedPrincipal.h" +#include "nsIInputStream.h" +#include "nsJSPrincipals.h" +#include "nsJSEnvironment.h" +#include "XPCInlines.h" + +#ifdef XP_WIN +# include <windows.h> +#endif + +using namespace mozilla; +using namespace mozilla::dom; +using namespace xpc; +using namespace JS; +using namespace js; +using mozilla::dom::PerThreadAtomCache; + +/***************************************************************************/ + +const char* const XPCJSRuntime::mStrings[] = { + "constructor", // IDX_CONSTRUCTOR + "toString", // IDX_TO_STRING + "toSource", // IDX_TO_SOURCE + "value", // IDX_VALUE + "QueryInterface", // IDX_QUERY_INTERFACE + "Components", // IDX_COMPONENTS + "Cc", // IDX_CC + "Ci", // IDX_CI + "Cr", // IDX_CR + "Cu", // IDX_CU + "Services", // IDX_SERVICES + "wrappedJSObject", // IDX_WRAPPED_JSOBJECT + "prototype", // IDX_PROTOTYPE + "eval", // IDX_EVAL + "controllers", // IDX_CONTROLLERS + "Controllers", // IDX_CONTROLLERS_CLASS + "length", // IDX_LENGTH + "name", // IDX_NAME + "undefined", // IDX_UNDEFINED + "", // IDX_EMPTYSTRING + "fileName", // IDX_FILENAME + "lineNumber", // IDX_LINENUMBER + "columnNumber", // IDX_COLUMNNUMBER + "stack", // IDX_STACK + "message", // IDX_MESSAGE + "cause", // IDX_CAUSE + "errors", // IDX_ERRORS + "lastIndex", // IDX_LASTINDEX + "then", // IDX_THEN + "isInstance", // IDX_ISINSTANCE + "Infinity", // IDX_INFINITY + "NaN", // IDX_NAN + "classId", // IDX_CLASS_ID + "interfaceId", // IDX_INTERFACE_ID + "initializer", // IDX_INITIALIZER + "print", // IDX_PRINT + "fetch", // IDX_FETCH + "crypto", // IDX_CRYPTO + "indexedDB", // IDX_INDEXEDDB + "structuredClone", // IDX_STRUCTUREDCLONE +}; + +/***************************************************************************/ + +// *Some* NativeSets are referenced from mClassInfo2NativeSetMap. +// *All* NativeSets are referenced from mNativeSetMap. +// So, in mClassInfo2NativeSetMap we just clear references to the unmarked. +// In mNativeSetMap we clear the references to the unmarked *and* delete them. + +class AsyncFreeSnowWhite : public Runnable { + public: + NS_IMETHOD Run() override { + AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("Incremental CC", GCCC); + AUTO_PROFILER_LABEL("AsyncFreeSnowWhite::Run", GCCC_FreeSnowWhite); + + TimeStamp start = TimeStamp::Now(); + // 2 ms budget, given that kICCSliceBudget is only 3 ms + js::SliceBudget budget = js::SliceBudget(js::TimeBudget(2)); + bool hadSnowWhiteObjects = + nsCycleCollector_doDeferredDeletionWithBudget(budget); + Telemetry::Accumulate( + Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING, + uint32_t((TimeStamp::Now() - start).ToMilliseconds())); + if (hadSnowWhiteObjects && !mContinuation) { + mContinuation = true; + if (NS_FAILED(Dispatch())) { + mActive = false; + } + } else { + mActive = false; + } + return NS_OK; + } + + nsresult Dispatch() { + nsCOMPtr<nsIRunnable> self(this); + return NS_DispatchToCurrentThreadQueue(self.forget(), 500, + EventQueuePriority::Idle); + } + + void Start(bool aContinuation = false, bool aPurge = false) { + if (mContinuation) { + mContinuation = aContinuation; + } + mPurge = aPurge; + if (!mActive && NS_SUCCEEDED(Dispatch())) { + mActive = true; + } + } + + AsyncFreeSnowWhite() + : Runnable("AsyncFreeSnowWhite"), + mContinuation(false), + mActive(false), + mPurge(false) {} + + public: + bool mContinuation; + bool mActive; + bool mPurge; +}; + +namespace xpc { + +CompartmentPrivate::CompartmentPrivate( + JS::Compartment* c, mozilla::UniquePtr<XPCWrappedNativeScope> scope, + mozilla::BasePrincipal* origin, const SiteIdentifier& site) + : originInfo(origin, site), + wantXrays(false), + allowWaivers(true), + isWebExtensionContentScript(false), + isUAWidgetCompartment(false), + hasExclusiveExpandos(false), + wasShutdown(false), + mWrappedJSMap(mozilla::MakeUnique<JSObject2WrappedJSMap>()), + mScope(std::move(scope)) { + MOZ_COUNT_CTOR(xpc::CompartmentPrivate); +} + +CompartmentPrivate::~CompartmentPrivate() { + MOZ_COUNT_DTOR(xpc::CompartmentPrivate); +} + +void CompartmentPrivate::SystemIsBeingShutDown() { + // We may call this multiple times when the compartment contains more than one + // realm. + if (!wasShutdown) { + mWrappedJSMap->ShutdownMarker(); + wasShutdown = true; + } +} + +RealmPrivate::RealmPrivate(JS::Realm* realm) : scriptability(realm) { + mozilla::PodArrayZero(wrapperDenialWarnings); +} + +/* static */ +void RealmPrivate::Init(HandleObject aGlobal, const SiteIdentifier& aSite) { + MOZ_ASSERT(aGlobal); + DebugOnly<const JSClass*> clasp = JS::GetClass(aGlobal); + MOZ_ASSERT(clasp->slot0IsISupports() || dom::IsDOMClass(clasp)); + + Realm* realm = GetObjectRealmOrNull(aGlobal); + + // Create the realm private. + RealmPrivate* realmPriv = new RealmPrivate(realm); + MOZ_ASSERT(!GetRealmPrivate(realm)); + SetRealmPrivate(realm, realmPriv); + + nsIPrincipal* principal = GetRealmPrincipal(realm); + Compartment* c = JS::GetCompartment(aGlobal); + + // Create the compartment private if needed. + if (CompartmentPrivate* priv = CompartmentPrivate::Get(c)) { + MOZ_ASSERT(priv->originInfo.IsSameOrigin(principal)); + } else { + auto scope = mozilla::MakeUnique<XPCWrappedNativeScope>(c, aGlobal); + priv = new CompartmentPrivate(c, std::move(scope), + BasePrincipal::Cast(principal), aSite); + JS_SetCompartmentPrivate(c, priv); + } +} + +// As XPCJSRuntime can live longer than when we shutdown the observer service, +// we have our own getter to account for this. +static nsCOMPtr<nsIObserverService> GetObserverService() { + if (AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal)) { + return nullptr; + } + return mozilla::services::GetObserverService(); +} + +static bool TryParseLocationURICandidate( + const nsACString& uristr, RealmPrivate::LocationHint aLocationHint, + nsIURI** aURI) { + static constexpr auto kGRE = "resource://gre/"_ns; + static constexpr auto kToolkit = "chrome://global/"_ns; + static constexpr auto kBrowser = "chrome://browser/"_ns; + + if (aLocationHint == RealmPrivate::LocationHintAddon) { + // Blacklist some known locations which are clearly not add-on related. + if (StringBeginsWith(uristr, kGRE) || StringBeginsWith(uristr, kToolkit) || + StringBeginsWith(uristr, kBrowser)) { + return false; + } + + // -- GROSS HACK ALERT -- + // The Yandex Elements 8.10.2 extension implements its own "xb://" URL + // scheme. If we call NS_NewURI() on an "xb://..." URL, we'll end up + // calling into the extension's own JS-implemented nsIProtocolHandler + // object, which we can't allow while we're iterating over the JS heap. + // So just skip any such URL. + // -- GROSS HACK ALERT -- + if (StringBeginsWith(uristr, "xb"_ns)) { + return false; + } + } + + nsCOMPtr<nsIURI> uri; + if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), uristr))) { + return false; + } + + nsAutoCString scheme; + if (NS_FAILED(uri->GetScheme(scheme))) { + return false; + } + + // Cannot really map data: and blob:. + // Also, data: URIs are pretty memory hungry, which is kinda bad + // for memory reporter use. + if (scheme.EqualsLiteral("data") || scheme.EqualsLiteral("blob")) { + return false; + } + + uri.forget(aURI); + return true; +} + +bool RealmPrivate::TryParseLocationURI(RealmPrivate::LocationHint aLocationHint, + nsIURI** aURI) { + if (!aURI) { + return false; + } + + // Need to parse the URI. + if (location.IsEmpty()) { + return false; + } + + // Handle Sandbox location strings. + // A sandbox string looks like this, for anonymous sandboxes, and builds + // where Sandbox location tagging is enabled: + // + // <sandboxName> (from: <js-stack-frame-filename>:<lineno>) + // + // where <sandboxName> is user-provided via Cu.Sandbox() + // and <js-stack-frame-filename> and <lineno> is the stack frame location + // from where Cu.Sandbox was called. + // + // Otherwise, it is simply the caller-provided name, which is usually a URI. + // + // <js-stack-frame-filename> furthermore is "free form", often using a + // "uri -> uri -> ..." chain. The following code will and must handle this + // common case. + // + // It should be noted that other parts of the code may already rely on the + // "format" of these strings. + + static const nsDependentCString from("(from: "); + static const nsDependentCString arrow(" -> "); + static const size_t fromLength = from.Length(); + static const size_t arrowLength = arrow.Length(); + + // See: XPCComponents.cpp#AssembleSandboxMemoryReporterName + int32_t idx = location.Find(from); + if (idx < 0) { + return TryParseLocationURICandidate(location, aLocationHint, aURI); + } + + // When parsing we're looking for the right-most URI. This URI may be in + // <sandboxName>, so we try this first. + if (TryParseLocationURICandidate(Substring(location, 0, idx), aLocationHint, + aURI)) { + return true; + } + + // Not in <sandboxName> so we need to inspect <js-stack-frame-filename> and + // the chain that is potentially contained within and grab the rightmost + // item that is actually a URI. + + // First, hack off the :<lineno>) part as well + int32_t ridx = location.RFind(":"_ns); + nsAutoCString chain( + Substring(location, idx + fromLength, ridx - idx - fromLength)); + + // Loop over the "->" chain. This loop also works for non-chains, or more + // correctly chains with only one item. + for (;;) { + idx = chain.RFind(arrow); + if (idx < 0) { + // This is the last chain item. Try to parse what is left. + return TryParseLocationURICandidate(chain, aLocationHint, aURI); + } + + // Try to parse current chain item + if (TryParseLocationURICandidate(Substring(chain, idx + arrowLength), + aLocationHint, aURI)) { + return true; + } + + // Current chain item couldn't be parsed. + // Strip current item and continue. + chain = Substring(chain, 0, idx); + } + + MOZ_CRASH("Chain parser loop does not terminate"); +} + +static bool PrincipalImmuneToScriptPolicy(nsIPrincipal* aPrincipal) { + // System principal gets a free pass. + if (aPrincipal->IsSystemPrincipal()) { + return true; + } + + auto* principal = BasePrincipal::Cast(aPrincipal); + + // ExpandedPrincipal gets a free pass. + if (principal->Is<ExpandedPrincipal>()) { + return true; + } + + // WebExtension principals get a free pass. + if (principal->AddonPolicy()) { + return true; + } + + // pdf.js is a special-case too. + if (nsContentUtils::IsPDFJS(principal)) { + return true; + } + + // Check whether our URI is an "about:" URI that allows scripts. If it is, + // we need to allow JS to run. + if (aPrincipal->SchemeIs("about")) { + uint32_t flags; + nsresult rv = aPrincipal->GetAboutModuleFlags(&flags); + if (NS_SUCCEEDED(rv) && (flags & nsIAboutModule::ALLOW_SCRIPT)) { + return true; + } + } + + return false; +} + +void RealmPrivate::RegisterStackFrame(JSStackFrameBase* aFrame) { + mJSStackFrames.PutEntry(aFrame); +} + +void RealmPrivate::UnregisterStackFrame(JSStackFrameBase* aFrame) { + mJSStackFrames.RemoveEntry(aFrame); +} + +void RealmPrivate::NukeJSStackFrames() { + for (const auto& key : mJSStackFrames.Keys()) { + key->Clear(); + } + + mJSStackFrames.Clear(); +} + +void RegisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame) { + RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm); + if (!realmPrivate) { + return; + } + + realmPrivate->RegisterStackFrame(aStackFrame); +} + +void UnregisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame) { + RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm); + if (!realmPrivate) { + return; + } + + realmPrivate->UnregisterStackFrame(aStackFrame); +} + +void NukeJSStackFrames(JS::Realm* aRealm) { + RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm); + if (!realmPrivate) { + return; + } + + realmPrivate->NukeJSStackFrames(); +} + +Scriptability::Scriptability(JS::Realm* realm) + : mScriptBlocks(0), + mWindowAllowsScript(true), + mScriptBlockedByPolicy(false) { + nsIPrincipal* prin = nsJSPrincipals::get(JS::GetRealmPrincipals(realm)); + + mImmuneToScriptPolicy = PrincipalImmuneToScriptPolicy(prin); + if (mImmuneToScriptPolicy) { + return; + } + // If we're not immune, we should have a real principal with a URI. + // Check the principal against the new-style domain policy. + bool policyAllows; + nsresult rv = prin->GetIsScriptAllowedByPolicy(&policyAllows); + if (NS_SUCCEEDED(rv)) { + mScriptBlockedByPolicy = !policyAllows; + return; + } + // Something went wrong - be safe and block script. + mScriptBlockedByPolicy = true; +} + +bool Scriptability::Allowed() { + return mWindowAllowsScript && !mScriptBlockedByPolicy && mScriptBlocks == 0; +} + +bool Scriptability::IsImmuneToScriptPolicy() { return mImmuneToScriptPolicy; } + +void Scriptability::Block() { ++mScriptBlocks; } + +void Scriptability::Unblock() { + MOZ_ASSERT(mScriptBlocks > 0); + --mScriptBlocks; +} + +void Scriptability::SetWindowAllowsScript(bool aAllowed) { + mWindowAllowsScript = aAllowed || mImmuneToScriptPolicy; +} + +/* static */ +bool Scriptability::AllowedIfExists(JSObject* aScope) { + RealmPrivate* realmPrivate = RealmPrivate::Get(aScope); + return realmPrivate ? realmPrivate->scriptability.Allowed() : true; +} + +/* static */ +Scriptability& Scriptability::Get(JSObject* aScope) { + return RealmPrivate::Get(aScope)->scriptability; +} + +bool IsUAWidgetCompartment(JS::Compartment* compartment) { + // We always eagerly create compartment privates for UA Widget compartments. + CompartmentPrivate* priv = CompartmentPrivate::Get(compartment); + return priv && priv->isUAWidgetCompartment; +} + +bool IsUAWidgetScope(JS::Realm* realm) { + return IsUAWidgetCompartment(JS::GetCompartmentForRealm(realm)); +} + +bool IsInUAWidgetScope(JSObject* obj) { + return IsUAWidgetCompartment(JS::GetCompartment(obj)); +} + +bool CompartmentOriginInfo::MightBeWebContent() const { + // Compartments with principals that are either the system principal or an + // expanded principal are definitely not web content. + return !nsContentUtils::IsSystemOrExpandedPrincipal(mOrigin); +} + +bool MightBeWebContentCompartment(JS::Compartment* compartment) { + if (CompartmentPrivate* priv = CompartmentPrivate::Get(compartment)) { + return priv->originInfo.MightBeWebContent(); + } + + // No CompartmentPrivate; try IsSystemCompartment. + return !js::IsSystemCompartment(compartment); +} + +bool CompartmentOriginInfo::IsSameOrigin(nsIPrincipal* aOther) const { + return mOrigin->FastEquals(aOther); +} + +/* static */ +bool CompartmentOriginInfo::Subsumes(JS::Compartment* aCompA, + JS::Compartment* aCompB) { + CompartmentPrivate* apriv = CompartmentPrivate::Get(aCompA); + CompartmentPrivate* bpriv = CompartmentPrivate::Get(aCompB); + MOZ_ASSERT(apriv); + MOZ_ASSERT(bpriv); + return apriv->originInfo.mOrigin->FastSubsumes(bpriv->originInfo.mOrigin); +} + +/* static */ +bool CompartmentOriginInfo::SubsumesIgnoringFPD(JS::Compartment* aCompA, + JS::Compartment* aCompB) { + CompartmentPrivate* apriv = CompartmentPrivate::Get(aCompA); + CompartmentPrivate* bpriv = CompartmentPrivate::Get(aCompB); + MOZ_ASSERT(apriv); + MOZ_ASSERT(bpriv); + return apriv->originInfo.mOrigin->FastSubsumesIgnoringFPD( + bpriv->originInfo.mOrigin); +} + +void SetCompartmentChangedDocumentDomain(JS::Compartment* compartment) { + // Note: we call this for all compartments that contain realms with a + // particular principal. Not all of these compartments have a + // CompartmentPrivate (for instance the temporary compartment/realm + // created by the JS engine for off-thread parsing). + if (CompartmentPrivate* priv = CompartmentPrivate::Get(compartment)) { + priv->originInfo.SetChangedDocumentDomain(); + } +} + +JSObject* UnprivilegedJunkScope() { + return XPCJSRuntime::Get()->UnprivilegedJunkScope(); +} + +JSObject* UnprivilegedJunkScope(const fallible_t&) { + return XPCJSRuntime::Get()->UnprivilegedJunkScope(fallible); +} + +bool IsUnprivilegedJunkScope(JSObject* obj) { + return XPCJSRuntime::Get()->IsUnprivilegedJunkScope(obj); +} + +JSObject* NACScope(JSObject* global) { + // If we're a chrome global, just use ourselves. + if (AccessCheck::isChrome(global)) { + return global; + } + + JSObject* scope = UnprivilegedJunkScope(); + JS::ExposeObjectToActiveJS(scope); + return scope; +} + +JSObject* PrivilegedJunkScope() { return XPCJSRuntime::Get()->LoaderGlobal(); } + +JSObject* CompilationScope() { return XPCJSRuntime::Get()->LoaderGlobal(); } + +nsGlobalWindowInner* WindowOrNull(JSObject* aObj) { + MOZ_ASSERT(aObj); + MOZ_ASSERT(!js::IsWrapper(aObj)); + + nsGlobalWindowInner* win = nullptr; + UNWRAP_NON_WRAPPER_OBJECT(Window, aObj, win); + return win; +} + +nsGlobalWindowInner* WindowGlobalOrNull(JSObject* aObj) { + MOZ_ASSERT(aObj); + JSObject* glob = JS::GetNonCCWObjectGlobal(aObj); + + return WindowOrNull(glob); +} + +nsGlobalWindowInner* SandboxWindowOrNull(JSObject* aObj, JSContext* aCx) { + MOZ_ASSERT(aObj); + + if (!IsSandbox(aObj)) { + return nullptr; + } + + // Sandbox can't be a Proxy so it must have a static prototype. + JSObject* proto = GetStaticPrototype(aObj); + if (!proto || !IsSandboxPrototypeProxy(proto)) { + return nullptr; + } + + proto = js::CheckedUnwrapDynamic(proto, aCx, /* stopAtWindowProxy = */ false); + if (!proto) { + return nullptr; + } + return WindowOrNull(proto); +} + +nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx) { + JSObject* glob = JS::CurrentGlobalOrNull(cx); + return glob ? WindowOrNull(glob) : nullptr; +} + +// Nukes all wrappers into or out of the given realm, and prevents new +// wrappers from being created. Additionally marks the realm as +// unscriptable after wrappers have been nuked. +// +// Note: This should *only* be called for browser or extension realms. +// Wrappers between web compartments must never be cut in web-observable +// ways. +void NukeAllWrappersForRealm( + JSContext* cx, JS::Realm* realm, + js::NukeReferencesToWindow nukeReferencesToWindow) { + // We do the following: + // * Nuke all wrappers into the realm. + // * Nuke all wrappers out of the realm's compartment, once we have nuked all + // realms in it. + js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(), realm, + nukeReferencesToWindow, + js::NukeAllReferences); + + // Mark the realm as unscriptable. + xpc::RealmPrivate::Get(realm)->scriptability.Block(); +} + +} // namespace xpc + +static void CompartmentDestroyedCallback(JS::GCContext* gcx, + JS::Compartment* compartment) { + // NB - This callback may be called in JS_DestroyContext, which happens + // after the XPCJSRuntime has been torn down. + + // Get the current compartment private into a UniquePtr (which will do the + // cleanup for us), and null out the private (which may already be null). + mozilla::UniquePtr<CompartmentPrivate> priv( + CompartmentPrivate::Get(compartment)); + JS_SetCompartmentPrivate(compartment, nullptr); +} + +static size_t CompartmentSizeOfIncludingThisCallback( + MallocSizeOf mallocSizeOf, JS::Compartment* compartment) { + CompartmentPrivate* priv = CompartmentPrivate::Get(compartment); + return priv ? priv->SizeOfIncludingThis(mallocSizeOf) : 0; +} + +/* + * Return true if there exists a non-system inner window which is a current + * inner window and whose reflector is gray. We don't merge system + * compartments, so we don't use them to trigger merging CCs. + */ +bool XPCJSRuntime::UsefulToMergeZones() const { + MOZ_ASSERT(NS_IsMainThread()); + + // Turns out, actually making this return true often enough makes Windows + // mochitest-gl OOM a lot. Need to figure out what's going on there; see + // bug 1277036. + + return false; +} + +void XPCJSRuntime::TraceNativeBlackRoots(JSTracer* trc) { + if (CycleCollectedJSContext* ccx = GetContext()) { + const auto* cx = static_cast<const XPCJSContext*>(ccx); + if (AutoMarkingPtr* roots = cx->mAutoRoots) { + roots->TraceJSAll(trc); + } + } + + if (mIID2NativeInterfaceMap) { + mIID2NativeInterfaceMap->Trace(trc); + } + + dom::TraceBlackJS(trc); +} + +void XPCJSRuntime::TraceAdditionalNativeGrayRoots(JSTracer* trc) { + XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(this, trc); +} + +void XPCJSRuntime::TraverseAdditionalNativeRoots( + nsCycleCollectionNoteRootCallback& cb) { + XPCWrappedNativeScope::SuspectAllWrappers(cb); + + auto* parti = NS_CYCLE_COLLECTION_PARTICIPANT(nsXPCWrappedJS); + for (auto* wjs : mSubjectToFinalizationWJS) { + MOZ_DIAGNOSTIC_ASSERT(wjs->IsSubjectToFinalization()); + cb.NoteXPCOMRoot(ToSupports(wjs), parti); + } +} + +void XPCJSRuntime::UnmarkSkippableJSHolders() { + CycleCollectedJSRuntime::UnmarkSkippableJSHolders(); +} + +void XPCJSRuntime::PrepareForForgetSkippable() { + nsCOMPtr<nsIObserverService> obs = xpc::GetObserverService(); + if (obs) { + obs->NotifyObservers(nullptr, "cycle-collector-forget-skippable", nullptr); + } +} + +void XPCJSRuntime::BeginCycleCollectionCallback(CCReason aReason) { + nsJSContext::BeginCycleCollectionCallback(aReason); + + nsCOMPtr<nsIObserverService> obs = xpc::GetObserverService(); + if (obs) { + obs->NotifyObservers(nullptr, "cycle-collector-begin", nullptr); + } +} + +void XPCJSRuntime::EndCycleCollectionCallback(CycleCollectorResults& aResults) { + nsJSContext::EndCycleCollectionCallback(aResults); + + nsCOMPtr<nsIObserverService> obs = xpc::GetObserverService(); + if (obs) { + obs->NotifyObservers(nullptr, "cycle-collector-end", nullptr); + } +} + +void XPCJSRuntime::DispatchDeferredDeletion(bool aContinuation, bool aPurge) { + mAsyncSnowWhiteFreer->Start(aContinuation, aPurge); +} + +void xpc_UnmarkSkippableJSHolders() { + if (nsXPConnect::GetRuntimeInstance()) { + nsXPConnect::GetRuntimeInstance()->UnmarkSkippableJSHolders(); + } +} + +/* static */ +void XPCJSRuntime::GCSliceCallback(JSContext* cx, JS::GCProgress progress, + const JS::GCDescription& desc) { + XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); + if (!self) { + return; + } + + nsCOMPtr<nsIObserverService> obs = xpc::GetObserverService(); + if (obs) { + switch (progress) { + case JS::GC_CYCLE_BEGIN: + obs->NotifyObservers(nullptr, "garbage-collector-begin", nullptr); + break; + case JS::GC_CYCLE_END: + obs->NotifyObservers(nullptr, "garbage-collector-end", nullptr); + break; + default: + break; + } + } + + CrashReporter::SetGarbageCollecting(progress == JS::GC_CYCLE_BEGIN); + + if (self->mPrevGCSliceCallback) { + (*self->mPrevGCSliceCallback)(cx, progress, desc); + } +} + +/* static */ +void XPCJSRuntime::DoCycleCollectionCallback(JSContext* cx) { + // The GC has detected that a CC at this point would collect a tremendous + // amount of garbage that is being revivified unnecessarily. + // + // The GC_WAITING reason is a little overloaded here, but we want to do + // a CC to allow Realms to be collected when they are referenced by a cycle. + NS_DispatchToCurrentThread(NS_NewRunnableFunction( + "XPCJSRuntime::DoCycleCollectionCallback", + []() { nsJSContext::CycleCollectNow(CCReason::GC_WAITING, nullptr); })); + + XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); + if (!self) { + return; + } + + if (self->mPrevDoCycleCollectionCallback) { + (*self->mPrevDoCycleCollectionCallback)(cx); + } +} + +void XPCJSRuntime::CustomGCCallback(JSGCStatus status) { + nsTArray<xpcGCCallback> callbacks(extraGCCallbacks.Clone()); + for (uint32_t i = 0; i < callbacks.Length(); ++i) { + callbacks[i](status); + } +} + +/* static */ +void XPCJSRuntime::FinalizeCallback(JS::GCContext* gcx, JSFinalizeStatus status, + void* data) { + XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); + if (!self) { + return; + } + + switch (status) { + case JSFINALIZE_GROUP_PREPARE: { + MOZ_ASSERT(!self->mDoingFinalization, "bad state"); + + MOZ_ASSERT(!self->mGCIsRunning, "bad state"); + self->mGCIsRunning = true; + + self->mDoingFinalization = true; + + break; + } + case JSFINALIZE_GROUP_START: { + MOZ_ASSERT(self->mDoingFinalization, "bad state"); + + MOZ_ASSERT(self->mGCIsRunning, "bad state"); + self->mGCIsRunning = false; + + break; + } + case JSFINALIZE_GROUP_END: { + MOZ_ASSERT(self->mDoingFinalization, "bad state"); + self->mDoingFinalization = false; + + break; + } + case JSFINALIZE_COLLECTION_END: { + MOZ_ASSERT(!self->mGCIsRunning, "bad state"); + self->mGCIsRunning = true; + + if (CycleCollectedJSContext* ccx = self->GetContext()) { + const auto* cx = static_cast<const XPCJSContext*>(ccx); + if (AutoMarkingPtr* roots = cx->mAutoRoots) { + roots->MarkAfterJSFinalizeAll(); + } + + // Now we are going to recycle any unused WrappedNativeTearoffs. + // We do this by iterating all the live callcontexts + // and marking the tearoffs in use. And then we + // iterate over all the WrappedNative wrappers and sweep their + // tearoffs. + // + // This allows us to perhaps minimize the growth of the + // tearoffs. And also makes us not hold references to interfaces + // on our wrapped natives that we are not actually using. + // + // XXX We may decide to not do this on *every* gc cycle. + + XPCCallContext* ccxp = cx->GetCallContext(); + while (ccxp) { + // Deal with the strictness of callcontext that + // complains if you ask for a tearoff when + // it is in a state where the tearoff could not + // possibly be valid. + if (ccxp->CanGetTearOff()) { + XPCWrappedNativeTearOff* to = ccxp->GetTearOff(); + if (to) { + to->Mark(); + } + } + ccxp = ccxp->GetPrevCallContext(); + } + } + + XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs(); + + // Now we need to kill the 'Dying' XPCWrappedNativeProtos. + // + // We transferred these native objects to this list when their JSObjects + // were finalized. We did not destroy them immediately at that point + // because the ordering of JS finalization is not deterministic and we did + // not yet know if any wrappers that might still be referencing the protos + // were still yet to be finalized and destroyed. We *do* know that the + // protos' JSObjects would not have been finalized if there were any + // wrappers that referenced the proto but were not themselves slated for + // finalization in this gc cycle. + // + // At this point we know that any and all wrappers that might have been + // referencing the protos in the dying list are themselves dead. So, we + // can safely delete all the protos in the list. + self->mDyingWrappedNativeProtos.clear(); + + MOZ_ASSERT(self->mGCIsRunning, "bad state"); + self->mGCIsRunning = false; + + break; + } + } +} + +/* static */ +void XPCJSRuntime::WeakPointerZonesCallback(JSTracer* trc, void* data) { + // Called before each sweeping slice -- after processing any final marking + // triggered by barriers -- to clear out any references to things that are + // about to be finalized and update any pointers to moved GC things. + XPCJSRuntime* self = static_cast<XPCJSRuntime*>(data); + + // This callback is always called from within the GC so set the mGCIsRunning + // flag to prevent AssertInvalidWrappedJSNotInTable from trying to call back + // into the JS API. This has often already been set by FinalizeCallback by the + // time we get here, but it may not be if we are doing a shutdown GC or if we + // are called for compacting GC. + AutoRestore<bool> restoreState(self->mGCIsRunning); + self->mGCIsRunning = true; + + self->mWrappedJSMap->UpdateWeakPointersAfterGC(trc); + self->mUAWidgetScopeMap.traceWeak(trc); +} + +/* static */ +void XPCJSRuntime::WeakPointerCompartmentCallback(JSTracer* trc, + JS::Compartment* comp, + void* data) { + // Called immediately after the ZoneGroup weak pointer callback, but only + // once for each compartment that is being swept. + CompartmentPrivate* xpcComp = CompartmentPrivate::Get(comp); + if (xpcComp) { + xpcComp->UpdateWeakPointersAfterGC(trc); + } +} + +void CompartmentPrivate::UpdateWeakPointersAfterGC(JSTracer* trc) { + mRemoteProxies.traceWeak(trc); + mWrappedJSMap->UpdateWeakPointersAfterGC(trc); + mScope->UpdateWeakPointersAfterGC(trc); +} + +void XPCJSRuntime::CustomOutOfMemoryCallback() { + if (!Preferences::GetBool("memory.dump_reports_on_oom")) { + return; + } + + nsCOMPtr<nsIMemoryInfoDumper> dumper = + do_GetService("@mozilla.org/memory-info-dumper;1"); + if (!dumper) { + return; + } + + // If this fails, it fails silently. + dumper->DumpMemoryInfoToTempDir(u"due-to-JS-OOM"_ns, + /* anonymize = */ false, + /* minimizeMemoryUsage = */ false); +} + +void XPCJSRuntime::OnLargeAllocationFailure() { + CycleCollectedJSRuntime::SetLargeAllocationFailure(OOMState::Reporting); + + nsCOMPtr<nsIObserverService> os = xpc::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, "memory-pressure", u"heap-minimize"); + } + + CycleCollectedJSRuntime::SetLargeAllocationFailure(OOMState::Reported); +} + +class LargeAllocationFailureRunnable final : public Runnable { + Mutex mMutex MOZ_UNANNOTATED; + CondVar mCondVar; + bool mWaiting; + + virtual ~LargeAllocationFailureRunnable() { MOZ_ASSERT(!mWaiting); } + + protected: + NS_IMETHOD Run() override { + MOZ_ASSERT(NS_IsMainThread()); + + XPCJSRuntime::Get()->OnLargeAllocationFailure(); + + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mWaiting); + + mWaiting = false; + mCondVar.Notify(); + return NS_OK; + } + + public: + LargeAllocationFailureRunnable() + : mozilla::Runnable("LargeAllocationFailureRunnable"), + mMutex("LargeAllocationFailureRunnable::mMutex"), + mCondVar(mMutex, "LargeAllocationFailureRunnable::mCondVar"), + mWaiting(true) { + MOZ_ASSERT(!NS_IsMainThread()); + } + + void BlockUntilDone() { + MOZ_ASSERT(!NS_IsMainThread()); + + MutexAutoLock lock(mMutex); + while (mWaiting) { + mCondVar.Wait(); + } + } +}; + +static void OnLargeAllocationFailureCallback() { + // This callback can be called from any thread, including internal JS helper + // and DOM worker threads. We need to send the low-memory event via the + // observer service which can only be called on the main thread, so proxy to + // the main thread if we're not there already. The purpose of this callback + // is to synchronously free some memory so the caller can retry a failed + // allocation, so block on the completion. + + if (NS_IsMainThread()) { + XPCJSRuntime::Get()->OnLargeAllocationFailure(); + return; + } + + RefPtr<LargeAllocationFailureRunnable> r = new LargeAllocationFailureRunnable; + if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(r)))) { + return; + } + + r->BlockUntilDone(); +} + +// Usually this is used through nsIPlatformInfo. However, being able to query +// this interface on all threads risk triggering some main-thread assertions +// which is not guaranteed by the callers of GetBuildId. +extern const char gToolkitBuildID[]; + +bool mozilla::GetBuildId(JS::BuildIdCharVector* aBuildID) { + size_t length = std::char_traits<char>::length(gToolkitBuildID); + return aBuildID->append(gToolkitBuildID, length); +} + +size_t XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) { + size_t n = 0; + n += mallocSizeOf(this); + n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf); + n += mIID2NativeInterfaceMap->SizeOfIncludingThis(mallocSizeOf); + n += mClassInfo2NativeSetMap->ShallowSizeOfIncludingThis(mallocSizeOf); + n += mNativeSetMap->SizeOfIncludingThis(mallocSizeOf); + + n += CycleCollectedJSRuntime::SizeOfExcludingThis(mallocSizeOf); + + // There are other XPCJSRuntime members that could be measured; the above + // ones have been seen by DMD to be worth measuring. More stuff may be + // added later. + + return n; +} + +size_t CompartmentPrivate::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) { + size_t n = mallocSizeOf(this); + n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf); + n += mWrappedJSMap->SizeOfWrappedJS(mallocSizeOf); + return n; +} + +/***************************************************************************/ + +void XPCJSRuntime::Shutdown(JSContext* cx) { + // This destructor runs before ~CycleCollectedJSContext, which does the actual + // JS_DestroyContext() call. But destroying the context triggers one final GC, + // which can call back into the context with various callbacks if we aren't + // careful. Remove the relevant callbacks, but leave the weak pointer + // callbacks to clear out any remaining table entries. + JS_RemoveFinalizeCallback(cx, FinalizeCallback); + xpc_DelocalizeRuntime(JS_GetRuntime(cx)); + + JS::SetGCSliceCallback(cx, mPrevGCSliceCallback); + + nsScriptSecurityManager::ClearJSCallbacks(cx); + + // Clean up and destroy maps. Any remaining entries in mWrappedJSMap will be + // cleaned up by the weak pointer callbacks. + mIID2NativeInterfaceMap = nullptr; + + mClassInfo2NativeSetMap = nullptr; + + mNativeSetMap = nullptr; + + // Prevent ~LinkedList assertion failures if we leaked things. + mWrappedNativeScopes.clear(); + + mSubjectToFinalizationWJS.clear(); + + CycleCollectedJSRuntime::Shutdown(cx); +} + +XPCJSRuntime::~XPCJSRuntime() { + MOZ_COUNT_DTOR_INHERITED(XPCJSRuntime, CycleCollectedJSRuntime); +} + +// If |*anonymizeID| is non-zero and this is a user realm, the name will +// be anonymized. +static void GetRealmName(JS::Realm* realm, nsCString& name, int* anonymizeID, + bool replaceSlashes) { + if (*anonymizeID && !js::IsSystemRealm(realm)) { + name.AppendPrintf("<anonymized-%d>", *anonymizeID); + *anonymizeID += 1; + } else if (JSPrincipals* principals = JS::GetRealmPrincipals(realm)) { + nsresult rv = nsJSPrincipals::get(principals)->GetScriptLocation(name); + if (NS_FAILED(rv)) { + name.AssignLiteral("(unknown)"); + } + + // If the realm's location (name) differs from the principal's script + // location, append the realm's location to allow differentiation of + // multiple realms owned by the same principal (e.g. components owned + // by the system or null principal). + RealmPrivate* realmPrivate = RealmPrivate::Get(realm); + if (realmPrivate) { + const nsACString& location = realmPrivate->GetLocation(); + if (!location.IsEmpty() && !location.Equals(name)) { + name.AppendLiteral(", "); + name.Append(location); + } + } + + if (*anonymizeID) { + // We might have a file:// URL that includes a path from the local + // filesystem, which should be omitted if we're anonymizing. + static const char* filePrefix = "file://"; + int filePos = name.Find(filePrefix); + if (filePos >= 0) { + int pathPos = filePos + strlen(filePrefix); + int lastSlashPos = -1; + for (int i = pathPos; i < int(name.Length()); i++) { + if (name[i] == '/' || name[i] == '\\') { + lastSlashPos = i; + } + } + if (lastSlashPos != -1) { + name.ReplaceLiteral(pathPos, lastSlashPos - pathPos, "<anonymized>"); + } else { + // Something went wrong. Anonymize the entire path to be + // safe. + name.Truncate(pathPos); + name += "<anonymized?!>"; + } + } + + // We might have a location like this: + // inProcessBrowserChildGlobal?ownedBy=http://www.example.com/ + // The owner should be omitted if it's not a chrome: URI and we're + // anonymizing. + static const char* ownedByPrefix = "inProcessBrowserChildGlobal?ownedBy="; + int ownedByPos = name.Find(ownedByPrefix); + if (ownedByPos >= 0) { + const char* chrome = "chrome:"; + int ownerPos = ownedByPos + strlen(ownedByPrefix); + const nsDependentCSubstring& ownerFirstPart = + Substring(name, ownerPos, strlen(chrome)); + if (!ownerFirstPart.EqualsASCII(chrome)) { + name.Truncate(ownerPos); + name += "<anonymized>"; + } + } + } + + // A hack: replace forward slashes with '\\' so they aren't + // treated as path separators. Users of the reporters + // (such as about:memory) have to undo this change. + if (replaceSlashes) { + name.ReplaceChar('/', '\\'); + } + } else { + name.AssignLiteral("null-principal"); + } +} + +extern void xpc::GetCurrentRealmName(JSContext* cx, nsCString& name) { + RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); + if (!global) { + name.AssignLiteral("no global"); + return; + } + + JS::Realm* realm = GetNonCCWObjectRealm(global); + int anonymizeID = 0; + GetRealmName(realm, name, &anonymizeID, false); +} + +void xpc::AddGCCallback(xpcGCCallback cb) { + XPCJSRuntime::Get()->AddGCCallback(cb); +} + +void xpc::RemoveGCCallback(xpcGCCallback cb) { + XPCJSRuntime::Get()->RemoveGCCallback(cb); +} + +static int64_t JSMainRuntimeGCHeapDistinguishedAmount() { + JSContext* cx = danger::GetJSContext(); + return int64_t(JS_GetGCParameter(cx, JSGC_TOTAL_CHUNKS)) * js::gc::ChunkSize; +} + +static int64_t JSMainRuntimeTemporaryPeakDistinguishedAmount() { + JSContext* cx = danger::GetJSContext(); + return JS::PeakSizeOfTemporary(cx); +} + +static int64_t JSMainRuntimeCompartmentsSystemDistinguishedAmount() { + JSContext* cx = danger::GetJSContext(); + return JS::SystemCompartmentCount(cx); +} + +static int64_t JSMainRuntimeCompartmentsUserDistinguishedAmount() { + JSContext* cx = XPCJSContext::Get()->Context(); + return JS::UserCompartmentCount(cx); +} + +static int64_t JSMainRuntimeRealmsSystemDistinguishedAmount() { + JSContext* cx = danger::GetJSContext(); + return JS::SystemRealmCount(cx); +} + +static int64_t JSMainRuntimeRealmsUserDistinguishedAmount() { + JSContext* cx = XPCJSContext::Get()->Context(); + return JS::UserRealmCount(cx); +} + +class JSMainRuntimeTemporaryPeakReporter final : public nsIMemoryReporter { + ~JSMainRuntimeTemporaryPeakReporter() = default; + + public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) override { + MOZ_COLLECT_REPORT( + "js-main-runtime-temporary-peak", KIND_OTHER, UNITS_BYTES, + JSMainRuntimeTemporaryPeakDistinguishedAmount(), + "Peak transient data size in the main JSRuntime (the current size " + "of which is reported as " + "'explicit/js-non-window/runtime/temporary')."); + + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(JSMainRuntimeTemporaryPeakReporter, nsIMemoryReporter) + +// The REPORT* macros do an unconditional report. The ZRREPORT* macros are for +// realms and zones; they aggregate any entries smaller than +// SUNDRIES_THRESHOLD into the "sundries/gc-heap" and "sundries/malloc-heap" +// entries for the realm. + +#define SUNDRIES_THRESHOLD js::MemoryReportingSundriesThreshold() + +#define REPORT(_path, _kind, _units, _amount, _desc) \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::_kind, \ + nsIMemoryReporter::_units, _amount, \ + nsLiteralCString(_desc), data); + +#define REPORT_BYTES(_path, _kind, _amount, _desc) \ + REPORT(_path, _kind, UNITS_BYTES, _amount, _desc); + +#define REPORT_GC_BYTES(_path, _amount, _desc) \ + do { \ + size_t amount = _amount; /* evaluate _amount only once */ \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::KIND_NONHEAP, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + gcTotal += amount; \ + } while (0) + +// Report realm/zone non-GC (KIND_HEAP) bytes. +#define ZRREPORT_BYTES(_path, _amount, _desc) \ + do { \ + /* Assign _descLiteral plus "" into a char* to prove that it's */ \ + /* actually a literal. */ \ + size_t amount = _amount; /* evaluate _amount only once */ \ + if (amount >= SUNDRIES_THRESHOLD) { \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::KIND_HEAP, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + } else { \ + sundriesMallocHeap += amount; \ + } \ + } while (0) + +// Report realm/zone GC bytes. +#define ZRREPORT_GC_BYTES(_path, _amount, _desc) \ + do { \ + size_t amount = _amount; /* evaluate _amount only once */ \ + if (amount >= SUNDRIES_THRESHOLD) { \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::KIND_NONHEAP, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + gcTotal += amount; \ + } else { \ + sundriesGCHeap += amount; \ + } \ + } while (0) + +// Report realm/zone non-heap bytes. +#define ZRREPORT_NONHEAP_BYTES(_path, _amount, _desc) \ + do { \ + size_t amount = _amount; /* evaluate _amount only once */ \ + if (amount >= SUNDRIES_THRESHOLD) { \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::KIND_NONHEAP, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + } else { \ + sundriesNonHeap += amount; \ + } \ + } while (0) + +// Report runtime bytes. +#define RREPORT_BYTES(_path, _kind, _amount, _desc) \ + do { \ + size_t amount = _amount; /* evaluate _amount only once */ \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::_kind, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + rtTotal += amount; \ + } while (0) + +// Report GC thing bytes. +#define MREPORT_BYTES(_path, _kind, _amount, _desc) \ + do { \ + size_t amount = _amount; /* evaluate _amount only once */ \ + handleReport->Callback(""_ns, _path, nsIMemoryReporter::_kind, \ + nsIMemoryReporter::UNITS_BYTES, amount, \ + nsLiteralCString(_desc), data); \ + gcThingTotal += amount; \ + } while (0) + +MOZ_DEFINE_MALLOC_SIZE_OF(JSMallocSizeOf) + +namespace xpc { + +static void ReportZoneStats(const JS::ZoneStats& zStats, + const xpc::ZoneStatsExtras& extras, + nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize, + size_t* gcTotalOut = nullptr) { + const nsCString& pathPrefix = extras.pathPrefix; + size_t gcTotal = 0; + size_t sundriesGCHeap = 0; + size_t sundriesMallocHeap = 0; + size_t sundriesNonHeap = 0; + + MOZ_ASSERT(!gcTotalOut == zStats.isTotals); + + ZRREPORT_GC_BYTES(pathPrefix + "symbols/gc-heap"_ns, zStats.symbolsGCHeap, + "Symbols."); + + ZRREPORT_GC_BYTES( + pathPrefix + "gc-heap-arena-admin"_ns, zStats.gcHeapArenaAdmin, + "Bookkeeping information and alignment padding within GC arenas."); + + ZRREPORT_GC_BYTES(pathPrefix + "unused-gc-things"_ns, + zStats.unusedGCThings.totalSize(), + "Unused GC thing cells within non-empty arenas."); + + ZRREPORT_BYTES(pathPrefix + "unique-id-map"_ns, zStats.uniqueIdMap, + "Address-independent cell identities."); + + ZRREPORT_BYTES(pathPrefix + "propmap-tables"_ns, zStats.initialPropMapTable, + "Tables storing property map information."); + + ZRREPORT_BYTES(pathPrefix + "shape-tables"_ns, zStats.shapeTables, + "Tables storing shape information."); + + ZRREPORT_BYTES(pathPrefix + "compartments/compartment-objects"_ns, + zStats.compartmentObjects, + "The JS::Compartment objects in this zone."); + + ZRREPORT_BYTES( + pathPrefix + "compartments/cross-compartment-wrapper-tables"_ns, + zStats.crossCompartmentWrappersTables, + "The cross-compartment wrapper tables."); + + ZRREPORT_BYTES( + pathPrefix + "compartments/private-data"_ns, + zStats.compartmentsPrivateData, + "Extra data attached to each compartment by XPConnect, including " + "its wrapped-js."); + + ZRREPORT_GC_BYTES(pathPrefix + "jit-codes-gc-heap"_ns, zStats.jitCodesGCHeap, + "References to executable code pools used by the JITs."); + + ZRREPORT_GC_BYTES(pathPrefix + "getter-setters-gc-heap"_ns, + zStats.getterSettersGCHeap, + "Information for getter/setter properties."); + + ZRREPORT_GC_BYTES(pathPrefix + "property-maps/gc-heap/compact"_ns, + zStats.compactPropMapsGCHeap, + "Information about object properties."); + + ZRREPORT_GC_BYTES(pathPrefix + "property-maps/gc-heap/normal"_ns, + zStats.normalPropMapsGCHeap, + "Information about object properties."); + + ZRREPORT_GC_BYTES(pathPrefix + "property-maps/gc-heap/dict"_ns, + zStats.dictPropMapsGCHeap, + "Information about dictionary mode object properties."); + + ZRREPORT_BYTES(pathPrefix + "property-maps/malloc-heap/children"_ns, + zStats.propMapChildren, "Tables for PropMap children."); + + ZRREPORT_BYTES(pathPrefix + "property-maps/malloc-heap/tables"_ns, + zStats.propMapTables, "HashTables for PropMaps."); + + ZRREPORT_GC_BYTES(pathPrefix + "scopes/gc-heap"_ns, zStats.scopesGCHeap, + "Scope information for scripts."); + + ZRREPORT_BYTES(pathPrefix + "scopes/malloc-heap"_ns, zStats.scopesMallocHeap, + "Arrays of binding names and other binding-related data."); + + ZRREPORT_GC_BYTES(pathPrefix + "regexp-shareds/gc-heap"_ns, + zStats.regExpSharedsGCHeap, "Shared compiled regexp data."); + + ZRREPORT_BYTES(pathPrefix + "regexp-shareds/malloc-heap"_ns, + zStats.regExpSharedsMallocHeap, + "Shared compiled regexp data."); + + ZRREPORT_BYTES(pathPrefix + "regexp-zone"_ns, zStats.regexpZone, + "The regexp zone and regexp data."); + + ZRREPORT_BYTES(pathPrefix + "jit-zone"_ns, zStats.jitZone, "The JIT zone."); + + ZRREPORT_BYTES(pathPrefix + "baseline/optimized-stubs"_ns, + zStats.baselineStubsOptimized, + "The Baseline JIT's optimized IC stubs (excluding code)."); + + ZRREPORT_BYTES(pathPrefix + "script-counts-map"_ns, zStats.scriptCountsMap, + "Profiling-related information for scripts."); + + ZRREPORT_NONHEAP_BYTES(pathPrefix + "code/ion"_ns, zStats.code.ion, + "Code generated by the IonMonkey JIT."); + + ZRREPORT_NONHEAP_BYTES(pathPrefix + "code/baseline"_ns, zStats.code.baseline, + "Code generated by the Baseline JIT."); + + ZRREPORT_NONHEAP_BYTES(pathPrefix + "code/regexp"_ns, zStats.code.regexp, + "Code generated by the regexp JIT."); + + ZRREPORT_NONHEAP_BYTES( + pathPrefix + "code/other"_ns, zStats.code.other, + "Code generated by the JITs for wrappers and trampolines."); + + ZRREPORT_NONHEAP_BYTES(pathPrefix + "code/unused"_ns, zStats.code.unused, + "Memory allocated by one of the JITs to hold code, " + "but which is currently unused."); + + size_t stringsNotableAboutMemoryGCHeap = 0; + size_t stringsNotableAboutMemoryMallocHeap = 0; + +#define MAYBE_INLINE "The characters may be inline or on the malloc heap." +#define MAYBE_OVERALLOCATED \ + "Sometimes over-allocated to simplify string concatenation." + + for (size_t i = 0; i < zStats.notableStrings.length(); i++) { + const JS::NotableStringInfo& info = zStats.notableStrings[i]; + + MOZ_ASSERT(!zStats.isTotals); + + // We don't do notable string detection when anonymizing, because + // there's a good chance its for crash submission, and the memory + // required for notable string detection is high. + MOZ_ASSERT(!anonymize); + + nsDependentCString notableString(info.buffer.get()); + + // Viewing about:memory generates many notable strings which contain + // "string(length=". If we report these as notable, then we'll create + // even more notable strings the next time we open about:memory (unless + // there's a GC in the meantime), and so on ad infinitum. + // + // To avoid cluttering up about:memory like this, we stick notable + // strings which contain "string(length=" into their own bucket. +#define STRING_LENGTH "string(length=" + if (FindInReadable(nsLiteralCString(STRING_LENGTH), notableString)) { + stringsNotableAboutMemoryGCHeap += info.gcHeapLatin1; + stringsNotableAboutMemoryGCHeap += info.gcHeapTwoByte; + stringsNotableAboutMemoryMallocHeap += info.mallocHeapLatin1; + stringsNotableAboutMemoryMallocHeap += info.mallocHeapTwoByte; + continue; + } + + // Escape / to \ before we put notableString into the memory reporter + // path, because we don't want any forward slashes in the string to + // count as path separators. + nsCString escapedString(notableString); + escapedString.ReplaceSubstring("/", "\\"); + + bool truncated = notableString.Length() < info.length; + + nsCString path = + pathPrefix + + nsPrintfCString("strings/" STRING_LENGTH "%zu, copies=%d, \"%s\"%s)/", + info.length, info.numCopies, escapedString.get(), + truncated ? " (truncated)" : ""); + + if (info.gcHeapLatin1 > 0) { + REPORT_GC_BYTES(path + "gc-heap/latin1"_ns, info.gcHeapLatin1, + "Latin1 strings. " MAYBE_INLINE); + } + + if (info.gcHeapTwoByte > 0) { + REPORT_GC_BYTES(path + "gc-heap/two-byte"_ns, info.gcHeapTwoByte, + "TwoByte strings. " MAYBE_INLINE); + } + + if (info.mallocHeapLatin1 > 0) { + REPORT_BYTES(path + "malloc-heap/latin1"_ns, KIND_HEAP, + info.mallocHeapLatin1, + "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED); + } + + if (info.mallocHeapTwoByte > 0) { + REPORT_BYTES( + path + "malloc-heap/two-byte"_ns, KIND_HEAP, info.mallocHeapTwoByte, + "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED); + } + } + + nsCString nonNotablePath = pathPrefix; + nonNotablePath += (zStats.isTotals || anonymize) + ? "strings/"_ns + : "strings/string(<non-notable strings>)/"_ns; + + if (zStats.stringInfo.gcHeapLatin1 > 0) { + REPORT_GC_BYTES(nonNotablePath + "gc-heap/latin1"_ns, + zStats.stringInfo.gcHeapLatin1, + "Latin1 strings. " MAYBE_INLINE); + } + + if (zStats.stringInfo.gcHeapTwoByte > 0) { + REPORT_GC_BYTES(nonNotablePath + "gc-heap/two-byte"_ns, + zStats.stringInfo.gcHeapTwoByte, + "TwoByte strings. " MAYBE_INLINE); + } + + if (zStats.stringInfo.mallocHeapLatin1 > 0) { + REPORT_BYTES(nonNotablePath + "malloc-heap/latin1"_ns, KIND_HEAP, + zStats.stringInfo.mallocHeapLatin1, + "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED); + } + + if (zStats.stringInfo.mallocHeapTwoByte > 0) { + REPORT_BYTES(nonNotablePath + "malloc-heap/two-byte"_ns, KIND_HEAP, + zStats.stringInfo.mallocHeapTwoByte, + "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED); + } + + if (stringsNotableAboutMemoryGCHeap > 0) { + MOZ_ASSERT(!zStats.isTotals); + REPORT_GC_BYTES( + pathPrefix + "strings/string(<about-memory>)/gc-heap"_ns, + stringsNotableAboutMemoryGCHeap, + "Strings that contain the characters '" STRING_LENGTH + "', which " + "are probably from about:memory itself." MAYBE_INLINE + " We filter them out rather than display them, because displaying " + "them would create even more such strings every time about:memory " + "is refreshed."); + } + + if (stringsNotableAboutMemoryMallocHeap > 0) { + MOZ_ASSERT(!zStats.isTotals); + REPORT_BYTES( + pathPrefix + "strings/string(<about-memory>)/malloc-heap"_ns, KIND_HEAP, + stringsNotableAboutMemoryMallocHeap, + "Non-inline string characters of strings that contain the " + "characters '" STRING_LENGTH + "', which are probably from " + "about:memory itself. " MAYBE_OVERALLOCATED + " We filter them out rather than display them, because displaying " + "them would create even more such strings every time about:memory " + "is refreshed."); + } + + const JS::ShapeInfo& shapeInfo = zStats.shapeInfo; + if (shapeInfo.shapesGCHeapShared > 0) { + REPORT_GC_BYTES(pathPrefix + "shapes/gc-heap/shared"_ns, + shapeInfo.shapesGCHeapShared, "Shared shapes."); + } + + if (shapeInfo.shapesGCHeapDict > 0) { + REPORT_GC_BYTES(pathPrefix + "shapes/gc-heap/dict"_ns, + shapeInfo.shapesGCHeapDict, "Shapes in dictionary mode."); + } + + if (shapeInfo.shapesGCHeapBase > 0) { + REPORT_GC_BYTES(pathPrefix + "shapes/gc-heap/base"_ns, + shapeInfo.shapesGCHeapBase, + "Base shapes, which collate data common to many shapes."); + } + + if (shapeInfo.shapesMallocHeapCache > 0) { + REPORT_BYTES(pathPrefix + "shapes/malloc-heap/shape-cache"_ns, KIND_HEAP, + shapeInfo.shapesMallocHeapCache, + "Shape cache hash set for adding properties."); + } + + if (sundriesGCHeap > 0) { + // We deliberately don't use ZRREPORT_GC_BYTES here. + REPORT_GC_BYTES( + pathPrefix + "sundries/gc-heap"_ns, sundriesGCHeap, + "The sum of all 'gc-heap' measurements that are too small to be " + "worth showing individually."); + } + + if (sundriesMallocHeap > 0) { + // We deliberately don't use ZRREPORT_BYTES here. + REPORT_BYTES( + pathPrefix + "sundries/malloc-heap"_ns, KIND_HEAP, sundriesMallocHeap, + "The sum of all 'malloc-heap' measurements that are too small to " + "be worth showing individually."); + } + + if (sundriesNonHeap > 0) { + // We deliberately don't use ZRREPORT_NONHEAP_BYTES here. + REPORT_BYTES(pathPrefix + "sundries/other-heap"_ns, KIND_NONHEAP, + sundriesNonHeap, + "The sum of non-malloc/gc measurements that are too small to " + "be worth showing individually."); + } + + if (gcTotalOut) { + *gcTotalOut += gcTotal; + } + +#undef STRING_LENGTH +} + +static void ReportClassStats(const ClassInfo& classInfo, const nsACString& path, + nsIHandleReportCallback* handleReport, + nsISupports* data, size_t& gcTotal) { + // We deliberately don't use ZRREPORT_BYTES, so that these per-class values + // don't go into sundries. + + if (classInfo.objectsGCHeap > 0) { + REPORT_GC_BYTES(path + "objects/gc-heap"_ns, classInfo.objectsGCHeap, + "Objects, including fixed slots."); + } + + if (classInfo.objectsMallocHeapSlots > 0) { + REPORT_BYTES(path + "objects/malloc-heap/slots"_ns, KIND_HEAP, + classInfo.objectsMallocHeapSlots, "Non-fixed object slots."); + } + + if (classInfo.objectsMallocHeapElementsNormal > 0) { + REPORT_BYTES(path + "objects/malloc-heap/elements/normal"_ns, KIND_HEAP, + classInfo.objectsMallocHeapElementsNormal, + "Normal (non-wasm) indexed elements."); + } + + if (classInfo.objectsMallocHeapElementsAsmJS > 0) { + REPORT_BYTES(path + "objects/malloc-heap/elements/asm.js"_ns, KIND_HEAP, + classInfo.objectsMallocHeapElementsAsmJS, + "asm.js array buffer elements allocated in the malloc heap."); + } + + if (classInfo.objectsMallocHeapGlobalData > 0) { + REPORT_BYTES(path + "objects/malloc-heap/global-data"_ns, KIND_HEAP, + classInfo.objectsMallocHeapGlobalData, + "Data for global objects."); + } + + if (classInfo.objectsMallocHeapGlobalVarNamesSet > 0) { + REPORT_BYTES(path + "objects/malloc-heap/global-varnames-set"_ns, KIND_HEAP, + classInfo.objectsMallocHeapGlobalVarNamesSet, + "Set of global names."); + } + + if (classInfo.objectsMallocHeapMisc > 0) { + REPORT_BYTES(path + "objects/malloc-heap/misc"_ns, KIND_HEAP, + classInfo.objectsMallocHeapMisc, "Miscellaneous object data."); + } + + if (classInfo.objectsNonHeapElementsNormal > 0) { + REPORT_BYTES(path + "objects/non-heap/elements/normal"_ns, KIND_NONHEAP, + classInfo.objectsNonHeapElementsNormal, + "Memory-mapped non-shared array buffer elements."); + } + + if (classInfo.objectsNonHeapElementsShared > 0) { + REPORT_BYTES( + path + "objects/non-heap/elements/shared"_ns, KIND_NONHEAP, + classInfo.objectsNonHeapElementsShared, + "Memory-mapped shared array buffer elements. These elements are " + "shared between one or more runtimes; the reported size is divided " + "by the buffer's refcount."); + } + + // WebAssembly memories are always non-heap-allocated (mmap). We never put + // these under sundries, because (a) in practice they're almost always + // larger than the sundries threshold, and (b) we'd need a third category of + // sundries ("non-heap"), which would be a pain. + if (classInfo.objectsNonHeapElementsWasm > 0) { + REPORT_BYTES(path + "objects/non-heap/elements/wasm"_ns, KIND_NONHEAP, + classInfo.objectsNonHeapElementsWasm, + "wasm/asm.js array buffer elements allocated outside both the " + "malloc heap and the GC heap."); + } + if (classInfo.objectsNonHeapElementsWasmShared > 0) { + REPORT_BYTES( + path + "objects/non-heap/elements/wasm-shared"_ns, KIND_NONHEAP, + classInfo.objectsNonHeapElementsWasmShared, + "wasm/asm.js array buffer elements allocated outside both the " + "malloc heap and the GC heap. These elements are shared between " + "one or more runtimes; the reported size is divided by the " + "buffer's refcount."); + } + + if (classInfo.objectsNonHeapCodeWasm > 0) { + REPORT_BYTES(path + "objects/non-heap/code/wasm"_ns, KIND_NONHEAP, + classInfo.objectsNonHeapCodeWasm, + "AOT-compiled wasm/asm.js code."); + } +} + +static void ReportRealmStats(const JS::RealmStats& realmStats, + const xpc::RealmStatsExtras& extras, + nsIHandleReportCallback* handleReport, + nsISupports* data, size_t* gcTotalOut = nullptr) { + static const nsDependentCString addonPrefix("explicit/add-ons/"); + + size_t gcTotal = 0, sundriesGCHeap = 0, sundriesMallocHeap = 0; + nsAutoCString realmJSPathPrefix(extras.jsPathPrefix); + nsAutoCString realmDOMPathPrefix(extras.domPathPrefix); + + MOZ_ASSERT(!gcTotalOut == realmStats.isTotals); + + nsCString nonNotablePath = realmJSPathPrefix; + nonNotablePath += realmStats.isTotals + ? "classes/"_ns + : "classes/class(<non-notable classes>)/"_ns; + + ReportClassStats(realmStats.classInfo, nonNotablePath, handleReport, data, + gcTotal); + + for (size_t i = 0; i < realmStats.notableClasses.length(); i++) { + MOZ_ASSERT(!realmStats.isTotals); + const JS::NotableClassInfo& classInfo = realmStats.notableClasses[i]; + + nsCString classPath = + realmJSPathPrefix + + nsPrintfCString("classes/class(%s)/", classInfo.className_.get()); + + ReportClassStats(classInfo, classPath, handleReport, data, gcTotal); + } + + // Note that we use realmDOMPathPrefix here. This is because we measure + // orphan DOM nodes in the JS reporter, but we want to report them in a "dom" + // sub-tree rather than a "js" sub-tree. + ZRREPORT_BYTES( + realmDOMPathPrefix + "orphan-nodes"_ns, realmStats.objectsPrivate, + "Orphan DOM nodes, i.e. those that are only reachable from JavaScript " + "objects."); + + ZRREPORT_GC_BYTES( + realmJSPathPrefix + "scripts/gc-heap"_ns, realmStats.scriptsGCHeap, + "JSScript instances. There is one per user-defined function in a " + "script, and one for the top-level code in a script."); + + ZRREPORT_BYTES(realmJSPathPrefix + "scripts/malloc-heap/data"_ns, + realmStats.scriptsMallocHeapData, + "Various variable-length tables in JSScripts."); + + ZRREPORT_BYTES(realmJSPathPrefix + "baseline/data"_ns, + realmStats.baselineData, + "The Baseline JIT's compilation data (BaselineScripts)."); + + ZRREPORT_BYTES(realmJSPathPrefix + "baseline/fallback-stubs"_ns, + realmStats.baselineStubsFallback, + "The Baseline JIT's fallback IC stubs (excluding code)."); + + ZRREPORT_BYTES(realmJSPathPrefix + "ion-data"_ns, realmStats.ionData, + "The IonMonkey JIT's compilation data (IonScripts)."); + + ZRREPORT_BYTES(realmJSPathPrefix + "jit-scripts"_ns, realmStats.jitScripts, + "JIT data associated with scripts."); + + ZRREPORT_BYTES(realmJSPathPrefix + "realm-object"_ns, realmStats.realmObject, + "The JS::Realm object itself."); + + ZRREPORT_BYTES( + realmJSPathPrefix + "realm-tables"_ns, realmStats.realmTables, + "Realm-wide tables storing object group information and wasm instances."); + + ZRREPORT_BYTES(realmJSPathPrefix + "inner-views"_ns, + realmStats.innerViewsTable, + "The table for array buffer inner views."); + + ZRREPORT_BYTES( + realmJSPathPrefix + "object-metadata"_ns, realmStats.objectMetadataTable, + "The table used by debugging tools for tracking object metadata"); + + ZRREPORT_BYTES(realmJSPathPrefix + "saved-stacks-set"_ns, + realmStats.savedStacksSet, "The saved stacks set."); + + ZRREPORT_BYTES(realmJSPathPrefix + "non-syntactic-lexical-scopes-table"_ns, + realmStats.nonSyntacticLexicalScopesTable, + "The non-syntactic lexical scopes table."); + + ZRREPORT_BYTES(realmJSPathPrefix + "jit-realm"_ns, realmStats.jitRealm, + "The JIT realm."); + + if (sundriesGCHeap > 0) { + // We deliberately don't use ZRREPORT_GC_BYTES here. + REPORT_GC_BYTES( + realmJSPathPrefix + "sundries/gc-heap"_ns, sundriesGCHeap, + "The sum of all 'gc-heap' measurements that are too small to be " + "worth showing individually."); + } + + if (sundriesMallocHeap > 0) { + // We deliberately don't use ZRREPORT_BYTES here. + REPORT_BYTES( + realmJSPathPrefix + "sundries/malloc-heap"_ns, KIND_HEAP, + sundriesMallocHeap, + "The sum of all 'malloc-heap' measurements that are too small to " + "be worth showing individually."); + } + + if (gcTotalOut) { + *gcTotalOut += gcTotal; + } +} + +static void ReportScriptSourceStats(const ScriptSourceInfo& scriptSourceInfo, + const nsACString& path, + nsIHandleReportCallback* handleReport, + nsISupports* data, size_t& rtTotal) { + if (scriptSourceInfo.misc > 0) { + RREPORT_BYTES(path + "misc"_ns, KIND_HEAP, scriptSourceInfo.misc, + "Miscellaneous data relating to JavaScript source code."); + } +} + +void ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats, + const nsACString& rtPath, + nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize, + size_t* rtTotalOut) { + size_t gcTotal = 0; + + for (const auto& zStats : rtStats.zoneStatsVector) { + const xpc::ZoneStatsExtras* extras = + static_cast<const xpc::ZoneStatsExtras*>(zStats.extra); + ReportZoneStats(zStats, *extras, handleReport, data, anonymize, &gcTotal); + } + + for (const auto& realmStats : rtStats.realmStatsVector) { + const xpc::RealmStatsExtras* extras = + static_cast<const xpc::RealmStatsExtras*>(realmStats.extra); + + ReportRealmStats(realmStats, *extras, handleReport, data, &gcTotal); + } + + // Report the rtStats.runtime numbers under "runtime/", and compute their + // total for later. + + size_t rtTotal = 0; + + RREPORT_BYTES(rtPath + "runtime/runtime-object"_ns, KIND_HEAP, + rtStats.runtime.object, "The JSRuntime object."); + + RREPORT_BYTES(rtPath + "runtime/atoms-table"_ns, KIND_HEAP, + rtStats.runtime.atomsTable, "The atoms table."); + + RREPORT_BYTES(rtPath + "runtime/atoms-mark-bitmaps"_ns, KIND_HEAP, + rtStats.runtime.atomsMarkBitmaps, + "Mark bitmaps for atoms held by each zone."); + + RREPORT_BYTES(rtPath + "runtime/self-host-stencil"_ns, KIND_HEAP, + rtStats.runtime.selfHostStencil, + "The self-hosting CompilationStencil."); + + RREPORT_BYTES(rtPath + "runtime/contexts"_ns, KIND_HEAP, + rtStats.runtime.contexts, + "JSContext objects and structures that belong to them."); + + RREPORT_BYTES( + rtPath + "runtime/temporary"_ns, KIND_HEAP, rtStats.runtime.temporary, + "Transient data (mostly parse nodes) held by the JSRuntime during " + "compilation."); + + RREPORT_BYTES(rtPath + "runtime/interpreter-stack"_ns, KIND_HEAP, + rtStats.runtime.interpreterStack, "JS interpreter frames."); + + RREPORT_BYTES( + rtPath + "runtime/shared-immutable-strings-cache"_ns, KIND_HEAP, + rtStats.runtime.sharedImmutableStringsCache, + "Immutable strings (such as JS scripts' source text) shared across all " + "JSRuntimes."); + + RREPORT_BYTES(rtPath + "runtime/shared-intl-data"_ns, KIND_HEAP, + rtStats.runtime.sharedIntlData, + "Shared internationalization data."); + + RREPORT_BYTES(rtPath + "runtime/uncompressed-source-cache"_ns, KIND_HEAP, + rtStats.runtime.uncompressedSourceCache, + "The uncompressed source code cache."); + + RREPORT_BYTES(rtPath + "runtime/script-data"_ns, KIND_HEAP, + rtStats.runtime.scriptData, + "The table holding script data shared in the runtime."); + + nsCString nonNotablePath = + rtPath + + nsPrintfCString( + "runtime/script-sources/source(scripts=%d, <non-notable files>)/", + rtStats.runtime.scriptSourceInfo.numScripts); + + ReportScriptSourceStats(rtStats.runtime.scriptSourceInfo, nonNotablePath, + handleReport, data, rtTotal); + + for (size_t i = 0; i < rtStats.runtime.notableScriptSources.length(); i++) { + const JS::NotableScriptSourceInfo& scriptSourceInfo = + rtStats.runtime.notableScriptSources[i]; + + // Escape / to \ before we put the filename into the memory reporter + // path, because we don't want any forward slashes in the string to + // count as path separators. Consumers of memory reporters (e.g. + // about:memory) will convert them back to / after doing path + // splitting. + nsCString escapedFilename; + if (anonymize) { + escapedFilename.AppendPrintf("<anonymized-source-%d>", int(i)); + } else { + nsDependentCString filename(scriptSourceInfo.filename_.get()); + escapedFilename.Append(filename); + escapedFilename.ReplaceSubstring("/", "\\"); + } + + nsCString notablePath = + rtPath + + nsPrintfCString("runtime/script-sources/source(scripts=%d, %s)/", + scriptSourceInfo.numScripts, escapedFilename.get()); + + ReportScriptSourceStats(scriptSourceInfo, notablePath, handleReport, data, + rtTotal); + } + + RREPORT_BYTES(rtPath + "runtime/gc/marker"_ns, KIND_HEAP, + rtStats.runtime.gc.marker, "The GC mark stack and gray roots."); + + RREPORT_BYTES(rtPath + "runtime/gc/nursery-committed"_ns, KIND_NONHEAP, + rtStats.runtime.gc.nurseryCommitted, + "Memory being used by the GC's nursery."); + + RREPORT_BYTES( + rtPath + "runtime/gc/nursery-malloced-buffers"_ns, KIND_HEAP, + rtStats.runtime.gc.nurseryMallocedBuffers, + "Out-of-line slots and elements belonging to objects in the nursery."); + + RREPORT_BYTES(rtPath + "runtime/gc/store-buffer/vals"_ns, KIND_HEAP, + rtStats.runtime.gc.storeBufferVals, + "Values in the store buffer."); + + RREPORT_BYTES(rtPath + "runtime/gc/store-buffer/cells"_ns, KIND_HEAP, + rtStats.runtime.gc.storeBufferCells, + "Cells in the store buffer."); + + RREPORT_BYTES(rtPath + "runtime/gc/store-buffer/slots"_ns, KIND_HEAP, + rtStats.runtime.gc.storeBufferSlots, + "Slots in the store buffer."); + + RREPORT_BYTES(rtPath + "runtime/gc/store-buffer/whole-cells"_ns, KIND_HEAP, + rtStats.runtime.gc.storeBufferWholeCells, + "Whole cells in the store buffer."); + + RREPORT_BYTES(rtPath + "runtime/gc/store-buffer/generics"_ns, KIND_HEAP, + rtStats.runtime.gc.storeBufferGenerics, + "Generic things in the store buffer."); + + RREPORT_BYTES(rtPath + "runtime/jit-lazylink"_ns, KIND_HEAP, + rtStats.runtime.jitLazyLink, + "IonMonkey compilations waiting for lazy linking."); + + if (rtTotalOut) { + *rtTotalOut = rtTotal; + } + + // Report GC numbers that don't belong to a realm. + + // We don't want to report decommitted memory in "explicit", so we just + // change the leading "explicit/" to "decommitted/". + nsCString rtPath2(rtPath); + rtPath2.ReplaceLiteral(0, strlen("explicit"), "decommitted"); + + REPORT_GC_BYTES( + rtPath2 + "gc-heap/decommitted-pages"_ns, rtStats.gcHeapDecommittedPages, + "GC arenas in non-empty chunks that is decommitted, i.e. it takes up " + "address space but no physical memory or swap space."); + + REPORT_GC_BYTES( + rtPath + "gc-heap/unused-chunks"_ns, rtStats.gcHeapUnusedChunks, + "Empty GC chunks which will soon be released unless claimed for new " + "allocations."); + + REPORT_GC_BYTES(rtPath + "gc-heap/unused-arenas"_ns, + rtStats.gcHeapUnusedArenas, + "Empty GC arenas within non-empty chunks."); + + REPORT_GC_BYTES(rtPath + "gc-heap/chunk-admin"_ns, rtStats.gcHeapChunkAdmin, + "Bookkeeping information within GC chunks."); + + // gcTotal is the sum of everything we've reported for the GC heap. It + // should equal rtStats.gcHeapChunkTotal. + MOZ_ASSERT(gcTotal == rtStats.gcHeapChunkTotal); +} + +} // namespace xpc + +class JSMainRuntimeRealmsReporter final : public nsIMemoryReporter { + ~JSMainRuntimeRealmsReporter() = default; + + public: + NS_DECL_ISUPPORTS + + struct Data { + int anonymizeID; + js::Vector<nsCString, 0, js::SystemAllocPolicy> paths; + }; + + static void RealmCallback(JSContext* cx, void* vdata, Realm* realm, + const JS::AutoRequireNoGC& nogc) { + // silently ignore OOM errors + Data* data = static_cast<Data*>(vdata); + nsCString path; + GetRealmName(realm, path, &data->anonymizeID, /* replaceSlashes = */ true); + path.Insert(js::IsSystemRealm(realm) ? "js-main-runtime-realms/system/"_ns + : "js-main-runtime-realms/user/"_ns, + 0); + mozilla::Unused << data->paths.append(path); + } + + NS_IMETHOD CollectReports(nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize) override { + // First we collect the realm paths. Then we report them. Doing + // the two steps interleaved is a bad idea, because calling + // |handleReport| from within RealmCallback() leads to all manner + // of assertions. + + Data d; + d.anonymizeID = anonymize ? 1 : 0; + JS::IterateRealms(XPCJSContext::Get()->Context(), &d, RealmCallback); + + for (auto& path : d.paths) { + REPORT(nsCString(path), KIND_OTHER, UNITS_COUNT, 1, + "A live realm in the main JSRuntime."); + } + + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(JSMainRuntimeRealmsReporter, nsIMemoryReporter) + +MOZ_DEFINE_MALLOC_SIZE_OF(OrphanMallocSizeOf) + +namespace xpc { + +class OrphanReporter : public JS::ObjectPrivateVisitor { + public: + explicit OrphanReporter(GetISupportsFun aGetISupports) + : JS::ObjectPrivateVisitor(aGetISupports), mState(OrphanMallocSizeOf) {} + + virtual size_t sizeOfIncludingThis(nsISupports* aSupports) override { + nsCOMPtr<nsINode> node = do_QueryInterface(aSupports); + if (!node || node->IsInComposedDoc()) { + return 0; + } + + // This is an orphan node. If we haven't already handled the sub-tree that + // this node belongs to, measure the sub-tree's size and then record its + // root so we don't measure it again. + nsCOMPtr<nsINode> orphanTree = node->SubtreeRoot(); + if (!orphanTree || mState.HaveSeenPtr(orphanTree.get())) { + return 0; + } + + nsWindowSizes sizes(mState); + mozilla::dom::Document::AddSizeOfNodeTree(*orphanTree, sizes); + + // We combine the node size with nsStyleSizes here. It's not ideal, but it's + // hard to get the style structs measurements out to nsWindowMemoryReporter. + // Also, we drop mServoData in UnbindFromTree(), so in theory any + // non-in-tree element won't have any style data to measure. + // + // FIXME(emilio): We should ideally not do this, since ShadowRoots keep + // their StyleSheets alive even when detached from a document, and those + // could be significant in theory. + return sizes.getTotalSize(); + } + + private: + SizeOfState mState; +}; + +#ifdef DEBUG +static bool StartsWithExplicit(nsACString& s) { + return StringBeginsWith(s, "explicit/"_ns); +} +#endif + +class XPCJSRuntimeStats : public JS::RuntimeStats { + WindowPaths* mWindowPaths; + WindowPaths* mTopWindowPaths; + int mAnonymizeID; + + public: + XPCJSRuntimeStats(WindowPaths* windowPaths, WindowPaths* topWindowPaths, + bool anonymize) + : JS::RuntimeStats(JSMallocSizeOf), + mWindowPaths(windowPaths), + mTopWindowPaths(topWindowPaths), + mAnonymizeID(anonymize ? 1 : 0) {} + + ~XPCJSRuntimeStats() { + for (size_t i = 0; i != realmStatsVector.length(); ++i) { + delete static_cast<xpc::RealmStatsExtras*>(realmStatsVector[i].extra); + } + + for (size_t i = 0; i != zoneStatsVector.length(); ++i) { + delete static_cast<xpc::ZoneStatsExtras*>(zoneStatsVector[i].extra); + } + } + + virtual void initExtraZoneStats(JS::Zone* zone, JS::ZoneStats* zStats, + const JS::AutoRequireNoGC& nogc) override { + xpc::ZoneStatsExtras* extras = new xpc::ZoneStatsExtras; + extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/"); + + // Get some global in this zone. + Rooted<Realm*> realm(dom::RootingCx(), js::GetAnyRealmInZone(zone)); + if (realm) { + RootedObject global(dom::RootingCx(), JS::GetRealmGlobalOrNull(realm)); + if (global) { + RefPtr<nsGlobalWindowInner> window; + if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))) { + // The global is a |window| object. Use the path prefix that + // we should have already created for it. + if (mTopWindowPaths->Get(window->WindowID(), &extras->pathPrefix)) { + extras->pathPrefix.AppendLiteral("/js-"); + } + } + } + } + + extras->pathPrefix += nsPrintfCString("zone(0x%p)/", (void*)zone); + + MOZ_ASSERT(StartsWithExplicit(extras->pathPrefix)); + + zStats->extra = extras; + } + + virtual void initExtraRealmStats(Realm* realm, JS::RealmStats* realmStats, + const JS::AutoRequireNoGC& nogc) override { + xpc::RealmStatsExtras* extras = new xpc::RealmStatsExtras; + nsCString rName; + GetRealmName(realm, rName, &mAnonymizeID, /* replaceSlashes = */ true); + + // Get the realm's global. + bool needZone = true; + RootedObject global(dom::RootingCx(), JS::GetRealmGlobalOrNull(realm)); + if (global) { + RefPtr<nsGlobalWindowInner> window; + if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))) { + // The global is a |window| object. Use the path prefix that + // we should have already created for it. + if (mWindowPaths->Get(window->WindowID(), &extras->jsPathPrefix)) { + extras->domPathPrefix.Assign(extras->jsPathPrefix); + extras->domPathPrefix.AppendLiteral("/dom/"); + extras->jsPathPrefix.AppendLiteral("/js-"); + needZone = false; + } else { + extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/"); + extras->domPathPrefix.AssignLiteral( + "explicit/dom/unknown-window-global?!/"); + } + } else { + extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/"); + extras->domPathPrefix.AssignLiteral( + "explicit/dom/non-window-global?!/"); + } + } else { + extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/"); + extras->domPathPrefix.AssignLiteral("explicit/dom/no-global?!/"); + } + + if (needZone) { + extras->jsPathPrefix += + nsPrintfCString("zone(0x%p)/", (void*)js::GetRealmZone(realm)); + } + + extras->jsPathPrefix += "realm("_ns + rName + ")/"_ns; + + // extras->jsPathPrefix is used for almost all the realm-specific + // reports. At this point it has the form + // "<something>realm(<rname>)/". + // + // extras->domPathPrefix is used for DOM orphan nodes, which are + // counted by the JS reporter but reported as part of the DOM + // measurements. At this point it has the form "<something>/dom/" if + // this realm belongs to an nsGlobalWindow, and + // "explicit/dom/<something>?!/" otherwise (in which case it shouldn't + // be used, because non-nsGlobalWindow realms shouldn't have + // orphan DOM nodes). + + MOZ_ASSERT(StartsWithExplicit(extras->jsPathPrefix)); + MOZ_ASSERT(StartsWithExplicit(extras->domPathPrefix)); + + realmStats->extra = extras; + } +}; + +void JSReporter::CollectReports(WindowPaths* windowPaths, + WindowPaths* topWindowPaths, + nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize) { + XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance(); + + // In the first step we get all the stats and stash them in a local + // data structure. In the second step we pass all the stashed stats to + // the callback. Separating these steps is important because the + // callback may be a JS function, and executing JS while getting these + // stats seems like a bad idea. + + XPCJSRuntimeStats rtStats(windowPaths, topWindowPaths, anonymize); + OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject); + JSContext* cx = XPCJSContext::Get()->Context(); + if (!JS::CollectRuntimeStats(cx, &rtStats, &orphanReporter, anonymize)) { + return; + } + + // Collect JS stats not associated with a Runtime such as helper threads or + // global tracelogger data. We do this here in JSReporter::CollectReports + // as this is used for the main Runtime in process. + JS::GlobalStats gStats(JSMallocSizeOf); + if (!JS::CollectGlobalStats(&gStats)) { + return; + } + + size_t xpcJSRuntimeSize = xpcrt->SizeOfIncludingThis(JSMallocSizeOf); + + size_t wrappedJSSize = + xpcrt->GetMultiCompartmentWrappedJSMap()->SizeOfWrappedJS(JSMallocSizeOf); + + XPCWrappedNativeScope::ScopeSizeInfo sizeInfo(JSMallocSizeOf); + XPCWrappedNativeScope::AddSizeOfAllScopesIncludingThis(cx, &sizeInfo); + + mozJSModuleLoader* loader = mozJSModuleLoader::Get(); + size_t jsModuleLoaderSize = + loader ? loader->SizeOfIncludingThis(JSMallocSizeOf) : 0; + mozJSModuleLoader* devToolsLoader = mozJSModuleLoader::GetDevToolsLoader(); + size_t jsDevToolsModuleLoaderSize = + devToolsLoader ? devToolsLoader->SizeOfIncludingThis(JSMallocSizeOf) : 0; + + // This is the second step (see above). First we report stuff in the + // "explicit" tree, then we report other stuff. + + size_t rtTotal = 0; + xpc::ReportJSRuntimeExplicitTreeStats(rtStats, "explicit/js-non-window/"_ns, + handleReport, data, anonymize, + &rtTotal); + + // Report the sums of the realm numbers. + xpc::RealmStatsExtras realmExtrasTotal; + realmExtrasTotal.jsPathPrefix.AssignLiteral("js-main-runtime/realms/"); + realmExtrasTotal.domPathPrefix.AssignLiteral("window-objects/dom/"); + ReportRealmStats(rtStats.realmTotals, realmExtrasTotal, handleReport, data); + + xpc::ZoneStatsExtras zExtrasTotal; + zExtrasTotal.pathPrefix.AssignLiteral("js-main-runtime/zones/"); + ReportZoneStats(rtStats.zTotals, zExtrasTotal, handleReport, data, anonymize); + + // Report the sum of the runtime/ numbers. + REPORT_BYTES( + "js-main-runtime/runtime"_ns, KIND_OTHER, rtTotal, + "The sum of all measurements under 'explicit/js-non-window/runtime/'."); + + // Report the number of HelperThread + + REPORT("js-helper-threads/idle"_ns, KIND_OTHER, UNITS_COUNT, + gStats.helperThread.idleThreadCount, + "The current number of idle JS HelperThreads."); + + REPORT( + "js-helper-threads/active"_ns, KIND_OTHER, UNITS_COUNT, + gStats.helperThread.activeThreadCount, + "The current number of active JS HelperThreads. Memory held by these is" + " not reported."); + + // Report the numbers for memory used by wasm Runtime state. + REPORT_BYTES("wasm-runtime"_ns, KIND_OTHER, rtStats.runtime.wasmRuntime, + "The memory used for wasm runtime bookkeeping."); + + // Although wasm guard pages aren't committed in memory they can be very + // large and contribute greatly to vsize and so are worth reporting. + if (rtStats.runtime.wasmGuardPages > 0) { + REPORT_BYTES( + "wasm-guard-pages"_ns, KIND_OTHER, rtStats.runtime.wasmGuardPages, + "Guard pages mapped after the end of wasm memories, reserved for " + "optimization tricks, but not committed and thus never contributing" + " to RSS, only vsize."); + } + + // Report the numbers for memory outside of realms. + + REPORT_BYTES("js-main-runtime/gc-heap/unused-chunks"_ns, KIND_OTHER, + rtStats.gcHeapUnusedChunks, + "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."); + + REPORT_BYTES("js-main-runtime/gc-heap/unused-arenas"_ns, KIND_OTHER, + rtStats.gcHeapUnusedArenas, + "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."); + + REPORT_BYTES("js-main-runtime/gc-heap/chunk-admin"_ns, KIND_OTHER, + rtStats.gcHeapChunkAdmin, + "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."); + + // Report a breakdown of the committed GC space. + + REPORT_BYTES("js-main-runtime-gc-heap-committed/unused/chunks"_ns, KIND_OTHER, + rtStats.gcHeapUnusedChunks, + "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."); + + REPORT_BYTES("js-main-runtime-gc-heap-committed/unused/arenas"_ns, KIND_OTHER, + rtStats.gcHeapUnusedArenas, + "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/objects"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.object, + "Unused object cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/strings"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.string, + "Unused string cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.symbol, + "Unused symbol cells within non-empty arenas."); + + REPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.shape, + "Unused shape cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.baseShape, + "Unused base shape cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/getter-setters"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.getterSetter, + "Unused getter-setter cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/property-maps"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.propMap, + "Unused property map cells within non-empty arenas."); + + REPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.scope, + "Unused scope cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.script, + "Unused script cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.jitcode, + "Unused jitcode cells within non-empty arenas."); + + REPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"), + KIND_OTHER, rtStats.zTotals.unusedGCThings.regExpShared, + "Unused regexpshared cells within non-empty arenas."); + + REPORT_BYTES("js-main-runtime-gc-heap-committed/used/chunk-admin"_ns, + KIND_OTHER, rtStats.gcHeapChunkAdmin, + "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."); + + REPORT_BYTES("js-main-runtime-gc-heap-committed/used/arena-admin"_ns, + KIND_OTHER, rtStats.zTotals.gcHeapArenaAdmin, + "The same as 'js-main-runtime/zones/gc-heap-arena-admin'."); + + size_t gcThingTotal = 0; + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/objects"), + KIND_OTHER, rtStats.realmTotals.classInfo.objectsGCHeap, + "Used object cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/strings"), + KIND_OTHER, rtStats.zTotals.stringInfo.sizeOfLiveGCThings(), + "Used string cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/symbols"), + KIND_OTHER, rtStats.zTotals.symbolsGCHeap, + "Used symbol cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/shapes"), + KIND_OTHER, + rtStats.zTotals.shapeInfo.shapesGCHeapShared + + rtStats.zTotals.shapeInfo.shapesGCHeapDict, + "Used shape cells."); + + MREPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"), + KIND_OTHER, rtStats.zTotals.shapeInfo.shapesGCHeapBase, + "Used base shape cells."); + + MREPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/getter-setters"), + KIND_OTHER, rtStats.zTotals.getterSettersGCHeap, + "Used getter/setter cells."); + + MREPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/property-maps"), + KIND_OTHER, + rtStats.zTotals.dictPropMapsGCHeap + + rtStats.zTotals.compactPropMapsGCHeap + + rtStats.zTotals.normalPropMapsGCHeap, + "Used property map cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/scopes"), + KIND_OTHER, rtStats.zTotals.scopesGCHeap, "Used scope cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/scripts"), + KIND_OTHER, rtStats.realmTotals.scriptsGCHeap, + "Used script cells."); + + MREPORT_BYTES(nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"), + KIND_OTHER, rtStats.zTotals.jitCodesGCHeap, + "Used jitcode cells."); + + MREPORT_BYTES( + nsLiteralCString( + "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"), + KIND_OTHER, rtStats.zTotals.regExpSharedsGCHeap, + "Used regexpshared cells."); + + MOZ_ASSERT(gcThingTotal == rtStats.gcHeapGCThings); + (void)gcThingTotal; + + // Report xpconnect. + + REPORT_BYTES("explicit/xpconnect/runtime"_ns, KIND_HEAP, xpcJSRuntimeSize, + "The XPConnect runtime."); + + REPORT_BYTES("explicit/xpconnect/wrappedjs"_ns, KIND_HEAP, wrappedJSSize, + "Wrappers used to implement XPIDL interfaces with JS."); + + REPORT_BYTES("explicit/xpconnect/scopes"_ns, KIND_HEAP, + sizeInfo.mScopeAndMapSize, "XPConnect scopes."); + + REPORT_BYTES("explicit/xpconnect/proto-iface-cache"_ns, KIND_HEAP, + sizeInfo.mProtoAndIfaceCacheSize, + "Prototype and interface binding caches."); + + REPORT_BYTES("explicit/xpconnect/js-module-loader"_ns, KIND_HEAP, + jsModuleLoaderSize, "XPConnect's JS module loader."); + REPORT_BYTES("explicit/xpconnect/js-devtools-module-loader"_ns, KIND_HEAP, + jsDevToolsModuleLoaderSize, "DevTools's JS module loader."); + + // Report HelperThreadState. + + REPORT_BYTES("explicit/js-non-window/helper-thread/heap-other"_ns, KIND_HEAP, + gStats.helperThread.stateData, + "Memory used by HelperThreadState."); + + REPORT_BYTES("explicit/js-non-window/helper-thread/parse-task"_ns, KIND_HEAP, + gStats.helperThread.parseTask, + "The memory used by ParseTasks waiting in HelperThreadState."); + + REPORT_BYTES( + "explicit/js-non-window/helper-thread/ion-compile-task"_ns, KIND_HEAP, + gStats.helperThread.ionCompileTask, + "The memory used by IonCompileTasks waiting in HelperThreadState."); + + REPORT_BYTES( + "explicit/js-non-window/helper-thread/wasm-compile"_ns, KIND_HEAP, + gStats.helperThread.wasmCompile, + "The memory used by Wasm compilations waiting in HelperThreadState."); + + REPORT_BYTES("explicit/js-non-window/helper-thread/contexts"_ns, KIND_HEAP, + gStats.helperThread.contexts, + "The memory used by the JSContexts in HelperThreadState."); +} + +static nsresult JSSizeOfTab(JSObject* objArg, size_t* jsObjectsSize, + size_t* jsStringsSize, size_t* jsPrivateSize, + size_t* jsOtherSize) { + JSContext* cx = XPCJSContext::Get()->Context(); + JS::RootedObject obj(cx, objArg); + + TabSizes sizes; + OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject); + NS_ENSURE_TRUE( + JS::AddSizeOfTab(cx, obj, moz_malloc_size_of, &orphanReporter, &sizes), + NS_ERROR_OUT_OF_MEMORY); + + *jsObjectsSize = sizes.objects_; + *jsStringsSize = sizes.strings_; + *jsPrivateSize = sizes.private_; + *jsOtherSize = sizes.other_; + return NS_OK; +} + +} // namespace xpc + +static void AccumulateTelemetryCallback(JSMetric id, uint32_t sample) { + // clang-format off + switch (id) { +#define CASE_ACCUMULATE(NAME, _) \ + case JSMetric::NAME: \ + Telemetry::Accumulate(Telemetry::NAME, sample); \ + break; + + FOR_EACH_JS_METRIC(CASE_ACCUMULATE) +#undef CASE_ACCUMULATE + + default: + MOZ_CRASH("Bad metric id"); + } + // clang-format on +} + +static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) { + switch (counter) { + case JSUseCounter::ASMJS: + SetUseCounter(obj, eUseCounter_custom_JS_asmjs); + break; + case JSUseCounter::WASM: + SetUseCounter(obj, eUseCounter_custom_JS_wasm); + break; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected JSUseCounter id"); + } +} + +static void GetRealmNameCallback(JSContext* cx, Realm* realm, char* buf, + size_t bufsize, + const JS::AutoRequireNoGC& nogc) { + nsCString name; + // This is called via the JSAPI and isn't involved in memory reporting, so + // we don't need to anonymize realm names. + int anonymizeID = 0; + GetRealmName(realm, name, &anonymizeID, /* replaceSlashes = */ false); + if (name.Length() >= bufsize) { + name.Truncate(bufsize - 1); + } + memcpy(buf, name.get(), name.Length() + 1); +} + +static void DestroyRealm(JS::GCContext* gcx, JS::Realm* realm) { + // Get the current compartment private into an AutoPtr (which will do the + // cleanup for us), and null out the private field. + mozilla::UniquePtr<RealmPrivate> priv(RealmPrivate::Get(realm)); + JS::SetRealmPrivate(realm, nullptr); +} + +static bool PreserveWrapper(JSContext* cx, JS::Handle<JSObject*> obj) { + MOZ_ASSERT(cx); + MOZ_ASSERT(obj); + MOZ_ASSERT(mozilla::dom::IsDOMObject(obj)); + + if (!mozilla::dom::TryPreserveWrapper(obj)) { + return false; + } + + MOZ_ASSERT(!mozilla::dom::HasReleasedWrapper(obj), + "There should be no released wrapper since we just preserved it"); + + return true; +} + +static nsresult ReadSourceFromFilename(JSContext* cx, const char* filename, + char16_t** twoByteSource, + char** utf8Source, size_t* len) { + MOZ_ASSERT(*len == 0); + MOZ_ASSERT((twoByteSource != nullptr) != (utf8Source != nullptr), + "must be called requesting only one of UTF-8 or UTF-16 source"); + MOZ_ASSERT_IF(twoByteSource, !*twoByteSource); + MOZ_ASSERT_IF(utf8Source, !*utf8Source); + + nsresult rv; + + // mozJSSubScriptLoader prefixes the filenames of the scripts it loads with + // the filename of its caller. Axe that if present. + const char* arrow; + while ((arrow = strstr(filename, " -> "))) { + filename = arrow + strlen(" -> "); + } + + // Get the URI. + nsCOMPtr<nsIURI> uri; + rv = NS_NewURI(getter_AddRefs(uri), filename); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIChannel> scriptChannel; + rv = NS_NewChannel(getter_AddRefs(scriptChannel), uri, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_OTHER); + NS_ENSURE_SUCCESS(rv, rv); + + // Only allow local reading. + nsCOMPtr<nsIURI> actualUri; + rv = scriptChannel->GetURI(getter_AddRefs(actualUri)); + NS_ENSURE_SUCCESS(rv, rv); + nsCString scheme; + rv = actualUri->GetScheme(scheme); + NS_ENSURE_SUCCESS(rv, rv); + if (!scheme.EqualsLiteral("file") && !scheme.EqualsLiteral("jar")) { + return NS_OK; + } + + // Explicitly set the content type so that we don't load the + // exthandler to guess it. + scriptChannel->SetContentType("text/plain"_ns); + + nsCOMPtr<nsIInputStream> scriptStream; + rv = scriptChannel->Open(getter_AddRefs(scriptStream)); + NS_ENSURE_SUCCESS(rv, rv); + + uint64_t rawLen; + rv = scriptStream->Available(&rawLen); + NS_ENSURE_SUCCESS(rv, rv); + if (!rawLen) { + return NS_ERROR_FAILURE; + } + + // Technically, this should be SIZE_MAX, but we don't run on machines + // where that would be less than UINT32_MAX, and the latter is already + // well beyond a reasonable limit. + if (rawLen > UINT32_MAX) { + return NS_ERROR_FILE_TOO_BIG; + } + + // Allocate a buffer the size of the file to initially fill with the UTF-8 + // contents of the file. Use the JS allocator so that if UTF-8 source was + // requested, we can return this memory directly. + JS::UniqueChars buf(js_pod_malloc<char>(rawLen)); + if (!buf) { + return NS_ERROR_OUT_OF_MEMORY; + } + + char* ptr = buf.get(); + char* end = ptr + rawLen; + while (ptr < end) { + uint32_t bytesRead; + rv = scriptStream->Read(ptr, PointerRangeSize(ptr, end), &bytesRead); + if (NS_FAILED(rv)) { + return rv; + } + MOZ_ASSERT(bytesRead > 0, "stream promised more bytes before EOF"); + ptr += bytesRead; + } + + if (utf8Source) { + // |buf| is already UTF-8, so we can directly return it. + *len = rawLen; + *utf8Source = buf.release(); + } else { + MOZ_ASSERT(twoByteSource != nullptr); + + // |buf| can't be directly returned -- convert it to UTF-16. + + // On success this overwrites |*twoByteSource| and |*len|. + rv = ScriptLoader::ConvertToUTF16( + scriptChannel, reinterpret_cast<const unsigned char*>(buf.get()), + rawLen, u"UTF-8"_ns, nullptr, *twoByteSource, *len); + NS_ENSURE_SUCCESS(rv, rv); + + if (!*twoByteSource) { + return NS_ERROR_FAILURE; + } + } + + return NS_OK; +} + +// The JS engine calls this object's 'load' member function when it needs +// the source for a chrome JS function. See the comment in the XPCJSRuntime +// constructor. +class XPCJSSourceHook : public js::SourceHook { + bool load(JSContext* cx, const char* filename, char16_t** twoByteSource, + char** utf8Source, size_t* length) override { + MOZ_ASSERT((twoByteSource != nullptr) != (utf8Source != nullptr), + "must be called requesting only one of UTF-8 or UTF-16 source"); + + *length = 0; + if (twoByteSource) { + *twoByteSource = nullptr; + } else { + *utf8Source = nullptr; + } + + if (!nsContentUtils::IsSystemCaller(cx)) { + return true; + } + + if (!filename) { + return true; + } + + nsresult rv = + ReadSourceFromFilename(cx, filename, twoByteSource, utf8Source, length); + if (NS_FAILED(rv)) { + xpc::Throw(cx, rv); + return false; + } + + return true; + } +}; + +static const JSWrapObjectCallbacks WrapObjectCallbacks = { + xpc::WrapperFactory::Rewrap, xpc::WrapperFactory::PrepareForWrapping}; + +XPCJSRuntime::XPCJSRuntime(JSContext* aCx) + : CycleCollectedJSRuntime(aCx), + mWrappedJSMap(mozilla::MakeUnique<JSObject2WrappedJSMap>()), + mIID2NativeInterfaceMap(mozilla::MakeUnique<IID2NativeInterfaceMap>()), + mClassInfo2NativeSetMap(mozilla::MakeUnique<ClassInfo2NativeSetMap>()), + mNativeSetMap(mozilla::MakeUnique<NativeSetMap>()), + mWrappedNativeScopes(), + mGCIsRunning(false), + mNativesToReleaseArray(), + mDoingFinalization(false), + mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite()) { + MOZ_COUNT_CTOR_INHERITED(XPCJSRuntime, CycleCollectedJSRuntime); +} + +/* static */ +XPCJSRuntime* XPCJSRuntime::Get() { return nsXPConnect::GetRuntimeInstance(); } + +// Subclass of JS::ubi::Base for DOM reflector objects for the JS::ubi::Node +// memory analysis framework; see js/public/UbiNode.h. In +// XPCJSRuntime::Initialize, we register the ConstructUbiNode function as a hook +// with the SpiderMonkey runtime for it to use to construct ubi::Nodes of this +// class for JSObjects whose class has the JSCLASS_IS_DOMJSCLASS flag set. +// ReflectorNode specializes Concrete<JSObject> for DOM reflector nodes, +// reporting the edge from the JSObject to the nsINode it represents, in +// addition to the usual edges departing any normal JSObject. +namespace JS { +namespace ubi { +class ReflectorNode : public Concrete<JSObject> { + protected: + explicit ReflectorNode(JSObject* ptr) : Concrete<JSObject>(ptr) {} + + public: + static void construct(void* storage, JSObject* ptr) { + new (storage) ReflectorNode(ptr); + } + js::UniquePtr<JS::ubi::EdgeRange> edges(JSContext* cx, + bool wantNames) const override; +}; + +js::UniquePtr<EdgeRange> ReflectorNode::edges(JSContext* cx, + bool wantNames) const { + js::UniquePtr<SimpleEdgeRange> range(static_cast<SimpleEdgeRange*>( + Concrete<JSObject>::edges(cx, wantNames).release())); + if (!range) { + return nullptr; + } + // UNWRAP_NON_WRAPPER_OBJECT assumes the object is completely initialized, + // but ours may not be. Luckily, UnwrapDOMObjectToISupports checks for the + // uninitialized case (and returns null if uninitialized), so we can use that + // to guard against uninitialized objects. + nsISupports* supp = UnwrapDOMObjectToISupports(&get()); + if (supp) { + JS::AutoSuppressGCAnalysis nogc; // bug 1582326 + + nsINode* node; + // UnwrapDOMObjectToISupports can only return non-null if its argument is + // an actual DOM object, not a cross-compartment wrapper. + if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Node, &get(), node))) { + char16_t* edgeName = nullptr; + if (wantNames) { + edgeName = NS_xstrdup(u"Reflected Node"); + } + if (!range->addEdge(Edge(edgeName, node))) { + return nullptr; + } + } + } + return js::UniquePtr<EdgeRange>(range.release()); +} + +} // Namespace ubi +} // Namespace JS + +void ConstructUbiNode(void* storage, JSObject* ptr) { + JS::ubi::ReflectorNode::construct(storage, ptr); +} + +void XPCJSRuntime::Initialize(JSContext* cx) { + mLoaderGlobal.init(cx, nullptr); + + // these jsids filled in later when we have a JSContext to work with. + mStrIDs[0] = JS::PropertyKey::Void(); + + nsScriptSecurityManager::GetScriptSecurityManager()->InitJSCallbacks(cx); + + // Unconstrain the runtime's threshold on nominal heap size, to avoid + // triggering GC too often if operating continuously near an arbitrary + // finite threshold (0xffffffff is infinity for uint32_t parameters). + // This leaves the maximum-JS_malloc-bytes threshold still in effect + // to cause period, and we hope hygienic, last-ditch GCs from within + // the GC's allocator. + JS_SetGCParameter(cx, JSGC_MAX_BYTES, 0xffffffff); + + JS_SetDestroyCompartmentCallback(cx, CompartmentDestroyedCallback); + JS_SetSizeOfIncludingThisCompartmentCallback( + cx, CompartmentSizeOfIncludingThisCallback); + JS::SetDestroyRealmCallback(cx, DestroyRealm); + JS::SetRealmNameCallback(cx, GetRealmNameCallback); + mPrevGCSliceCallback = JS::SetGCSliceCallback(cx, GCSliceCallback); + mPrevDoCycleCollectionCallback = + JS::SetDoCycleCollectionCallback(cx, DoCycleCollectionCallback); + JS_AddFinalizeCallback(cx, FinalizeCallback, nullptr); + JS_AddWeakPointerZonesCallback(cx, WeakPointerZonesCallback, this); + JS_AddWeakPointerCompartmentCallback(cx, WeakPointerCompartmentCallback, + this); + JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks); + if (XRE_IsE10sParentProcess()) { + JS::SetFilenameValidationCallback( + nsContentSecurityUtils::ValidateScriptFilename); + } + js::SetPreserveWrapperCallbacks(cx, PreserveWrapper, HasReleasedWrapper); + JS_InitReadPrincipalsCallback(cx, nsJSPrincipals::ReadPrincipals); + JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback); + JS_SetSetUseCounterCallback(cx, SetUseCounterCallback); + + js::SetWindowProxyClass(cx, &OuterWindowProxyClass); + + JS::SetXrayJitInfo(&gXrayJitInfo); + JS::SetProcessLargeAllocationFailureCallback( + OnLargeAllocationFailureCallback); + + // The WasmAltDataType is build by the JS engine from the build id. + JS::SetProcessBuildIdOp(GetBuildId); + FetchUtil::InitWasmAltDataType(); + + // The JS engine needs to keep the source code around in order to implement + // Function.prototype.toSource(). It'd be nice to not have to do this for + // chrome code and simply stub out requests for source on it. Life is not so + // easy, unfortunately. Nobody relies on chrome toSource() working in core + // browser code, but chrome tests use it. The worst offenders are addons, + // which like to monkeypatch chrome functions by calling toSource() on them + // and using regular expressions to modify them. We avoid keeping most browser + // JS source code in memory by setting LAZY_SOURCE on JS::CompileOptions when + // compiling some chrome code. This causes the JS engine not save the source + // code in memory. When the JS engine is asked to provide the source for a + // function compiled with LAZY_SOURCE, it calls SourceHook to load it. + /// + // Note we do have to retain the source code in memory for scripts compiled in + // isRunOnce mode and compiled function bodies (from + // JS::CompileFunction). In practice, this means content scripts and event + // handlers. + mozilla::UniquePtr<XPCJSSourceHook> hook(new XPCJSSourceHook); + js::SetSourceHook(cx, std::move(hook)); + + // Register memory reporters and distinguished amount functions. + RegisterStrongMemoryReporter(new JSMainRuntimeRealmsReporter()); + RegisterStrongMemoryReporter(new JSMainRuntimeTemporaryPeakReporter()); + RegisterJSMainRuntimeGCHeapDistinguishedAmount( + JSMainRuntimeGCHeapDistinguishedAmount); + RegisterJSMainRuntimeTemporaryPeakDistinguishedAmount( + JSMainRuntimeTemporaryPeakDistinguishedAmount); + RegisterJSMainRuntimeCompartmentsSystemDistinguishedAmount( + JSMainRuntimeCompartmentsSystemDistinguishedAmount); + RegisterJSMainRuntimeCompartmentsUserDistinguishedAmount( + JSMainRuntimeCompartmentsUserDistinguishedAmount); + RegisterJSMainRuntimeRealmsSystemDistinguishedAmount( + JSMainRuntimeRealmsSystemDistinguishedAmount); + RegisterJSMainRuntimeRealmsUserDistinguishedAmount( + JSMainRuntimeRealmsUserDistinguishedAmount); + mozilla::RegisterJSSizeOfTab(JSSizeOfTab); + + // Set the callback for reporting memory to ubi::Node. + JS::ubi::SetConstructUbiNodeForDOMObjectCallback(cx, &ConstructUbiNode); + + xpc_LocalizeRuntime(JS_GetRuntime(cx)); +} + +bool XPCJSRuntime::InitializeStrings(JSContext* cx) { + // if it is our first context then we need to generate our string ids + if (mStrIDs[0].isVoid()) { + RootedString str(cx); + for (unsigned i = 0; i < XPCJSContext::IDX_TOTAL_COUNT; i++) { + str = JS_AtomizeAndPinString(cx, mStrings[i]); + if (!str) { + mStrIDs[0] = JS::PropertyKey::Void(); + return false; + } + mStrIDs[i] = PropertyKey::fromPinnedString(str); + } + + if (!mozilla::dom::DefineStaticJSVals(cx)) { + return false; + } + } + + return true; +} + +bool XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const JSClass* clasp, + char (&name)[72]) const { + if (clasp != &XPC_WN_Proto_JSClass) { + return false; + } + + XPCWrappedNativeProto* p = XPCWrappedNativeProto::Get(obj); + // Nothing here can GC. The analysis would otherwise think that ~nsCOMPtr + // could GC, but that's only possible if nsIXPCScriptable::GetJSClass() + // somehow released a reference to the nsIXPCScriptable, which isn't going to + // happen. + JS::AutoSuppressGCAnalysis nogc; + nsCOMPtr<nsIXPCScriptable> scr = p->GetScriptable(); + if (!scr) { + return false; + } + + SprintfLiteral(name, "JS Object (%s - %s)", clasp->name, + scr->GetJSClass()->name); + return true; +} + +bool XPCJSRuntime::NoteCustomGCThingXPCOMChildren( + const JSClass* clasp, JSObject* obj, + nsCycleCollectionTraversalCallback& cb) const { + if (clasp != &XPC_WN_Tearoff_JSClass) { + return false; + } + + // A tearoff holds a strong reference to its native object + // (see XPCWrappedNative::FlatJSObjectFinalized). Its XPCWrappedNative + // will be held alive through tearoff's XPC_WN_TEAROFF_FLAT_OBJECT_SLOT, + // which points to the XPCWrappedNative's mFlatJSObject. + XPCWrappedNativeTearOff* to = XPCWrappedNativeTearOff::Get(obj); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME( + cb, "XPCWrappedNativeTearOff::Get(obj)->mNative"); + cb.NoteXPCOMChild(to->GetNative()); + return true; +} + +/***************************************************************************/ + +void XPCJSRuntime::DebugDump(int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS(("XPCJSRuntime @ %p", this)); + XPC_LOG_INDENT(); + + // iterate wrappers... + XPC_LOG_ALWAYS(("mWrappedJSMap @ %p with %d wrappers(s)", mWrappedJSMap.get(), + mWrappedJSMap->Count())); + if (depth && mWrappedJSMap->Count()) { + XPC_LOG_INDENT(); + mWrappedJSMap->Dump(depth); + XPC_LOG_OUTDENT(); + } + + XPC_LOG_ALWAYS(("mIID2NativeInterfaceMap @ %p with %d interface(s)", + mIID2NativeInterfaceMap.get(), + mIID2NativeInterfaceMap->Count())); + + XPC_LOG_ALWAYS(("mClassInfo2NativeSetMap @ %p with %d sets(s)", + mClassInfo2NativeSetMap.get(), + mClassInfo2NativeSetMap->Count())); + + XPC_LOG_ALWAYS(("mNativeSetMap @ %p with %d sets(s)", mNativeSetMap.get(), + mNativeSetMap->Count())); + + // iterate sets... + if (depth && mNativeSetMap->Count()) { + XPC_LOG_INDENT(); + for (auto i = mNativeSetMap->Iter(); !i.done(); i.next()) { + i.get()->DebugDump(depth); + } + XPC_LOG_OUTDENT(); + } + + XPC_LOG_OUTDENT(); +#endif +} + +/***************************************************************************/ + +void XPCJSRuntime::AddGCCallback(xpcGCCallback cb) { + MOZ_ASSERT(cb, "null callback"); + extraGCCallbacks.AppendElement(cb); +} + +void XPCJSRuntime::RemoveGCCallback(xpcGCCallback cb) { + MOZ_ASSERT(cb, "null callback"); + bool found = extraGCCallbacks.RemoveElement(cb); + if (!found) { + NS_ERROR("Removing a callback which was never added."); + } +} + +JSObject* XPCJSRuntime::GetUAWidgetScope(JSContext* cx, + nsIPrincipal* principal) { + MOZ_ASSERT(!principal->IsSystemPrincipal(), "Running UA Widget in chrome"); + + RootedObject scope(cx); + do { + RefPtr<BasePrincipal> key = BasePrincipal::Cast(principal); + if (Principal2JSObjectMap::Ptr p = mUAWidgetScopeMap.lookup(key)) { + scope = p->value(); + break; // Need ~RefPtr to run, and potentially GC, before returning. + } + + SandboxOptions options; + options.sandboxName.AssignLiteral("UA Widget Scope"); + options.wantXrays = false; + options.wantComponents = false; + options.isUAWidgetScope = true; + + // Use an ExpandedPrincipal to create asymmetric security. + MOZ_ASSERT(!nsContentUtils::IsExpandedPrincipal(principal)); + nsTArray<nsCOMPtr<nsIPrincipal>> principalAsArray{principal}; + RefPtr<ExpandedPrincipal> ep = ExpandedPrincipal::Create( + principalAsArray, principal->OriginAttributesRef()); + + // Create the sandbox. + RootedValue v(cx); + nsresult rv = CreateSandboxObject( + cx, &v, static_cast<nsIExpandedPrincipal*>(ep), options); + NS_ENSURE_SUCCESS(rv, nullptr); + scope = &v.toObject(); + + JSObject* unwrapped = js::UncheckedUnwrap(scope); + MOZ_ASSERT(xpc::IsInUAWidgetScope(unwrapped)); + + MOZ_ALWAYS_TRUE(mUAWidgetScopeMap.putNew(key, unwrapped)); + } while (false); + + return scope; +} + +JSObject* XPCJSRuntime::UnprivilegedJunkScope(const mozilla::fallible_t&) { + if (!mUnprivilegedJunkScope) { + dom::AutoJSAPI jsapi; + jsapi.Init(); + JSContext* cx = jsapi.cx(); + + SandboxOptions options; + options.sandboxName.AssignLiteral("XPConnect Junk Compartment"); + options.invisibleToDebugger = true; + + RootedValue sandbox(cx); + nsresult rv = CreateSandboxObject(cx, &sandbox, nullptr, options); + NS_ENSURE_SUCCESS(rv, nullptr); + + mUnprivilegedJunkScope = + SandboxPrivate::GetPrivate(sandbox.toObjectOrNull()); + } + MOZ_ASSERT(mUnprivilegedJunkScope->GetWrapper(), + "Wrapper should have same lifetime as weak reference"); + return mUnprivilegedJunkScope->GetWrapper(); +} + +JSObject* XPCJSRuntime::UnprivilegedJunkScope() { + JSObject* scope = UnprivilegedJunkScope(fallible); + MOZ_RELEASE_ASSERT(scope); + return scope; +} + +bool XPCJSRuntime::IsUnprivilegedJunkScope(JSObject* obj) { + return mUnprivilegedJunkScope && obj == mUnprivilegedJunkScope->GetWrapper(); +} + +void XPCJSRuntime::DeleteSingletonScopes() { + // We're pretty late in shutdown, so we call ReleaseWrapper on the scopes. + // This way the GC can collect them immediately, and we don't rely on the CC + // to clean up. + if (RefPtr<SandboxPrivate> sandbox = mUnprivilegedJunkScope.get()) { + sandbox->ReleaseWrapper(sandbox); + mUnprivilegedJunkScope = nullptr; + } + mLoaderGlobal = nullptr; +} + +JSObject* XPCJSRuntime::LoaderGlobal() { + if (!mLoaderGlobal) { + RefPtr loader = mozJSModuleLoader::Get(); + + dom::AutoJSAPI jsapi; + jsapi.Init(); + + mLoaderGlobal = loader->GetSharedGlobal(jsapi.cx()); + MOZ_RELEASE_ASSERT(!JS_IsExceptionPending(jsapi.cx())); + } + return mLoaderGlobal; +} + +uint32_t GetAndClampCPUCount() { + // See HelperThreads.cpp for why we want between 2-8 threads + int32_t proc = GetNumberOfProcessors(); + if (proc < 2) { + return 2; + } + return std::min(proc, 8); +} diff --git a/js/xpconnect/src/XPCJSWeakReference.cpp b/js/xpconnect/src/XPCJSWeakReference.cpp new file mode 100644 index 0000000000..fbf2e22441 --- /dev/null +++ b/js/xpconnect/src/XPCJSWeakReference.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "XPCJSWeakReference.h" + +#include "nsContentUtils.h" + +using namespace JS; + +xpcJSWeakReference::xpcJSWeakReference() = default; + +NS_IMPL_ISUPPORTS(xpcJSWeakReference, xpcIJSWeakReference) + +nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object) { + if (!object.isObject()) { + return NS_OK; + } + + JS::RootedObject obj(cx, &object.toObject()); + + XPCCallContext ccx(cx); + + // See if the object is a wrapped native that supports weak references. + nsCOMPtr<nsISupports> supports = xpc::ReflectorToISupportsDynamic(obj, cx); + nsCOMPtr<nsISupportsWeakReference> supportsWeakRef = + do_QueryInterface(supports); + if (supportsWeakRef) { + supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent)); + if (mReferent) { + return NS_OK; + } + } + // If it's not a wrapped native, or it is a wrapped native that does not + // support weak references, fall back to getting a weak ref to the object. + + // See if object is a wrapped JSObject. + RefPtr<nsXPCWrappedJS> wrapped; + nsresult rv = nsXPCWrappedJS::GetNewOrUsed(cx, obj, NS_GET_IID(nsISupports), + getter_AddRefs(wrapped)); + if (!wrapped) { + NS_ERROR("can't get nsISupportsWeakReference wrapper for obj"); + return rv; + } + + return wrapped->GetWeakReference(getter_AddRefs(mReferent)); +} + +NS_IMETHODIMP +xpcJSWeakReference::Get(JSContext* aCx, MutableHandleValue aRetval) { + aRetval.setNull(); + + if (!mReferent) { + return NS_OK; + } + + nsCOMPtr<nsISupports> supports = do_QueryReferent(mReferent); + if (!supports) { + return NS_OK; + } + + nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(supports); + if (!wrappedObj) { + // We have a generic XPCOM object that supports weak references here. + // Wrap it and pass it out. + return nsContentUtils::WrapNative(aCx, supports, &NS_GET_IID(nsISupports), + aRetval); + } + + JS::RootedObject obj(aCx, wrappedObj->GetJSObject()); + if (!obj) { + return NS_OK; + } + + // Most users of XPCWrappedJS don't need to worry about + // re-wrapping because things are implicitly rewrapped by + // xpcconvert. However, because we're doing this directly + // through the native call context, we need to call + // JS_WrapObject(). + if (!JS_WrapObject(aCx, &obj)) { + return NS_ERROR_FAILURE; + } + + aRetval.setObject(*obj); + return NS_OK; +} diff --git a/js/xpconnect/src/XPCJSWeakReference.h b/js/xpconnect/src/XPCJSWeakReference.h new file mode 100644 index 0000000000..b70b5dd9fd --- /dev/null +++ b/js/xpconnect/src/XPCJSWeakReference.h @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpcjsweakreference_h___ +#define xpcjsweakreference_h___ + +#include "xpcIJSWeakReference.h" +#include "nsIWeakReferenceUtils.h" +#include "mozilla/Attributes.h" + +class xpcJSWeakReference final : public xpcIJSWeakReference { + ~xpcJSWeakReference() = default; + + public: + xpcJSWeakReference(); + nsresult Init(JSContext* cx, const JS::Value& object); + + NS_DECL_ISUPPORTS + NS_DECL_XPCIJSWEAKREFERENCE + + private: + nsWeakPtr mReferent; +}; + +#endif // xpcjsweakreference_h___ diff --git a/js/xpconnect/src/XPCLocale.cpp b/js/xpconnect/src/XPCLocale.cpp new file mode 100644 index 0000000000..c61a25e17e --- /dev/null +++ b/js/xpconnect/src/XPCLocale.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" + +#include "js/LocaleSensitive.h" + +#include "nsIObserver.h" +#include "nsIObserverService.h" +#include "nsComponentManagerUtils.h" +#include "nsIPrefService.h" +#include "nsServiceManagerUtils.h" +#include "mozilla/Services.h" +#include "mozilla/CycleCollectedJSRuntime.h" +#include "mozilla/CycleCollectedJSContext.h" +#include "mozilla/intl/LocaleService.h" +#include "mozilla/Preferences.h" + +#include "xpcpublic.h" +#include "xpcprivate.h" + +using namespace mozilla; +using mozilla::intl::LocaleService; + +class XPCLocaleObserver : public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + void Init(); + + private: + virtual ~XPCLocaleObserver() = default; +}; + +NS_IMPL_ISUPPORTS(XPCLocaleObserver, nsIObserver); + +void XPCLocaleObserver::Init() { + nsCOMPtr<nsIObserverService> observerService = + mozilla::services::GetObserverService(); + + observerService->AddObserver(this, "intl:app-locales-changed", false); + + Preferences::AddStrongObserver(this, "javascript.use_us_english_locale"); +} + +NS_IMETHODIMP +XPCLocaleObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if (!strcmp(aTopic, "intl:app-locales-changed") || + (!strcmp(aTopic, "nsPref:changed") && + !NS_strcmp(aData, u"javascript.use_us_english_locale"))) { + JSRuntime* rt = CycleCollectedJSRuntime::Get()->Runtime(); + if (!xpc_LocalizeRuntime(rt)) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; + } + + return NS_ERROR_UNEXPECTED; +} + +/** + * JS locale callbacks implemented by XPCOM modules. These are theoretically + * safe for use on multiple threads. Unfortunately, the intl code underlying + * these XPCOM modules doesn't yet support this, so in practice + * XPCLocaleCallbacks are limited to the main thread. + */ +struct XPCLocaleCallbacks : public JSLocaleCallbacks { + XPCLocaleCallbacks() { + MOZ_COUNT_CTOR(XPCLocaleCallbacks); + + // Disable the toLocaleUpper/Lower case hooks to use the standard, + // locale-insensitive definition from String.prototype. (These hooks are + // only consulted when JS_HAS_INTL_API is not set.) Since JS_HAS_INTL_API + // is always set, these hooks should be disabled. + localeToUpperCase = nullptr; + localeToLowerCase = nullptr; + localeCompare = nullptr; + localeToUnicode = nullptr; + + // It's going to be retained by the ObserverService. + RefPtr<XPCLocaleObserver> locObs = new XPCLocaleObserver(); + locObs->Init(); + } + + ~XPCLocaleCallbacks() { + AssertThreadSafety(); + MOZ_COUNT_DTOR(XPCLocaleCallbacks); + } + + /** + * Return the XPCLocaleCallbacks that's hidden away in |rt|. (This impl uses + * the locale callbacks struct to store away its per-context data.) + */ + static XPCLocaleCallbacks* This(JSRuntime* rt) { + // Locale information for |cx| was associated using xpc_LocalizeContext; + // assert and double-check this. + const JSLocaleCallbacks* lc = JS_GetLocaleCallbacks(rt); + MOZ_ASSERT(lc); + MOZ_ASSERT(lc->localeToUpperCase == nullptr); + MOZ_ASSERT(lc->localeToLowerCase == nullptr); + MOZ_ASSERT(lc->localeCompare == nullptr); + MOZ_ASSERT(lc->localeToUnicode == nullptr); + + const XPCLocaleCallbacks* ths = static_cast<const XPCLocaleCallbacks*>(lc); + ths->AssertThreadSafety(); + return const_cast<XPCLocaleCallbacks*>(ths); + } + + private: + void AssertThreadSafety() const { + NS_ASSERT_OWNINGTHREAD(XPCLocaleCallbacks); + } + + NS_DECL_OWNINGTHREAD +}; + +bool xpc_LocalizeRuntime(JSRuntime* rt) { + // We want to assign the locale callbacks only the first time we + // localize the context. + // All consequent calls to this function are result of language changes + // and should not assign it again. + const JSLocaleCallbacks* lc = JS_GetLocaleCallbacks(rt); + if (!lc) { + JS_SetLocaleCallbacks(rt, new XPCLocaleCallbacks()); + } + + // Set the default locale. + + // Check a pref to see if we should use US English locale regardless + // of the system locale. + if (Preferences::GetBool("javascript.use_us_english_locale", false)) { + return JS_SetDefaultLocale(rt, "en-US"); + } + + // No pref has been found, so get the default locale from the + // regional prefs locales. + AutoTArray<nsCString, 10> rpLocales; + LocaleService::GetInstance()->GetRegionalPrefsLocales(rpLocales); + + MOZ_ASSERT(rpLocales.Length() > 0); + return JS_SetDefaultLocale(rt, rpLocales[0].get()); +} + +void xpc_DelocalizeRuntime(JSRuntime* rt) { + const XPCLocaleCallbacks* lc = XPCLocaleCallbacks::This(rt); + JS_SetLocaleCallbacks(rt, nullptr); + delete lc; +} diff --git a/js/xpconnect/src/XPCLog.cpp b/js/xpconnect/src/XPCLog.cpp new file mode 100644 index 0000000000..e0efa87fa1 --- /dev/null +++ b/js/xpconnect/src/XPCLog.cpp @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Debug Logging support. */ + +#include "XPCLog.h" +#include "mozilla/Logging.h" +#include "mozilla/Sprintf.h" +#include "mozilla/mozalloc.h" +#include "prlog.h" +#include <string.h> +#include <stdarg.h> + +// this all only works for DEBUG... +#ifdef DEBUG + +# define SPACE_COUNT 200 +# define LINE_LEN 200 +# define INDENT_FACTOR 2 + +# define CAN_RUN (g_InitState == 1 || (g_InitState == 0 && Init())) + +static char* g_Spaces; +static int g_InitState = 0; +static int g_Indent = 0; +static mozilla::LazyLogModule g_LogMod("xpclog"); + +static bool Init() { + g_Spaces = new char[SPACE_COUNT + 1]; + if (!g_Spaces || !MOZ_LOG_TEST(g_LogMod, mozilla::LogLevel::Error)) { + g_InitState = 1; + XPC_Log_Finish(); + return false; + } + memset(g_Spaces, ' ', SPACE_COUNT); + g_Spaces[SPACE_COUNT] = 0; + g_InitState = 1; + return true; +} + +void XPC_Log_Finish() { + if (g_InitState == 1) { + delete[] g_Spaces; + } + g_InitState = -1; +} + +void XPC_Log_print(const char* fmt, ...) { + va_list ap; + char line[LINE_LEN]; + + va_start(ap, fmt); + VsprintfLiteral(line, fmt, ap); + va_end(ap); + if (g_Indent) { + PR_LogPrint("%s%s", g_Spaces + SPACE_COUNT - (INDENT_FACTOR * g_Indent), + line); + } else { + PR_LogPrint("%s", line); + } +} + +bool XPC_Log_Check(int i) { + return CAN_RUN && MOZ_LOG_TEST(g_LogMod, mozilla::LogLevel::Error); +} + +void XPC_Log_Indent() { + if (INDENT_FACTOR * (++g_Indent) > SPACE_COUNT) { + g_Indent--; + } +} + +void XPC_Log_Outdent() { + if (--g_Indent < 0) { + g_Indent++; + } +} + +void XPC_Log_Clear_Indent() { g_Indent = 0; } + +#endif diff --git a/js/xpconnect/src/XPCLog.h b/js/xpconnect/src/XPCLog.h new file mode 100644 index 0000000000..66bacf90e2 --- /dev/null +++ b/js/xpconnect/src/XPCLog.h @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Debug Logging support. */ + +#ifndef xpclog_h___ +#define xpclog_h___ + +#include "mozilla/Attributes.h" +#include "mozilla/Logging.h" + +/* + * This uses mozilla/Logging.h. The module name used here is 'xpclog'. + * These environment settings should work... + * + * SET MOZ_LOG=xpclog:5 + * SET MOZ_LOG_FILE=logfile.txt + * + * usage: + * XPC_LOG_ERROR(("my comment number %d", 5)) // note the double parens + * + */ + +#ifdef DEBUG +# define XPC_LOG_INTERNAL(number, _args) \ + do { \ + if (XPC_Log_Check(number)) { \ + XPC_Log_print _args; \ + } \ + } while (0) + +# define XPC_LOG_ALWAYS(_args) XPC_LOG_INTERNAL(1, _args) +# define XPC_LOG_ERROR(_args) XPC_LOG_INTERNAL(2, _args) +# define XPC_LOG_WARNING(_args) XPC_LOG_INTERNAL(3, _args) +# define XPC_LOG_DEBUG(_args) XPC_LOG_INTERNAL(4, _args) +# define XPC_LOG_FLUSH() PR_LogFlush() +# define XPC_LOG_INDENT() XPC_Log_Indent() +# define XPC_LOG_OUTDENT() XPC_Log_Outdent() +# define XPC_LOG_CLEAR_INDENT() XPC_Log_Clear_Indent() +# define XPC_LOG_FINISH() XPC_Log_Finish() + +extern "C" { + +void XPC_Log_print(const char* fmt, ...) MOZ_FORMAT_PRINTF(1, 2); +bool XPC_Log_Check(int i); +void XPC_Log_Indent(); +void XPC_Log_Outdent(); +void XPC_Log_Clear_Indent(); +void XPC_Log_Finish(); + +} // extern "C" + +#else + +# define XPC_LOG_ALWAYS(_args) ((void)0) +# define XPC_LOG_ERROR(_args) ((void)0) +# define XPC_LOG_WARNING(_args) ((void)0) +# define XPC_LOG_DEBUG(_args) ((void)0) +# define XPC_LOG_FLUSH() ((void)0) +# define XPC_LOG_INDENT() ((void)0) +# define XPC_LOG_OUTDENT() ((void)0) +# define XPC_LOG_CLEAR_INDENT() ((void)0) +# define XPC_LOG_FINISH() ((void)0) +#endif + +#endif /* xpclog_h___ */ diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp new file mode 100644 index 0000000000..e2d2857a82 --- /dev/null +++ b/js/xpconnect/src/XPCMaps.cpp @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Private maps (hashtables). */ + +#include "mozilla/MathAlgorithms.h" +#include "mozilla/MemoryReporting.h" +#include "xpcprivate.h" +#include "XPCMaps.h" + +#include "js/HashTable.h" + +using namespace mozilla; + +/***************************************************************************/ +// implement JSObject2WrappedJSMap... + +void JSObject2WrappedJSMap::UpdateWeakPointersAfterGC(JSTracer* trc) { + // Check all wrappers and update their JSObject pointer if it has been + // moved. Release any wrappers whose weakly held JSObject has died. + + nsTArray<RefPtr<nsXPCWrappedJS>> dying; + for (auto iter = mTable.modIter(); !iter.done(); iter.next()) { + nsXPCWrappedJS* wrapper = iter.get().value(); + MOZ_ASSERT(wrapper, "found a null JS wrapper!"); + + // There's no need to walk the entire chain, because only the root can be + // subject to finalization due to the double release behavior in Release. + // See the comment at the top of XPCWrappedJS.cpp about nsXPCWrappedJS + // lifetime. + if (wrapper && wrapper->IsSubjectToFinalization()) { + wrapper->UpdateObjectPointerAfterGC(trc); + if (!wrapper->GetJSObjectPreserveColor()) { + dying.AppendElement(dont_AddRef(wrapper)); + } + } + + // Remove or update the JSObject key in the table if necessary. + if (!JS_UpdateWeakPointerAfterGC(trc, &iter.get().mutableKey())) { + iter.remove(); + } + } +} + +void JSObject2WrappedJSMap::ShutdownMarker() { + for (auto iter = mTable.iter(); !iter.done(); iter.next()) { + nsXPCWrappedJS* wrapper = iter.get().value(); + MOZ_ASSERT(wrapper, "found a null JS wrapper!"); + MOZ_ASSERT(wrapper->IsValid(), "found an invalid JS wrapper!"); + wrapper->SystemIsBeingShutDown(); + } +} + +size_t JSObject2WrappedJSMap::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = mallocSizeOf(this); + n += mTable.shallowSizeOfExcludingThis(mallocSizeOf); + return n; +} + +size_t JSObject2WrappedJSMap::SizeOfWrappedJS( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = 0; + for (auto iter = mTable.iter(); !iter.done(); iter.next()) { + n += iter.get().value()->SizeOfIncludingThis(mallocSizeOf); + } + return n; +} + +/***************************************************************************/ +// implement Native2WrappedNativeMap... + +Native2WrappedNativeMap::Native2WrappedNativeMap() + : mMap(XPC_NATIVE_MAP_LENGTH) {} + +size_t Native2WrappedNativeMap::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = mallocSizeOf(this); + n += mMap.shallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mMap.iter(); !iter.done(); iter.next()) { + n += mallocSizeOf(iter.get().value()); + } + return n; +} + +/***************************************************************************/ +// implement IID2NativeInterfaceMap... + +IID2NativeInterfaceMap::IID2NativeInterfaceMap() + : mMap(XPC_NATIVE_INTERFACE_MAP_LENGTH) {} + +size_t IID2NativeInterfaceMap::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = mallocSizeOf(this); + n += mMap.shallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mMap.iter(); !iter.done(); iter.next()) { + n += iter.get().value()->SizeOfIncludingThis(mallocSizeOf); + } + return n; +} + +/***************************************************************************/ +// implement ClassInfo2NativeSetMap... + +ClassInfo2NativeSetMap::ClassInfo2NativeSetMap() + : mMap(XPC_NATIVE_SET_MAP_LENGTH) {} + +size_t ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) { + size_t n = mallocSizeOf(this); + n += mMap.shallowSizeOfExcludingThis(mallocSizeOf); + return n; +} + +/***************************************************************************/ +// implement ClassInfo2WrappedNativeProtoMap... + +ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap() + : mMap(XPC_NATIVE_PROTO_MAP_LENGTH) {} + +size_t ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = mallocSizeOf(this); + n += mMap.shallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mMap.iter(); !iter.done(); iter.next()) { + n += mallocSizeOf(iter.get().value()); + } + return n; +} + +/***************************************************************************/ +// implement NativeSetMap... + +bool NativeSetHasher::match(Key key, Lookup lookup) { + // The |key| argument is for the existing table entry and |lookup| is the + // value passed by the caller that is being compared with it. + XPCNativeSet* SetInTable = key; + XPCNativeSet* Set = lookup->GetBaseSet(); + XPCNativeInterface* Addition = lookup->GetAddition(); + + if (!Set) { + // This is a special case to deal with the invariant that says: + // "All sets have exactly one nsISupports interface and it comes first." + // See XPCNativeSet::NewInstance for details. + // + // Though we might have a key that represents only one interface, we + // know that if that one interface were contructed into a set then + // it would end up really being a set with two interfaces (except for + // the case where the one interface happened to be nsISupports). + + return (SetInTable->GetInterfaceCount() == 1 && + SetInTable->GetInterfaceAt(0) == Addition) || + (SetInTable->GetInterfaceCount() == 2 && + SetInTable->GetInterfaceAt(1) == Addition); + } + + if (!Addition && Set == SetInTable) { + return true; + } + + uint16_t count = Set->GetInterfaceCount(); + if (count + (Addition ? 1 : 0) != SetInTable->GetInterfaceCount()) { + return false; + } + + XPCNativeInterface** CurrentInTable = SetInTable->GetInterfaceArray(); + XPCNativeInterface** Current = Set->GetInterfaceArray(); + for (uint16_t i = 0; i < count; i++) { + if (*(Current++) != *(CurrentInTable++)) { + return false; + } + } + return !Addition || Addition == *(CurrentInTable++); +} + +NativeSetMap::NativeSetMap() : mSet(XPC_NATIVE_SET_MAP_LENGTH) {} + +size_t NativeSetMap::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t n = mallocSizeOf(this); + n += mSet.shallowSizeOfExcludingThis(mallocSizeOf); + for (auto iter = mSet.iter(); !iter.done(); iter.next()) { + n += iter.get()->SizeOfIncludingThis(mallocSizeOf); + } + return n; +} + +/***************************************************************************/ diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h new file mode 100644 index 0000000000..f1d32ab61c --- /dev/null +++ b/js/xpconnect/src/XPCMaps.h @@ -0,0 +1,386 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Private maps (hashtables). */ + +#ifndef xpcmaps_h___ +#define xpcmaps_h___ + +#include "mozilla/AllocPolicy.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/HashTable.h" + +#include "js/GCHashTable.h" + +/***************************************************************************/ +// default initial sizes for maps (hashtables) + +#define XPC_JS_MAP_LENGTH 32 + +#define XPC_NATIVE_MAP_LENGTH 8 +#define XPC_NATIVE_PROTO_MAP_LENGTH 8 +#define XPC_DYING_NATIVE_PROTO_MAP_LENGTH 8 +#define XPC_NATIVE_INTERFACE_MAP_LENGTH 32 +#define XPC_NATIVE_SET_MAP_LENGTH 32 +#define XPC_WRAPPER_MAP_LENGTH 8 + +/*************************/ + +class JSObject2WrappedJSMap { + using Map = js::HashMap<JS::Heap<JSObject*>, nsXPCWrappedJS*, + js::StableCellHasher<JS::Heap<JSObject*>>, + InfallibleAllocPolicy>; + + public: + JSObject2WrappedJSMap() = default; + + inline nsXPCWrappedJS* Find(JSObject* Obj) { + MOZ_ASSERT(Obj, "bad param"); + Map::Ptr p = mTable.lookup(Obj); + return p ? p->value() : nullptr; + } + +#ifdef DEBUG + inline bool HasWrapper(nsXPCWrappedJS* wrapper) { + for (auto iter = mTable.iter(); !iter.done(); iter.next()) { + if (iter.get().value() == wrapper) { + return true; + } + } + return false; + } +#endif + + inline nsXPCWrappedJS* Add(JSContext* cx, nsXPCWrappedJS* wrapper) { + MOZ_ASSERT(wrapper, "bad param"); + JSObject* obj = wrapper->GetJSObjectPreserveColor(); + Map::AddPtr p = mTable.lookupForAdd(obj); + if (p) { + return p->value(); + } + if (!mTable.add(p, obj, wrapper)) { + return nullptr; + } + return wrapper; + } + + inline void Remove(nsXPCWrappedJS* wrapper) { + MOZ_ASSERT(wrapper, "bad param"); + mTable.remove(wrapper->GetJSObjectPreserveColor()); + } + + inline uint32_t Count() { return mTable.count(); } + + inline void Dump(int16_t depth) { + for (auto iter = mTable.iter(); !iter.done(); iter.next()) { + iter.get().value()->DebugDump(depth); + } + } + + void UpdateWeakPointersAfterGC(JSTracer* trc); + + void ShutdownMarker(); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + // Report the sum of SizeOfIncludingThis() for all wrapped JS in the map. + // Each wrapped JS is only in one map. + size_t SizeOfWrappedJS(mozilla::MallocSizeOf mallocSizeOf) const; + + private: + Map mTable{XPC_JS_MAP_LENGTH}; +}; + +/*************************/ + +class Native2WrappedNativeMap { + using Map = mozilla::HashMap<nsISupports*, XPCWrappedNative*, + mozilla::DefaultHasher<nsISupports*>, + mozilla::MallocAllocPolicy>; + + public: + Native2WrappedNativeMap(); + + XPCWrappedNative* Find(nsISupports* obj) const { + MOZ_ASSERT(obj, "bad param"); + Map::Ptr ptr = mMap.lookup(obj); + return ptr ? ptr->value() : nullptr; + } + + XPCWrappedNative* Add(XPCWrappedNative* wrapper) { + MOZ_ASSERT(wrapper, "bad param"); + nsISupports* obj = wrapper->GetIdentityObject(); + Map::AddPtr ptr = mMap.lookupForAdd(obj); + MOZ_ASSERT(!ptr, "wrapper already in new scope!"); + if (ptr) { + return ptr->value(); + } + if (!mMap.add(ptr, obj, wrapper)) { + return nullptr; + } + return wrapper; + } + + void Clear() { mMap.clear(); } + + uint32_t Count() { return mMap.count(); } + + Map::Iterator Iter() { return mMap.iter(); } + Map::ModIterator ModIter() { return mMap.modIter(); } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + private: + Map mMap; +}; + +/*************************/ + +struct IIDHasher { + using Key = const nsIID*; + using Lookup = Key; + + // Note this is returning the hash of the bit pattern of the first part of the + // nsID, not the hash of the pointer to the nsID. + static mozilla::HashNumber hash(Lookup lookup) { + uintptr_t v; + memcpy(&v, lookup, sizeof(v)); + return mozilla::HashGeneric(v); + } + + static bool match(Key key, Lookup lookup) { return key->Equals(*lookup); } +}; + +class IID2NativeInterfaceMap { + using Map = mozilla::HashMap<const nsIID*, XPCNativeInterface*, IIDHasher, + mozilla::MallocAllocPolicy>; + + public: + IID2NativeInterfaceMap(); + + XPCNativeInterface* Find(REFNSIID iid) const { + Map::Ptr ptr = mMap.lookup(&iid); + return ptr ? ptr->value() : nullptr; + } + + bool AddNew(XPCNativeInterface* iface) { + MOZ_ASSERT(iface, "bad param"); + const nsIID* iid = iface->GetIID(); + return mMap.putNew(iid, iface); + } + + void Remove(XPCNativeInterface* iface) { + MOZ_ASSERT(iface, "bad param"); + mMap.remove(iface->GetIID()); + } + + uint32_t Count() { return mMap.count(); } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + void Trace(JSTracer* trc); + + private: + Map mMap; +}; + +/*************************/ + +class ClassInfo2NativeSetMap { + using Map = mozilla::HashMap<nsIClassInfo*, RefPtr<XPCNativeSet>, + mozilla::DefaultHasher<nsIClassInfo*>, + mozilla::MallocAllocPolicy>; + + public: + ClassInfo2NativeSetMap(); + + XPCNativeSet* Find(nsIClassInfo* info) const { + auto ptr = mMap.lookup(info); + return ptr ? ptr->value().get() : nullptr; + } + + XPCNativeSet* Add(nsIClassInfo* info, XPCNativeSet* set) { + MOZ_ASSERT(info, "bad param"); + auto ptr = mMap.lookupForAdd(info); + if (ptr) { + return ptr->value(); + } + if (!mMap.add(ptr, info, set)) { + return nullptr; + } + return set; + } + + void Remove(nsIClassInfo* info) { + MOZ_ASSERT(info, "bad param"); + mMap.remove(info); + } + + uint32_t Count() { return mMap.count(); } + + // ClassInfo2NativeSetMap holds pointers to *some* XPCNativeSets. + // So we don't want to count those XPCNativeSets, because they are better + // counted elsewhere (i.e. in XPCJSContext::mNativeSetMap, which holds + // pointers to *all* XPCNativeSets). Hence the "Shallow". + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + private: + Map mMap; +}; + +/*************************/ + +class ClassInfo2WrappedNativeProtoMap { + using Map = mozilla::HashMap<nsIClassInfo*, XPCWrappedNativeProto*, + mozilla::DefaultHasher<nsIClassInfo*>, + mozilla::MallocAllocPolicy>; + + public: + ClassInfo2WrappedNativeProtoMap(); + + XPCWrappedNativeProto* Find(nsIClassInfo* info) const { + auto ptr = mMap.lookup(info); + return ptr ? ptr->value() : nullptr; + } + + XPCWrappedNativeProto* Add(nsIClassInfo* info, XPCWrappedNativeProto* proto) { + MOZ_ASSERT(info, "bad param"); + auto ptr = mMap.lookupForAdd(info); + if (ptr) { + return ptr->value(); + } + if (!mMap.add(ptr, info, proto)) { + return nullptr; + } + return proto; + } + + void Clear() { mMap.clear(); } + + uint32_t Count() { return mMap.count(); } + + Map::Iterator Iter() { return mMap.iter(); } + Map::ModIterator ModIter() { return mMap.modIter(); } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + private: + Map mMap; +}; + +/*************************/ + +struct NativeSetHasher { + using Key = XPCNativeSet*; + using Lookup = const XPCNativeSetKey*; + + static mozilla::HashNumber hash(Lookup lookup) { return lookup->Hash(); } + static bool match(Key key, Lookup lookup); +}; + +class NativeSetMap { + using Set = mozilla::HashSet<XPCNativeSet*, NativeSetHasher, + mozilla::MallocAllocPolicy>; + + public: + NativeSetMap(); + + XPCNativeSet* Find(const XPCNativeSetKey* key) const { + auto ptr = mSet.lookup(key); + return ptr ? *ptr : nullptr; + } + + XPCNativeSet* Add(const XPCNativeSetKey* key, XPCNativeSet* set) { + MOZ_ASSERT(key, "bad param"); + MOZ_ASSERT(set, "bad param"); + auto ptr = mSet.lookupForAdd(key); + if (ptr) { + return *ptr; + } + if (!mSet.add(ptr, set)) { + return nullptr; + } + return set; + } + + bool AddNew(const XPCNativeSetKey* key, XPCNativeSet* set) { + XPCNativeSet* set2 = Add(key, set); + if (!set2) { + return false; + } +#ifdef DEBUG + XPCNativeSetKey key2(set); + MOZ_ASSERT(key->Hash() == key2.Hash()); + MOZ_ASSERT(set2 == set, "Should not have found an existing entry"); +#endif + return true; + } + + void Remove(XPCNativeSet* set) { + MOZ_ASSERT(set, "bad param"); + + XPCNativeSetKey key(set); + mSet.remove(&key); + } + + uint32_t Count() { return mSet.count(); } + + Set::Iterator Iter() { return mSet.iter(); } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + private: + Set mSet; +}; + +/***************************************************************************/ + +class JSObject2JSObjectMap { + using Map = JS::GCHashMap<JS::Heap<JSObject*>, JS::Heap<JSObject*>, + js::StableCellHasher<JS::Heap<JSObject*>>, + js::SystemAllocPolicy>; + + public: + JSObject2JSObjectMap() = default; + + inline JSObject* Find(JSObject* key) { + MOZ_ASSERT(key, "bad param"); + if (Map::Ptr p = mTable.lookup(key)) { + return p->value(); + } + return nullptr; + } + + /* Note: If the entry already exists, return the old value. */ + inline JSObject* Add(JSContext* cx, JSObject* key, JSObject* value) { + MOZ_ASSERT(key, "bad param"); + Map::AddPtr p = mTable.lookupForAdd(key); + if (p) { + JSObject* oldValue = p->value(); + p->value() = value; + return oldValue; + } + if (!mTable.add(p, key, value)) { + return nullptr; + } + MOZ_ASSERT(xpc::ObjectScope(key)->mWaiverWrapperMap == this); + return value; + } + + inline void Remove(JSObject* key) { + MOZ_ASSERT(key, "bad param"); + mTable.remove(key); + } + + inline uint32_t Count() { return mTable.count(); } + + void UpdateWeakPointers(JSTracer* trc) { mTable.traceWeak(trc); } + + private: + Map mTable{XPC_WRAPPER_MAP_LENGTH}; +}; + +#endif /* xpcmaps_h___ */ diff --git a/js/xpconnect/src/XPCModule.cpp b/js/xpconnect/src/XPCModule.cpp new file mode 100644 index 0000000000..c668df2bb3 --- /dev/null +++ b/js/xpconnect/src/XPCModule.cpp @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#define XPCONNECT_MODULE +#include "xpcprivate.h" + +nsresult xpcModuleCtor() { + nsXPConnect::InitStatics(); + + return NS_OK; +} + +void xpcModuleDtor() { + // Release our singletons + nsXPConnect::ReleaseXPConnectSingleton(); +} diff --git a/js/xpconnect/src/XPCModule.h b/js/xpconnect/src/XPCModule.h new file mode 100644 index 0000000000..d539750753 --- /dev/null +++ b/js/xpconnect/src/XPCModule.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "mozJSSubScriptLoader.h" + +/* Module implementation for the xpconnect library. */ + +#define XPCVARIANT_CONTRACTID "@mozilla.org/xpcvariant;1" + +// {FE4F7592-C1FC-4662-AC83-538841318803} +#define SCRIPTABLE_INTERFACES_CID \ + { \ + 0xfe4f7592, 0xc1fc, 0x4662, { \ + 0xac, 0x83, 0x53, 0x88, 0x41, 0x31, 0x88, 0x3 \ + } \ + } + +#define MOZJSSUBSCRIPTLOADER_CONTRACTID "@mozilla.org/moz/jssubscript-loader;1" + +nsresult xpcModuleCtor(); +void xpcModuleDtor(); diff --git a/js/xpconnect/src/XPCRuntimeService.cpp b/js/xpconnect/src/XPCRuntimeService.cpp new file mode 100644 index 0000000000..2c283ea2bc --- /dev/null +++ b/js/xpconnect/src/XPCRuntimeService.cpp @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "xpc_make_class.h" + +#include "nsContentUtils.h" +#include "BackstagePass.h" +#include "mozilla/Result.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/WebIDLGlobalNameHash.h" +#include "mozilla/dom/IndexedDatabaseManager.h" +#include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/ipc/PBackgroundSharedTypes.h" + +using namespace mozilla::dom; + +NS_IMPL_ISUPPORTS(BackstagePass, nsIXPCScriptable, nsIGlobalObject, + nsIClassInfo, nsIScriptObjectPrincipal, + nsISupportsWeakReference) + +BackstagePass::BackstagePass() + : mPrincipal(nsContentUtils::GetSystemPrincipal()), mWrapper(nullptr) {} + +// XXX(nika): It appears we don't have support for mayresolve hooks in +// nsIXPCScriptable, and I don't really want to add it because I'd rather just +// kill nsIXPCScriptable alltogether, so we don't use it here. + +// The nsIXPCScriptable map declaration that will generate stubs for us... +#define XPC_MAP_CLASSNAME BackstagePass +#define XPC_MAP_QUOTED_CLASSNAME "BackstagePass" +#define XPC_MAP_FLAGS \ + (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \ + XPC_SCRIPTABLE_WANT_FINALIZE | XPC_SCRIPTABLE_WANT_PRECREATE | \ + XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \ + XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \ + XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \ + XPC_SCRIPTABLE_IS_GLOBAL_OBJECT | \ + XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES) +#include "xpc_map_end.h" /* This will #undef the above */ + +JSObject* BackstagePass::GetGlobalJSObject() { + if (mWrapper) { + return mWrapper->GetFlatJSObject(); + } + return nullptr; +} + +JSObject* BackstagePass::GetGlobalJSObjectPreserveColor() const { + if (mWrapper) { + return mWrapper->GetFlatJSObjectPreserveColor(); + } + return nullptr; +} + +void BackstagePass::SetGlobalObject(JSObject* global) { + nsISupports* p = XPCWrappedNative::Get(global); + MOZ_ASSERT(p); + mWrapper = static_cast<XPCWrappedNative*>(p); +} + +NS_IMETHODIMP +BackstagePass::Resolve(nsIXPConnectWrappedNative* wrapper, JSContext* cx, + JSObject* objArg, jsid idArg, bool* resolvedp, + bool* _retval) { + JS::RootedObject obj(cx, objArg); + JS::RootedId id(cx, idArg); + *_retval = + WebIDLGlobalNameHash::ResolveForSystemGlobal(cx, obj, id, resolvedp); + if (!*_retval) { + return NS_ERROR_FAILURE; + } + + if (*resolvedp) { + return NS_OK; + } + + XPCJSContext* xpccx = XPCJSContext::Get(); + if (id == xpccx->GetStringID(XPCJSContext::IDX_FETCH)) { + *_retval = xpc::SandboxCreateFetch(cx, obj); + if (!*_retval) { + return NS_ERROR_FAILURE; + } + *resolvedp = true; + } else if (id == xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) { + *_retval = xpc::SandboxCreateCrypto(cx, obj); + if (!*_retval) { + return NS_ERROR_FAILURE; + } + *resolvedp = true; + } else if (id == xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) { + *_retval = IndexedDatabaseManager::DefineIndexedDB(cx, obj); + if (!*_retval) { + return NS_ERROR_FAILURE; + } + *resolvedp = true; + } else if (id == xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE)) { + *_retval = xpc::SandboxCreateStructuredClone(cx, obj); + if (!*_retval) { + return NS_ERROR_FAILURE; + } + *resolvedp = true; + } + + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx, + JSObject* objArg, + JS::MutableHandleIdVector properties, + bool enumerableOnly, bool* _retval) { + JS::RootedObject obj(cx, objArg); + + XPCJSContext* xpccx = XPCJSContext::Get(); + if (!properties.append(xpccx->GetStringID(XPCJSContext::IDX_FETCH)) || + !properties.append(xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) || + !properties.append(xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) || + !properties.append( + xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE))) { + return NS_ERROR_FAILURE; + } + + *_retval = WebIDLGlobalNameHash::NewEnumerateSystemGlobal(cx, obj, properties, + enumerableOnly); + return *_retval ? NS_OK : NS_ERROR_FAILURE; +} + +/***************************************************************************/ +NS_IMETHODIMP +BackstagePass::GetInterfaces(nsTArray<nsIID>& aArray) { + aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCScriptable), + NS_GET_IID(nsIScriptObjectPrincipal)}; + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::GetScriptableHelper(nsIXPCScriptable** retval) { + nsCOMPtr<nsIXPCScriptable> scriptable = this; + scriptable.forget(retval); + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +BackstagePass::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.AssignLiteral("BackstagePass"); + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::GetClassID(nsCID** aClassID) { + *aClassID = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +BackstagePass::Finalize(nsIXPConnectWrappedNative* wrapper, JS::GCContext* gcx, + JSObject* obj) { + nsCOMPtr<nsIGlobalObject> bsp(do_QueryInterface(wrapper->Native())); + MOZ_ASSERT(bsp); + static_cast<BackstagePass*>(bsp.get())->ForgetGlobalObject(); + return NS_OK; +} + +NS_IMETHODIMP +BackstagePass::PreCreate(nsISupports* nativeObj, JSContext* cx, + JSObject* globalObj, JSObject** parentObj) { + // We do the same trick here as for WindowSH. Return the js global + // as parent, so XPConenct can find the right scope and the wrapper + // that already exists. + nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(nativeObj)); + MOZ_ASSERT(global, "nativeObj not a global object!"); + + JSObject* jsglobal = global->GetGlobalJSObject(); + if (jsglobal) { + *parentObj = jsglobal; + } + return NS_OK; +} + +mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> +BackstagePass::GetStorageKey() { + MOZ_ASSERT(NS_IsMainThread()); + + mozilla::ipc::PrincipalInfo principalInfo; + nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &principalInfo); + if (NS_FAILED(rv)) { + return mozilla::Err(rv); + } + + MOZ_ASSERT(principalInfo.type() == + mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo); + + return std::move(principalInfo); +} diff --git a/js/xpconnect/src/XPCSelfHostedShmem.cpp b/js/xpconnect/src/XPCSelfHostedShmem.cpp new file mode 100644 index 0000000000..e5c8578ccd --- /dev/null +++ b/js/xpconnect/src/XPCSelfHostedShmem.cpp @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "XPCSelfHostedShmem.h" +#include "xpcprivate.h" + +// static +mozilla::StaticRefPtr<xpc::SelfHostedShmem> + xpc::SelfHostedShmem::sSelfHostedXdr; + +NS_IMPL_ISUPPORTS(xpc::SelfHostedShmem, nsIMemoryReporter) + +// static +xpc::SelfHostedShmem& xpc::SelfHostedShmem::GetSingleton() { + MOZ_ASSERT_IF(!sSelfHostedXdr, NS_IsMainThread()); + + if (!sSelfHostedXdr) { + sSelfHostedXdr = new SelfHostedShmem; + } + + return *sSelfHostedXdr; +} + +void xpc::SelfHostedShmem::InitMemoryReporter() { + mozilla::RegisterWeakMemoryReporter(this); +} + +// static +void xpc::SelfHostedShmem::Shutdown() { + MOZ_ASSERT(NS_IsMainThread()); + // NOTE: We cannot call UnregisterWeakMemoryReporter(sSelfHostedXdr) as the + // service is shutdown at the time this call is made. In any cases, this would + // already be done when the memory reporter got destroyed. + sSelfHostedXdr = nullptr; +} + +void xpc::SelfHostedShmem::InitFromParent(ContentType aXdr) { + MOZ_ASSERT(XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mLen, "Shouldn't call this more than once"); + + size_t len = aXdr.Length(); + auto shm = mozilla::MakeUnique<base::SharedMemory>(); + if (NS_WARN_IF(!shm->CreateFreezeable(len))) { + return; + } + + if (NS_WARN_IF(!shm->Map(len))) { + return; + } + + void* address = shm->memory(); + memcpy(address, aXdr.Elements(), aXdr.LengthBytes()); + + base::SharedMemory roCopy; + if (NS_WARN_IF(!shm->ReadOnlyCopy(&roCopy))) { + return; + } + + mMem = std::move(shm); + mHandle = roCopy.TakeHandle(); + mLen = len; +} + +bool xpc::SelfHostedShmem::InitFromChild(::base::SharedMemoryHandle aHandle, + size_t aLen) { + MOZ_ASSERT(!XRE_IsParentProcess()); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mLen, "Shouldn't call this more than once"); + + auto shm = mozilla::MakeUnique<base::SharedMemory>(); + if (NS_WARN_IF(!shm->SetHandle(std::move(aHandle), /* read_only */ true))) { + return false; + } + + if (NS_WARN_IF(!shm->Map(aLen))) { + return false; + } + + // Note: mHandle remains empty, as content processes are not spawning more + // content processes. + mMem = std::move(shm); + mLen = aLen; + return true; +} + +xpc::SelfHostedShmem::ContentType xpc::SelfHostedShmem::Content() const { + if (!mMem) { + MOZ_ASSERT(mLen == 0); + return ContentType(); + } + return ContentType(reinterpret_cast<uint8_t*>(mMem->memory()), mLen); +} + +const mozilla::UniqueFileHandle& xpc::SelfHostedShmem::Handle() const { + return mHandle; +} + +NS_IMETHODIMP +xpc::SelfHostedShmem::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) { + // If this is the parent process, then we have a handle and this instance owns + // the data and shares it with other processes, otherwise this is shared data. + if (XRE_IsParentProcess()) { + // This does not exactly report the amount of data mapped by the system, + // but the space requested when creating the handle. + MOZ_COLLECT_REPORT("explicit/js-non-window/shared-memory/self-hosted-xdr", + KIND_NONHEAP, UNITS_BYTES, mLen, + "Memory used to initialize the JS engine with the " + "self-hosted code encoded by the parent process."); + } + return NS_OK; +} diff --git a/js/xpconnect/src/XPCSelfHostedShmem.h b/js/xpconnect/src/XPCSelfHostedShmem.h new file mode 100644 index 0000000000..0fcb1ed05c --- /dev/null +++ b/js/xpconnect/src/XPCSelfHostedShmem.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpcselfhostedshmem_h___ +#define xpcselfhostedshmem_h___ + +#include "base/shared_memory.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/UniquePtrExtensions.h" +#include "mozilla/Span.h" +#include "mozilla/StaticPtr.h" +#include "nsIMemoryReporter.h" +#include "nsIObserver.h" +#include "nsIThread.h" + +namespace xpc { + +// This class is a singleton which holds a file-mapping of the Self Hosted +// Stencil XDR, to be shared by the parent process with all the child processes. +// +// It is either initialized by the parent process by monitoring when the Self +// hosted stencil is produced, or by the content process by reading a shared +// memory-mapped file. +class SelfHostedShmem final : public nsIMemoryReporter { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIMEMORYREPORTER + + // NOTE: This type is identical to JS::SelfHostedCache, but we repeat it to + // avoid including JS engine API in ipc code. + using ContentType = mozilla::Span<const uint8_t>; + + static SelfHostedShmem& GetSingleton(); + + // Initialize this singleton with the content of the Self-hosted Stencil XDR. + // This will be used to initialize the shared memory which would hold a copy. + // + // This function is not thread-safe and should be call at most once and from + // the main thread. + void InitFromParent(ContentType aXdr); + + // Initialize this singleton with the content coming from the parent process, + // using a file handle which maps to the memory pages of the parent process. + // + // This function is not thread-safe and should be call at most once and from + // the main thread. + [[nodiscard]] bool InitFromChild(base::SharedMemoryHandle aHandle, + size_t aLen); + + // Return a span over the read-only XDR content of the self-hosted stencil. + ContentType Content() const; + + // Return the file handle which is under which the content is mapped. + const mozilla::UniqueFileHandle& Handle() const; + + // Register this class to the memory reporter service. + void InitMemoryReporter(); + + // Unregister this class from the memory reporter service, and delete the + // memory associated with the shared memory. As the memory is borrowed by the + // JS engine, this function should be called after JS_Shutdown. + // + // NOTE: This is not using the Observer service which would call Shutdown + // while JS code might still be running during shutdown process. + static void Shutdown(); + + private: + SelfHostedShmem() = default; + ~SelfHostedShmem() = default; + + static mozilla::StaticRefPtr<SelfHostedShmem> sSelfHostedXdr; + + // read-only file Handle used to transfer from the parent process to content + // processes. + mozilla::UniqueFileHandle mHandle; + + // Shared memory used by JS runtime initialization. + mozilla::UniquePtr<base::SharedMemory> mMem; + + // Length of the content within the shared memory. + size_t mLen = 0; +}; + +} // namespace xpc + +#endif // !xpcselfhostedshmem_h___ diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp new file mode 100644 index 0000000000..124c2ed37d --- /dev/null +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -0,0 +1,1539 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsXULAppAPI.h" +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/Array.h" // JS::NewArrayObject +#include "js/CallAndConstruct.h" // JS_CallFunctionValue +#include "js/CharacterEncoding.h" +#include "js/CompilationAndEvaluation.h" // JS::Evaluate +#include "js/ContextOptions.h" +#include "js/Printf.h" +#include "js/PropertyAndElement.h" // JS_DefineElement, JS_DefineFunctions, JS_DefineProperty +#include "js/PropertySpec.h" +#include "js/SourceText.h" // JS::SourceText +#include "mozilla/ChaosMode.h" +#include "mozilla/dom/AutoEntryScript.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/IOInterposer.h" +#include "mozilla/Preferences.h" +#include "mozilla/Utf8.h" // mozilla::Utf8Unit +#include "nsServiceManagerUtils.h" +#include "nsComponentManagerUtils.h" +#include "nsExceptionHandler.h" +#include "nsIServiceManager.h" +#include "nsIFile.h" +#include "nsString.h" +#include "nsIDirectoryService.h" +#include "nsDirectoryServiceDefs.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nscore.h" +#include "nsArrayEnumerator.h" +#include "nsCOMArray.h" +#include "nsDirectoryServiceUtils.h" +#include "nsCOMPtr.h" +#include "nsJSPrincipals.h" +#include "nsJSUtils.h" +#include "xpcpublic.h" +#include "xpcprivate.h" +#include "BackstagePass.h" +#include "nsIScriptSecurityManager.h" +#include "nsIPrincipal.h" +#include "nsJSUtils.h" + +#include "nsIXULRuntime.h" +#include "nsIAppStartup.h" +#include "Components.h" +#include "ProfilerControl.h" + +#ifdef ANDROID +# include <android/log.h> +# include "XREShellData.h" +#endif + +#ifdef XP_WIN +# include "mozilla/mscom/ProcessRuntime.h" +# include "mozilla/ScopeExit.h" +# include "mozilla/widget/AudioSession.h" +# include "mozilla/WinDllServices.h" +# include "mozilla/WindowsBCryptInitialization.h" +# include <windows.h> +# if defined(MOZ_SANDBOX) +# include "XREShellData.h" +# include "sandboxBroker.h" +# endif +#endif + +#ifdef MOZ_CODE_COVERAGE +# include "mozilla/CodeCoverageHandler.h" +#endif + +// all this crap is needed to do the interactive shell stuff +#include <stdlib.h> +#include <errno.h> +#ifdef HAVE_IO_H +# include <io.h> /* for isatty() */ +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> /* for isatty() */ +#endif + +#ifdef ENABLE_TESTS +# include "xpctest_private.h" +#endif + +// Fuzzing support for XPC runtime fuzzing +#ifdef FUZZING_INTERFACES +# include "xpcrtfuzzing/xpcrtfuzzing.h" +# include "XREShellData.h" +static bool fuzzDoDebug = !!getenv("MOZ_FUZZ_DEBUG"); +static bool fuzzHaveModule = !!getenv("FUZZER"); +#endif // FUZZING_INTERFACES + +using namespace mozilla; +using namespace JS; +using mozilla::dom::AutoEntryScript; +using mozilla::dom::AutoJSAPI; + +class XPCShellDirProvider : public nsIDirectoryServiceProvider2 { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + NS_DECL_NSIDIRECTORYSERVICEPROVIDER2 + + XPCShellDirProvider() = default; + ~XPCShellDirProvider() = default; + + // The platform resource folder + void SetGREDirs(nsIFile* greDir); + void ClearGREDirs() { + mGREDir = nullptr; + mGREBinDir = nullptr; + } + // The application resource folder + void SetAppDir(nsIFile* appFile); + void ClearAppDir() { mAppDir = nullptr; } + // The app executable + void SetAppFile(nsIFile* appFile); + void ClearAppFile() { mAppFile = nullptr; } + + private: + nsCOMPtr<nsIFile> mGREDir; + nsCOMPtr<nsIFile> mGREBinDir; + nsCOMPtr<nsIFile> mAppDir; + nsCOMPtr<nsIFile> mAppFile; +}; + +#ifdef XP_WIN +class MOZ_STACK_CLASS AutoAudioSession { + public: + AutoAudioSession() { widget::StartAudioSession(); } + + ~AutoAudioSession() { widget::StopAudioSession(); } +}; +#endif + +#define EXITCODE_RUNTIME_ERROR 3 +#define EXITCODE_FILE_NOT_FOUND 4 + +static FILE* gOutFile = nullptr; +static FILE* gErrFile = nullptr; +static FILE* gInFile = nullptr; + +static int gExitCode = 0; +static bool gQuitting = false; +static bool reportWarnings = true; +static bool compileOnly = false; + +static JSPrincipals* gJSPrincipals = nullptr; +static nsAutoString* gWorkingDirectory = nullptr; + +static bool GetLocationProperty(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.thisv().isObject()) { + JS_ReportErrorASCII(cx, "Unexpected this value for GetLocationProperty"); + return false; + } +#if !defined(XP_WIN) && !defined(XP_UNIX) + // XXX: your platform should really implement this + return false; +#else + JS::AutoFilename filename; + if (JS::DescribeScriptedCaller(cx, &filename) && filename.get()) { + NS_ConvertUTF8toUTF16 filenameString(filename.get()); + +# if defined(XP_WIN) + // replace forward slashes with backslashes, + // since nsLocalFileWin chokes on them + char16_t* start = filenameString.BeginWriting(); + char16_t* end = filenameString.EndWriting(); + + while (start != end) { + if (*start == L'/') { + *start = L'\\'; + } + start++; + } +# endif + + nsCOMPtr<nsIFile> location; + nsresult rv = + NS_NewLocalFile(filenameString, false, getter_AddRefs(location)); + + if (!location && gWorkingDirectory) { + // could be a relative path, try appending it to the cwd + // and then normalize + nsAutoString absolutePath(*gWorkingDirectory); + absolutePath.Append(filenameString); + + rv = NS_NewLocalFile(absolutePath, false, getter_AddRefs(location)); + } + + if (location) { + bool symlink; + // don't normalize symlinks, because that's kind of confusing + if (NS_SUCCEEDED(location->IsSymlink(&symlink)) && !symlink) + location->Normalize(); + RootedObject locationObj(cx); + RootedObject scope(cx, JS::CurrentGlobalOrNull(cx)); + rv = nsXPConnect::XPConnect()->WrapNative( + cx, scope, location, NS_GET_IID(nsIFile), locationObj.address()); + if (NS_SUCCEEDED(rv) && locationObj) { + args.rval().setObject(*locationObj); + } + } + } + + return true; +#endif +} + +static bool GetLine(JSContext* cx, char* bufp, FILE* file, const char* prompt) { + fputs(prompt, gOutFile); + fflush(gOutFile); + + char line[4096] = {'\0'}; + while (true) { + if (fgets(line, sizeof line, file)) { + strcpy(bufp, line); + return true; + } + if (errno != EINTR) { + return false; + } + } +} + +static bool ReadLine(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + // While 4096 might be quite arbitrary, this is something to be fixed in + // bug 105707. It is also the same limit as in ProcessFile. + char buf[4096]; + RootedString str(cx); + + /* If a prompt was specified, construct the string */ + if (args.length() > 0) { + str = JS::ToString(cx, args[0]); + if (!str) { + return false; + } + } else { + str = JS_GetEmptyString(cx); + } + + /* Get a line from the infile */ + JS::UniqueChars strBytes = JS_EncodeStringToLatin1(cx, str); + if (!strBytes || !GetLine(cx, buf, gInFile, strBytes.get())) { + return false; + } + + /* Strip newline character added by GetLine() */ + unsigned int buflen = strlen(buf); + if (buflen == 0) { + if (feof(gInFile)) { + args.rval().setNull(); + return true; + } + } else if (buf[buflen - 1] == '\n') { + --buflen; + } + + /* Turn buf into a JSString */ + str = JS_NewStringCopyN(cx, buf, buflen); + if (!str) { + return false; + } + + args.rval().setString(str); + return true; +} + +static bool Print(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + args.rval().setUndefined(); + +#ifdef FUZZING_INTERFACES + if (fuzzHaveModule && !fuzzDoDebug) { + // When fuzzing and not debugging, suppress any print() output, + // as it slows down fuzzing and makes libFuzzer's output hard + // to read. + return true; + } +#endif // FUZZING_INTERFACES + + RootedString str(cx); + nsAutoCString utf8output; + + for (unsigned i = 0; i < args.length(); i++) { + str = ToString(cx, args[i]); + if (!str) { + return false; + } + + JS::UniqueChars utf8str = JS_EncodeStringToUTF8(cx, str); + if (!utf8str) { + return false; + } + + if (i) { + utf8output.Append(' '); + } + utf8output.Append(utf8str.get(), strlen(utf8str.get())); + } + utf8output.Append('\n'); + fputs(utf8output.get(), gOutFile); + fflush(gOutFile); + return true; +} + +static bool Dump(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + args.rval().setUndefined(); + + if (!args.length()) { + return true; + } + + RootedString str(cx, ToString(cx, args[0])); + if (!str) { + return false; + } + + JS::UniqueChars utf8str = JS_EncodeStringToUTF8(cx, str); + if (!utf8str) { + return false; + } + +#ifdef ANDROID + __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.get()); +#endif +#ifdef XP_WIN + if (IsDebuggerPresent()) { + nsAutoJSString wstr; + if (!wstr.init(cx, str)) { + return false; + } + OutputDebugStringW(wstr.get()); + } +#endif + fputs(utf8str.get(), gOutFile); + fflush(gOutFile); + return true; +} + +static bool Load(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + JS::RootedObject thisObject(cx); + if (!args.computeThis(cx, &thisObject)) { + return false; + } + if (!JS_IsGlobalObject(thisObject)) { + JS_ReportErrorASCII(cx, "Trying to load() into a non-global object"); + return false; + } + + RootedString str(cx); + for (unsigned i = 0; i < args.length(); i++) { + str = ToString(cx, args[i]); + if (!str) { + return false; + } + JS::UniqueChars filename = JS_EncodeStringToUTF8(cx, str); + if (!filename) { + return false; + } + JS::CompileOptions options(cx); + options.setIsRunOnce(true).setSkipFilenameValidation(true); + JS::Rooted<JSScript*> script( + cx, JS::CompileUtf8Path(cx, options, filename.get())); + if (!script) { + return false; + } + + if (!compileOnly) { + if (!JS_ExecuteScript(cx, script)) { + return false; + } + } + } + args.rval().setUndefined(); + return true; +} + +static bool Quit(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + gExitCode = 0; + if (!ToInt32(cx, args.get(0), &gExitCode)) { + return false; + } + + gQuitting = true; + // exit(0); + return false; +} + +static bool DumpXPC(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = CallArgsFromVp(argc, vp); + + uint16_t depth = 2; + if (args.length() > 0) { + if (!JS::ToUint16(cx, args[0], &depth)) { + return false; + } + } + + nsXPConnect::XPConnect()->DebugDump(int16_t(depth)); + args.rval().setUndefined(); + return true; +} + +static bool GC(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + JS_GC(cx); + + args.rval().setUndefined(); + return true; +} + +#ifdef JS_GC_ZEAL +static bool GCZeal(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + uint32_t zeal; + if (!ToUint32(cx, args.get(0), &zeal)) { + return false; + } + + JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ); + args.rval().setUndefined(); + return true; +} +#endif + +static bool SendCommand(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + if (args.length() == 0) { + JS_ReportErrorASCII(cx, "Function takes at least one argument!"); + return false; + } + + RootedString str(cx, ToString(cx, args[0])); + if (!str) { + JS_ReportErrorASCII(cx, "Could not convert argument 1 to string!"); + return false; + } + + if (args.get(1).isObject() && !JS_ObjectIsFunction(&args[1].toObject())) { + JS_ReportErrorASCII(cx, "Could not convert argument 2 to function!"); + return false; + } + + if (!XRE_SendTestShellCommand( + cx, str, args.length() > 1 ? args[1].address() : nullptr)) { + JS_ReportErrorASCII(cx, "Couldn't send command!"); + return false; + } + + args.rval().setUndefined(); + return true; +} + +static bool Options(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = CallArgsFromVp(argc, vp); + ContextOptions oldContextOptions = ContextOptionsRef(cx); + + RootedString str(cx); + JS::UniqueChars opt; + for (unsigned i = 0; i < args.length(); ++i) { + str = ToString(cx, args[i]); + if (!str) { + return false; + } + + opt = JS_EncodeStringToUTF8(cx, str); + if (!opt) { + return false; + } + + if (strcmp(opt.get(), "strict_mode") == 0) { + ContextOptionsRef(cx).toggleStrictMode(); + } else { + JS_ReportErrorUTF8(cx, + "unknown option name '%s'. The valid name is " + "strict_mode.", + opt.get()); + return false; + } + } + + UniqueChars names; + if (names && oldContextOptions.strictMode()) { + names = JS_sprintf_append(std::move(names), "%s%s", names ? "," : "", + "strict_mode"); + if (!names) { + JS_ReportOutOfMemory(cx); + return false; + } + } + + str = JS_NewStringCopyZ(cx, names.get()); + if (!str) { + return false; + } + + args.rval().setString(str); + return true; +} + +static PersistentRootedValue* sScriptedInterruptCallback = nullptr; + +static bool XPCShellInterruptCallback(JSContext* cx) { + MOZ_ASSERT(sScriptedInterruptCallback->initialized()); + RootedValue callback(cx, *sScriptedInterruptCallback); + + // If no interrupt callback was set by script, no-op. + if (callback.isUndefined()) { + return true; + } + + MOZ_ASSERT(js::IsFunctionObject(&callback.toObject())); + + JSAutoRealm ar(cx, &callback.toObject()); + RootedValue rv(cx); + if (!JS_CallFunctionValue(cx, nullptr, callback, + JS::HandleValueArray::empty(), &rv) || + !rv.isBoolean()) { + NS_WARNING("Scripted interrupt callback failed! Terminating script."); + JS_ClearPendingException(cx); + return false; + } + + return rv.toBoolean(); +} + +static bool SetInterruptCallback(JSContext* cx, unsigned argc, Value* vp) { + MOZ_ASSERT(sScriptedInterruptCallback->initialized()); + + // Sanity-check args. + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (args.length() != 1) { + JS_ReportErrorASCII(cx, "Wrong number of arguments"); + return false; + } + + // Allow callers to remove the interrupt callback by passing undefined. + if (args[0].isUndefined()) { + *sScriptedInterruptCallback = UndefinedValue(); + return true; + } + + // Otherwise, we should have a function object. + if (!args[0].isObject() || !js::IsFunctionObject(&args[0].toObject())) { + JS_ReportErrorASCII(cx, "Argument must be a function"); + return false; + } + + *sScriptedInterruptCallback = args[0]; + + return true; +} + +static bool SimulateNoScriptActivity(JSContext* cx, unsigned argc, Value* vp) { + // Sanity-check args. + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (args.length() != 1 || !args[0].isInt32() || args[0].toInt32() < 0) { + JS_ReportErrorASCII(cx, "Expected a positive integer argument"); + return false; + } + + // This mimics mozilla::SpinEventLoopUntil but instead of spinning the + // event loop we sleep, to make sure we don't run script. + xpc::AutoScriptActivity asa(false); + PR_Sleep(PR_SecondsToInterval(args[0].toInt32())); + + args.rval().setUndefined(); + return true; +} + +static bool RegisterAppManifest(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (args.length() != 1) { + JS_ReportErrorASCII(cx, "Wrong number of arguments"); + return false; + } + if (!args[0].isObject()) { + JS_ReportErrorASCII(cx, + "Expected object as argument 1 to registerAppManifest"); + return false; + } + + Rooted<JSObject*> arg1(cx, &args[0].toObject()); + nsCOMPtr<nsIFile> file; + nsresult rv = nsXPConnect::XPConnect()->WrapJS(cx, arg1, NS_GET_IID(nsIFile), + getter_AddRefs(file)); + if (NS_FAILED(rv)) { + XPCThrower::Throw(rv, cx); + return false; + } + rv = XRE_AddManifestLocation(NS_APP_LOCATION, file); + if (NS_FAILED(rv)) { + XPCThrower::Throw(rv, cx); + return false; + } + return true; +} + +#ifdef ANDROID +static bool ChangeTestShellDir(JSContext* cx, unsigned argc, Value* vp) { + // This method should only be used by testing/xpcshell/head.js to change to + // the correct directory on Android Remote XPCShell tests. + // + // TODO: Bug 1801725 - Find a more ergonomic way to do this than exposing + // identical methods in XPCShellEnvironment and XPCShellImpl to chdir on + // android for Remote XPCShell tests on Android. + CallArgs args = CallArgsFromVp(argc, vp); + + if (args.length() != 1) { + JS_ReportErrorASCII(cx, "changeTestShellDir() takes one argument"); + return false; + } + + nsAutoJSCString path; + if (!path.init(cx, args[0])) { + JS_ReportErrorASCII( + cx, "changeTestShellDir(): could not convert argument 1 to string"); + return false; + } + + if (chdir(path.get())) { + JS_ReportErrorASCII(cx, "changeTestShellDir(): could not change directory"); + return false; + } + + return true; +} +#endif + +#ifdef ENABLE_TESTS +static bool RegisterXPCTestComponents(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (args.length() != 0) { + JS_ReportErrorASCII(cx, "Wrong number of arguments"); + return false; + } + nsresult rv = xpcTestRegisterComponents(); + if (NS_FAILED(rv)) { + XPCThrower::Throw(rv, cx); + return false; + } + return true; +} +#endif + +static const JSFunctionSpec glob_functions[] = { + // clang-format off + JS_FN("print", Print, 0,0), + JS_FN("readline", ReadLine, 1,0), + JS_FN("load", Load, 1,0), + JS_FN("quit", Quit, 0,0), + JS_FN("dumpXPC", DumpXPC, 1,0), + JS_FN("dump", Dump, 1,0), + JS_FN("gc", GC, 0,0), +#ifdef JS_GC_ZEAL + JS_FN("gczeal", GCZeal, 1,0), +#endif + JS_FN("options", Options, 0,0), + JS_FN("sendCommand", SendCommand, 1,0), + JS_FN("atob", xpc::Atob, 1,0), + JS_FN("btoa", xpc::Btoa, 1,0), + JS_FN("setInterruptCallback", SetInterruptCallback, 1,0), + JS_FN("simulateNoScriptActivity", SimulateNoScriptActivity, 1,0), + JS_FN("registerAppManifest", RegisterAppManifest, 1, 0), +#ifdef ANDROID + JS_FN("changeTestShellDir", ChangeTestShellDir, 1,0), +#endif +#ifdef ENABLE_TESTS + JS_FN("registerXPCTestComponents", RegisterXPCTestComponents, 0, 0), +#endif + JS_FS_END + // clang-format on +}; + +/***************************************************************************/ + +typedef enum JSShellErrNum { +#define MSG_DEF(name, number, count, exception, format) name = number, +#include "jsshell.msg" +#undef MSG_DEF + JSShellErr_Limit +} JSShellErrNum; + +static const JSErrorFormatString jsShell_ErrorFormatString[JSShellErr_Limit] = { +#define MSG_DEF(name, number, count, exception, format) {#name, format, count}, +#include "jsshell.msg" +#undef MSG_DEF +}; + +static const JSErrorFormatString* my_GetErrorMessage( + void* userRef, const unsigned errorNumber) { + if (errorNumber == 0 || errorNumber >= JSShellErr_Limit) { + return nullptr; + } + + return &jsShell_ErrorFormatString[errorNumber]; +} + +static bool ProcessUtf8Line(AutoJSAPI& jsapi, const char* buffer, + int startline) { + JSContext* cx = jsapi.cx(); + JS::CompileOptions options(cx); + options.setFileAndLine("typein", startline) + .setIsRunOnce(true) + .setSkipFilenameValidation(true); + + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (!srcBuf.init(cx, buffer, strlen(buffer), JS::SourceOwnership::Borrowed)) { + return false; + } + + JS::RootedScript script(cx, JS::Compile(cx, options, srcBuf)); + if (!script) { + return false; + } + if (compileOnly) { + return true; + } + + JS::RootedValue result(cx); + if (!JS_ExecuteScript(cx, script, &result)) { + return false; + } + + if (result.isUndefined()) { + return true; + } + + RootedString str(cx, JS::ToString(cx, result)); + if (!str) { + return false; + } + + JS::UniqueChars bytes = JS_EncodeStringToLatin1(cx, str); + if (!bytes) { + return false; + } + + fprintf(gOutFile, "%s\n", bytes.get()); + return true; +} + +static bool ProcessFile(AutoJSAPI& jsapi, const char* filename, FILE* file, + bool forceTTY) { + JSContext* cx = jsapi.cx(); + JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx)); + MOZ_ASSERT(global); + + if (forceTTY) { + file = stdin; + } else if (!isatty(fileno(file))) { + /* + * It's not interactive - just execute it. + * + * Support the UNIX #! shell hack; gobble the first line if it starts + * with '#'. + */ + int ch = fgetc(file); + if (ch == '#') { + while ((ch = fgetc(file)) != EOF) { + if (ch == '\n' || ch == '\r') { + break; + } + } + } + ungetc(ch, file); + + JS::UniqueChars filenameUtf8 = JS::EncodeNarrowToUtf8(jsapi.cx(), filename); + if (!filenameUtf8) { + return false; + } + + JS::RootedScript script(cx); + JS::RootedValue unused(cx); + JS::CompileOptions options(cx); + options.setFileAndLine(filenameUtf8.get(), 1) + .setIsRunOnce(true) + .setNoScriptRval(true) + .setSkipFilenameValidation(true); + script = JS::CompileUtf8File(cx, options, file); + if (!script) { + return false; + } + return compileOnly || JS_ExecuteScript(cx, script, &unused); + } + + /* It's an interactive filehandle; drop into read-eval-print loop. */ + int lineno = 1; + bool hitEOF = false; + do { + char buffer[4096]; + char* bufp = buffer; + *bufp = '\0'; + + /* + * Accumulate lines until we get a 'compilable unit' - one that either + * generates an error (before running out of source) or that compiles + * cleanly. This should be whenever we get a complete statement that + * coincides with the end of a line. + */ + int startline = lineno; + do { + if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) { + hitEOF = true; + break; + } + bufp += strlen(bufp); + lineno++; + } while ( + !JS_Utf8BufferIsCompilableUnit(cx, global, buffer, strlen(buffer))); + + if (!ProcessUtf8Line(jsapi, buffer, startline)) { + jsapi.ReportException(); + } + } while (!hitEOF && !gQuitting); + + fprintf(gOutFile, "\n"); + return true; +} + +static bool Process(AutoJSAPI& jsapi, const char* filename, bool forceTTY) { + FILE* file; + + if (forceTTY || !filename || strcmp(filename, "-") == 0) { + file = stdin; + } else { + file = fopen(filename, "r"); + if (!file) { + /* + * Use Latin1 variant here because the encoding of the return value + * of strerror function can be non-UTF-8. + */ + JS_ReportErrorNumberLatin1(jsapi.cx(), my_GetErrorMessage, nullptr, + JSSMSG_CANT_OPEN, filename, strerror(errno)); + gExitCode = EXITCODE_FILE_NOT_FOUND; + return false; + } + } + + bool ok = ProcessFile(jsapi, filename, file, forceTTY); + if (file != stdin) { + fclose(file); + } + return ok; +} + +static int usage() { + fprintf(gErrFile, "%s\n", JS_GetImplementationVersion()); + fprintf( + gErrFile, + "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-WwxiCmIp] " + "[-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n"); + return 2; +} + +static bool printUsageAndSetExitCode() { + gExitCode = usage(); + return false; +} + +static bool ProcessArgs(AutoJSAPI& jsapi, char** argv, int argc, + XPCShellDirProvider* aDirProvider) { + JSContext* cx = jsapi.cx(); + const char rcfilename[] = "xpcshell.js"; + FILE* rcfile; + int rootPosition; + JS::Rooted<JSObject*> argsObj(cx); + char* filename = nullptr; + bool isInteractive = true; + bool forceTTY = false; + + rcfile = fopen(rcfilename, "r"); + if (rcfile) { + printf("[loading '%s'...]\n", rcfilename); + bool ok = ProcessFile(jsapi, rcfilename, rcfile, false); + fclose(rcfile); + if (!ok) { + return false; + } + } + + JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx)); + + /* + * Scan past all optional arguments so we can create the arguments object + * before processing any -f options, which must interleave properly with + * -v and -w options. This requires two passes, and without getopt, we'll + * have to keep the option logic here and in the second for loop in sync. + * First of all, find out the first argument position which will be passed + * as a script file to be executed. + */ + for (rootPosition = 0; rootPosition < argc; rootPosition++) { + if (argv[rootPosition][0] != '-' || argv[rootPosition][1] == '\0') { + ++rootPosition; + break; + } + + bool isPairedFlag = + argv[rootPosition][0] != '\0' && + (argv[rootPosition][1] == 'v' || argv[rootPosition][1] == 'f' || + argv[rootPosition][1] == 'e'); + if (isPairedFlag && rootPosition < argc - 1) { + ++rootPosition; // Skip over the 'foo' portion of |-v foo|, |-f foo|, or + // |-e foo|. + } + } + + /* + * Create arguments early and define it to root it, so it's safe from any + * GC calls nested below, and so it is available to -f <file> arguments. + */ + argsObj = JS::NewArrayObject(cx, 0); + if (!argsObj) { + return 1; + } + if (!JS_DefineProperty(cx, global, "arguments", argsObj, 0)) { + return 1; + } + + for (int j = 0, length = argc - rootPosition; j < length; j++) { + RootedString str(cx, JS_NewStringCopyZ(cx, argv[rootPosition++])); + if (!str || !JS_DefineElement(cx, argsObj, j, str, JSPROP_ENUMERATE)) { + return 1; + } + } + + for (int i = 0; i < argc; i++) { + if (argv[i][0] != '-' || argv[i][1] == '\0') { + filename = argv[i++]; + isInteractive = false; + break; + } + switch (argv[i][1]) { + case 'W': + reportWarnings = false; + break; + case 'w': + reportWarnings = true; + break; + case 'x': + break; + case 'd': + /* This used to try to turn on the debugger. */ + break; + case 'm': + break; + case 'f': + if (++i == argc) { + return printUsageAndSetExitCode(); + } + if (!Process(jsapi, argv[i], false)) { + return false; + } + /* + * XXX: js -f foo.js should interpret foo.js and then + * drop into interactive mode, but that breaks test + * harness. Just execute foo.js for now. + */ + isInteractive = false; + break; + case 'i': + isInteractive = forceTTY = true; + break; + case 'e': { + RootedValue rval(cx); + + if (++i == argc) { + return printUsageAndSetExitCode(); + } + + JS::CompileOptions opts(cx); + opts.setSkipFilenameValidation(true); + opts.setFileAndLine("-e", 1); + + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (srcBuf.init(cx, argv[i], strlen(argv[i]), + JS::SourceOwnership::Borrowed)) { + JS::Evaluate(cx, opts, srcBuf, &rval); + } + + isInteractive = false; + break; + } + case 'C': + compileOnly = true; + isInteractive = false; + break; + default: + return printUsageAndSetExitCode(); + } + } + + if (filename || isInteractive) { + return Process(jsapi, filename, forceTTY); + } + return true; +} + +/***************************************************************************/ + +static bool GetCurrentWorkingDirectory(nsAString& workingDirectory) { +#if !defined(XP_WIN) && !defined(XP_UNIX) + // XXX: your platform should really implement this + return false; +#elif XP_WIN + DWORD requiredLength = GetCurrentDirectoryW(0, nullptr); + workingDirectory.SetLength(requiredLength); + GetCurrentDirectoryW(workingDirectory.Length(), + (LPWSTR)workingDirectory.BeginWriting()); + // we got a trailing null there + workingDirectory.SetLength(requiredLength); + workingDirectory.Replace(workingDirectory.Length() - 1, 1, L'\\'); +#elif defined(XP_UNIX) + nsAutoCString cwd; + // 1024 is just a guess at a sane starting value + size_t bufsize = 1024; + char* result = nullptr; + while (result == nullptr) { + cwd.SetLength(bufsize); + result = getcwd(cwd.BeginWriting(), cwd.Length()); + if (!result) { + if (errno != ERANGE) { + return false; + } + // need to make the buffer bigger + bufsize *= 2; + } + } + // size back down to the actual string length + cwd.SetLength(strlen(result) + 1); + cwd.Replace(cwd.Length() - 1, 1, '/'); + CopyUTF8toUTF16(cwd, workingDirectory); +#endif + return true; +} + +static JSSecurityCallbacks shellSecurityCallbacks; + +int XRE_XPCShellMain(int argc, char** argv, char** envp, + const XREShellData* aShellData) { + MOZ_ASSERT(aShellData); + + JSContext* cx; + int result = 0; + nsresult rv; + +#ifdef ANDROID + gOutFile = aShellData->outFile; + gErrFile = aShellData->errFile; +#else + gOutFile = stdout; + gErrFile = stderr; +#endif + gInFile = stdin; + + NS_LogInit(); + + mozilla::LogModule::Init(argc, argv); + + // This guard ensures that all threads that attempt to register themselves + // with the IOInterposer will be properly tracked. + mozilla::IOInterposerInit ioInterposerGuard; + + XRE_InitCommandLine(argc, argv); + + char aLocal; + profiler_init(&aLocal); + +#ifdef MOZ_ASAN_REPORTER + PR_SetEnv("MOZ_DISABLE_ASAN_REPORTER=1"); +#endif + + if (PR_GetEnv("MOZ_CHAOSMODE")) { + ChaosFeature feature = ChaosFeature::Any; + long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16); + if (featureInt) { + // NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature. + feature = static_cast<ChaosFeature>(featureInt); + } + ChaosMode::SetChaosFeature(feature); + } + + if (ChaosMode::isActive(ChaosFeature::Any)) { + printf_stderr( + "*** You are running in chaos test mode. See ChaosMode.h. ***\n"); + } + +#ifdef XP_WIN + // Some COM settings are global to the process and must be set before any non- + // trivial COM is run in the application. Since these settings may affect + // stability, we should instantiate COM ASAP so that we can ensure that these + // global settings are configured before anything can interfere. + mscom::ProcessRuntime mscom; +#endif + + // The provider needs to outlive the call to shutting down XPCOM. + XPCShellDirProvider dirprovider; + + { // Start scoping nsCOMPtrs + nsCOMPtr<nsIFile> appFile; + rv = XRE_GetBinaryPath(getter_AddRefs(appFile)); + if (NS_FAILED(rv)) { + printf("Couldn't find application file.\n"); + return 1; + } + nsCOMPtr<nsIFile> appDir; + rv = appFile->GetParent(getter_AddRefs(appDir)); + if (NS_FAILED(rv)) { + printf("Couldn't get application directory.\n"); + return 1; + } + + dirprovider.SetAppFile(appFile); + + nsCOMPtr<nsIFile> greDir; + if (argc > 1 && !strcmp(argv[1], "-g")) { + if (argc < 3) { + return usage(); + } + + rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(greDir)); + if (NS_FAILED(rv)) { + printf("Couldn't use given GRE dir.\n"); + return 1; + } + + dirprovider.SetGREDirs(greDir); + + argc -= 2; + argv += 2; + } else { +#ifdef XP_MACOSX + // On OSX, the GreD needs to point to Contents/Resources in the .app + // bundle. Libraries will be loaded at a relative path to GreD, i.e. + // ../MacOS. + nsCOMPtr<nsIFile> tmpDir; + XRE_GetFileFromPath(argv[0], getter_AddRefs(greDir)); + greDir->GetParent(getter_AddRefs(tmpDir)); + tmpDir->Clone(getter_AddRefs(greDir)); + tmpDir->SetNativeLeafName("Resources"_ns); + bool dirExists = false; + tmpDir->Exists(&dirExists); + if (dirExists) { + greDir = tmpDir.forget(); + } + dirprovider.SetGREDirs(greDir); +#else + nsAutoString workingDir; + if (!GetCurrentWorkingDirectory(workingDir)) { + printf("GetCurrentWorkingDirectory failed.\n"); + return 1; + } + rv = NS_NewLocalFile(workingDir, true, getter_AddRefs(greDir)); + if (NS_FAILED(rv)) { + printf("NS_NewLocalFile failed.\n"); + return 1; + } +#endif + } + + if (argc > 1 && !strcmp(argv[1], "-a")) { + if (argc < 3) { + return usage(); + } + + nsCOMPtr<nsIFile> dir; + rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(dir)); + if (NS_SUCCEEDED(rv)) { + appDir = dir; + dirprovider.SetAppDir(appDir); + } + if (NS_FAILED(rv)) { + printf("Couldn't use given appdir.\n"); + return 1; + } + argc -= 2; + argv += 2; + } + + while (argc > 1 && !strcmp(argv[1], "-r")) { + if (argc < 3) { + return usage(); + } + + nsCOMPtr<nsIFile> lf; + rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(lf)); + if (NS_FAILED(rv)) { + printf("Couldn't get manifest file.\n"); + return 1; + } + XRE_AddManifestLocation(NS_APP_LOCATION, lf); + + argc -= 2; + argv += 2; + } + + const char* val = getenv("MOZ_CRASHREPORTER"); + if (val && *val && !CrashReporter::IsDummy()) { + rv = CrashReporter::SetExceptionHandler(greDir, true); + if (NS_FAILED(rv)) { + printf("CrashReporter::SetExceptionHandler failed!\n"); + return 1; + } + MOZ_ASSERT(CrashReporter::GetEnabled()); + } + + if (argc > 1 && !strcmp(argv[1], "--greomni")) { + nsCOMPtr<nsIFile> greOmni; + XRE_GetFileFromPath(argv[2], getter_AddRefs(greOmni)); + XRE_InitOmnijar(greOmni, greOmni); + argc -= 2; + argv += 2; + } + + rv = NS_InitXPCOM(nullptr, appDir, &dirprovider); + if (NS_FAILED(rv)) { + printf("NS_InitXPCOM failed!\n"); + return 1; + } + + // xpc::ErrorReport::LogToConsoleWithStack needs this to print errors + // to stderr. + Preferences::SetBool("browser.dom.window.dump.enabled", true); + Preferences::SetBool("devtools.console.stdout.chrome", true); + + AutoJSAPI jsapi; + jsapi.Init(); + cx = jsapi.cx(); + + // Override the default XPConnect interrupt callback. We could store the + // old one and restore it before shutting down, but there's not really a + // reason to bother. + sScriptedInterruptCallback = new PersistentRootedValue; + sScriptedInterruptCallback->init(cx, UndefinedValue()); + + JS_AddInterruptCallback(cx, XPCShellInterruptCallback); + + argc--; + argv++; + + nsCOMPtr<nsIPrincipal> systemprincipal; + // Fetch the system principal and store it away in a global, to use for + // script compilation in Load() and ProcessFile() (including interactive + // eval loop) + { + nsCOMPtr<nsIScriptSecurityManager> securityManager = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && securityManager) { + rv = securityManager->GetSystemPrincipal( + getter_AddRefs(systemprincipal)); + if (NS_FAILED(rv)) { + fprintf(gErrFile, + "+++ Failed to obtain SystemPrincipal from " + "ScriptSecurityManager service.\n"); + } else { + // fetch the JS principals and stick in a global + gJSPrincipals = nsJSPrincipals::get(systemprincipal); + JS_HoldPrincipals(gJSPrincipals); + } + } else { + fprintf(gErrFile, + "+++ Failed to get ScriptSecurityManager service, running " + "without principals"); + } + } + + const JSSecurityCallbacks* scb = JS_GetSecurityCallbacks(cx); + MOZ_ASSERT( + scb, + "We are assuming that nsScriptSecurityManager::Init() has been run"); + shellSecurityCallbacks = *scb; + JS_SetSecurityCallbacks(cx, &shellSecurityCallbacks); + + auto backstagePass = MakeRefPtr<BackstagePass>(); + + // Make the default XPCShell global use a fresh zone (rather than the + // System Zone) to improve cross-zone test coverage. + JS::RealmOptions options; + options.creationOptions().setNewCompartmentAndZone(); + xpc::SetPrefableRealmOptions(options); + + // Even if we're building in a configuration where source is + // discarded, there's no reason to do that on XPCShell, and doing so + // might break various automation scripts. + options.behaviors().setDiscardSource(false); + + JS::Rooted<JSObject*> glob(cx); + rv = xpc::InitClassesWithNewWrappedGlobal( + cx, static_cast<nsIGlobalObject*>(backstagePass), systemprincipal, 0, + options, &glob); + if (NS_FAILED(rv)) { + return 1; + } + + // Initialize e10s check on the main thread, if not already done + BrowserTabsRemoteAutostart(); +#if defined(XP_WIN) + // Plugin may require audio session if installed plugin can initialize + // asynchronized. + AutoAudioSession audioSession; + + // Ensure that DLL Services are running + RefPtr<DllServices> dllSvc(DllServices::Get()); + dllSvc->StartUntrustedModulesProcessor(true); + auto dllServicesDisable = + MakeScopeExit([&dllSvc]() { dllSvc->DisableFull(); }); + +# if defined(MOZ_SANDBOX) + // Required for sandboxed child processes. + if (aShellData->sandboxBrokerServices) { + SandboxBroker::Initialize(aShellData->sandboxBrokerServices); + SandboxBroker::GeckoDependentInitialize(); + } else { + NS_WARNING( + "Failed to initialize broker services, sandboxed " + "processes will fail to start."); + } +# endif // defined(MOZ_SANDBOX) + + { + DebugOnly<bool> result = WindowsBCryptInitialization(); + MOZ_ASSERT(result); + } +#endif // defined(XP_WIN) + +#ifdef MOZ_CODE_COVERAGE + CodeCoverageHandler::Init(); +#endif + + { + if (!glob) { + return 1; + } + + nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service()); + if (!appStartup) { + return 1; + } + appStartup->DoneStartingUp(); + + backstagePass->SetGlobalObject(glob); + + JSAutoRealm ar(cx, glob); + + if (!JS_InitReflectParse(cx, glob)) { + return 1; + } + + if (!JS_DefineFunctions(cx, glob, glob_functions)) { + return 1; + } + + nsAutoString workingDirectory; + if (GetCurrentWorkingDirectory(workingDirectory)) { + gWorkingDirectory = &workingDirectory; + } + + JS_DefineProperty(cx, glob, "__LOCATION__", GetLocationProperty, nullptr, + 0); + + { +#ifdef FUZZING_INTERFACES + if (fuzzHaveModule) { +# ifdef LIBFUZZER + // argv[0] was removed previously, but libFuzzer expects it + argc++; + argv--; + + result = FuzzXPCRuntimeStart(&jsapi, &argc, &argv, + aShellData->fuzzerDriver); +# elif AFLFUZZ + MOZ_CRASH("AFL is unsupported for XPC runtime fuzzing integration"); +# endif + } else { +#endif + // We are almost certainly going to run script here, so we need an + // AutoEntryScript. This is Gecko-specific and not in any spec. + AutoEntryScript aes(backstagePass, "xpcshell argument processing"); + + // If an exception is thrown, we'll set our return code + // appropriately, and then let the AutoEntryScript destructor report + // the error to the console. + if (!ProcessArgs(aes, argv, argc, &dirprovider)) { + if (gExitCode) { + result = gExitCode; + } else if (gQuitting) { + result = 0; + } else { + result = EXITCODE_RUNTIME_ERROR; + } + } +#ifdef FUZZING_INTERFACES + } +#endif + } + + // Signal that we're now shutting down. + nsCOMPtr<nsIObserver> obs = do_QueryInterface(appStartup); + if (obs) { + obs->Observe(nullptr, "quit-application-forced", nullptr); + } + + JS_DropPrincipals(cx, gJSPrincipals); + JS_SetAllNonReservedSlotsToUndefined(glob); + JS::RootedObject lexicalEnv(cx, JS_GlobalLexicalEnvironment(glob)); + JS_SetAllNonReservedSlotsToUndefined(lexicalEnv); + JS_GC(cx); + } + JS_GC(cx); + + dirprovider.ClearGREDirs(); + dirprovider.ClearAppDir(); + dirprovider.ClearAppFile(); + } // this scopes the nsCOMPtrs + + if (!XRE_ShutdownTestShell()) { + NS_ERROR("problem shutting down testshell"); + } + + // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM + rv = NS_ShutdownXPCOM(nullptr); + MOZ_ASSERT(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); + + // Shut down the crashreporter service to prevent leaking some strings it + // holds. + if (CrashReporter::GetEnabled()) { + CrashReporter::UnsetExceptionHandler(); + } + + // This must precede NS_LogTerm(), otherwise xpcshell return non-zero + // during some tests, which causes failures. + profiler_shutdown(); + + NS_LogTerm(); + + XRE_DeinitCommandLine(); + + return result; +} + +void XPCShellDirProvider::SetGREDirs(nsIFile* greDir) { + mGREDir = greDir; + mGREDir->Clone(getter_AddRefs(mGREBinDir)); + +#ifdef XP_MACOSX + nsAutoCString leafName; + mGREDir->GetNativeLeafName(leafName); + if (leafName.EqualsLiteral("Resources")) { + mGREBinDir->SetNativeLeafName("MacOS"_ns); + } +#endif +} + +void XPCShellDirProvider::SetAppFile(nsIFile* appFile) { mAppFile = appFile; } + +void XPCShellDirProvider::SetAppDir(nsIFile* appDir) { mAppDir = appDir; } + +NS_IMETHODIMP_(MozExternalRefCountType) +XPCShellDirProvider::AddRef() { return 2; } + +NS_IMETHODIMP_(MozExternalRefCountType) +XPCShellDirProvider::Release() { return 1; } + +NS_IMPL_QUERY_INTERFACE(XPCShellDirProvider, nsIDirectoryServiceProvider, + nsIDirectoryServiceProvider2) + +NS_IMETHODIMP +XPCShellDirProvider::GetFile(const char* prop, bool* persistent, + nsIFile** result) { + if (mGREDir && !strcmp(prop, NS_GRE_DIR)) { + *persistent = true; + return mGREDir->Clone(result); + } else if (mGREBinDir && !strcmp(prop, NS_GRE_BIN_DIR)) { + *persistent = true; + return mGREBinDir->Clone(result); + } else if (mAppFile && !strcmp(prop, XRE_EXECUTABLE_FILE)) { + *persistent = true; + return mAppFile->Clone(result); + } else if (mGREDir && !strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR)) { + nsCOMPtr<nsIFile> file; + *persistent = true; + if (NS_FAILED(mGREDir->Clone(getter_AddRefs(file))) || + NS_FAILED(file->AppendNative("defaults"_ns)) || + NS_FAILED(file->AppendNative("pref"_ns))) + return NS_ERROR_FAILURE; + file.forget(result); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +XPCShellDirProvider::GetFiles(const char* prop, nsISimpleEnumerator** result) { + if (mGREDir && !strcmp(prop, "ChromeML")) { + nsCOMArray<nsIFile> dirs; + + nsCOMPtr<nsIFile> file; + mGREDir->Clone(getter_AddRefs(file)); + file->AppendNative("chrome"_ns); + dirs.AppendObject(file); + + nsresult rv = + NS_GetSpecialDirectory(NS_APP_CHROME_DIR, getter_AddRefs(file)); + if (NS_SUCCEEDED(rv)) { + dirs.AppendObject(file); + } + + return NS_NewArrayEnumerator(result, dirs, NS_GET_IID(nsIFile)); + } else if (!strcmp(prop, NS_APP_PREFS_DEFAULTS_DIR_LIST)) { + nsCOMArray<nsIFile> dirs; + nsCOMPtr<nsIFile> appDir; + bool exists; + if (mAppDir && NS_SUCCEEDED(mAppDir->Clone(getter_AddRefs(appDir))) && + NS_SUCCEEDED(appDir->AppendNative("defaults"_ns)) && + NS_SUCCEEDED(appDir->AppendNative("preferences"_ns)) && + NS_SUCCEEDED(appDir->Exists(&exists)) && exists) { + dirs.AppendObject(appDir); + return NS_NewArrayEnumerator(result, dirs, NS_GET_IID(nsIFile)); + } + return NS_ERROR_FAILURE; + } + return NS_ERROR_FAILURE; +} diff --git a/js/xpconnect/src/XPCString.cpp b/js/xpconnect/src/XPCString.cpp new file mode 100644 index 0000000000..634d7efcbd --- /dev/null +++ b/js/xpconnect/src/XPCString.cpp @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Infrastructure for sharing DOMString data with JSStrings. + * + * Importing an nsAString into JS: + * If possible (GetSharedBufferHandle works) use the external string support in + * JS to create a JSString that points to the readable's buffer. We keep a + * reference to the buffer handle until the JSString is finalized. + * + * Exporting a JSString as an nsAReadable: + * Wrap the JSString with a root-holding XPCJSReadableStringWrapper, which roots + * the string and exposes its buffer via the nsAString interface, as + * well as providing refcounting support. + */ + +#include "nscore.h" +#include "nsString.h" +#include "nsStringBuffer.h" +#include "jsapi.h" +#include "xpcpublic.h" + +using namespace JS; + +const XPCStringConvert::LiteralExternalString + XPCStringConvert::sLiteralExternalString; + +const XPCStringConvert::DOMStringExternalString + XPCStringConvert::sDOMStringExternalString; + +const XPCStringConvert::DynamicAtomExternalString + XPCStringConvert::sDynamicAtomExternalString; + +void XPCStringConvert::LiteralExternalString::finalize(char16_t* aChars) const { + // Nothing to do. +} + +size_t XPCStringConvert::LiteralExternalString::sizeOfBuffer( + const char16_t* aChars, mozilla::MallocSizeOf aMallocSizeOf) const { + // This string's buffer is not heap-allocated, so its malloc size is 0. + return 0; +} + +void XPCStringConvert::DOMStringExternalString::finalize( + char16_t* aChars) const { + nsStringBuffer* buf = nsStringBuffer::FromData(aChars); + buf->Release(); +} + +size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer( + const char16_t* aChars, mozilla::MallocSizeOf aMallocSizeOf) const { + // We promised the JS engine we would not GC. Enforce that: + JS::AutoCheckCannotGC autoCannotGC; + + const nsStringBuffer* buf = + nsStringBuffer::FromData(const_cast<char16_t*>(aChars)); + // We want sizeof including this, because the entire string buffer is owned by + // the external string. But only report here if we're unshared; if we're + // shared then we don't know who really owns this data. + return buf->SizeOfIncludingThisIfUnshared(aMallocSizeOf); +} + +void XPCStringConvert::DynamicAtomExternalString::finalize( + char16_t* aChars) const { + nsDynamicAtom* atom = nsDynamicAtom::FromChars(aChars); + // nsDynamicAtom::Release is always-inline and defined in a translation unit + // we can't get to here. So we need to go through nsAtom::Release to call + // it. + static_cast<nsAtom*>(atom)->Release(); +} + +size_t XPCStringConvert::DynamicAtomExternalString::sizeOfBuffer( + const char16_t* aChars, mozilla::MallocSizeOf aMallocSizeOf) const { + // We return 0 here because NS_AddSizeOfAtoms reports all memory associated + // with atoms in the atom table. + return 0; +} + +// convert a readable to a JSString, copying string data +// static +bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable, + nsStringBuffer** sharedBuffer, + MutableHandleValue vp) { + *sharedBuffer = nullptr; + + uint32_t length = readable.Length(); + + if (readable.IsLiteral()) { + return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp); + } + + nsStringBuffer* buf = nsStringBuffer::FromString(readable); + if (buf) { + bool shared; + if (!StringBufferToJSVal(cx, buf, length, vp, &shared)) { + return false; + } + if (shared) { + *sharedBuffer = buf; + } + return true; + } + + // blech, have to copy. + JSString* str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length); + if (!str) { + return false; + } + vp.setString(str); + return true; +} + +namespace xpc { + +bool NonVoidStringToJsval(JSContext* cx, nsAString& str, + MutableHandleValue rval) { + nsStringBuffer* sharedBuffer; + if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) { + return false; + } + + if (sharedBuffer) { + // The string was shared but ReadableToJSVal didn't addref it. + // Move the ownership from str to jsstr. + str.ForgetSharedBuffer(); + } + return true; +} + +} // namespace xpc diff --git a/js/xpconnect/src/XPCThrower.cpp b/js/xpconnect/src/XPCThrower.cpp new file mode 100644 index 0000000000..bee0a0b0f5 --- /dev/null +++ b/js/xpconnect/src/XPCThrower.cpp @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Code for throwing errors into JavaScript. */ + +#include "xpcprivate.h" +#include "XPCWrapper.h" +#include "js/CharacterEncoding.h" +#include "js/Printf.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/Exceptions.h" +#include "nsString.h" + +using namespace mozilla; +using namespace mozilla::dom; + +bool XPCThrower::sVerbose = true; + +// static +void XPCThrower::Throw(nsresult rv, JSContext* cx) { + const char* format; + if (JS_IsExceptionPending(cx)) { + return; + } + if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &format)) { + format = ""; + } + dom::Throw(cx, rv, nsDependentCString(format)); +} + +namespace xpc { + +bool Throw(JSContext* cx, nsresult rv) { + XPCThrower::Throw(rv, cx); + return false; +} + +} // namespace xpc + +/* + * If there has already been an exception thrown, see if we're throwing the + * same sort of exception, and if we are, don't clobber the old one. ccx + * should be the current call context. + */ +// static +bool XPCThrower::CheckForPendingException(nsresult result, JSContext* cx) { + RefPtr<Exception> e = XPCJSContext::Get()->GetPendingException(); + if (!e) { + return false; + } + XPCJSContext::Get()->SetPendingException(nullptr); + + if (e->GetResult() != result) { + return false; + } + + ThrowExceptionObject(cx, e); + return true; +} + +// static +void XPCThrower::Throw(nsresult rv, XPCCallContext& ccx) { + char* sz; + const char* format; + + if (CheckForPendingException(rv, ccx)) { + return; + } + + if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &format)) { + format = ""; + } + + sz = (char*)format; + NS_ENSURE_TRUE_VOID(sz); + + if (sz && sVerbose) { + Verbosify(ccx, &sz, false); + } + + dom::Throw(ccx, rv, nsDependentCString(sz)); + + if (sz && sz != format) { + js_free(sz); + } +} + +// static +void XPCThrower::ThrowBadResult(nsresult rv, nsresult result, + XPCCallContext& ccx) { + char* sz; + const char* format; + const char* name; + + /* + * If there is a pending exception when the native call returns and + * it has the same error result as returned by the native call, then + * the native call may be passing through an error from a previous JS + * call. So we'll just throw that exception into our JS. Note that + * we don't need to worry about NS_ERROR_UNCATCHABLE_EXCEPTION, + * because presumably there would be no pending exception for that + * nsresult! + */ + + if (CheckForPendingException(result, ccx)) { + return; + } + + // else... + + if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &format) || + !format) { + format = ""; + } + + if (nsXPCException::NameAndFormatForNSResult(result, &name, nullptr) && + name) { + sz = JS_smprintf("%s 0x%x (%s)", format, (unsigned)result, name).release(); + } else { + sz = JS_smprintf("%s 0x%x", format, (unsigned)result).release(); + } + NS_ENSURE_TRUE_VOID(sz); + + if (sz && sVerbose) { + Verbosify(ccx, &sz, true); + } + + dom::Throw(ccx, result, nsDependentCString(sz)); + + if (sz) { + js_free(sz); + } +} + +// static +void XPCThrower::ThrowBadParam(nsresult rv, unsigned paramNum, + XPCCallContext& ccx) { + char* sz; + const char* format; + + if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &format)) { + format = ""; + } + + sz = JS_smprintf("%s arg %d", format, paramNum).release(); + NS_ENSURE_TRUE_VOID(sz); + + if (sz && sVerbose) { + Verbosify(ccx, &sz, true); + } + + dom::Throw(ccx, rv, nsDependentCString(sz)); + + if (sz) { + js_free(sz); + } +} + +// static +void XPCThrower::Verbosify(XPCCallContext& ccx, char** psz, bool own) { + char* sz = nullptr; + + if (ccx.HasInterfaceAndMember()) { + XPCNativeInterface* iface = ccx.GetInterface(); + jsid id = ccx.GetMember()->GetName(); + const char* name; + JS::UniqueChars bytes; + if (!id.isVoid()) { + bytes = JS_EncodeStringToLatin1(ccx, id.toString()); + name = bytes ? bytes.get() : ""; + } else { + name = "Unknown"; + } + sz = + JS_smprintf("%s [%s.%s]", *psz, iface->GetNameString(), name).release(); + } + + if (sz) { + if (own) { + js_free(*psz); + } + *psz = sz; + } +} diff --git a/js/xpconnect/src/XPCVariant.cpp b/js/xpconnect/src/XPCVariant.cpp new file mode 100644 index 0000000000..73e6279f15 --- /dev/null +++ b/js/xpconnect/src/XPCVariant.cpp @@ -0,0 +1,764 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* nsIVariant implementation for xpconnect. */ + +#include "mozilla/Range.h" + +#include "xpcprivate.h" + +#include "jsfriendapi.h" +#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject +#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit +#include "js/friend/WindowProxy.h" // js::ToWindowIfWindowProxy +#include "js/PropertyAndElement.h" // JS_GetElement +#include "js/Wrapper.h" +#include "mozilla/HoldDropJSObjects.h" + +using namespace JS; +using namespace mozilla; +using namespace xpc; + +NS_IMPL_CLASSINFO(XPCVariant, nullptr, 0, XPCVARIANT_CID) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant) + NS_INTERFACE_MAP_ENTRY(XPCVariant) + NS_INTERFACE_MAP_ENTRY(nsIVariant) + NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_IMPL_QUERY_CLASSINFO(XPCVariant) +NS_INTERFACE_MAP_END +NS_IMPL_CI_INTERFACE_GETTER(XPCVariant, XPCVariant, nsIVariant) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant) +NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant) + +XPCVariant::XPCVariant(JSContext* cx, const Value& aJSVal) : mJSVal(aJSVal) { + if (!mJSVal.isPrimitive()) { + // XXXbholley - The innerization here was from bug 638026. Blake says + // the basic problem was that we were storing the C++ inner but the JS + // outer, which meant that, after navigation, the JS inner could be + // collected, which would cause us to try to recreate the JS inner at + // some later point after teardown, which would crash. This is shouldn't + // be a problem anymore because SetParentToWindow will do the right + // thing, but I'm saving the cleanup here for another day. Blake thinks + // that we should just not store the WN if we're creating a variant for + // an outer window. + JSObject* obj = js::ToWindowIfWindowProxy(&mJSVal.toObject()); + mJSVal = JS::ObjectValue(*obj); + + JSObject* unwrapped = + js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false); + mReturnRawObject = !(unwrapped && IsWrappedNativeReflector(unwrapped)); + } else { + mReturnRawObject = false; + } + + if (aJSVal.isGCThing()) { + mozilla::HoldJSObjects(this); + } +} + +XPCVariant::~XPCVariant() { Cleanup(); } + +NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant) + tmp->mData.Traverse(cb); +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant) + tmp->Cleanup(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(XPCVariant) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJSVal) +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +// static +already_AddRefed<XPCVariant> XPCVariant::newVariant(JSContext* cx, + const Value& aJSVal) { + RefPtr<XPCVariant> variant = new XPCVariant(cx, aJSVal); + if (!variant->InitializeData(cx)) { + return nullptr; + } + + return variant.forget(); +} + +void XPCVariant::Cleanup() { + mData.Cleanup(); + + if (!GetJSValPreserveColor().isGCThing()) { + return; + } + mJSVal = JS::NullValue(); + mozilla::DropJSObjects(this); +} + +// Helper class to give us a namespace for the table based code below. +class XPCArrayHomogenizer { + private: + enum Type { + tNull = 0, // null value + tInt, // Integer + tDbl, // Double + tBool, // Boolean + tStr, // String + tID, // ID + tArr, // Array + tISup, // nsISupports (really just a plain JSObject) + tUnk, // Unknown. Used only for initial state. + + tTypeCount, // Just a count for table dimensioning. + + tVar, // nsVariant - last ditch if no other common type found. + tErr // No valid state or type has this value. + }; + + // Table has tUnk as a state (column) but not as a type (row). + static const Type StateTable[tTypeCount][tTypeCount - 1]; + + public: + static bool GetTypeForArray(JSContext* cx, HandleObject array, + uint32_t length, nsXPTType* resultType, + nsID* resultID); +}; + +// Current state is the column down the side. +// Current type is the row along the top. +// New state is in the box at the intersection. + +const XPCArrayHomogenizer::Type + XPCArrayHomogenizer::StateTable[tTypeCount][tTypeCount - 1] = { + /* tNull,tInt ,tDbl ,tBool,tStr ,tID ,tArr ,tISup */ + /* tNull */ {tNull, tVar, tVar, tVar, tStr, tID, tVar, tISup}, + /* tInt */ {tVar, tInt, tDbl, tVar, tVar, tVar, tVar, tVar}, + /* tDbl */ {tVar, tDbl, tDbl, tVar, tVar, tVar, tVar, tVar}, + /* tBool */ {tVar, tVar, tVar, tBool, tVar, tVar, tVar, tVar}, + /* tStr */ {tStr, tVar, tVar, tVar, tStr, tVar, tVar, tVar}, + /* tID */ {tID, tVar, tVar, tVar, tVar, tID, tVar, tVar}, + /* tArr */ {tErr, tErr, tErr, tErr, tErr, tErr, tErr, tErr}, + /* tISup */ {tISup, tVar, tVar, tVar, tVar, tVar, tVar, tISup}, + /* tUnk */ {tNull, tInt, tDbl, tBool, tStr, tID, tVar, tISup}}; + +// static +bool XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, HandleObject array, + uint32_t length, + nsXPTType* resultType, + nsID* resultID) { + Type state = tUnk; + Type type; + + RootedValue val(cx); + RootedObject jsobj(cx); + for (uint32_t i = 0; i < length; i++) { + if (!JS_GetElement(cx, array, i, &val)) { + return false; + } + + if (val.isInt32()) { + type = tInt; + } else if (val.isDouble()) { + type = tDbl; + } else if (val.isBoolean()) { + type = tBool; + } else if (val.isUndefined() || val.isSymbol() || val.isBigInt()) { + state = tVar; + break; + } else if (val.isNull()) { + type = tNull; + } else if (val.isString()) { + type = tStr; + } else { + MOZ_RELEASE_ASSERT(val.isObject(), "invalid type of jsval!"); + jsobj = &val.toObject(); + + bool isArray; + if (!JS::IsArrayObject(cx, jsobj, &isArray)) { + return false; + } + + if (isArray) { + type = tArr; + } else if (xpc::JSValue2ID(cx, val)) { + type = tID; + } else { + type = tISup; + } + } + + MOZ_ASSERT(state != tErr, "bad state table!"); + MOZ_ASSERT(type != tErr, "bad type!"); + MOZ_ASSERT(type != tVar, "bad type!"); + MOZ_ASSERT(type != tUnk, "bad type!"); + + state = StateTable[state][type]; + + MOZ_ASSERT(state != tErr, "bad state table!"); + MOZ_ASSERT(state != tUnk, "bad state table!"); + + if (state == tVar) { + break; + } + } + + switch (state) { + case tInt: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INT32); + break; + case tDbl: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::DOUBLE); + break; + case tBool: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::BOOL); + break; + case tStr: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::PWSTRING); + break; + case tID: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::NSIDPTR); + break; + case tISup: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE); + *resultID = NS_GET_IID(nsISupports); + break; + case tNull: + // FALL THROUGH + case tVar: + *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE); + *resultID = NS_GET_IID(nsIVariant); + break; + case tArr: + // FALL THROUGH + case tUnk: + // FALL THROUGH + case tErr: + // FALL THROUGH + default: + NS_ERROR("bad state"); + return false; + } + return true; +} + +bool XPCVariant::InitializeData(JSContext* cx) { + js::AutoCheckRecursionLimit recursion(cx); + if (!recursion.check(cx)) { + return false; + } + + RootedValue val(cx, GetJSVal()); + + if (val.isInt32()) { + mData.SetFromInt32(val.toInt32()); + return true; + } + if (val.isDouble()) { + mData.SetFromDouble(val.toDouble()); + return true; + } + if (val.isBoolean()) { + mData.SetFromBool(val.toBoolean()); + return true; + } + // We can't represent symbol or BigInt on C++ side, so pretend it is void. + if (val.isUndefined() || val.isSymbol() || val.isBigInt()) { + mData.SetToVoid(); + return true; + } + if (val.isNull()) { + mData.SetToEmpty(); + return true; + } + if (val.isString()) { + RootedString str(cx, val.toString()); + if (!str) { + return false; + } + + MOZ_ASSERT(mData.GetType() == nsIDataType::VTYPE_EMPTY, + "Why do we already have data?"); + + size_t length = JS_GetStringLength(str); + mData.AllocateWStringWithSize(length); + + mozilla::Range<char16_t> destChars(mData.u.wstr.mWStringValue, length); + if (!JS_CopyStringChars(cx, destChars, str)) { + return false; + } + + MOZ_ASSERT(mData.u.wstr.mWStringValue[length] == '\0'); + return true; + } + if (Maybe<nsID> id = xpc::JSValue2ID(cx, val)) { + mData.SetFromID(id.ref()); + return true; + } + + // leaving only JSObject... + MOZ_RELEASE_ASSERT(val.isObject(), "invalid type of jsval!"); + + RootedObject jsobj(cx, &val.toObject()); + + // Let's see if it is a js array object. + + uint32_t len; + + bool isArray; + if (!JS::IsArrayObject(cx, jsobj, &isArray) || + (isArray && !JS::GetArrayLength(cx, jsobj, &len))) { + return false; + } + + if (isArray) { + if (!len) { + // Zero length array + mData.SetToEmptyArray(); + return true; + } + + nsXPTType type; + nsID id; + + if (!XPCArrayHomogenizer::GetTypeForArray(cx, jsobj, len, &type, &id)) { + return false; + } + + if (!XPCConvert::JSData2Native(cx, &mData.u.array.mArrayValue, val, type, + &id, len, nullptr)) + return false; + + const nsXPTType& elty = type.ArrayElementType(); + mData.mType = nsIDataType::VTYPE_ARRAY; + if (elty.IsInterfacePointer()) { + mData.u.array.mArrayInterfaceID = id; + } + mData.u.array.mArrayCount = len; + mData.u.array.mArrayType = elty.Tag(); + + return true; + } + + // XXX This could be smarter and pick some more interesting iface. + + nsIXPConnect* xpc = nsIXPConnect::XPConnect(); + nsCOMPtr<nsISupports> wrapper; + const nsIID& iid = NS_GET_IID(nsISupports); + + if (NS_FAILED(xpc->WrapJS(cx, jsobj, iid, getter_AddRefs(wrapper)))) { + return false; + } + + mData.SetFromInterface(iid, wrapper); + return true; +} + +NS_IMETHODIMP +XPCVariant::GetAsJSVal(MutableHandleValue result) { + result.set(GetJSVal()); + return NS_OK; +} + +// static +bool XPCVariant::VariantDataToJS(JSContext* cx, nsIVariant* variant, + nsresult* pErr, MutableHandleValue pJSVal) { + // Get the type early because we might need to spoof it below. + uint16_t type = variant->GetDataType(); + + RootedValue realVal(cx); + nsresult rv = variant->GetAsJSVal(&realVal); + + if (NS_SUCCEEDED(rv) && + (realVal.isPrimitive() || type == nsIDataType::VTYPE_ARRAY || + type == nsIDataType::VTYPE_EMPTY_ARRAY || + type == nsIDataType::VTYPE_ID)) { + if (!JS_WrapValue(cx, &realVal)) { + return false; + } + pJSVal.set(realVal); + return true; + } + + nsCOMPtr<XPCVariant> xpcvariant = do_QueryInterface(variant); + if (xpcvariant && xpcvariant->mReturnRawObject) { + MOZ_ASSERT(type == nsIDataType::VTYPE_INTERFACE || + type == nsIDataType::VTYPE_INTERFACE_IS, + "Weird variant"); + + if (!JS_WrapValue(cx, &realVal)) { + return false; + } + pJSVal.set(realVal); + return true; + } + + // else, it's an object and we really need to double wrap it if we've + // already decided that its 'natural' type is as some sort of interface. + + // We just fall through to the code below and let it do what it does. + + // The nsIVariant is not a XPCVariant (or we act like it isn't). + // So we extract the data and do the Right Thing. + + // We ASSUME that the variant implementation can do these conversions... + + nsID iid; + + switch (type) { + case nsIDataType::VTYPE_INT8: + case nsIDataType::VTYPE_INT16: + case nsIDataType::VTYPE_INT32: + case nsIDataType::VTYPE_INT64: + case nsIDataType::VTYPE_UINT8: + case nsIDataType::VTYPE_UINT16: + case nsIDataType::VTYPE_UINT32: + case nsIDataType::VTYPE_UINT64: + case nsIDataType::VTYPE_FLOAT: + case nsIDataType::VTYPE_DOUBLE: { + double d; + if (NS_FAILED(variant->GetAsDouble(&d))) { + return false; + } + pJSVal.set(JS_NumberValue(d)); + return true; + } + case nsIDataType::VTYPE_BOOL: { + bool b; + if (NS_FAILED(variant->GetAsBool(&b))) { + return false; + } + pJSVal.setBoolean(b); + return true; + } + case nsIDataType::VTYPE_CHAR: { + char c; + if (NS_FAILED(variant->GetAsChar(&c))) { + return false; + } + return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&c, {TD_CHAR}, + &iid, 0, pErr); + } + case nsIDataType::VTYPE_WCHAR: { + char16_t wc; + if (NS_FAILED(variant->GetAsWChar(&wc))) { + return false; + } + return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&wc, {TD_WCHAR}, + &iid, 0, pErr); + } + case nsIDataType::VTYPE_ID: { + if (NS_FAILED(variant->GetAsID(&iid))) { + return false; + } + nsID* v = &iid; + return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&v, + {TD_NSIDPTR}, &iid, 0, pErr); + } + case nsIDataType::VTYPE_ASTRING: { + nsAutoString astring; + if (NS_FAILED(variant->GetAsAString(astring))) { + return false; + } + return XPCConvert::NativeData2JS(cx, pJSVal, &astring, {TD_ASTRING}, &iid, + 0, pErr); + } + case nsIDataType::VTYPE_CSTRING: { + nsAutoCString cString; + if (NS_FAILED(variant->GetAsACString(cString))) { + return false; + } + return XPCConvert::NativeData2JS(cx, pJSVal, &cString, {TD_CSTRING}, &iid, + 0, pErr); + } + case nsIDataType::VTYPE_UTF8STRING: { + nsUTF8String utf8String; + if (NS_FAILED(variant->GetAsAUTF8String(utf8String))) { + return false; + } + return XPCConvert::NativeData2JS(cx, pJSVal, &utf8String, {TD_UTF8STRING}, + &iid, 0, pErr); + } + case nsIDataType::VTYPE_CHAR_STR: { + char* pc; + if (NS_FAILED(variant->GetAsString(&pc))) { + return false; + } + bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pc, + {TD_PSTRING}, &iid, 0, pErr); + free(pc); + return success; + } + case nsIDataType::VTYPE_STRING_SIZE_IS: { + char* pc; + uint32_t size; + if (NS_FAILED(variant->GetAsStringWithSize(&size, &pc))) { + return false; + } + bool success = XPCConvert::NativeData2JS( + cx, pJSVal, (const void*)&pc, {TD_PSTRING_SIZE_IS}, &iid, size, pErr); + free(pc); + return success; + } + case nsIDataType::VTYPE_WCHAR_STR: { + char16_t* pwc; + if (NS_FAILED(variant->GetAsWString(&pwc))) { + return false; + } + bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc, + {TD_PSTRING}, &iid, 0, pErr); + free(pwc); + return success; + } + case nsIDataType::VTYPE_WSTRING_SIZE_IS: { + char16_t* pwc; + uint32_t size; + if (NS_FAILED(variant->GetAsWStringWithSize(&size, &pwc))) { + return false; + } + bool success = + XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc, + {TD_PWSTRING_SIZE_IS}, &iid, size, pErr); + free(pwc); + return success; + } + case nsIDataType::VTYPE_INTERFACE: + case nsIDataType::VTYPE_INTERFACE_IS: { + nsISupports* pi; + nsID* piid; + if (NS_FAILED(variant->GetAsInterface(&piid, (void**)&pi))) { + return false; + } + + iid = *piid; + free((char*)piid); + + bool success = XPCConvert::NativeData2JS( + cx, pJSVal, (const void*)&pi, {TD_INTERFACE_IS_TYPE}, &iid, 0, pErr); + if (pi) { + pi->Release(); + } + return success; + } + case nsIDataType::VTYPE_ARRAY: { + nsDiscriminatedUnion du; + nsresult rv; + + rv = variant->GetAsArray( + &du.u.array.mArrayType, &du.u.array.mArrayInterfaceID, + &du.u.array.mArrayCount, &du.u.array.mArrayValue); + if (NS_FAILED(rv)) { + return false; + } + + // must exit via VARIANT_DONE from here on... + du.mType = nsIDataType::VTYPE_ARRAY; + + uint16_t elementType = du.u.array.mArrayType; + const nsID* pid = nullptr; + + nsXPTType::Idx xptIndex; + switch (elementType) { + case nsIDataType::VTYPE_INT8: + xptIndex = nsXPTType::Idx::INT8; + break; + case nsIDataType::VTYPE_INT16: + xptIndex = nsXPTType::Idx::INT16; + break; + case nsIDataType::VTYPE_INT32: + xptIndex = nsXPTType::Idx::INT32; + break; + case nsIDataType::VTYPE_INT64: + xptIndex = nsXPTType::Idx::INT64; + break; + case nsIDataType::VTYPE_UINT8: + xptIndex = nsXPTType::Idx::UINT8; + break; + case nsIDataType::VTYPE_UINT16: + xptIndex = nsXPTType::Idx::UINT16; + break; + case nsIDataType::VTYPE_UINT32: + xptIndex = nsXPTType::Idx::UINT32; + break; + case nsIDataType::VTYPE_UINT64: + xptIndex = nsXPTType::Idx::UINT64; + break; + case nsIDataType::VTYPE_FLOAT: + xptIndex = nsXPTType::Idx::FLOAT; + break; + case nsIDataType::VTYPE_DOUBLE: + xptIndex = nsXPTType::Idx::DOUBLE; + break; + case nsIDataType::VTYPE_BOOL: + xptIndex = nsXPTType::Idx::BOOL; + break; + case nsIDataType::VTYPE_CHAR: + xptIndex = nsXPTType::Idx::CHAR; + break; + case nsIDataType::VTYPE_WCHAR: + xptIndex = nsXPTType::Idx::WCHAR; + break; + case nsIDataType::VTYPE_ID: + xptIndex = nsXPTType::Idx::NSIDPTR; + break; + case nsIDataType::VTYPE_CHAR_STR: + xptIndex = nsXPTType::Idx::PSTRING; + break; + case nsIDataType::VTYPE_WCHAR_STR: + xptIndex = nsXPTType::Idx::PWSTRING; + break; + case nsIDataType::VTYPE_INTERFACE: + pid = &NS_GET_IID(nsISupports); + xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE; + break; + case nsIDataType::VTYPE_INTERFACE_IS: + pid = &du.u.array.mArrayInterfaceID; + xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE; + break; + + // The rest are illegal. + case nsIDataType::VTYPE_VOID: + case nsIDataType::VTYPE_ASTRING: + case nsIDataType::VTYPE_CSTRING: + case nsIDataType::VTYPE_UTF8STRING: + case nsIDataType::VTYPE_WSTRING_SIZE_IS: + case nsIDataType::VTYPE_STRING_SIZE_IS: + case nsIDataType::VTYPE_ARRAY: + case nsIDataType::VTYPE_EMPTY_ARRAY: + case nsIDataType::VTYPE_EMPTY: + default: + NS_ERROR("bad type in array!"); + return false; + } + + bool success = XPCConvert::NativeData2JS( + cx, pJSVal, (const void*)&du.u.array.mArrayValue, + nsXPTType::MkArrayType(xptIndex), pid, du.u.array.mArrayCount, pErr); + + return success; + } + case nsIDataType::VTYPE_EMPTY_ARRAY: { + JSObject* array = JS::NewArrayObject(cx, 0); + if (!array) { + return false; + } + pJSVal.setObject(*array); + return true; + } + case nsIDataType::VTYPE_VOID: + pJSVal.setUndefined(); + return true; + case nsIDataType::VTYPE_EMPTY: + pJSVal.setNull(); + return true; + default: + NS_ERROR("bad type in variant!"); + return false; + } +} + +/***************************************************************************/ +/***************************************************************************/ +// XXX These default implementations need to be improved to allow for +// some more interesting conversions. + +uint16_t XPCVariant::GetDataType() { return mData.GetType(); } + +NS_IMETHODIMP XPCVariant::GetAsInt8(uint8_t* _retval) { + return mData.ConvertToInt8(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsInt16(int16_t* _retval) { + return mData.ConvertToInt16(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsInt32(int32_t* _retval) { + return mData.ConvertToInt32(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsInt64(int64_t* _retval) { + return mData.ConvertToInt64(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsUint8(uint8_t* _retval) { + return mData.ConvertToUint8(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsUint16(uint16_t* _retval) { + return mData.ConvertToUint16(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsUint32(uint32_t* _retval) { + return mData.ConvertToUint32(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsUint64(uint64_t* _retval) { + return mData.ConvertToUint64(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsFloat(float* _retval) { + return mData.ConvertToFloat(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsDouble(double* _retval) { + return mData.ConvertToDouble(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsBool(bool* _retval) { + return mData.ConvertToBool(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsChar(char* _retval) { + return mData.ConvertToChar(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsWChar(char16_t* _retval) { + return mData.ConvertToWChar(_retval); +} + +NS_IMETHODIMP_(nsresult) XPCVariant::GetAsID(nsID* retval) { + return mData.ConvertToID(retval); +} + +NS_IMETHODIMP XPCVariant::GetAsAString(nsAString& _retval) { + return mData.ConvertToAString(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsACString(nsACString& _retval) { + return mData.ConvertToACString(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsAUTF8String(nsAUTF8String& _retval) { + return mData.ConvertToAUTF8String(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsString(char** _retval) { + return mData.ConvertToString(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsWString(char16_t** _retval) { + return mData.ConvertToWString(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsISupports(nsISupports** _retval) { + return mData.ConvertToISupports(_retval); +} + +NS_IMETHODIMP XPCVariant::GetAsInterface(nsIID** iid, void** iface) { + return mData.ConvertToInterface(iid, iface); +} + +NS_IMETHODIMP_(nsresult) +XPCVariant::GetAsArray(uint16_t* type, nsIID* iid, uint32_t* count, + void** ptr) { + return mData.ConvertToArray(type, iid, count, ptr); +} + +NS_IMETHODIMP XPCVariant::GetAsStringWithSize(uint32_t* size, char** str) { + return mData.ConvertToStringWithSize(size, str); +} + +NS_IMETHODIMP XPCVariant::GetAsWStringWithSize(uint32_t* size, char16_t** str) { + return mData.ConvertToWStringWithSize(size, str); +} diff --git a/js/xpconnect/src/XPCWrappedJS.cpp b/js/xpconnect/src/XPCWrappedJS.cpp new file mode 100644 index 0000000000..d01c801600 --- /dev/null +++ b/js/xpconnect/src/XPCWrappedJS.cpp @@ -0,0 +1,686 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Class that wraps JS objects to appear as XPCOM objects. */ + +#include "xpcprivate.h" +#include "XPCMaps.h" +#include "mozilla/DeferredFinalize.h" +#include "mozilla/HoldDropJSObjects.h" +#include "mozilla/Sprintf.h" +#include "js/Object.h" // JS::GetCompartment +#include "js/RealmIterators.h" +#include "nsCCUncollectableMarker.h" +#include "nsContentUtils.h" +#include "nsThreadUtils.h" + +using namespace mozilla; + +// NOTE: much of the fancy footwork is done in xpcstubs.cpp + +// nsXPCWrappedJS lifetime. +// +// An nsXPCWrappedJS is either rooting its JS object or is subject to +// finalization. The subject-to-finalization state lets wrappers support +// nsSupportsWeakReference in the case where the underlying JS object +// is strongly owned, but the wrapper itself is only weakly owned. +// +// A wrapper is rooting its JS object whenever its refcount is greater than 1. +// In this state, root wrappers are always added to the cycle collector graph. +// The wrapper keeps around an extra refcount, added in the constructor, to +// support the possibility of an eventual transition to the +// subject-to-finalization state. This extra refcount is ignored by the cycle +// collector, which traverses the "self" edge for this refcount. +// +// When the refcount of a rooting wrapper drops to 1, if there is no weak +// reference to the wrapper (which can only happen for the root wrapper), it is +// immediately Destroy()'d. Otherwise, it becomes subject to finalization. +// +// When a wrapper is subject to finalization, the wrapper has a refcount of 1. +// It is now owned exclusively by its JS object. Either a weak reference will be +// turned into a strong ref which will bring its refcount up to 2 and change the +// wrapper back to the rooting state, or it will stay alive until the JS object +// dies. If the JS object dies, then when +// JSObject2WrappedJSMap::UpdateWeakPointersAfterGC is called (via the JS +// engine's weak pointer zone or compartment callbacks) it will find the wrapper +// and call Release() on it, destroying the wrapper. Otherwise, the wrapper will +// stay alive, even if it no longer has a weak reference to it. +// +// When the wrapper is subject to finalization, it is kept alive by an implicit +// reference from the JS object which is invisible to the cycle collector, so +// the cycle collector does not traverse any children of wrappers that are +// subject to finalization. This will result in a leak if a wrapper in the +// non-rooting state has an aggregated native that keeps alive the wrapper's JS +// object. See bug 947049. + +// If traversing wrappedJS wouldn't release it, nor cause any other objects to +// be added to the graph, there is no need to add it to the graph at all. +bool nsXPCWrappedJS::CanSkip() { + if (!nsCCUncollectableMarker::sGeneration) { + return false; + } + + // If this wrapper holds a gray object, need to trace it. + // We can't skip it even if it is subject to finalization, because we want to + // be able to collect it if the JS object is gray. + JSObject* obj = GetJSObjectPreserveColor(); + if (obj && JS::ObjectIsMarkedGray(obj)) { + return false; + } + + // For non-root wrappers, check if the root wrapper will be + // added to the CC graph. + if (!IsRootWrapper()) { + // mRoot points to null after unlinking. + NS_ENSURE_TRUE(mRoot, false); + return mRoot->CanSkip(); + } + + // At this point, the WJS must be a root wrapper with a black JS object, so + // if it is subject to finalization, the JS object will be holding it alive + // so it will be okay to skip it. + + // For the root wrapper, check if there is an aggregated + // native object that will be added to the CC graph. + if (!IsAggregatedToNative()) { + return true; + } + + nsISupports* agg = GetAggregatedNativeObject(); + nsXPCOMCycleCollectionParticipant* cp = nullptr; + CallQueryInterface(agg, &cp); + nsISupports* canonical = nullptr; + agg->QueryInterface(NS_GET_IID(nsCycleCollectionISupports), + reinterpret_cast<void**>(&canonical)); + return cp && canonical && cp->CanSkipThis(canonical); +} + +NS_IMETHODIMP +NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::TraverseNative( + void* p, nsCycleCollectionTraversalCallback& cb) { + nsISupports* s = static_cast<nsISupports*>(p); + MOZ_ASSERT(CheckForRightISupports(s), + "not the nsISupports pointer we expect"); + nsXPCWrappedJS* tmp = Downcast(s); + + nsrefcnt refcnt = tmp->mRefCnt.get(); + if (cb.WantDebugInfo()) { + char name[72]; + SprintfLiteral(name, "nsXPCWrappedJS (%s)", tmp->mInfo->Name()); + cb.DescribeRefCountedNode(refcnt, name); + } else { + NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsXPCWrappedJS, refcnt) + } + + if (tmp->IsSubjectToFinalization()) { + // If the WJS is subject to finalization, then it can be held alive by its + // JS object. We represent this edge by using NoteWeakMapping. The linked + // list of subject-to-finalization WJS acts like a known-black weak map. + cb.NoteWeakMapping(tmp->GetJSObjectPreserveColor(), s, + NS_CYCLE_COLLECTION_PARTICIPANT(nsXPCWrappedJS)); + } + + // Don't let the extra reference for nsSupportsWeakReference keep a WJS alive. + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "self"); + cb.NoteXPCOMChild(s); + + if (tmp->IsRootWrapper()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "aggregated native"); + cb.NoteXPCOMChild(tmp->GetAggregatedNativeObject()); + } else { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "root"); + cb.NoteXPCOMChild(ToSupports(tmp->GetRootWrapper())); + } + + return NS_OK; +} + +NS_IMPL_CYCLE_COLLECTION_SINGLE_ZONE_SCRIPT_HOLDER_CLASS(nsXPCWrappedJS) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXPCWrappedJS) + tmp->Unlink(); + // Note: Unlink already calls ClearWeakReferences, so no need for + // NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCE here. +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXPCWrappedJS) + // See the comment at the top of this file for the explanation of + // the weird tracing condition. + if (!tmp->IsSubjectToFinalization()) { + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJSObj) + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +// WJS are JS holders, so we'll always add them as roots in CCs and we can +// remove them from the purple buffer in between CCs. +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXPCWrappedJS) + return true; +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsXPCWrappedJS) + return tmp->CanSkip(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsXPCWrappedJS) + return tmp->CanSkip(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + +nsXPCWrappedJS* nsIXPConnectWrappedJS::AsXPCWrappedJS() { + return static_cast<nsXPCWrappedJS*>(this); +} + +nsresult nsIXPConnectWrappedJS::AggregatedQueryInterface(REFNSIID aIID, + void** aInstancePtr) { + MOZ_ASSERT(AsXPCWrappedJS()->IsAggregatedToNative(), + "bad AggregatedQueryInterface call"); + *aInstancePtr = nullptr; + + if (!AsXPCWrappedJS()->IsValid()) { + return NS_ERROR_UNEXPECTED; + } + + // Put this here rather that in DelegatedQueryInterface because it needs + // to be in QueryInterface before the possible delegation to 'outer', but + // we don't want to do this check twice in one call in the normal case: + // once in QueryInterface and once in DelegatedQueryInterface. + if (aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS))) { + NS_ADDREF(this); + *aInstancePtr = (void*)this; + return NS_OK; + } + + return AsXPCWrappedJS()->DelegatedQueryInterface(aIID, aInstancePtr); +} + +NS_IMETHODIMP +nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr) { + if (nullptr == aInstancePtr) { + MOZ_ASSERT(false, "null pointer"); + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = nullptr; + + if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) { + *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(nsXPCWrappedJS); + return NS_OK; + } + + if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports))) { + *aInstancePtr = NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Upcast(this); + return NS_OK; + } + + if (!IsValid()) { + return NS_ERROR_UNEXPECTED; + } + + if (aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJSUnmarkGray))) { + *aInstancePtr = nullptr; + + mJSObj.exposeToActiveJS(); + + // Just return some error value since one isn't supposed to use + // nsIXPConnectWrappedJSUnmarkGray objects for anything. + return NS_ERROR_FAILURE; + } + + // Always check for this first so that our 'outer' can get this interface + // from us without recurring into a call to the outer's QI! + if (aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS))) { + NS_ADDREF(this); + *aInstancePtr = (void*)static_cast<nsIXPConnectWrappedJS*>(this); + return NS_OK; + } + + nsISupports* outer = GetAggregatedNativeObject(); + if (outer) { + return outer->QueryInterface(aIID, aInstancePtr); + } + + // else... + + return DelegatedQueryInterface(aIID, aInstancePtr); +} + +// For a description of nsXPCWrappedJS lifetime and reference counting, see +// the comment at the top of this file. + +MozExternalRefCountType nsXPCWrappedJS::AddRef(void) { + MOZ_RELEASE_ASSERT(NS_IsMainThread(), + "nsXPCWrappedJS::AddRef called off main thread"); + + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); + nsISupports* base = + NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Upcast(this); + nsrefcnt cnt = mRefCnt.incr(base); + NS_LOG_ADDREF(this, cnt, "nsXPCWrappedJS", sizeof(*this)); + + if (2 == cnt && IsValid()) { + GetJSObject(); // Unmark gray JSObject. + + // This WJS is no longer subject to finalization. + if (isInList()) { + remove(); + } + } + + return cnt; +} + +MozExternalRefCountType nsXPCWrappedJS::Release(void) { + MOZ_RELEASE_ASSERT(NS_IsMainThread(), + "nsXPCWrappedJS::Release called off main thread"); + MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); + NS_ASSERT_OWNINGTHREAD(nsXPCWrappedJS); + + bool shouldDelete = false; + nsISupports* base = + NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Upcast(this); + nsrefcnt cnt = mRefCnt.decr(base, &shouldDelete); + NS_LOG_RELEASE(this, cnt, "nsXPCWrappedJS"); + + if (0 == cnt) { + if (MOZ_UNLIKELY(shouldDelete)) { + mRefCnt.stabilizeForDeletion(); + DeleteCycleCollectable(); + } else { + mRefCnt.incr(base); + Destroy(); + mRefCnt.decr(base); + } + } else if (1 == cnt) { + // If we are not a root wrapper being used from a weak reference, + // then the extra ref is not needed and we can let ourselves be + // deleted. + if (!HasWeakReferences()) { + return Release(); + } + + if (IsValid()) { + XPCJSRuntime::Get()->AddSubjectToFinalizationWJS(this); + } + + MOZ_ASSERT(IsRootWrapper(), + "Only root wrappers should have weak references"); + } + return cnt; +} + +NS_IMETHODIMP_(void) +nsXPCWrappedJS::DeleteCycleCollectable(void) { delete this; } + +NS_IMETHODIMP +nsXPCWrappedJS::GetWeakReference(nsIWeakReference** aInstancePtr) { + if (!IsRootWrapper()) { + return mRoot->GetWeakReference(aInstancePtr); + } + + return nsSupportsWeakReference::GetWeakReference(aInstancePtr); +} + +JSObject* nsXPCWrappedJS::GetJSObject() { return mJSObj; } + +JSObject* nsIXPConnectWrappedJS::GetJSObjectGlobal() { + JSObject* obj = AsXPCWrappedJS()->mJSObj; + if (js::IsCrossCompartmentWrapper(obj)) { + JS::Compartment* comp = JS::GetCompartment(obj); + return js::GetFirstGlobalInCompartment(comp); + } + return JS::GetNonCCWObjectGlobal(obj); +} + +// static +nsresult nsXPCWrappedJS::GetNewOrUsed(JSContext* cx, JS::HandleObject jsObj, + REFNSIID aIID, + nsXPCWrappedJS** wrapperResult) { + // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread. + MOZ_RELEASE_ASSERT(NS_IsMainThread(), + "nsXPCWrappedJS::GetNewOrUsed called off main thread"); + + MOZ_RELEASE_ASSERT(js::GetContextCompartment(cx) == + JS::GetCompartment(jsObj)); + + const nsXPTInterfaceInfo* info = GetInterfaceInfo(aIID); + if (!info) { + return NS_ERROR_FAILURE; + } + + JS::RootedObject rootJSObj(cx, GetRootJSObject(cx, jsObj)); + if (!rootJSObj) { + return NS_ERROR_FAILURE; + } + + xpc::CompartmentPrivate* rootComp = xpc::CompartmentPrivate::Get(rootJSObj); + MOZ_ASSERT(rootComp); + + // Find any existing wrapper. + RefPtr<nsXPCWrappedJS> root = rootComp->GetWrappedJSMap()->Find(rootJSObj); + MOZ_ASSERT_IF(root, !nsXPConnect::GetRuntimeInstance() + ->GetMultiCompartmentWrappedJSMap() + ->Find(rootJSObj)); + if (!root) { + root = nsXPConnect::GetRuntimeInstance() + ->GetMultiCompartmentWrappedJSMap() + ->Find(rootJSObj); + } + + nsresult rv = NS_ERROR_FAILURE; + if (root) { + RefPtr<nsXPCWrappedJS> wrapper = root->FindOrFindInherited(aIID); + if (wrapper) { + wrapper.forget(wrapperResult); + return NS_OK; + } + } else if (rootJSObj != jsObj) { + // Make a new root wrapper, because there is no existing + // root wrapper, and the wrapper we are trying to make isn't + // a root. + const nsXPTInterfaceInfo* rootInfo = + GetInterfaceInfo(NS_GET_IID(nsISupports)); + if (!rootInfo) { + return NS_ERROR_FAILURE; + } + + root = new nsXPCWrappedJS(cx, rootJSObj, rootInfo, nullptr, &rv); + if (NS_FAILED(rv)) { + return rv; + } + } + + RefPtr<nsXPCWrappedJS> wrapper = + new nsXPCWrappedJS(cx, jsObj, info, root, &rv); + if (NS_FAILED(rv)) { + return rv; + } + wrapper.forget(wrapperResult); + return NS_OK; +} + +nsXPCWrappedJS::nsXPCWrappedJS(JSContext* cx, JSObject* aJSObj, + const nsXPTInterfaceInfo* aInfo, + nsXPCWrappedJS* root, nsresult* rv) + : mJSObj(aJSObj), mInfo(aInfo), mRoot(root ? root : this), mNext(nullptr) { + *rv = InitStub(mInfo->IID()); + // Continue even in the failure case, so that our refcounting/Destroy + // behavior works correctly. + + // There is an extra AddRef to support weak references to wrappers + // that are subject to finalization. See the top of the file for more + // details. + NS_ADDREF_THIS(); + + if (IsRootWrapper()) { + MOZ_ASSERT(!IsMultiCompartment(), "mNext is always nullptr here"); + if (!xpc::CompartmentPrivate::Get(mJSObj)->GetWrappedJSMap()->Add(cx, + this)) { + *rv = NS_ERROR_OUT_OF_MEMORY; + } + } else { + NS_ADDREF(mRoot); + mNext = mRoot->mNext; + mRoot->mNext = this; + + // We always start wrappers in the per-compartment table. If adding + // this wrapper to the chain causes it to cross compartments, we need + // to migrate the chain to the global table on the XPCJSContext. + if (mRoot->IsMultiCompartment()) { + xpc::CompartmentPrivate::Get(mRoot->mJSObj) + ->GetWrappedJSMap() + ->Remove(mRoot); + auto destMap = + nsXPConnect::GetRuntimeInstance()->GetMultiCompartmentWrappedJSMap(); + if (!destMap->Add(cx, mRoot)) { + *rv = NS_ERROR_OUT_OF_MEMORY; + } + } + } + + mozilla::HoldJSObjects(this); +} + +nsXPCWrappedJS::~nsXPCWrappedJS() { Destroy(); } + +void XPCJSRuntime::RemoveWrappedJS(nsXPCWrappedJS* wrapper) { + AssertInvalidWrappedJSNotInTable(wrapper); + if (!wrapper->IsValid()) { + return; + } + + // It is possible for the same JS XPCOM implementation object to be wrapped + // with a different interface in multiple JS::Compartments. In this case, the + // wrapper chain will contain references to multiple compartments. While we + // always store single-compartment chains in the per-compartment wrapped-js + // table, chains in the multi-compartment wrapped-js table may contain + // single-compartment chains, if they have ever contained a wrapper in a + // different compartment. Since removal requires a lookup anyway, we just do + // the remove on both tables unconditionally. + MOZ_ASSERT_IF( + wrapper->IsMultiCompartment(), + !xpc::CompartmentPrivate::Get(wrapper->GetJSObjectPreserveColor()) + ->GetWrappedJSMap() + ->HasWrapper(wrapper)); + GetMultiCompartmentWrappedJSMap()->Remove(wrapper); + xpc::CompartmentPrivate::Get(wrapper->GetJSObjectPreserveColor()) + ->GetWrappedJSMap() + ->Remove(wrapper); +} + +#ifdef DEBUG +static JS::CompartmentIterResult NotHasWrapperAssertionCallback( + JSContext* cx, void* data, JS::Compartment* comp) { + auto wrapper = static_cast<nsXPCWrappedJS*>(data); + auto xpcComp = xpc::CompartmentPrivate::Get(comp); + MOZ_ASSERT_IF(xpcComp, !xpcComp->GetWrappedJSMap()->HasWrapper(wrapper)); + return JS::CompartmentIterResult::KeepGoing; +} +#endif + +void XPCJSRuntime::AssertInvalidWrappedJSNotInTable( + nsXPCWrappedJS* wrapper) const { +#ifdef DEBUG + if (!wrapper->IsValid()) { + MOZ_ASSERT(!GetMultiCompartmentWrappedJSMap()->HasWrapper(wrapper)); + if (!mGCIsRunning) { + JSContext* cx = XPCJSContext::Get()->Context(); + JS_IterateCompartments(cx, wrapper, NotHasWrapperAssertionCallback); + } + } +#endif +} + +void nsXPCWrappedJS::Destroy() { + MOZ_ASSERT(1 == int32_t(mRefCnt), "should be stabilized for deletion"); + + if (IsRootWrapper()) { + nsXPConnect::GetRuntimeInstance()->RemoveWrappedJS(this); + } + Unlink(); +} + +void nsXPCWrappedJS::Unlink() { + nsXPConnect::GetRuntimeInstance()->AssertInvalidWrappedJSNotInTable(this); + + if (IsValid()) { + XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); + if (rt) { + if (IsRootWrapper()) { + rt->RemoveWrappedJS(this); + } + } + + mJSObj = nullptr; + } + + if (IsRootWrapper()) { + if (isInList()) { + remove(); + } + ClearWeakReferences(); + } else if (mRoot) { + // unlink this wrapper + nsXPCWrappedJS* cur = mRoot; + while (1) { + if (cur->mNext == this) { + cur->mNext = mNext; + break; + } + cur = cur->mNext; + MOZ_ASSERT(cur, "failed to find wrapper in its own chain"); + } + + // Note: unlinking this wrapper may have changed us from a multi- + // compartment wrapper chain to a single-compartment wrapper chain. We + // leave the wrapper in the multi-compartment table as it is likely to + // need to be multi-compartment again in the future and, moreover, we + // cannot get a JSContext here. + + // let the root go + NS_RELEASE(mRoot); + } + + if (mOuter) { + XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); + if (rt->GCIsRunning()) { + DeferredFinalize(mOuter.forget().take()); + } else { + mOuter = nullptr; + } + } + + mozilla::DropJSObjects(this); +} + +bool nsXPCWrappedJS::IsMultiCompartment() const { + MOZ_ASSERT(IsRootWrapper()); + JS::Compartment* compartment = Compartment(); + nsXPCWrappedJS* next = mNext; + while (next) { + if (next->Compartment() != compartment) { + return true; + } + next = next->mNext; + } + return false; +} + +nsXPCWrappedJS* nsXPCWrappedJS::Find(REFNSIID aIID) { + if (aIID.Equals(NS_GET_IID(nsISupports))) { + return mRoot; + } + + for (nsXPCWrappedJS* cur = mRoot; cur; cur = cur->mNext) { + if (aIID.Equals(cur->GetIID())) { + return cur; + } + } + + return nullptr; +} + +// check if asking for an interface that some wrapper in the chain inherits from +nsXPCWrappedJS* nsXPCWrappedJS::FindInherited(REFNSIID aIID) { + MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsISupports)), "bad call sequence"); + + for (nsXPCWrappedJS* cur = mRoot; cur; cur = cur->mNext) { + if (cur->mInfo->HasAncestor(aIID)) { + return cur; + } + } + + return nullptr; +} + +nsresult nsIXPConnectWrappedJS::GetInterfaceIID(nsIID** iid) { + MOZ_ASSERT(iid, "bad param"); + + *iid = AsXPCWrappedJS()->GetIID().Clone(); + return NS_OK; +} + +void nsXPCWrappedJS::SystemIsBeingShutDown() { + // XXX It turns out that it is better to leak here then to do any Releases + // and have them propagate into all sorts of mischief as the system is being + // shutdown. This was learned the hard way :( + + // mJSObj == nullptr is used to indicate that the wrapper is no longer valid + // and that calls should fail without trying to use any of the + // xpconnect mechanisms. 'IsValid' is implemented by checking this pointer. + + // Clear the contents of the pointer using unsafeGet() to avoid + // triggering post barriers in shutdown, as this will access the chunk + // containing mJSObj, which may have been freed at this point. This is safe + // if we are not currently running an incremental GC. + MOZ_ASSERT(!JS::IsIncrementalGCInProgress(xpc_GetSafeJSContext())); + *mJSObj.unsafeGet() = nullptr; + if (isInList()) { + remove(); + } + + // Notify other wrappers in the chain. + if (mNext) { + mNext->SystemIsBeingShutDown(); + } +} + +size_t nsXPCWrappedJS::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + // mJSObject is a JS pointer, so don't measure the object. mInfo is + // not dynamically allocated. mRoot is not measured because it is + // either |this| or we have already measured it. mOuter is rare and + // probably not uniquely owned by this. + size_t n = mallocSizeOf(this); + n += nsAutoXPTCStub::SizeOfExcludingThis(mallocSizeOf); + + // Wrappers form a linked list via the mNext field, so include them all + // in the measurement. Only root wrappers are stored in the map, so + // everything will be measured exactly once. + if (mNext) { + n += mNext->SizeOfIncludingThis(mallocSizeOf); + } + + return n; +} + +/***************************************************************************/ + +nsresult nsIXPConnectWrappedJS::DebugDump(int16_t depth) { + return AsXPCWrappedJS()->DebugDump(depth); +} + +nsresult nsXPCWrappedJS::DebugDump(int16_t depth) { +#ifdef DEBUG + XPC_LOG_ALWAYS( + ("nsXPCWrappedJS @ %p with mRefCnt = %" PRIuPTR, this, mRefCnt.get())); + XPC_LOG_INDENT(); + + XPC_LOG_ALWAYS(("%s wrapper around JSObject @ %p", + IsRootWrapper() ? "ROOT" : "non-root", mJSObj.get())); + const char* name = mInfo->Name(); + XPC_LOG_ALWAYS(("interface name is %s", name)); + auto iid = mInfo->IID().ToString(); + XPC_LOG_ALWAYS(("IID number is %s", iid.get())); + XPC_LOG_ALWAYS(("nsXPTInterfaceInfo @ %p", mInfo)); + + if (!IsRootWrapper()) { + XPC_LOG_OUTDENT(); + } + if (mNext) { + if (IsRootWrapper()) { + XPC_LOG_ALWAYS(("Additional wrappers for this object...")); + XPC_LOG_INDENT(); + } + mNext->DebugDump(depth); + if (IsRootWrapper()) { + XPC_LOG_OUTDENT(); + } + } + if (IsRootWrapper()) { + XPC_LOG_OUTDENT(); + } +#endif + return NS_OK; +} diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp new file mode 100644 index 0000000000..0c1627fdc4 --- /dev/null +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -0,0 +1,1094 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Sharable code and data for wrapper around JSObjects. */ + +#include "xpcprivate.h" +#include "js/CallAndConstruct.h" // JS_CallFunctionValue +#include "js/Object.h" // JS::GetClass +#include "js/Printf.h" +#include "js/PropertyAndElement.h" // JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_HasPropertyById, JS_SetProperty, JS_SetPropertyById +#include "nsArrayEnumerator.h" +#include "nsINamed.h" +#include "nsIScriptError.h" +#include "nsWrapperCache.h" +#include "AccessCheck.h" +#include "nsJSUtils.h" +#include "nsPrintfCString.h" +#include "mozilla/Attributes.h" +#include "mozilla/dom/AutoEntryScript.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/DOMExceptionBinding.h" +#include "mozilla/dom/MozQueryInterface.h" + +#include "jsapi.h" +#include "jsfriendapi.h" + +using namespace xpc; +using namespace JS; +using namespace mozilla; +using namespace mozilla::dom; + +bool AutoScriptEvaluate::StartEvaluating(HandleObject scope) { + MOZ_ASSERT(!mEvaluated, + "AutoScriptEvaluate::Evaluate should only be called once"); + + if (!mJSContext) { + return true; + } + + mEvaluated = true; + + mAutoRealm.emplace(mJSContext, scope); + + // Saving the exception state keeps us from interfering with another script + // that may also be running on this context. This occurred first with the + // js debugger, as described in + // http://bugzilla.mozilla.org/show_bug.cgi?id=88130 but presumably could + // show up in any situation where a script calls into a wrapped js component + // on the same context, while the context has a nonzero exception state. + mState.emplace(mJSContext); + + return true; +} + +AutoScriptEvaluate::~AutoScriptEvaluate() { + if (!mJSContext || !mEvaluated) { + return; + } + mState->restore(); +} + +// It turns out that some errors may be not worth reporting. So, this +// function is factored out to manage that. +bool xpc_IsReportableErrorCode(nsresult code) { + if (NS_SUCCEEDED(code)) { + return false; + } + + switch (code) { + // Error codes that we don't want to report as errors... + // These generally indicate bad interface design AFAIC. + case NS_ERROR_FACTORY_REGISTER_AGAIN: + case NS_BASE_STREAM_WOULD_BLOCK: + return false; + default: + return true; + } +} + +// A little stack-based RAII class to help management of the XPCJSContext +// PendingResult. +class MOZ_STACK_CLASS AutoSavePendingResult { + public: + explicit AutoSavePendingResult(XPCJSContext* xpccx) : mXPCContext(xpccx) { + // Save any existing pending result and reset to NS_OK for this invocation. + mSavedResult = xpccx->GetPendingResult(); + xpccx->SetPendingResult(NS_OK); + } + ~AutoSavePendingResult() { mXPCContext->SetPendingResult(mSavedResult); } + + private: + XPCJSContext* mXPCContext; + nsresult mSavedResult; +}; + +// static +const nsXPTInterfaceInfo* nsXPCWrappedJS::GetInterfaceInfo(REFNSIID aIID) { + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID); + if (!info || info->IsBuiltinClass()) { + return nullptr; + } + + return info; +} + +// static +JSObject* nsXPCWrappedJS::CallQueryInterfaceOnJSObject(JSContext* cx, + JSObject* jsobjArg, + HandleObject scope, + REFNSIID aIID) { + js::AssertSameCompartment(scope, jsobjArg); + + RootedObject jsobj(cx, jsobjArg); + RootedValue arg(cx); + RootedValue retval(cx); + RootedObject retObj(cx); + RootedValue fun(cx); + + // In bug 503926, we added a security check to make sure that we don't + // invoke content QI functions. In the modern world, this is probably + // unnecessary, because invoking QI involves passing an IID object to + // content, which will fail. But we do a belt-and-suspenders check to + // make sure that content can never trigger the rat's nest of code below. + // Once we completely turn off XPConnect for the web, this can definitely + // go away. + if (!AccessCheck::isChrome(jsobj) || + !AccessCheck::isChrome(js::UncheckedUnwrap(jsobj))) { + return nullptr; + } + + // OK, it looks like we'll be calling into JS code. + AutoScriptEvaluate scriptEval(cx); + + // XXX we should install an error reporter that will send reports to + // the JS error console service. + if (!scriptEval.StartEvaluating(scope)) { + return nullptr; + } + + // check upfront for the existence of the function property + HandleId funid = + XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_QUERY_INTERFACE); + if (!JS_GetPropertyById(cx, jsobj, funid, &fun) || fun.isPrimitive()) { + return nullptr; + } + + dom::MozQueryInterface* mozQI = nullptr; + if (NS_SUCCEEDED(UNWRAP_OBJECT(MozQueryInterface, &fun, mozQI))) { + if (mozQI->QueriesTo(aIID)) { + return jsobj.get(); + } + return nullptr; + } + + if (!xpc::ID2JSValue(cx, aIID, &arg)) { + return nullptr; + } + + // Throwing NS_NOINTERFACE is the prescribed way to fail QI from JS. It is + // not an exception that is ever worth reporting, but we don't want to eat + // all exceptions either. + + bool success = + JS_CallFunctionValue(cx, jsobj, fun, HandleValueArray(arg), &retval); + if (!success && JS_IsExceptionPending(cx)) { + RootedValue jsexception(cx, NullValue()); + + if (JS_GetPendingException(cx, &jsexception)) { + if (jsexception.isObject()) { + // XPConnect may have constructed an object to represent a + // C++ QI failure. See if that is the case. + JS::Rooted<JSObject*> exceptionObj(cx, &jsexception.toObject()); + Exception* e = nullptr; + UNWRAP_OBJECT(Exception, &exceptionObj, e); + + if (e && e->GetResult() == NS_NOINTERFACE) { + JS_ClearPendingException(cx); + } + } else if (jsexception.isNumber()) { + nsresult rv; + // JS often throws an nsresult. + if (jsexception.isDouble()) + // Visual Studio 9 doesn't allow casting directly from + // a double to an enumeration type, contrary to + // 5.2.9(10) of C++11, so add an intermediate cast. + rv = (nsresult)(uint32_t)(jsexception.toDouble()); + else + rv = (nsresult)(jsexception.toInt32()); + + if (rv == NS_NOINTERFACE) JS_ClearPendingException(cx); + } + } + } else if (!success) { + NS_WARNING("QI hook ran OOMed - this is probably a bug!"); + } + + if (success) success = JS_ValueToObject(cx, retval, &retObj); + + return success ? retObj.get() : nullptr; +} + +/***************************************************************************/ + +namespace { + +class WrappedJSNamed final : public nsINamed { + nsCString mName; + + ~WrappedJSNamed() = default; + + public: + NS_DECL_ISUPPORTS + + explicit WrappedJSNamed(const nsACString& aName) : mName(aName) {} + + NS_IMETHOD GetName(nsACString& aName) override { + aName = mName; + aName.AppendLiteral(":JS"); + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(WrappedJSNamed, nsINamed) + +} // anonymous namespace + +/***************************************************************************/ + +// static +nsresult nsXPCWrappedJS::DelegatedQueryInterface(REFNSIID aIID, + void** aInstancePtr) { + if (aIID.Equals(NS_GET_IID(nsIXPConnectJSObjectHolder))) { + // This needs to call NS_ADDREF directly instead of using nsCOMPtr<>, + // because the latter does a QI in an assert, and we're already in a QI, so + // it would cause infinite recursion. + NS_ADDREF(this); + *aInstancePtr = (void*)static_cast<nsIXPConnectJSObjectHolder*>(this); + return NS_OK; + } + + // Ensure that we are asking for a non-builtinclass interface, and avoid even + // setting up our AutoEntryScript if we are. Don't bother doing that check + // if our IID is nsISupports: we know that's not builtinclass, and we QI to + // it a _lot_. + if (!aIID.Equals(NS_GET_IID(nsISupports))) { + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID); + if (!info || info->IsBuiltinClass()) { + MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsISupportsWeakReference)), + "Later code for nsISupportsWeakReference is being skipped"); + MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsISimpleEnumerator)), + "Later code for nsISimpleEnumerator is being skipped"); + MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsINamed)), + "Later code for nsINamed is being skipped"); + *aInstancePtr = nullptr; + return NS_NOINTERFACE; + } + } + + MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsWrapperCache)), + "Where did we get non-builtinclass interface info for this??"); + + // QI on an XPCWrappedJS can run script, so we need an AutoEntryScript. + // This is inherently Gecko-specific. + // We check both nativeGlobal and nativeGlobal->GetGlobalJSObject() even + // though we have derived nativeGlobal from the JS global, because we know + // there are cases where this can happen. See bug 1094953. + RootedObject obj(RootingCx(), GetJSObject()); + nsIGlobalObject* nativeGlobal = NativeGlobal(js::UncheckedUnwrap(obj)); + NS_ENSURE_TRUE(nativeGlobal, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(nativeGlobal->HasJSGlobal(), NS_ERROR_FAILURE); + + AutoAllowLegacyScriptExecution exemption; + + AutoEntryScript aes(nativeGlobal, "XPCWrappedJS QueryInterface", + /* aIsMainThread = */ true); + XPCCallContext ccx(aes.cx()); + if (!ccx.IsValid()) { + *aInstancePtr = nullptr; + return NS_NOINTERFACE; + } + + // We now need to enter the realm of the actual JSObject* we are pointing at. + // But that may be a cross-compartment wrapper and therefore not have a + // well-defined realm, so enter the realm of the global that we grabbed back + // when we started pointing to our JSObject*. + RootedObject objScope(RootingCx(), GetJSObjectGlobal()); + JSAutoRealm ar(aes.cx(), objScope); + + // We support nsISupportsWeakReference iff the root wrapped JSObject + // claims to support it in its QueryInterface implementation. + if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) { + // We only want to expose one implementation from our aggregate. + nsXPCWrappedJS* root = GetRootWrapper(); + RootedObject rootScope(ccx, root->GetJSObjectGlobal()); + + // Fail if JSObject doesn't claim support for nsISupportsWeakReference + if (!root->IsValid() || !CallQueryInterfaceOnJSObject( + ccx, root->GetJSObject(), rootScope, aIID)) { + *aInstancePtr = nullptr; + return NS_NOINTERFACE; + } + + NS_ADDREF(root); + *aInstancePtr = (void*)static_cast<nsISupportsWeakReference*>(root); + return NS_OK; + } + + // If we're asked to QI to nsISimpleEnumerator and the wrapped object does not + // have a QueryInterface method, assume it is a JS iterator, and wrap it into + // an equivalent nsISimpleEnumerator. + if (aIID.Equals(NS_GET_IID(nsISimpleEnumerator))) { + bool found; + XPCJSContext* xpccx = ccx.GetContext(); + if (JS_HasPropertyById(aes.cx(), obj, + xpccx->GetStringID(xpccx->IDX_QUERY_INTERFACE), + &found) && + !found) { + nsresult rv; + nsCOMPtr<nsIJSEnumerator> jsEnum; + if (!XPCConvert::JSObject2NativeInterface( + aes.cx(), getter_AddRefs(jsEnum), obj, + &NS_GET_IID(nsIJSEnumerator), nullptr, &rv)) { + return rv; + } + nsCOMPtr<nsISimpleEnumerator> res = new XPCWrappedJSIterator(jsEnum); + res.forget(aInstancePtr); + return NS_OK; + } + } + + // Checks for any existing wrapper explicitly constructed for this iid. + // This includes the current wrapper. This also deals with the + // nsISupports case (for which it returns mRoot). + // Also check if asking for an interface from which one of our wrappers + // inherits. + if (nsXPCWrappedJS* sibling = FindOrFindInherited(aIID)) { + NS_ADDREF(sibling); + *aInstancePtr = sibling->GetXPTCStub(); + return NS_OK; + } + + // Check if the desired interface is a function interface. If so, we don't + // want to QI, because the function almost certainly doesn't have a + // QueryInterface property, and doesn't need one. + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID); + if (info && info->IsFunction()) { + RefPtr<nsXPCWrappedJS> wrapper; + nsresult rv = + nsXPCWrappedJS::GetNewOrUsed(ccx, obj, aIID, getter_AddRefs(wrapper)); + + // Do the same thing we do for the "check for any existing wrapper" case + // above. + if (NS_SUCCEEDED(rv) && wrapper) { + *aInstancePtr = wrapper.forget().take()->GetXPTCStub(); + } + return rv; + } + + // else we do the more expensive stuff... + + // check if the JSObject claims to implement this interface + RootedObject jsobj(ccx, + CallQueryInterfaceOnJSObject(ccx, obj, objScope, aIID)); + if (jsobj) { + // We can't use XPConvert::JSObject2NativeInterface() here + // since that can find a XPCWrappedNative directly on the + // proto chain, and we don't want that here. We need to find + // the actual JS object that claimed it supports the interface + // we're looking for or we'll potentially bypass security + // checks etc by calling directly through to a native found on + // the prototype chain. + // + // Instead, simply do the nsXPCWrappedJS part of + // XPConvert::JSObject2NativeInterface() here to make sure we + // get a new (or used) nsXPCWrappedJS. + RefPtr<nsXPCWrappedJS> wrapper; + nsresult rv = + nsXPCWrappedJS::GetNewOrUsed(ccx, jsobj, aIID, getter_AddRefs(wrapper)); + if (NS_SUCCEEDED(rv) && wrapper) { + // We need to go through the QueryInterface logic to make + // this return the right thing for the various 'special' + // interfaces; e.g. nsISimpleEnumerator. + rv = wrapper->QueryInterface(aIID, aInstancePtr); + return rv; + } + } + + // If we're asked to QI to nsINamed, we pretend that this is possible. We'll + // try to return a name that makes sense for the wrapped JS value. + if (aIID.Equals(NS_GET_IID(nsINamed))) { + nsCString name = GetFunctionName(ccx, obj); + RefPtr<WrappedJSNamed> named = new WrappedJSNamed(name); + *aInstancePtr = named.forget().take(); + return NS_OK; + } + + // else... + // no can do + *aInstancePtr = nullptr; + return NS_NOINTERFACE; +} + +// static +JSObject* nsXPCWrappedJS::GetRootJSObject(JSContext* cx, JSObject* aJSObjArg) { + RootedObject aJSObj(cx, aJSObjArg); + RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); + JSObject* result = + CallQueryInterfaceOnJSObject(cx, aJSObj, global, NS_GET_IID(nsISupports)); + if (!result) { + result = aJSObj; + } + return js::UncheckedUnwrap(result); +} + +// static +bool nsXPCWrappedJS::GetArraySizeFromParam(const nsXPTMethodInfo* method, + const nsXPTType& type, + nsXPTCMiniVariant* nativeParams, + uint32_t* result) { + if (type.Tag() != nsXPTType::T_LEGACY_ARRAY && + type.Tag() != nsXPTType::T_PSTRING_SIZE_IS && + type.Tag() != nsXPTType::T_PWSTRING_SIZE_IS) { + *result = 0; + return true; + } + + uint8_t argnum = type.ArgNum(); + const nsXPTParamInfo& param = method->Param(argnum); + + // This should be enforced by the xpidl compiler, but it's not. + // See bug 695235. + if (param.Type().Tag() != nsXPTType::T_U32) { + return false; + } + + // If the length is passed indirectly (as an outparam), dereference by an + // extra level. + if (param.IsIndirect()) { + *result = *(uint32_t*)nativeParams[argnum].val.p; + } else { + *result = nativeParams[argnum].val.u32; + } + return true; +} + +// static +bool nsXPCWrappedJS::GetInterfaceTypeFromParam(const nsXPTMethodInfo* method, + const nsXPTType& type, + nsXPTCMiniVariant* nativeParams, + nsID* result) { + result->Clear(); + + const nsXPTType& inner = type.InnermostType(); + if (inner.Tag() == nsXPTType::T_INTERFACE) { + // Directly get IID from nsXPTInterfaceInfo. + if (!inner.GetInterface()) { + return false; + } + + *result = inner.GetInterface()->IID(); + } else if (inner.Tag() == nsXPTType::T_INTERFACE_IS) { + // Get IID from a passed parameter. + const nsXPTParamInfo& param = method->Param(inner.ArgNum()); + if (param.Type().Tag() != nsXPTType::T_NSID && + param.Type().Tag() != nsXPTType::T_NSIDPTR) { + return false; + } + + void* ptr = nativeParams[inner.ArgNum()].val.p; + + // If our IID is passed as a pointer outparameter, an extra level of + // dereferencing is required. + if (ptr && param.Type().Tag() == nsXPTType::T_NSIDPTR && + param.IsIndirect()) { + ptr = *(nsID**)ptr; + } + + if (!ptr) { + return false; + } + + *result = *(nsID*)ptr; + } + return true; +} + +// static +void nsXPCWrappedJS::CleanupOutparams(const nsXPTMethodInfo* info, + nsXPTCMiniVariant* nativeParams, + bool inOutOnly, uint8_t count) { + // clean up any 'out' params handed in + for (uint8_t i = 0; i < count; i++) { + const nsXPTParamInfo& param = info->GetParam(i); + if (!param.IsOut()) { + continue; + } + + MOZ_ASSERT(param.IsIndirect(), "Outparams are always indirect"); + + // Don't try to clear optional out params that are not set. + if (param.IsOptional() && !nativeParams[i].val.p) { + continue; + } + + // Call 'CleanupValue' on parameters which we know to be initialized: + // 1. Complex parameters (initialized by caller) + // 2. 'inout' parameters (initialized by caller) + // 3. 'out' parameters when 'inOutOnly' is 'false' (initialized by us) + // + // We skip non-complex 'out' parameters before the call, as they may + // contain random junk. + if (param.Type().IsComplex() || param.IsIn() || !inOutOnly) { + uint32_t arrayLen = 0; + if (!GetArraySizeFromParam(info, param.Type(), nativeParams, &arrayLen)) { + continue; + } + + xpc::CleanupValue(param.Type(), nativeParams[i].val.p, arrayLen); + } + + // Ensure our parameters are in a clean state. Complex values are always + // handled by CleanupValue, and others have a valid null representation. + if (!param.Type().IsComplex()) { + param.Type().ZeroValue(nativeParams[i].val.p); + } + } +} + +nsresult nsXPCWrappedJS::CheckForException(XPCCallContext& ccx, + AutoEntryScript& aes, + HandleObject aObj, + const char* aPropertyName, + const char* anInterfaceName, + Exception* aSyntheticException) { + JSContext* cx = ccx.GetJSContext(); + MOZ_ASSERT(cx == aes.cx()); + RefPtr<Exception> xpc_exception = aSyntheticException; + /* this one would be set by our error reporter */ + + XPCJSContext* xpccx = ccx.GetContext(); + + // Get this right away in case we do something below to cause JS code + // to run. + nsresult pending_result = xpccx->GetPendingResult(); + + RootedValue js_exception(cx); + bool is_js_exception = JS_GetPendingException(cx, &js_exception); + + /* JS might throw an exception whether the reporter was called or not */ + if (is_js_exception) { + if (!xpc_exception) { + XPCConvert::JSValToXPCException(cx, &js_exception, anInterfaceName, + aPropertyName, + getter_AddRefs(xpc_exception)); + } + + /* cleanup and set failed even if we can't build an exception */ + if (!xpc_exception) { + xpccx->SetPendingException(nullptr); // XXX necessary? + } + } + + // Clear the pending exception now, because xpc_exception might be JS- + // implemented, so invoking methods on it might re-enter JS, which we can't + // do with an exception on the stack. + aes.ClearException(); + + if (xpc_exception) { + nsresult e_result = xpc_exception->GetResult(); + // Figure out whether or not we should report this exception. + bool reportable = xpc_IsReportableErrorCode(e_result); + if (reportable) { + // Ugly special case for GetInterface. It's "special" in the + // same way as QueryInterface in that a failure is not + // exceptional and shouldn't be reported. We have to do this + // check here instead of in xpcwrappedjs (like we do for QI) to + // avoid adding extra code to all xpcwrappedjs objects. + if (e_result == NS_ERROR_NO_INTERFACE && + !strcmp(anInterfaceName, "nsIInterfaceRequestor") && + !strcmp(aPropertyName, "getInterface")) { + reportable = false; + } + + // More special case, see bug 877760. + if (e_result == NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED) { + reportable = false; + } + } + + // Try to use the error reporter set on the context to handle this + // error if it came from a JS exception. + if (reportable && is_js_exception) { + // Note that we cleared the exception above, so we need to set it again, + // just so that we can tell the JS engine to pass it back to us via the + // error reporting callback. This is all very dumb. + JS_SetPendingException(cx, js_exception); + + // Enter the unwrapped object's realm. This is the realm that was used to + // enter the AutoEntryScript. + JSAutoRealm ar(cx, js::UncheckedUnwrap(aObj)); + aes.ReportException(); + reportable = false; + } + + if (reportable) { + if (nsJSUtils::DumpEnabled()) { + static const char line[] = + "************************************************************\n"; + static const char preamble[] = + "* Call to xpconnect wrapped JSObject produced this error: *\n"; + static const char cant_get_text[] = + "FAILED TO GET TEXT FROM EXCEPTION\n"; + + fputs(line, stdout); + fputs(preamble, stdout); + nsCString text; + xpc_exception->ToString(cx, text); + if (!text.IsEmpty()) { + fputs(text.get(), stdout); + fputs("\n", stdout); + } else + fputs(cant_get_text, stdout); + fputs(line, stdout); + } + + // Log the exception to the JS Console, so that users can do + // something with it. + nsCOMPtr<nsIConsoleService> consoleService( + do_GetService(XPC_CONSOLE_CONTRACTID)); + if (nullptr != consoleService) { + nsCOMPtr<nsIScriptError> scriptError = + do_QueryInterface(xpc_exception->GetData()); + + if (nullptr == scriptError) { + // No luck getting one from the exception, so + // try to cook one up. + scriptError = do_CreateInstance(XPC_SCRIPT_ERROR_CONTRACTID); + if (nullptr != scriptError) { + nsCString newMessage; + xpc_exception->ToString(cx, newMessage); + // try to get filename, lineno from the first + // stack frame location. + int32_t lineNumber = 0; + nsString sourceName; + + nsCOMPtr<nsIStackFrame> location = xpc_exception->GetLocation(); + if (location) { + // Get line number. + lineNumber = location->GetLineNumber(cx); + + // get a filename. + location->GetFilename(cx, sourceName); + } + + nsresult rv = scriptError->InitWithWindowID( + NS_ConvertUTF8toUTF16(newMessage), sourceName, u""_ns, + lineNumber, 0, 0, "XPConnect JavaScript", + nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx)); + if (NS_FAILED(rv)) { + scriptError = nullptr; + } + + rv = scriptError->InitSourceId(location->GetSourceId(cx)); + if (NS_FAILED(rv)) { + scriptError = nullptr; + } + } + } + if (nullptr != scriptError) { + consoleService->LogMessage(scriptError); + } + } + } + // Whether or not it passes the 'reportable' test, it might + // still be an error and we have to do the right thing here... + if (NS_FAILED(e_result)) { + xpccx->SetPendingException(xpc_exception); + return e_result; + } + } else { + // see if JS code signaled failure result without throwing exception + if (NS_FAILED(pending_result)) { + return pending_result; + } + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsXPCWrappedJS::CallMethod(uint16_t methodIndex, const nsXPTMethodInfo* info, + nsXPTCMiniVariant* nativeParams) { + // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread. + MOZ_RELEASE_ASSERT(NS_IsMainThread(), + "nsXPCWrappedJS::CallMethod called off main thread"); + + if (!IsValid()) { + return NS_ERROR_UNEXPECTED; + } + + // We need to reject an attempt to call a non-reflectable method before + // we do anything like AutoEntryScript which might allocate in the JS engine, + // because the method isn't marked with JS_HAZ_CAN_RUN_SCRIPT, and we want + // to be able to take advantage of that in the GC hazard analysis. + if (!info->IsReflectable()) { + return NS_ERROR_FAILURE; + } + + Value* sp = nullptr; + Value* argv = nullptr; + uint8_t i; + nsresult retval = NS_ERROR_FAILURE; + bool success; + bool readyToDoTheCall = false; + nsID param_iid; + bool foundDependentParam; + + // We're about to call into script via an XPCWrappedJS, so we need an + // AutoEntryScript. This is probably Gecko-specific at this point, and + // definitely will be when we turn off XPConnect for the web. + RootedObject obj(RootingCx(), GetJSObject()); + nsIGlobalObject* nativeGlobal = NativeGlobal(js::UncheckedUnwrap(obj)); + + AutoAllowLegacyScriptExecution exemption; + + AutoEntryScript aes(nativeGlobal, "XPCWrappedJS method call", + /* aIsMainThread = */ true); + XPCCallContext ccx(aes.cx()); + if (!ccx.IsValid()) { + return retval; + } + + JSContext* cx = ccx.GetJSContext(); + + if (!cx) { + return NS_ERROR_FAILURE; + } + + // We now need to enter the realm of the actual JSObject* we are pointing at. + // But that may be a cross-compartment wrapper and therefore not have a + // well-defined realm, so enter the realm of the global that we grabbed back + // when we started pointing to our JSObject*. + RootedObject scope(cx, GetJSObjectGlobal()); + JSAutoRealm ar(cx, scope); + + const nsXPTInterfaceInfo* interfaceInfo = GetInfo(); + JS::RootedId id(cx); + const char* name = info->NameOrDescription(); + if (!info->GetId(cx, id.get())) { + return NS_ERROR_FAILURE; + } + + // [optional_argc] has a different calling convention, which we don't + // support for JS-implemented components. + if (info->WantsOptArgc()) { + const char* str = + "IDL methods marked with [optional_argc] may not " + "be implemented in JS"; + // Throw and warn for good measure. + JS_ReportErrorASCII(cx, "%s", str); + NS_WARNING(str); + return CheckForException(ccx, aes, obj, name, interfaceInfo->Name()); + } + + RootedValue fval(cx); + RootedObject thisObj(cx, obj); + + RootedValueVector args(cx); + AutoScriptEvaluate scriptEval(cx); + + XPCJSRuntime* xpcrt = XPCJSRuntime::Get(); + XPCJSContext* xpccx = ccx.GetContext(); + AutoSavePendingResult apr(xpccx); + + // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this. + uint8_t paramCount = info->GetParamCount(); + uint8_t argc = paramCount; + if (info->HasRetval()) { + argc -= 1; + } + + if (!scriptEval.StartEvaluating(scope)) { + goto pre_call_clean_up; + } + + xpccx->SetPendingException(nullptr); + + // We use js_Invoke so that the gcthings we use as args will be rooted by + // the engine as we do conversions and prepare to do the function call. + + // setup stack + + // if this isn't a function call then we don't need to push extra stuff + if (!(info->IsSetter() || info->IsGetter())) { + // We get fval before allocating the stack to avoid gc badness that can + // happen if the GetProperty call leaves our request and the gc runs + // while the stack we allocate contains garbage. + + // If the interface is marked as a [function] then we will assume that + // our JSObject is a function and not an object with a named method. + + // In the xpidl [function] case we are making sure now that the + // JSObject is callable. If it is *not* callable then we silently + // fallback to looking up the named property... + // (because jst says he thinks this fallback is 'The Right Thing'.) + // + // In the normal (non-function) case we just lookup the property by + // name and as long as the object has such a named property we go ahead + // and try to make the call. If it turns out the named property is not + // a callable object then the JS engine will throw an error and we'll + // pass this along to the caller as an exception/result code. + + fval = ObjectValue(*obj); + if (!interfaceInfo->IsFunction() || + JS_TypeOfValue(ccx, fval) != JSTYPE_FUNCTION) { + if (!JS_GetPropertyById(cx, obj, id, &fval)) { + goto pre_call_clean_up; + } + // XXX We really want to factor out the error reporting better and + // specifically report the failure to find a function with this name. + // This is what we do below if the property is found but is not a + // function. We just need to factor better so we can get to that + // reporting path from here. + + thisObj = obj; + } + } + + if (!args.resize(argc)) { + retval = NS_ERROR_OUT_OF_MEMORY; + goto pre_call_clean_up; + } + + argv = args.begin(); + sp = argv; + + // build the args + // NB: This assignment *looks* wrong because we haven't yet called our + // function. However, we *have* already entered the compartmen that we're + // about to call, and that's the global that we want here. In other words: + // we're trusting the JS engine to come up with a good global to use for + // our object (whatever it was). + for (i = 0; i < argc; i++) { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + uint32_t array_count; + RootedValue val(cx, NullValue()); + + // Verify that null was not passed for a non-optional 'out' param. + if (param.IsOut() && !nativeParams[i].val.p && !param.IsOptional()) { + retval = NS_ERROR_INVALID_ARG; + goto pre_call_clean_up; + } + + if (param.IsIn()) { + const void* pv; + if (param.IsIndirect()) { + pv = nativeParams[i].val.p; + } else { + pv = &nativeParams[i]; + } + + if (!GetInterfaceTypeFromParam(info, type, nativeParams, ¶m_iid) || + !GetArraySizeFromParam(info, type, nativeParams, &array_count)) + goto pre_call_clean_up; + + if (!XPCConvert::NativeData2JS(cx, &val, pv, type, ¶m_iid, + array_count, nullptr)) + goto pre_call_clean_up; + } + + if (param.IsOut()) { + // create an 'out' object + RootedObject out_obj(cx, NewOutObject(cx)); + if (!out_obj) { + retval = NS_ERROR_OUT_OF_MEMORY; + goto pre_call_clean_up; + } + + if (param.IsIn()) { + if (!JS_SetPropertyById(cx, out_obj, + xpcrt->GetStringID(XPCJSContext::IDX_VALUE), + val)) { + goto pre_call_clean_up; + } + } + *sp++ = JS::ObjectValue(*out_obj); + } else + *sp++ = val; + } + + readyToDoTheCall = true; + +pre_call_clean_up: + // clean up any 'out' params handed in + CleanupOutparams(info, nativeParams, /* inOutOnly = */ true, paramCount); + + if (!readyToDoTheCall) { + return retval; + } + + // do the deed - note exceptions + + MOZ_ASSERT(!aes.HasException()); + + RefPtr<Exception> syntheticException; + RootedValue rval(cx); + if (info->IsGetter()) { + success = JS_GetProperty(cx, obj, name, &rval); + } else if (info->IsSetter()) { + rval = *argv; + success = JS_SetProperty(cx, obj, name, rval); + } else { + if (!fval.isPrimitive()) { + success = JS_CallFunctionValue(cx, thisObj, fval, args, &rval); + } else { + // The property was not an object so can't be a function. + // Let's build and 'throw' an exception. + + static const nsresult code = NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED; + static const char format[] = "%s \"%s\""; + const char* msg; + UniqueChars sz; + + if (nsXPCException::NameAndFormatForNSResult(code, nullptr, &msg) && + msg) { + sz = JS_smprintf(format, msg, name); + } + + XPCConvert::ConstructException( + code, sz.get(), interfaceInfo->Name(), name, nullptr, + getter_AddRefs(syntheticException), nullptr, nullptr); + success = false; + } + } + + if (!success) { + return CheckForException(ccx, aes, obj, name, interfaceInfo->Name(), + syntheticException); + } + + xpccx->SetPendingException(nullptr); // XXX necessary? + + // convert out args and result + // NOTE: this is the total number of native params, not just the args + // Convert independent params only. + // When we later convert the dependent params (if any) we will know that + // the params upon which they depend will have already been converted - + // regardless of ordering. + + foundDependentParam = false; + for (i = 0; i < paramCount; i++) { + const nsXPTParamInfo& param = info->GetParam(i); + MOZ_ASSERT(!param.IsShared(), "[shared] implies [noscript]!"); + if (!param.IsOut() || !nativeParams[i].val.p) { + continue; + } + + const nsXPTType& type = param.GetType(); + if (type.IsDependent()) { + foundDependentParam = true; + continue; + } + + RootedValue val(cx); + + if (¶m == info->GetRetval()) { + val = rval; + } else if (argv[i].isPrimitive()) { + break; + } else { + RootedObject obj(cx, &argv[i].toObject()); + if (!JS_GetPropertyById( + cx, obj, xpcrt->GetStringID(XPCJSContext::IDX_VALUE), &val)) { + break; + } + } + + // setup allocator and/or iid + + const nsXPTType& inner = type.InnermostType(); + if (inner.Tag() == nsXPTType::T_INTERFACE) { + if (!inner.GetInterface()) { + break; + } + param_iid = inner.GetInterface()->IID(); + } + + MOZ_ASSERT(param.IsIndirect(), "outparams are always indirect"); + if (!XPCConvert::JSData2Native(cx, nativeParams[i].val.p, val, type, + ¶m_iid, 0, nullptr)) + break; + } + + // if any params were dependent, then we must iterate again to convert them. + if (foundDependentParam && i == paramCount) { + for (i = 0; i < paramCount; i++) { + const nsXPTParamInfo& param = info->GetParam(i); + if (!param.IsOut()) { + continue; + } + + const nsXPTType& type = param.GetType(); + if (!type.IsDependent()) { + continue; + } + + RootedValue val(cx); + uint32_t array_count; + + if (¶m == info->GetRetval()) { + val = rval; + } else { + RootedObject obj(cx, &argv[i].toObject()); + if (!JS_GetPropertyById( + cx, obj, xpcrt->GetStringID(XPCJSContext::IDX_VALUE), &val)) { + break; + } + } + + // setup allocator and/or iid + + if (!GetInterfaceTypeFromParam(info, type, nativeParams, ¶m_iid) || + !GetArraySizeFromParam(info, type, nativeParams, &array_count)) + break; + + MOZ_ASSERT(param.IsIndirect(), "outparams are always indirect"); + if (!XPCConvert::JSData2Native(cx, nativeParams[i].val.p, val, type, + ¶m_iid, array_count, nullptr)) + break; + } + } + + if (i != paramCount) { + // We didn't manage all the result conversions! + // We have to cleanup any junk that *did* get converted. + CleanupOutparams(info, nativeParams, /* inOutOnly = */ false, i); + } else { + // set to whatever the JS code might have set as the result + retval = xpccx->GetPendingResult(); + } + + return retval; +} + +static const JSClass XPCOutParamClass = {"XPCOutParam", 0, JS_NULL_CLASS_OPS}; + +bool xpc::IsOutObject(JSContext* cx, JSObject* obj) { + return JS::GetClass(obj) == &XPCOutParamClass; +} + +JSObject* xpc::NewOutObject(JSContext* cx) { + return JS_NewObject(cx, &XPCOutParamClass); +} + +// static +void nsXPCWrappedJS::DebugDumpInterfaceInfo(const nsXPTInterfaceInfo* aInfo, + int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS(("nsXPTInterfaceInfo @ %p = ", aInfo)); + XPC_LOG_INDENT(); + const char* name = aInfo->Name(); + XPC_LOG_ALWAYS(("interface name is %s", name)); + auto iid = aInfo->IID().ToString(); + XPC_LOG_ALWAYS(("IID number is %s", iid.get())); + XPC_LOG_ALWAYS(("InterfaceInfo @ %p", aInfo)); + uint16_t methodCount = 0; + if (depth) { + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("parent @ %p", aInfo->GetParent())); + methodCount = aInfo->MethodCount(); + XPC_LOG_ALWAYS(("MethodCount = %d", methodCount)); + XPC_LOG_ALWAYS(("ConstantCount = %d", aInfo->ConstantCount())); + XPC_LOG_OUTDENT(); + } + XPC_LOG_ALWAYS(("method count = %d", methodCount)); + if (depth && methodCount) { + depth--; + XPC_LOG_INDENT(); + for (uint16_t i = 0; i < methodCount; i++) { + XPC_LOG_ALWAYS(("Method %d is %s%s", i, + aInfo->Method(i).IsReflectable() ? "" : " NOT ", + "reflectable")); + } + XPC_LOG_OUTDENT(); + depth++; + } + XPC_LOG_OUTDENT(); +#endif +} diff --git a/js/xpconnect/src/XPCWrappedJSIterator.cpp b/js/xpconnect/src/XPCWrappedJSIterator.cpp new file mode 100644 index 0000000000..a901050a4b --- /dev/null +++ b/js/xpconnect/src/XPCWrappedJSIterator.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" + +#include "mozilla/ResultExtensions.h" +#include "mozilla/dom/IteratorResultBinding.h" +#include "mozilla/dom/RootedDictionary.h" +#include "mozilla/dom/ScriptSettings.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace xpc; + +NS_IMPL_CYCLE_COLLECTION(XPCWrappedJSIterator, mEnum, mGlobal, mNext) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCWrappedJSIterator) +NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCWrappedJSIterator) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCWrappedJSIterator) + NS_INTERFACE_MAP_ENTRY(nsISimpleEnumerator) + NS_INTERFACE_MAP_ENTRY(nsISimpleEnumeratorBase) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, XPCWrappedJSIterator) +NS_INTERFACE_MAP_END + +XPCWrappedJSIterator::XPCWrappedJSIterator(nsIJSEnumerator* aEnum) + : mEnum(aEnum) { + nsCOMPtr<nsIXPConnectWrappedJS> wrapped = do_QueryInterface(aEnum); + MOZ_ASSERT(wrapped); + mGlobal = NativeGlobal(wrapped->GetJSObjectGlobal()); +} + +nsresult XPCWrappedJSIterator::HasMoreElements(bool* aRetVal) { + if (mHasNext.isNothing()) { + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(mGlobal)); + + JSContext* cx = jsapi.cx(); + + JS::RootedValue val(cx); + MOZ_TRY(mEnum->Next(cx, &val)); + + RootedDictionary<IteratorResult> result(cx); + if (!result.Init(cx, val)) { + return NS_ERROR_FAILURE; + } + + if (!result.mDone) { + if (result.mValue.isObject()) { + JS::RootedObject obj(cx, &result.mValue.toObject()); + + nsresult rv; + if (!XPCConvert::JSObject2NativeInterface(cx, getter_AddRefs(mNext), + obj, &NS_GET_IID(nsISupports), + nullptr, &rv)) { + return rv; + } + } else { + mNext = XPCVariant::newVariant(cx, result.mValue); + } + } + mHasNext = Some(!result.mDone); + } + *aRetVal = *mHasNext; + return NS_OK; +} + +nsresult XPCWrappedJSIterator::GetNext(nsISupports** aRetVal) { + bool hasMore; + MOZ_TRY(HasMoreElements(&hasMore)); + if (!hasMore) { + return NS_ERROR_FAILURE; + } + + mNext.forget(aRetVal); + mHasNext = Nothing(); + return NS_OK; +} + +nsresult XPCWrappedJSIterator::Iterator(nsIJSEnumerator** aRetVal) { + nsCOMPtr<nsIJSEnumerator> jsEnum = mEnum; + jsEnum.forget(aRetVal); + return NS_OK; +} + +nsresult XPCWrappedJSIterator::Entries(const nsID&, nsIJSEnumerator** aRetVal) { + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp new file mode 100644 index 0000000000..21f5c3e003 --- /dev/null +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -0,0 +1,1839 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Wrapper object for reflecting native xpcom objects into JavaScript. */ + +#include "xpcprivate.h" +#include "XPCMaps.h" +#include "nsWrapperCacheInlines.h" +#include "XPCLog.h" +#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject +#include "js/experimental/TypedData.h" // JS_GetTypedArrayLength, JS_IsTypedArrayObject +#include "js/MemoryFunctions.h" +#include "js/Object.h" // JS::GetPrivate, JS::SetPrivate, JS::SetReservedSlot +#include "js/Printf.h" +#include "js/PropertyAndElement.h" // JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById +#include "jsfriendapi.h" +#include "AccessCheck.h" +#include "WrapperFactory.h" +#include "XrayWrapper.h" + +#include "nsContentUtils.h" +#include "nsCycleCollectionNoteRootCallback.h" + +#include <new> +#include <stdint.h> +#include "mozilla/DeferredFinalize.h" +#include "mozilla/Likely.h" +#include "mozilla/Unused.h" +#include "mozilla/Sprintf.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/ProfilerLabels.h" +#include <algorithm> + +using namespace xpc; +using namespace mozilla; +using namespace mozilla::dom; +using namespace JS; + +/***************************************************************************/ + +NS_IMPL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) + +// No need to unlink the JS objects: if the XPCWrappedNative is cycle +// collected then its mFlatJSObject will be cycle collected too and +// finalization of the mFlatJSObject will unlink the JS objects (see +// XPC_WN_NoHelper_Finalize and FlatJSObjectFinalized). +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCWrappedNative) + tmp->ExpireWrapper(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(XPCWrappedNative) + if (!tmp->IsValid()) { + return NS_OK; + } + + if (MOZ_UNLIKELY(cb.WantDebugInfo())) { + char name[72]; + nsCOMPtr<nsIXPCScriptable> scr = tmp->GetScriptable(); + if (scr) { + SprintfLiteral(name, "XPCWrappedNative (%s)", scr->GetJSClass()->name); + } else { + SprintfLiteral(name, "XPCWrappedNative"); + } + + cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name); + } else { + NS_IMPL_CYCLE_COLLECTION_DESCRIBE(XPCWrappedNative, tmp->mRefCnt.get()) + } + + if (tmp->HasExternalReference()) { + // If our refcount is > 1, our reference to the flat JS object is + // considered "strong", and we're going to traverse it. + // + // If our refcount is <= 1, our reference to the flat JS object is + // considered "weak", and we're *not* going to traverse it. + // + // This reasoning is in line with the slightly confusing lifecycle rules + // for XPCWrappedNatives, described in a larger comment below and also + // on our wiki at http://wiki.mozilla.org/XPConnect_object_wrapping + + JSObject* obj = tmp->GetFlatJSObjectPreserveColor(); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFlatJSObject"); + cb.NoteJSChild(JS::GCCellPtr(obj)); + } + + // XPCWrappedNative keeps its native object alive. + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mIdentity"); + cb.NoteXPCOMChild(tmp->GetIdentityObject()); + + tmp->NoteTearoffs(cb); + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +void XPCWrappedNative::Suspect(nsCycleCollectionNoteRootCallback& cb) { + if (!IsValid() || IsWrapperExpired()) { + return; + } + + MOZ_ASSERT(NS_IsMainThread(), + "Suspecting wrapped natives from non-main thread"); + + // Only record objects that might be part of a cycle as roots, unless + // the callback wants all traces (a debug feature). Do this even if + // the XPCWN doesn't own the JS reflector object in case the reflector + // keeps alive other C++ things. This is safe because if the reflector + // had died the reference from the XPCWN to it would have been cleared. + JSObject* obj = GetFlatJSObjectPreserveColor(); + if (JS::ObjectIsMarkedGray(obj) || cb.WantAllTraces()) { + cb.NoteJSRoot(obj); + } +} + +void XPCWrappedNative::NoteTearoffs(nsCycleCollectionTraversalCallback& cb) { + // Tearoffs hold their native object alive. If their JS object hasn't been + // finalized yet we'll note the edge between the JS object and the native + // (see nsXPConnect::Traverse), but if their JS object has been finalized + // then the tearoff is only reachable through the XPCWrappedNative, so we + // record an edge here. + for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; + to = to->GetNextTearOff()) { + JSObject* jso = to->GetJSObjectPreserveColor(); + if (!jso) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "tearoff's mNative"); + cb.NoteXPCOMChild(to->GetNative()); + } + } +} + +#ifdef XPC_CHECK_CLASSINFO_CLAIMS +static void DEBUG_CheckClassInfoClaims(XPCWrappedNative* wrapper); +#else +# define DEBUG_CheckClassInfoClaims(wrapper) ((void)0) +#endif + +/***************************************************************************/ +static nsresult FinishCreate(JSContext* cx, XPCWrappedNativeScope* Scope, + XPCNativeInterface* Interface, + nsWrapperCache* cache, XPCWrappedNative* inWrapper, + XPCWrappedNative** resultWrapper); + +// static +// +// This method handles the special case of wrapping a new global object. +// +// The normal code path for wrapping natives goes through +// XPCConvert::NativeInterface2JSObject, XPCWrappedNative::GetNewOrUsed, +// and finally into XPCWrappedNative::Init. Unfortunately, this path assumes +// very early on that we have an XPCWrappedNativeScope and corresponding global +// JS object, which are the very things we need to create here. So we special- +// case the logic and do some things in a different order. +nsresult XPCWrappedNative::WrapNewGlobal(JSContext* cx, + xpcObjectHelper& nativeHelper, + nsIPrincipal* principal, + bool initStandardClasses, + JS::RealmOptions& aOptions, + XPCWrappedNative** wrappedGlobal) { + nsCOMPtr<nsISupports> identity = do_QueryInterface(nativeHelper.Object()); + + // The object should specify that it's meant to be global. + MOZ_ASSERT(nativeHelper.GetScriptableFlags() & + XPC_SCRIPTABLE_IS_GLOBAL_OBJECT); + + // We shouldn't be reusing globals. + MOZ_ASSERT(!nativeHelper.GetWrapperCache() || + !nativeHelper.GetWrapperCache()->GetWrapperPreserveColor()); + + // Get the nsIXPCScriptable. This will tell us the JSClass of the object + // we're going to create. + nsCOMPtr<nsIXPCScriptable> scrProto; + nsCOMPtr<nsIXPCScriptable> scrWrapper; + GatherScriptable(identity, nativeHelper.GetClassInfo(), + getter_AddRefs(scrProto), getter_AddRefs(scrWrapper)); + MOZ_ASSERT(scrWrapper); + + // Finally, we get to the JSClass. + const JSClass* clasp = scrWrapper->GetJSClass(); + MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL); + + // Create the global. + aOptions.creationOptions().setTrace(XPCWrappedNative::Trace); + xpc::SetPrefableRealmOptions(aOptions); + + RootedObject global(cx, + xpc::CreateGlobalObject(cx, clasp, principal, aOptions)); + if (!global) { + return NS_ERROR_FAILURE; + } + XPCWrappedNativeScope* scope = ObjectScope(global); + + // Immediately enter the global's realm, so that everything else we + // create ends up there. + JSAutoRealm ar(cx, global); + + // If requested, initialize the standard classes on the global. + if (initStandardClasses && !JS::InitRealmStandardClasses(cx)) { + return NS_ERROR_FAILURE; + } + + // Make a proto. + XPCWrappedNativeProto* proto = XPCWrappedNativeProto::GetNewOrUsed( + cx, scope, nativeHelper.GetClassInfo(), scrProto); + if (!proto) { + return NS_ERROR_FAILURE; + } + + // Set up the prototype on the global. + MOZ_ASSERT(proto->GetJSProtoObject()); + RootedObject protoObj(cx, proto->GetJSProtoObject()); + bool success = JS_SetPrototype(cx, global, protoObj); + if (!success) { + return NS_ERROR_FAILURE; + } + + // Construct the wrapper, which takes over the strong reference to the + // native object. + RefPtr<XPCWrappedNative> wrapper = + new XPCWrappedNative(std::move(identity), proto); + + // + // We don't call ::Init() on this wrapper, because our setup requirements + // are different for globals. We do our setup inline here, instead. + // + + wrapper->mScriptable = scrWrapper; + + // Set the JS object to the global we already created. + wrapper->SetFlatJSObject(global); + + // Set the reserved slot to the XPCWrappedNative. + static_assert(JSCLASS_GLOBAL_APPLICATION_SLOTS > 0, + "Need at least one slot for JSCLASS_SLOT0_IS_NSISUPPORTS"); + JS::SetObjectISupports(global, wrapper); + + // There are dire comments elsewhere in the code about how a GC can + // happen somewhere after wrapper initialization but before the wrapper is + // added to the hashtable in FinishCreate(). It's not clear if that can + // happen here, but let's just be safe for now. + AutoMarkingWrappedNativePtr wrapperMarker(cx, wrapper); + + // Call the common Init finish routine. This mainly just does an AddRef + // on behalf of XPConnect (the corresponding Release is in the finalizer + // hook), but it does some other miscellaneous things too, so we don't + // inline it. + success = wrapper->FinishInit(cx); + MOZ_ASSERT(success); + + // Go through some extra work to find the tearoff. This is kind of silly + // on a conceptual level: the point of tearoffs is to cache the results + // of QI-ing mIdentity to different interfaces, and we don't need that + // since we're dealing with nsISupports. But lots of code expects tearoffs + // to exist for everything, so we just follow along. + RefPtr<XPCNativeInterface> iface = + XPCNativeInterface::GetNewOrUsed(cx, &NS_GET_IID(nsISupports)); + MOZ_ASSERT(iface); + nsresult status; + success = wrapper->FindTearOff(cx, iface, false, &status); + if (!success) { + return status; + } + + // Call the common creation finish routine. This does all of the bookkeeping + // like inserting the wrapper into the wrapper map and setting up the wrapper + // cache. + nsresult rv = FinishCreate(cx, scope, iface, nativeHelper.GetWrapperCache(), + wrapper, wrappedGlobal); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +// static +nsresult XPCWrappedNative::GetNewOrUsed(JSContext* cx, xpcObjectHelper& helper, + XPCWrappedNativeScope* Scope, + XPCNativeInterface* Interface, + XPCWrappedNative** resultWrapper) { + MOZ_ASSERT(Interface); + nsWrapperCache* cache = helper.GetWrapperCache(); + + MOZ_ASSERT(!cache || !cache->GetWrapperPreserveColor(), + "We assume the caller already checked if it could get the " + "wrapper from the cache."); + + nsresult rv; + + MOZ_ASSERT(!Scope->GetRuntime()->GCIsRunning(), + "XPCWrappedNative::GetNewOrUsed called during GC"); + + nsCOMPtr<nsISupports> identity = do_QueryInterface(helper.Object()); + + if (!identity) { + NS_ERROR("This XPCOM object fails in QueryInterface to nsISupports!"); + return NS_ERROR_FAILURE; + } + + RefPtr<XPCWrappedNative> wrapper; + + Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap(); + // Some things are nsWrapperCache subclasses but never use the cache, so go + // ahead and check our map even if we have a cache and it has no existing + // wrapper: we might have an XPCWrappedNative anyway. + wrapper = map->Find(identity); + + if (wrapper) { + if (!wrapper->FindTearOff(cx, Interface, false, &rv)) { + MOZ_ASSERT(NS_FAILED(rv), "returning NS_OK on failure"); + return rv; + } + wrapper.forget(resultWrapper); + return NS_OK; + } + + // There is a chance that the object wants to have the self-same JSObject + // reflection regardless of the scope into which we are reflecting it. + // Many DOM objects require this. The scriptable helper specifies this + // in preCreate by indicating a 'parent' of a particular scope. + // + // To handle this we need to get the scriptable helper early and ask it. + // It is possible that we will then end up forwarding this entire call + // to this same function but with a different scope. + + // If we are making a wrapper for an nsIClassInfo singleton then + // We *don't* want to have it use the prototype meant for instances + // of that class. + uint32_t classInfoFlags; + bool isClassInfoSingleton = + helper.GetClassInfo() == helper.Object() && + NS_SUCCEEDED(helper.GetClassInfo()->GetFlags(&classInfoFlags)) && + (classInfoFlags & nsIClassInfo::SINGLETON_CLASSINFO); + + nsIClassInfo* info = helper.GetClassInfo(); + + nsCOMPtr<nsIXPCScriptable> scrProto; + nsCOMPtr<nsIXPCScriptable> scrWrapper; + + // Gather scriptable create info if we are wrapping something + // other than an nsIClassInfo object. We need to not do this for + // nsIClassInfo objects because often nsIClassInfo implementations + // are also nsIXPCScriptable helper implementations, but the helper + // code is obviously intended for the implementation of the class + // described by the nsIClassInfo, not for the class info object + // itself. + if (!isClassInfoSingleton) { + GatherScriptable(identity, info, getter_AddRefs(scrProto), + getter_AddRefs(scrWrapper)); + } + + RootedObject parent(cx, Scope->GetGlobalForWrappedNatives()); + + mozilla::Maybe<JSAutoRealm> ar; + + if (scrWrapper && scrWrapper->WantPreCreate()) { + RootedObject plannedParent(cx, parent); + nsresult rv = scrWrapper->PreCreate(identity, cx, parent, parent.address()); + if (NS_FAILED(rv)) { + return rv; + } + rv = NS_OK; + + MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent), + "Xray wrapper being used to parent XPCWrappedNative?"); + + MOZ_ASSERT(JS_IsGlobalObject(parent), + "Non-global being used to parent XPCWrappedNative?"); + + ar.emplace(static_cast<JSContext*>(cx), parent); + + if (parent != plannedParent) { + XPCWrappedNativeScope* betterScope = ObjectScope(parent); + MOZ_ASSERT(betterScope != Scope, + "How can we have the same scope for two different globals?"); + return GetNewOrUsed(cx, helper, betterScope, Interface, resultWrapper); + } + + // Take the performance hit of checking the hashtable again in case + // the preCreate call caused the wrapper to get created through some + // interesting path (the DOM code tends to make this happen sometimes). + + if (cache) { + RootedObject cached(cx, cache->GetWrapper()); + if (cached) { + wrapper = XPCWrappedNative::Get(cached); + } + } else { + wrapper = map->Find(identity); + } + + if (wrapper) { + if (!wrapper->FindTearOff(cx, Interface, false, &rv)) { + MOZ_ASSERT(NS_FAILED(rv), "returning NS_OK on failure"); + return rv; + } + wrapper.forget(resultWrapper); + return NS_OK; + } + } else { + ar.emplace(static_cast<JSContext*>(cx), parent); + } + + AutoMarkingWrappedNativeProtoPtr proto(cx); + + // If there is ClassInfo (and we are not building a wrapper for the + // nsIClassInfo interface) then we use a wrapper that needs a prototype. + + // Note that the security check happens inside FindTearOff - after the + // wrapper is actually created, but before JS code can see it. + + if (info && !isClassInfoSingleton) { + proto = XPCWrappedNativeProto::GetNewOrUsed(cx, Scope, info, scrProto); + if (!proto) { + return NS_ERROR_FAILURE; + } + + wrapper = new XPCWrappedNative(std::move(identity), proto); + } else { + RefPtr<XPCNativeInterface> iface = Interface; + if (!iface) { + iface = XPCNativeInterface::GetISupports(cx); + } + + XPCNativeSetKey key(cx, iface); + RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(cx, &key); + + if (!set) { + return NS_ERROR_FAILURE; + } + + wrapper = new XPCWrappedNative(std::move(identity), Scope, set.forget()); + } + + MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent), + "Xray wrapper being used to parent XPCWrappedNative?"); + + // We use an AutoMarkingPtr here because it is possible for JS gc to happen + // after we have Init'd the wrapper but *before* we add it to the hashtable. + // This would cause the mSet to get collected and we'd later crash. I've + // *seen* this happen. + AutoMarkingWrappedNativePtr wrapperMarker(cx, wrapper); + + if (!wrapper->Init(cx, scrWrapper)) { + return NS_ERROR_FAILURE; + } + + if (!wrapper->FindTearOff(cx, Interface, false, &rv)) { + MOZ_ASSERT(NS_FAILED(rv), "returning NS_OK on failure"); + return rv; + } + + return FinishCreate(cx, Scope, Interface, cache, wrapper, resultWrapper); +} + +static nsresult FinishCreate(JSContext* cx, XPCWrappedNativeScope* Scope, + XPCNativeInterface* Interface, + nsWrapperCache* cache, XPCWrappedNative* inWrapper, + XPCWrappedNative** resultWrapper) { + MOZ_ASSERT(inWrapper); + + Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap(); + + RefPtr<XPCWrappedNative> wrapper; + // Deal with the case where the wrapper got created as a side effect + // of one of our calls out of this code. Add() returns the (possibly + // pre-existing) wrapper that ultimately ends up in the map, which is + // what we want. + wrapper = map->Add(inWrapper); + if (!wrapper) { + return NS_ERROR_FAILURE; + } + + if (wrapper == inWrapper) { + JSObject* flat = wrapper->GetFlatJSObject(); + MOZ_ASSERT(!cache || !cache->GetWrapperPreserveColor() || + flat == cache->GetWrapperPreserveColor(), + "This object has a cached wrapper that's different from " + "the JSObject held by its native wrapper?"); + + if (cache && !cache->GetWrapperPreserveColor()) { + cache->SetWrapper(flat); + } + } + + DEBUG_CheckClassInfoClaims(wrapper); + wrapper.forget(resultWrapper); + return NS_OK; +} + +// This ctor is used if this object will have a proto. +XPCWrappedNative::XPCWrappedNative(nsCOMPtr<nsISupports>&& aIdentity, + XPCWrappedNativeProto* aProto) + : mMaybeProto(aProto), mSet(aProto->GetSet()) { + MOZ_ASSERT(NS_IsMainThread()); + + mIdentity = aIdentity; + mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID); + + MOZ_ASSERT(mMaybeProto, "bad ctor param"); + MOZ_ASSERT(mSet, "bad ctor param"); +} + +// This ctor is used if this object will NOT have a proto. +XPCWrappedNative::XPCWrappedNative(nsCOMPtr<nsISupports>&& aIdentity, + XPCWrappedNativeScope* aScope, + RefPtr<XPCNativeSet>&& aSet) + : mMaybeScope(TagScope(aScope)), mSet(std::move(aSet)) { + MOZ_ASSERT(NS_IsMainThread()); + + mIdentity = aIdentity; + mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID); + + MOZ_ASSERT(aScope, "bad ctor param"); + MOZ_ASSERT(mSet, "bad ctor param"); +} + +XPCWrappedNative::~XPCWrappedNative() { Destroy(); } + +void XPCWrappedNative::Destroy() { + mScriptable = nullptr; + +#ifdef DEBUG + // Check that this object has already been swept from the map. + XPCWrappedNativeScope* scope = GetScope(); + if (scope) { + Native2WrappedNativeMap* map = scope->GetWrappedNativeMap(); + MOZ_ASSERT(map->Find(GetIdentityObject()) != this); + } +#endif + + if (mIdentity) { + XPCJSRuntime* rt = GetRuntime(); + if (rt && rt->GetDoingFinalization()) { + DeferredFinalize(mIdentity.forget().take()); + } else { + mIdentity = nullptr; + } + } + + mMaybeScope = nullptr; +} + +// A hack for bug 517665, increase the probability for GC. +// TODO: Try removing this and just using the actual size of the object. +static const size_t GCMemoryFactor = 2; + +inline void XPCWrappedNative::SetFlatJSObject(JSObject* object) { + MOZ_ASSERT(!mFlatJSObject); + MOZ_ASSERT(object); + + JS::AddAssociatedMemory(object, sizeof(*this) * GCMemoryFactor, + JS::MemoryUse::XPCWrappedNative); + + mFlatJSObject = object; + mFlatJSObject.setFlags(FLAT_JS_OBJECT_VALID); +} + +inline void XPCWrappedNative::UnsetFlatJSObject() { + MOZ_ASSERT(mFlatJSObject); + + JS::RemoveAssociatedMemory(mFlatJSObject.unbarrieredGetPtr(), + sizeof(*this) * GCMemoryFactor, + JS::MemoryUse::XPCWrappedNative); + + mFlatJSObject = nullptr; + mFlatJSObject.unsetFlags(FLAT_JS_OBJECT_VALID); +} + +// This is factored out so that it can be called publicly. +// static +nsIXPCScriptable* XPCWrappedNative::GatherProtoScriptable( + nsIClassInfo* classInfo) { + MOZ_ASSERT(classInfo, "bad param"); + + nsCOMPtr<nsIXPCScriptable> helper; + nsresult rv = classInfo->GetScriptableHelper(getter_AddRefs(helper)); + if (NS_SUCCEEDED(rv) && helper) { + return helper; + } + + return nullptr; +} + +// static +void XPCWrappedNative::GatherScriptable(nsISupports* aObj, + nsIClassInfo* aClassInfo, + nsIXPCScriptable** aScrProto, + nsIXPCScriptable** aScrWrapper) { + MOZ_ASSERT(!*aScrProto, "bad param"); + MOZ_ASSERT(!*aScrWrapper, "bad param"); + + nsCOMPtr<nsIXPCScriptable> scrProto; + nsCOMPtr<nsIXPCScriptable> scrWrapper; + + // Get the class scriptable helper (if present) + if (aClassInfo) { + scrProto = GatherProtoScriptable(aClassInfo); + } + + // Do the same for the wrapper specific scriptable + scrWrapper = do_QueryInterface(aObj); + if (scrWrapper) { + // A whole series of assertions to catch bad uses of scriptable flags on + // the scrWrapper... + + // Can't set WANT_PRECREATE on an instance scriptable without also + // setting it on the class scriptable. + MOZ_ASSERT_IF(scrWrapper->WantPreCreate(), + scrProto && scrProto->WantPreCreate()); + + // Can't set DONT_ENUM_QUERY_INTERFACE on an instance scriptable + // without also setting it on the class scriptable (if present). + MOZ_ASSERT_IF(scrWrapper->DontEnumQueryInterface() && scrProto, + scrProto->DontEnumQueryInterface()); + + // Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable + // without also setting it on the class scriptable (if present). + MOZ_ASSERT_IF(scrWrapper->AllowPropModsDuringResolve() && scrProto, + scrProto->AllowPropModsDuringResolve()); + } else { + scrWrapper = scrProto; + } + + scrProto.forget(aScrProto); + scrWrapper.forget(aScrWrapper); +} + +bool XPCWrappedNative::Init(JSContext* cx, nsIXPCScriptable* aScriptable) { + // Setup our scriptable... + MOZ_ASSERT(!mScriptable); + mScriptable = aScriptable; + + // create our flatJSObject + + const JSClass* jsclazz = + mScriptable ? mScriptable->GetJSClass() : &XPC_WN_NoHelper_JSClass; + + // We should have the global jsclass flag if and only if we're a global. + MOZ_ASSERT_IF(mScriptable, !!mScriptable->IsGlobalObject() == + !!(jsclazz->flags & JSCLASS_IS_GLOBAL)); + + MOZ_ASSERT(jsclazz && jsclazz->name && jsclazz->flags && + jsclazz->getResolve() && jsclazz->hasFinalize(), + "bad class"); + + RootedObject protoJSObject(cx, HasProto() ? GetProto()->GetJSProtoObject() + : JS::GetRealmObjectPrototype(cx)); + if (!protoJSObject) { + return false; + } + + JSObject* object = JS_NewObjectWithGivenProto(cx, jsclazz, protoJSObject); + if (!object) { + return false; + } + + SetFlatJSObject(object); + + JS::SetObjectISupports(mFlatJSObject, this); + + return FinishInit(cx); +} + +bool XPCWrappedNative::FinishInit(JSContext* cx) { + // This reference will be released when mFlatJSObject is finalized. + // Since this reference will push the refcount to 2 it will also root + // mFlatJSObject; + MOZ_ASSERT(1 == mRefCnt, "unexpected refcount value"); + NS_ADDREF(this); + + return true; +} + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCWrappedNative) + NS_INTERFACE_MAP_ENTRY(nsIXPConnectWrappedNative) + NS_INTERFACE_MAP_ENTRY(nsIXPConnectJSObjectHolder) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPConnectWrappedNative) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCWrappedNative) + +// Release calls Destroy() immediately when the refcount drops to 0 to +// clear the weak references nsXPConnect has to XPCWNs and to ensure there +// are no pointers to dying protos. +NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(XPCWrappedNative, Destroy()) + +/* + * Wrapped Native lifetime management is messy! + * + * - At creation we push the refcount to 2 (only one of which is owned by + * the native caller that caused the wrapper creation). + * - During the JS GC Mark phase we mark any wrapper with a refcount > 1. + * - The *only* thing that can make the wrapper get destroyed is the + * finalization of mFlatJSObject. And *that* should only happen if the only + * reference is the single extra (internal) reference we hold. + * + * - The wrapper has a pointer to the nsISupports 'view' of the wrapped native + * object i.e... mIdentity. This is held until the wrapper's refcount goes + * to zero and the wrapper is released, or until an expired wrapper (i.e., + * one unlinked by the cycle collector) has had its JS object finalized. + * + * - The wrapper also has 'tearoffs'. It has one tearoff for each interface + * that is actually used on the native object. 'Used' means we have either + * needed to QueryInterface to verify the availability of that interface + * of that we've had to QueryInterface in order to actually make a call + * into the wrapped object via the pointer for the given interface. + * + * - Each tearoff's 'mNative' member (if non-null) indicates one reference + * held by our wrapper on the wrapped native for the given interface + * associated with the tearoff. If we release that reference then we set + * the tearoff's 'mNative' to null. + * + * - We use the occasion of the JavaScript GCCallback for the JSGC_MARK_END + * event to scan the tearoffs of all wrappers for non-null mNative members + * that represent unused references. We can tell that a given tearoff's + * mNative is unused by noting that no live XPCCallContexts hold a pointer + * to the tearoff. + * + * - As a time/space tradeoff we may decide to not do this scanning on + * *every* JavaScript GC. We *do* want to do this *sometimes* because + * we want to allow for wrapped native's to do their own tearoff patterns. + * So, we want to avoid holding references to interfaces that we don't need. + * At the same time, we don't want to be bracketing every call into a + * wrapped native object with a QueryInterface/Release pair. And we *never* + * make a call into the object except via the correct interface for which + * we've QI'd. + * + * - Each tearoff *can* have a mJSObject whose lazily resolved properties + * represent the methods/attributes/constants of that specific interface. + * This is optionally reflected into JavaScript as "foo.nsIFoo" when "foo" + * is the name of mFlatJSObject and "nsIFoo" is the name of the given + * interface associated with the tearoff. When we create the tearoff's + * mJSObject we set it's parent to be mFlatJSObject. This way we know that + * when mFlatJSObject get's collected there are no outstanding reachable + * tearoff mJSObjects. Note that we must clear the private of any lingering + * mJSObjects at this point because we have no guarentee of the *order* of + * finalization within a given gc cycle. + */ + +void XPCWrappedNative::FlatJSObjectFinalized() { + if (!IsValid()) { + return; + } + + // Iterate the tearoffs and null out each of their JSObject's privates. + // This will keep them from trying to access their pointers to the + // dying tearoff object. We can safely assume that those remaining + // JSObjects are about to be finalized too. + + for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; + to = to->GetNextTearOff()) { + JSObject* jso = to->GetJSObjectPreserveColor(); + if (jso) { + JS::SetReservedSlot(jso, XPCWrappedNativeTearOff::TearOffSlot, + JS::UndefinedValue()); + to->JSObjectFinalized(); + } + + // We also need to release any native pointers held... + RefPtr<nsISupports> native = to->TakeNative(); + if (native && GetRuntime()) { + DeferredFinalize(native.forget().take()); + } + + to->SetInterface(nullptr); + } + + nsWrapperCache* cache = nullptr; + CallQueryInterface(mIdentity, &cache); + if (cache) { + cache->ClearWrapper(mFlatJSObject.unbarrieredGetPtr()); + } + + UnsetFlatJSObject(); + + MOZ_ASSERT(mIdentity, "bad pointer!"); + + if (IsWrapperExpired()) { + Destroy(); + } + + // Note that it's not safe to touch mNativeWrapper here since it's + // likely that it has already been finalized. + + Release(); +} + +void XPCWrappedNative::FlatJSObjectMoved(JSObject* obj, const JSObject* old) { + JS::AutoAssertGCCallback inCallback; + MOZ_ASSERT(mFlatJSObject == old); + + nsWrapperCache* cache = nullptr; + CallQueryInterface(mIdentity, &cache); + if (cache) { + cache->UpdateWrapper(obj, old); + } + + mFlatJSObject = obj; +} + +void XPCWrappedNative::SystemIsBeingShutDown() { + if (!IsValid()) { + return; + } + + // The long standing strategy is to leak some objects still held at shutdown. + // The general problem is that propagating release out of xpconnect at + // shutdown time causes a world of problems. + + // We leak mIdentity (see above). + + // Short circuit future finalization. + JS::SetObjectISupports(mFlatJSObject, nullptr); + UnsetFlatJSObject(); + + XPCWrappedNativeProto* proto = GetProto(); + + if (HasProto()) { + proto->SystemIsBeingShutDown(); + } + + // We don't clear mScriptable here. The destructor will do it. + + // Cleanup the tearoffs. + for (XPCWrappedNativeTearOff* to = &mFirstTearOff; to; + to = to->GetNextTearOff()) { + if (JSObject* jso = to->GetJSObjectPreserveColor()) { + JS::SetReservedSlot(jso, XPCWrappedNativeTearOff::TearOffSlot, + JS::UndefinedValue()); + to->SetJSObject(nullptr); + } + // We leak the tearoff mNative + // (for the same reason we leak mIdentity - see above). + Unused << to->TakeNative().take(); + to->SetInterface(nullptr); + } +} + +/***************************************************************************/ + +bool XPCWrappedNative::ExtendSet(JSContext* aCx, + XPCNativeInterface* aInterface) { + if (!mSet->HasInterface(aInterface)) { + XPCNativeSetKey key(mSet, aInterface); + RefPtr<XPCNativeSet> newSet = XPCNativeSet::GetNewOrUsed(aCx, &key); + if (!newSet) { + return false; + } + + mSet = std::move(newSet); + } + return true; +} + +XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff( + JSContext* cx, XPCNativeInterface* aInterface, + bool needJSObject /* = false */, nsresult* pError /* = nullptr */) { + nsresult rv = NS_OK; + XPCWrappedNativeTearOff* to; + XPCWrappedNativeTearOff* firstAvailable = nullptr; + + XPCWrappedNativeTearOff* lastTearOff; + for (lastTearOff = to = &mFirstTearOff; to; + lastTearOff = to, to = to->GetNextTearOff()) { + if (to->GetInterface() == aInterface) { + if (needJSObject && !to->GetJSObjectPreserveColor()) { + AutoMarkingWrappedNativeTearOffPtr tearoff(cx, to); + bool ok = InitTearOffJSObject(cx, to); + // During shutdown, we don't sweep tearoffs. So make sure + // to unmark manually in case the auto-marker marked us. + // We shouldn't ever be getting here _during_ our + // Mark/Sweep cycle, so this should be safe. + to->Unmark(); + if (!ok) { + to = nullptr; + rv = NS_ERROR_OUT_OF_MEMORY; + } + } + if (pError) { + *pError = rv; + } + return to; + } + if (!firstAvailable && to->IsAvailable()) { + firstAvailable = to; + } + } + + to = firstAvailable; + + if (!to) { + to = lastTearOff->AddTearOff(); + } + + { + // Scope keeps |tearoff| from leaking across the rest of the function. + AutoMarkingWrappedNativeTearOffPtr tearoff(cx, to); + rv = InitTearOff(cx, to, aInterface, needJSObject); + // During shutdown, we don't sweep tearoffs. So make sure to unmark + // manually in case the auto-marker marked us. We shouldn't ever be + // getting here _during_ our Mark/Sweep cycle, so this should be safe. + to->Unmark(); + if (NS_FAILED(rv)) { + to = nullptr; + } + } + + if (pError) { + *pError = rv; + } + return to; +} + +XPCWrappedNativeTearOff* XPCWrappedNative::FindTearOff(JSContext* cx, + const nsIID& iid) { + RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, &iid); + return iface ? FindTearOff(cx, iface) : nullptr; +} + +nsresult XPCWrappedNative::InitTearOff(JSContext* cx, + XPCWrappedNativeTearOff* aTearOff, + XPCNativeInterface* aInterface, + bool needJSObject) { + // Determine if the object really does this interface... + + const nsIID* iid = aInterface->GetIID(); + nsISupports* identity = GetIdentityObject(); + + // This is an nsRefPtr instead of an nsCOMPtr because it may not be the + // canonical nsISupports for this object. + RefPtr<nsISupports> qiResult; + + // We are about to call out to other code. + // So protect our intended tearoff. + + aTearOff->SetReserved(); + + if (NS_FAILED(identity->QueryInterface(*iid, getter_AddRefs(qiResult))) || + !qiResult) { + aTearOff->SetInterface(nullptr); + return NS_ERROR_NO_INTERFACE; + } + + // Guard against trying to build a tearoff for a shared nsIClassInfo. + if (iid->Equals(NS_GET_IID(nsIClassInfo))) { + nsCOMPtr<nsISupports> alternate_identity(do_QueryInterface(qiResult)); + if (alternate_identity.get() != identity) { + aTearOff->SetInterface(nullptr); + return NS_ERROR_NO_INTERFACE; + } + } + + // Guard against trying to build a tearoff for an interface that is + // aggregated and is implemented as a nsIXPConnectWrappedJS using this + // self-same JSObject. The XBL system does this. If we mutate the set + // of this wrapper then we will shadow the method that XBL has added to + // the JSObject that it has inserted in the JS proto chain between our + // JSObject and our XPCWrappedNativeProto's JSObject. If we let this + // set mutation happen then the interface's methods will be added to + // our JSObject, but calls on those methods will get routed up to + // native code and into the wrappedJS - which will do a method lookup + // on *our* JSObject and find the same method and make another call + // into an infinite loop. + // see: http://bugzilla.mozilla.org/show_bug.cgi?id=96725 + + nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS(do_QueryInterface(qiResult)); + if (wrappedJS) { + RootedObject jso(cx, wrappedJS->GetJSObject()); + if (jso == mFlatJSObject) { + // The implementing JSObject is the same as ours! Just say OK + // without actually extending the set. + // + // XXX It is a little cheesy to have FindTearOff return an + // 'empty' tearoff. But this is the centralized place to do the + // QI activities on the underlying object. *And* most caller to + // FindTearOff only look for a non-null result and ignore the + // actual tearoff returned. The only callers that do use the + // returned tearoff make sure to check for either a non-null + // JSObject or a matching Interface before proceeding. + // I think we can get away with this bit of ugliness. + + aTearOff->SetInterface(nullptr); + return NS_OK; + } + } + + if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateWrapper( + cx, *iid, identity, GetClassInfo()))) { + // the security manager vetoed. It should have set an exception. + aTearOff->SetInterface(nullptr); + return NS_ERROR_XPC_SECURITY_MANAGER_VETO; + } + + // If this is not already in our set we need to extend our set. + // Note: we do not cache the result of the previous call to HasInterface() + // because we unlocked and called out in the interim and the result of the + // previous call might not be correct anymore. + + if (!mSet->HasInterface(aInterface) && !ExtendSet(cx, aInterface)) { + aTearOff->SetInterface(nullptr); + return NS_ERROR_NO_INTERFACE; + } + + aTearOff->SetInterface(aInterface); + aTearOff->SetNative(qiResult); + + if (needJSObject && !InitTearOffJSObject(cx, aTearOff)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; +} + +bool XPCWrappedNative::InitTearOffJSObject(JSContext* cx, + XPCWrappedNativeTearOff* to) { + JSObject* obj = JS_NewObject(cx, &XPC_WN_Tearoff_JSClass); + if (!obj) { + return false; + } + + JS::SetReservedSlot(obj, XPCWrappedNativeTearOff::TearOffSlot, + JS::PrivateValue(to)); + to->SetJSObject(obj); + + JS::SetReservedSlot(obj, XPCWrappedNativeTearOff::FlatObjectSlot, + JS::ObjectValue(*mFlatJSObject)); + return true; +} + +/***************************************************************************/ + +static bool Throw(nsresult errNum, XPCCallContext& ccx) { + XPCThrower::Throw(errNum, ccx); + return false; +} + +/***************************************************************************/ + +class MOZ_STACK_CLASS CallMethodHelper final { + XPCCallContext& mCallContext; + nsresult mInvokeResult; + const nsXPTInterfaceInfo* const mIFaceInfo; + const nsXPTMethodInfo* mMethodInfo; + nsISupports* const mCallee; + const uint16_t mVTableIndex; + HandleId mIdxValueId; + + AutoTArray<nsXPTCVariant, 8> mDispatchParams; + uint8_t mJSContextIndex; // TODO make const + uint8_t mOptArgcIndex; // TODO make const + + Value* const mArgv; + const uint32_t mArgc; + + MOZ_ALWAYS_INLINE bool GetArraySizeFromParam(const nsXPTType& type, + HandleValue maybeArray, + uint32_t* result); + + MOZ_ALWAYS_INLINE bool GetInterfaceTypeFromParam(const nsXPTType& type, + nsID* result) const; + + MOZ_ALWAYS_INLINE bool GetOutParamSource(uint8_t paramIndex, + MutableHandleValue srcp) const; + + MOZ_ALWAYS_INLINE bool GatherAndConvertResults(); + + MOZ_ALWAYS_INLINE bool QueryInterfaceFastPath(); + + nsXPTCVariant* GetDispatchParam(uint8_t paramIndex) { + if (paramIndex >= mJSContextIndex) { + paramIndex += 1; + } + if (paramIndex >= mOptArgcIndex) { + paramIndex += 1; + } + return &mDispatchParams[paramIndex]; + } + const nsXPTCVariant* GetDispatchParam(uint8_t paramIndex) const { + return const_cast<CallMethodHelper*>(this)->GetDispatchParam(paramIndex); + } + + MOZ_ALWAYS_INLINE bool InitializeDispatchParams(); + + MOZ_ALWAYS_INLINE bool ConvertIndependentParams(bool* foundDependentParam); + MOZ_ALWAYS_INLINE bool ConvertIndependentParam(uint8_t i); + MOZ_ALWAYS_INLINE bool ConvertDependentParams(); + MOZ_ALWAYS_INLINE bool ConvertDependentParam(uint8_t i); + + MOZ_ALWAYS_INLINE nsresult Invoke(); + + public: + explicit CallMethodHelper(XPCCallContext& ccx) + : mCallContext(ccx), + mInvokeResult(NS_ERROR_UNEXPECTED), + mIFaceInfo(ccx.GetInterface()->GetInterfaceInfo()), + mMethodInfo(nullptr), + mCallee(ccx.GetTearOff()->GetNative()), + mVTableIndex(ccx.GetMethodIndex()), + mIdxValueId(ccx.GetContext()->GetStringID(XPCJSContext::IDX_VALUE)), + mJSContextIndex(UINT8_MAX), + mOptArgcIndex(UINT8_MAX), + mArgv(ccx.GetArgv()), + mArgc(ccx.GetArgc()) + + { + // Success checked later. + mIFaceInfo->GetMethodInfo(mVTableIndex, &mMethodInfo); + } + + ~CallMethodHelper(); + + MOZ_ALWAYS_INLINE bool Call(); + + // Trace implementation so we can put our CallMethodHelper in a Rooted<T>. + void trace(JSTracer* aTrc); +}; + +// static +bool XPCWrappedNative::CallMethod(XPCCallContext& ccx, + CallMode mode /*= CALL_METHOD */) { + nsresult rv = ccx.CanCallNow(); + if (NS_FAILED(rv)) { + return Throw(rv, ccx); + } + + JS::Rooted<CallMethodHelper> helper(ccx, /* init = */ ccx); + return helper.get().Call(); +} + +bool CallMethodHelper::Call() { + mCallContext.SetRetVal(JS::UndefinedValue()); + + mCallContext.GetContext()->SetPendingException(nullptr); + + using Flags = js::ProfilingStackFrame::Flags; + if (mVTableIndex == 0) { + AUTO_PROFILER_LABEL_DYNAMIC_FAST(mIFaceInfo->Name(), "QueryInterface", DOM, + mCallContext.GetJSContext(), + uint32_t(Flags::STRING_TEMPLATE_METHOD) | + uint32_t(Flags::RELEVANT_FOR_JS)); + + return QueryInterfaceFastPath(); + } + + if (!mMethodInfo) { + Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, mCallContext); + return false; + } + + // Add profiler labels matching the WebIDL profiler labels, + // which also use the DOM category. + Flags templateFlag = Flags::STRING_TEMPLATE_METHOD; + if (mMethodInfo->IsGetter()) { + templateFlag = Flags::STRING_TEMPLATE_GETTER; + } + if (mMethodInfo->IsSetter()) { + templateFlag = Flags::STRING_TEMPLATE_SETTER; + } + AUTO_PROFILER_LABEL_DYNAMIC_FAST( + mIFaceInfo->Name(), mMethodInfo->NameOrDescription(), DOM, + mCallContext.GetJSContext(), + uint32_t(templateFlag) | uint32_t(Flags::RELEVANT_FOR_JS)); + + if (!InitializeDispatchParams()) { + return false; + } + + // Iterate through the params doing conversions of independent params only. + // When we later convert the dependent params (if any) we will know that + // the params upon which they depend will have already been converted - + // regardless of ordering. + bool foundDependentParam = false; + if (!ConvertIndependentParams(&foundDependentParam)) { + return false; + } + + if (foundDependentParam && !ConvertDependentParams()) { + return false; + } + + mInvokeResult = Invoke(); + + if (JS_IsExceptionPending(mCallContext)) { + return false; + } + + if (NS_FAILED(mInvokeResult)) { + ThrowBadResult(mInvokeResult, mCallContext); + return false; + } + + return GatherAndConvertResults(); +} + +CallMethodHelper::~CallMethodHelper() { + for (nsXPTCVariant& param : mDispatchParams) { + uint32_t arraylen = 0; + if (!GetArraySizeFromParam(param.type, UndefinedHandleValue, &arraylen)) { + continue; + } + + xpc::DestructValue(param.type, ¶m.val, arraylen); + } +} + +bool CallMethodHelper::GetArraySizeFromParam(const nsXPTType& type, + HandleValue maybeArray, + uint32_t* result) { + if (type.Tag() != nsXPTType::T_LEGACY_ARRAY && + type.Tag() != nsXPTType::T_PSTRING_SIZE_IS && + type.Tag() != nsXPTType::T_PWSTRING_SIZE_IS) { + *result = 0; + return true; + } + + uint8_t argnum = type.ArgNum(); + uint32_t* lengthp = &GetDispatchParam(argnum)->val.u32; + + // TODO fixup the various exceptions that are thrown + + // If the array length wasn't passed, it might have been listed as optional. + // When converting arguments from JS to C++, we pass the array as + // |maybeArray|, and give ourselves the chance to infer the length. Once we + // have it, we stick it in the right slot so that we can find it again when + // cleaning up the params. from the array. + if (argnum >= mArgc && maybeArray.isObject()) { + MOZ_ASSERT(mMethodInfo->Param(argnum).IsOptional()); + RootedObject arrayOrNull(mCallContext, &maybeArray.toObject()); + + bool isArray; + bool ok = false; + if (JS::IsArrayObject(mCallContext, maybeArray, &isArray) && isArray) { + ok = JS::GetArrayLength(mCallContext, arrayOrNull, lengthp); + } else if (JS_IsTypedArrayObject(&maybeArray.toObject())) { + size_t len = JS_GetTypedArrayLength(&maybeArray.toObject()); + if (len <= UINT32_MAX) { + *lengthp = len; + ok = true; + } + } + + if (!ok) { + return Throw(NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY, mCallContext); + } + } + + *result = *lengthp; + return true; +} + +bool CallMethodHelper::GetInterfaceTypeFromParam(const nsXPTType& type, + nsID* result) const { + result->Clear(); + + const nsXPTType& inner = type.InnermostType(); + if (inner.Tag() == nsXPTType::T_INTERFACE) { + if (!inner.GetInterface()) { + return Throw(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, mCallContext); + } + + *result = inner.GetInterface()->IID(); + } else if (inner.Tag() == nsXPTType::T_INTERFACE_IS) { + const nsXPTCVariant* param = GetDispatchParam(inner.ArgNum()); + if (param->type.Tag() != nsXPTType::T_NSID && + param->type.Tag() != nsXPTType::T_NSIDPTR) { + return Throw(NS_ERROR_UNEXPECTED, mCallContext); + } + + const void* ptr = ¶m->val; + if (param->type.Tag() == nsXPTType::T_NSIDPTR) { + ptr = *static_cast<nsID* const*>(ptr); + } + + if (!ptr) { + return ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, + inner.ArgNum(), mCallContext); + } + + *result = *static_cast<const nsID*>(ptr); + } + return true; +} + +bool CallMethodHelper::GetOutParamSource(uint8_t paramIndex, + MutableHandleValue srcp) const { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(paramIndex); + bool isRetval = ¶mInfo == mMethodInfo->GetRetval(); + + if (paramInfo.IsOut() && !isRetval) { + MOZ_ASSERT(paramIndex < mArgc || paramInfo.IsOptional(), + "Expected either enough arguments or an optional argument"); + Value arg = paramIndex < mArgc ? mArgv[paramIndex] : JS::NullValue(); + if (paramIndex < mArgc) { + RootedObject obj(mCallContext); + if (!arg.isPrimitive()) { + obj = &arg.toObject(); + } + if (!obj || !JS_GetPropertyById(mCallContext, obj, mIdxValueId, srcp)) { + // Explicitly passed in unusable value for out param. Note + // that if i >= mArgc we already know that |arg| is JS::NullValue(), + // and that's ok. + ThrowBadParam(NS_ERROR_XPC_NEED_OUT_OBJECT, paramIndex, mCallContext); + return false; + } + } + } + + return true; +} + +bool CallMethodHelper::GatherAndConvertResults() { + // now we iterate through the native params to gather and convert results + uint8_t paramCount = mMethodInfo->GetParamCount(); + for (uint8_t i = 0; i < paramCount; i++) { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i); + if (!paramInfo.IsOut()) { + continue; + } + + const nsXPTType& type = paramInfo.GetType(); + nsXPTCVariant* dp = GetDispatchParam(i); + RootedValue v(mCallContext, NullValue()); + + uint32_t array_count = 0; + nsID param_iid; + if (!GetInterfaceTypeFromParam(type, ¶m_iid) || + !GetArraySizeFromParam(type, UndefinedHandleValue, &array_count)) + return false; + + nsresult err; + if (!XPCConvert::NativeData2JS(mCallContext, &v, &dp->val, type, ¶m_iid, + array_count, &err)) { + ThrowBadParam(err, i, mCallContext); + return false; + } + + if (¶mInfo == mMethodInfo->GetRetval()) { + mCallContext.SetRetVal(v); + } else if (i < mArgc) { + // we actually assured this before doing the invoke + MOZ_ASSERT(mArgv[i].isObject(), "out var is not object"); + RootedObject obj(mCallContext, &mArgv[i].toObject()); + if (!JS_SetPropertyById(mCallContext, obj, mIdxValueId, v)) { + ThrowBadParam(NS_ERROR_XPC_CANT_SET_OUT_VAL, i, mCallContext); + return false; + } + } else { + MOZ_ASSERT(paramInfo.IsOptional(), + "Expected either enough arguments or an optional argument"); + } + } + + return true; +} + +bool CallMethodHelper::QueryInterfaceFastPath() { + MOZ_ASSERT(mVTableIndex == 0, + "Using the QI fast-path for a method other than QueryInterface"); + + if (mArgc < 1) { + Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, mCallContext); + return false; + } + + if (!mArgv[0].isObject()) { + ThrowBadParam(NS_ERROR_XPC_BAD_CONVERT_JS, 0, mCallContext); + return false; + } + + JS::RootedValue iidarg(mCallContext, mArgv[0]); + Maybe<nsID> iid = xpc::JSValue2ID(mCallContext, iidarg); + if (!iid) { + ThrowBadParam(NS_ERROR_XPC_BAD_CONVERT_JS, 0, mCallContext); + return false; + } + + nsISupports* qiresult = nullptr; + mInvokeResult = mCallee->QueryInterface(iid.ref(), (void**)&qiresult); + + if (NS_FAILED(mInvokeResult)) { + ThrowBadResult(mInvokeResult, mCallContext); + return false; + } + + RootedValue v(mCallContext, NullValue()); + nsresult err; + bool success = XPCConvert::NativeData2JS(mCallContext, &v, &qiresult, + {nsXPTType::T_INTERFACE_IS}, + iid.ptr(), 0, &err); + NS_IF_RELEASE(qiresult); + + if (!success) { + ThrowBadParam(err, 0, mCallContext); + return false; + } + + mCallContext.SetRetVal(v); + return true; +} + +bool CallMethodHelper::InitializeDispatchParams() { + const uint8_t wantsOptArgc = mMethodInfo->WantsOptArgc() ? 1 : 0; + const uint8_t wantsJSContext = mMethodInfo->WantsContext() ? 1 : 0; + const uint8_t paramCount = mMethodInfo->GetParamCount(); + uint8_t requiredArgs = paramCount; + + // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this. + if (mMethodInfo->HasRetval()) { + requiredArgs--; + } + + if (mArgc < requiredArgs || wantsOptArgc) { + if (wantsOptArgc) { + // The implicit JSContext*, if we have one, comes first. + mOptArgcIndex = requiredArgs + wantsJSContext; + } + + // skip over any optional arguments + while (requiredArgs && + mMethodInfo->GetParam(requiredArgs - 1).IsOptional()) { + requiredArgs--; + } + + if (mArgc < requiredArgs) { + Throw(NS_ERROR_XPC_NOT_ENOUGH_ARGS, mCallContext); + return false; + } + } + + mJSContextIndex = mMethodInfo->IndexOfJSContext(); + + // Allocate enough space in mDispatchParams up-front. + // XXX(Bug 1631371) Check if this should use a fallible operation as it + // pretended earlier. + mDispatchParams.AppendElements(paramCount + wantsJSContext + wantsOptArgc); + + // Initialize each parameter to a valid state (for safe cleanup later). + for (uint8_t i = 0, paramIdx = 0; i < mDispatchParams.Length(); i++) { + nsXPTCVariant& dp = mDispatchParams[i]; + + if (i == mJSContextIndex) { + // Fill in the JSContext argument + dp.type = nsXPTType::T_VOID; + dp.val.p = mCallContext; + } else if (i == mOptArgcIndex) { + // Fill in the optional_argc argument + dp.type = nsXPTType::T_U8; + dp.val.u8 = std::min<uint32_t>(mArgc, paramCount) - requiredArgs; + } else { + // Initialize normal arguments. + const nsXPTParamInfo& param = mMethodInfo->Param(paramIdx); + dp.type = param.Type(); + xpc::InitializeValue(dp.type, &dp.val); + + // Specify the correct storage/calling semantics. This will also set + // the `ptr` field to be self-referential. + if (param.IsIndirect()) { + dp.SetIndirect(); + } + + // Advance to the next normal parameter. + paramIdx++; + } + } + + return true; +} + +bool CallMethodHelper::ConvertIndependentParams(bool* foundDependentParam) { + const uint8_t paramCount = mMethodInfo->GetParamCount(); + for (uint8_t i = 0; i < paramCount; i++) { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i); + + if (paramInfo.GetType().IsDependent()) { + *foundDependentParam = true; + } else if (!ConvertIndependentParam(i)) { + return false; + } + } + + return true; +} + +bool CallMethodHelper::ConvertIndependentParam(uint8_t i) { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i); + const nsXPTType& type = paramInfo.Type(); + nsXPTCVariant* dp = GetDispatchParam(i); + + // Even if there's nothing to convert, we still need to examine the + // JSObject container for out-params. If it's null or otherwise invalid, + // we want to know before the call, rather than after. + // + // This is a no-op for 'in' params. + RootedValue src(mCallContext); + if (!GetOutParamSource(i, &src)) { + return false; + } + + // All that's left to do is value conversion. Bail early if we don't need + // to do that. + if (!paramInfo.IsIn()) { + return true; + } + + // Some types usually don't support default values, but we want to handle + // the default value if IsOptional is true. + if (i >= mArgc) { + MOZ_ASSERT(paramInfo.IsOptional(), "missing non-optional argument!"); + if (type.Tag() == nsXPTType::T_NSID) { + // Use a default value of the null ID for optional NSID objects. + dp->ext.nsid.Clear(); + return true; + } + + if (type.Tag() == nsXPTType::T_ARRAY) { + // Use a default value of empty array for optional Array objects. + dp->ext.array.Clear(); + return true; + } + } + + // We're definitely some variety of 'in' now, so there's something to + // convert. The source value for conversion depends on whether we're + // dealing with an 'in' or an 'inout' parameter. 'inout' was handled above, + // so all that's left is 'in'. + if (!paramInfo.IsOut()) { + // Handle the 'in' case. + MOZ_ASSERT(i < mArgc || paramInfo.IsOptional(), + "Expected either enough arguments or an optional argument"); + if (i < mArgc) { + src = mArgv[i]; + } else if (type.Tag() == nsXPTType::T_JSVAL) { + src.setUndefined(); + } else { + src.setNull(); + } + } + + nsID param_iid = {0}; + const nsXPTType& inner = type.InnermostType(); + if (inner.Tag() == nsXPTType::T_INTERFACE) { + if (!inner.GetInterface()) { + return ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, + mCallContext); + } + param_iid = inner.GetInterface()->IID(); + } + + nsresult err; + if (!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type, ¶m_iid, + 0, &err)) { + ThrowBadParam(err, i, mCallContext); + return false; + } + + return true; +} + +bool CallMethodHelper::ConvertDependentParams() { + const uint8_t paramCount = mMethodInfo->GetParamCount(); + for (uint8_t i = 0; i < paramCount; i++) { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i); + + if (!paramInfo.GetType().IsDependent()) { + continue; + } + if (!ConvertDependentParam(i)) { + return false; + } + } + + return true; +} + +bool CallMethodHelper::ConvertDependentParam(uint8_t i) { + const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i); + const nsXPTType& type = paramInfo.Type(); + nsXPTCVariant* dp = GetDispatchParam(i); + + // Even if there's nothing to convert, we still need to examine the + // JSObject container for out-params. If it's null or otherwise invalid, + // we want to know before the call, rather than after. + // + // This is a no-op for 'in' params. + RootedValue src(mCallContext); + if (!GetOutParamSource(i, &src)) { + return false; + } + + // All that's left to do is value conversion. Bail early if we don't need + // to do that. + if (!paramInfo.IsIn()) { + return true; + } + + // We're definitely some variety of 'in' now, so there's something to + // convert. The source value for conversion depends on whether we're + // dealing with an 'in' or an 'inout' parameter. 'inout' was handled above, + // so all that's left is 'in'. + if (!paramInfo.IsOut()) { + // Handle the 'in' case. + MOZ_ASSERT(i < mArgc || paramInfo.IsOptional(), + "Expected either enough arguments or an optional argument"); + src = i < mArgc ? mArgv[i] : JS::NullValue(); + } + + nsID param_iid; + uint32_t array_count; + if (!GetInterfaceTypeFromParam(type, ¶m_iid) || + !GetArraySizeFromParam(type, src, &array_count)) + return false; + + nsresult err; + + if (!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type, ¶m_iid, + array_count, &err)) { + ThrowBadParam(err, i, mCallContext); + return false; + } + + return true; +} + +nsresult CallMethodHelper::Invoke() { + uint32_t argc = mDispatchParams.Length(); + nsXPTCVariant* argv = mDispatchParams.Elements(); + + return NS_InvokeByIndex(mCallee, mVTableIndex, argc, argv); +} + +static void TraceParam(JSTracer* aTrc, void* aVal, const nsXPTType& aType, + uint32_t aArrayLen = 0) { + if (aType.Tag() == nsXPTType::T_JSVAL) { + JS::TraceRoot(aTrc, (JS::Value*)aVal, "XPCWrappedNative::CallMethod param"); + } else if (aType.Tag() == nsXPTType::T_ARRAY) { + auto* array = (xpt::detail::UntypedTArray*)aVal; + const nsXPTType& elty = aType.ArrayElementType(); + + for (uint32_t i = 0; i < array->Length(); ++i) { + TraceParam(aTrc, elty.ElementPtr(array->Elements(), i), elty); + } + } else if (aType.Tag() == nsXPTType::T_LEGACY_ARRAY && *(void**)aVal) { + const nsXPTType& elty = aType.ArrayElementType(); + + for (uint32_t i = 0; i < aArrayLen; ++i) { + TraceParam(aTrc, elty.ElementPtr(*(void**)aVal, i), elty); + } + } +} + +void CallMethodHelper::trace(JSTracer* aTrc) { + // We need to note each of our initialized parameters which contain jsvals. + for (nsXPTCVariant& param : mDispatchParams) { + // We only need to trace parameters which have an innermost JSVAL. + if (param.type.InnermostType().Tag() != nsXPTType::T_JSVAL) { + continue; + } + + uint32_t arrayLen = 0; + if (!GetArraySizeFromParam(param.type, UndefinedHandleValue, &arrayLen)) { + continue; + } + + TraceParam(aTrc, ¶m.val, param.type, arrayLen); + } +} + +/***************************************************************************/ +// interface methods + +JSObject* XPCWrappedNative::GetJSObject() { return GetFlatJSObject(); } + +XPCWrappedNative* nsIXPConnectWrappedNative::AsXPCWrappedNative() { + return static_cast<XPCWrappedNative*>(this); +} + +nsresult nsIXPConnectWrappedNative::DebugDump(int16_t depth) { + return AsXPCWrappedNative()->DebugDump(depth); +} + +nsresult XPCWrappedNative::DebugDump(int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS( + ("XPCWrappedNative @ %p with mRefCnt = %" PRIuPTR, this, mRefCnt.get())); + XPC_LOG_INDENT(); + + if (HasProto()) { + XPCWrappedNativeProto* proto = GetProto(); + if (depth && proto) { + proto->DebugDump(depth); + } else { + XPC_LOG_ALWAYS(("mMaybeProto @ %p", proto)); + } + } else + XPC_LOG_ALWAYS(("Scope @ %p", GetScope())); + + if (depth && mSet) { + mSet->DebugDump(depth); + } else { + XPC_LOG_ALWAYS(("mSet @ %p", mSet.get())); + } + + XPC_LOG_ALWAYS(("mFlatJSObject of %p", mFlatJSObject.unbarrieredGetPtr())); + XPC_LOG_ALWAYS(("mIdentity of %p", mIdentity.get())); + XPC_LOG_ALWAYS(("mScriptable @ %p", mScriptable.get())); + + if (depth && mScriptable) { + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("mFlags of %x", mScriptable->GetScriptableFlags())); + XPC_LOG_ALWAYS(("mJSClass @ %p", mScriptable->GetJSClass())); + XPC_LOG_OUTDENT(); + } + XPC_LOG_OUTDENT(); +#endif + return NS_OK; +} + +/***************************************************************************/ + +char* XPCWrappedNative::ToString( + XPCWrappedNativeTearOff* to /* = nullptr */) const { +#ifdef DEBUG +# define FMT_ADDR " @ 0x%p" +# define FMT_STR(str) str +# define PARAM_ADDR(w) , w +#else +# define FMT_ADDR "" +# define FMT_STR(str) +# define PARAM_ADDR(w) +#endif + + UniqueChars sz; + UniqueChars name; + + nsCOMPtr<nsIXPCScriptable> scr = GetScriptable(); + if (scr) { + name = JS_smprintf("%s", scr->GetJSClass()->name); + } + if (to) { + const char* fmt = name ? " (%s)" : "%s"; + name = JS_sprintf_append(std::move(name), fmt, + to->GetInterface()->GetNameString()); + } else if (!name) { + XPCNativeSet* set = GetSet(); + XPCNativeInterface** array = set->GetInterfaceArray(); + uint16_t count = set->GetInterfaceCount(); + MOZ_RELEASE_ASSERT(count >= 1, "Expected at least one interface"); + MOZ_ASSERT(*array[0]->GetIID() == NS_GET_IID(nsISupports), + "The first interface must be nsISupports"); + + // The first interface is always nsISupports, so don't print it, unless + // there are no others. + if (count == 1) { + name = JS_sprintf_append(std::move(name), "nsISupports"); + } else if (count == 2) { + name = + JS_sprintf_append(std::move(name), "%s", array[1]->GetNameString()); + } else { + for (uint16_t i = 1; i < count; i++) { + const char* fmt = (i == 1) ? "(%s" + : (i == count - 1) ? ", %s)" + : ", %s"; + name = + JS_sprintf_append(std::move(name), fmt, array[i]->GetNameString()); + } + } + } + + if (!name) { + return nullptr; + } + const char* fmt = "[xpconnect wrapped %s" FMT_ADDR FMT_STR(" (native") + FMT_ADDR FMT_STR(")") "]"; + if (scr) { + fmt = "[object %s" FMT_ADDR FMT_STR(" (native") FMT_ADDR FMT_STR(")") "]"; + } + sz = + JS_smprintf(fmt, name.get() PARAM_ADDR(this) PARAM_ADDR(mIdentity.get())); + + return sz.release(); + +#undef FMT_ADDR +#undef PARAM_ADDR +} + +/***************************************************************************/ + +#ifdef XPC_CHECK_CLASSINFO_CLAIMS +static void DEBUG_CheckClassInfoClaims(XPCWrappedNative* wrapper) { + if (!wrapper || !wrapper->GetClassInfo()) { + return; + } + + nsISupports* obj = wrapper->GetIdentityObject(); + XPCNativeSet* set = wrapper->GetSet(); + uint16_t count = set->GetInterfaceCount(); + for (uint16_t i = 0; i < count; i++) { + nsIClassInfo* clsInfo = wrapper->GetClassInfo(); + XPCNativeInterface* iface = set->GetInterfaceAt(i); + const nsXPTInterfaceInfo* info = iface->GetInterfaceInfo(); + nsISupports* ptr; + + nsresult rv = obj->QueryInterface(info->IID(), (void**)&ptr); + if (NS_SUCCEEDED(rv)) { + NS_RELEASE(ptr); + continue; + } + if (rv == NS_ERROR_OUT_OF_MEMORY) { + continue; + } + + // Houston, We have a problem... + + char* className = nullptr; + char* contractID = nullptr; + const char* interfaceName = info->Name(); + + clsInfo->GetContractID(&contractID); + if (wrapper->GetScriptable()) { + wrapper->GetScriptable()->GetClassName(&className); + } + + printf( + "\n!!! Object's nsIClassInfo lies about its interfaces!!!\n" + " classname: %s \n" + " contractid: %s \n" + " unimplemented interface name: %s\n\n", + className ? className : "<unknown>", + contractID ? contractID : "<unknown>", interfaceName); + + if (className) { + free(className); + } + if (contractID) { + free(contractID); + } + } +} +#endif diff --git a/js/xpconnect/src/XPCWrappedNativeInfo.cpp b/js/xpconnect/src/XPCWrappedNativeInfo.cpp new file mode 100644 index 0000000000..ec20145cad --- /dev/null +++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp @@ -0,0 +1,728 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Manage the shared info about interfaces for use by wrappedNatives. */ + +#include "xpcprivate.h" +#include "XPCMaps.h" +#include "js/Wrapper.h" + +#include "mozilla/MemoryReporting.h" +#include "nsIScriptError.h" +#include "nsPrintfCString.h" +#include "nsPointerHashKeys.h" + +using namespace JS; +using namespace mozilla; + +/***************************************************************************/ + +// XPCNativeMember + +// static +bool XPCNativeMember::GetCallInfo(JSObject* funobj, + RefPtr<XPCNativeInterface>* pInterface, + XPCNativeMember** pMember) { + funobj = js::UncheckedUnwrap(funobj); + Value memberVal = + js::GetFunctionNativeReserved(funobj, XPC_FUNCTION_NATIVE_MEMBER_SLOT); + + *pMember = static_cast<XPCNativeMember*>(memberVal.toPrivate()); + *pInterface = (*pMember)->GetInterface(); + + return true; +} + +bool XPCNativeMember::NewFunctionObject(XPCCallContext& ccx, + XPCNativeInterface* iface, + HandleObject parent, Value* pval) { + MOZ_ASSERT(!IsConstant(), + "Only call this if you're sure this is not a constant!"); + + return Resolve(ccx, iface, parent, pval); +} + +bool XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface, + HandleObject parent, Value* vp) { + MOZ_ASSERT(iface == GetInterface()); + if (IsConstant()) { + RootedValue resultVal(ccx); + nsCString name; + if (NS_FAILED(iface->GetInterfaceInfo()->GetConstant(mIndex, &resultVal, + getter_Copies(name)))) + return false; + + *vp = resultVal; + + return true; + } + // else... + + // This is a method or attribute - we'll be needing a function object + + int argc; + JSNative callback; + + if (IsMethod()) { + const nsXPTMethodInfo* info; + if (NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info))) { + return false; + } + + // Note: ASSUMES that retval is last arg. + argc = (int)info->ParamCount(); + if (info->HasRetval()) { + argc--; + } + + callback = XPC_WN_CallMethod; + } else { + argc = 0; + callback = XPC_WN_GetterSetter; + } + + jsid name = GetName(); + JS_MarkCrossZoneId(ccx, name); + + JSFunction* fun; + if (name.isString()) { + fun = js::NewFunctionByIdWithReserved(ccx, callback, argc, 0, name); + } else { + fun = js::NewFunctionWithReserved(ccx, callback, argc, 0, nullptr); + } + if (!fun) { + return false; + } + + JSObject* funobj = JS_GetFunctionObject(fun); + if (!funobj) { + return false; + } + + js::SetFunctionNativeReserved(funobj, XPC_FUNCTION_NATIVE_MEMBER_SLOT, + PrivateValue(this)); + js::SetFunctionNativeReserved(funobj, XPC_FUNCTION_PARENT_OBJECT_SLOT, + ObjectValue(*parent)); + + vp->setObject(*funobj); + + return true; +} + +/***************************************************************************/ +// XPCNativeInterface + +XPCNativeInterface::~XPCNativeInterface() { + XPCJSRuntime::Get()->GetIID2NativeInterfaceMap()->Remove(this); +} + +// static +already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( + JSContext* cx, const nsIID* iid) { + RefPtr<XPCNativeInterface> iface; + XPCJSRuntime* rt = XPCJSRuntime::Get(); + + IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap(); + if (!map) { + return nullptr; + } + + iface = map->Find(*iid); + + if (iface) { + return iface.forget(); + } + + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(*iid); + if (!info) { + return nullptr; + } + + return NewInstance(cx, map, info); +} + +// static +already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( + JSContext* cx, const nsXPTInterfaceInfo* info) { + RefPtr<XPCNativeInterface> iface; + + XPCJSRuntime* rt = XPCJSRuntime::Get(); + + IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap(); + if (!map) { + return nullptr; + } + + iface = map->Find(info->IID()); + + if (iface) { + return iface.forget(); + } + + return NewInstance(cx, map, info); +} + +// static +already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetNewOrUsed( + JSContext* cx, const char* name) { + const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByName(name); + return info ? GetNewOrUsed(cx, info) : nullptr; +} + +// static +already_AddRefed<XPCNativeInterface> XPCNativeInterface::GetISupports( + JSContext* cx) { + // XXX We should optimize this to cache this common XPCNativeInterface. + return GetNewOrUsed(cx, &NS_GET_IID(nsISupports)); +} + +// static +already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance( + JSContext* cx, IID2NativeInterfaceMap* aMap, + const nsXPTInterfaceInfo* aInfo) { + // XXX Investigate lazy init? This is a problem given the + // 'placement new' scheme - we need to at least know how big to make + // the object. We might do a scan of methods to determine needed size, + // then make our object, but avoid init'ing *any* members until asked? + // Find out how often we create these objects w/o really looking at + // (or using) the members. + + if (aInfo->IsMainProcessScriptableOnly() && !XRE_IsParentProcess()) { + nsCOMPtr<nsIConsoleService> console( + do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + if (console) { + const char* intfNameChars = aInfo->Name(); + nsPrintfCString errorMsg("Use of %s in content process is deprecated.", + intfNameChars); + + nsAutoString filename; + uint32_t lineno = 0, column = 0; + nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column); + nsCOMPtr<nsIScriptError> error( + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); + error->Init(NS_ConvertUTF8toUTF16(errorMsg), filename, u""_ns, lineno, + column, nsIScriptError::warningFlag, "chrome javascript"_ns, + false /* from private window */, + true /* from chrome context */); + console->LogMessage(error); + } + } + + // Make sure the code below does not GC. This means we don't need to trace the + // PropertyKeys in the MemberVector, or the XPCNativeInterface we create + // before it's added to the map. + JS::AutoCheckCannotGC nogc; + + const uint16_t methodCount = aInfo->MethodCount(); + const uint16_t constCount = aInfo->ConstantCount(); + const uint16_t totalCount = methodCount + constCount; + + using MemberVector = + mozilla::Vector<XPCNativeMember, 16, InfallibleAllocPolicy>; + MemberVector members; + MOZ_ALWAYS_TRUE(members.reserve(totalCount)); + + // NOTE: since getters and setters share a member, we might not use all + // of the member objects. + + for (unsigned int i = 0; i < methodCount; i++) { + const nsXPTMethodInfo& info = aInfo->Method(i); + + // don't reflect Addref or Release + if (i == 1 || i == 2) { + continue; + } + + if (!info.IsReflectable()) { + continue; + } + + jsid name; + if (!info.GetId(cx, name)) { + NS_ERROR("bad method name"); + return nullptr; + } + + if (info.IsSetter()) { + MOZ_ASSERT(!members.empty(), "bad setter"); + // Note: ASSUMES Getter/Setter pairs are next to each other + // This is a rule of the typelib spec. + XPCNativeMember* cur = &members.back(); + MOZ_ASSERT(cur->GetName() == name, "bad setter"); + MOZ_ASSERT(cur->IsReadOnlyAttribute(), "bad setter"); + MOZ_ASSERT(cur->GetIndex() == i - 1, "bad setter"); + cur->SetWritableAttribute(); + } else { + // XXX need better way to find dups + // MOZ_ASSERT(!LookupMemberByID(name),"duplicate method name"); + size_t indexInInterface = members.length(); + if (indexInInterface == XPCNativeMember::GetMaxIndexInInterface()) { + NS_WARNING("Too many members in interface"); + return nullptr; + } + XPCNativeMember cur; + cur.SetName(name); + if (info.IsGetter()) { + cur.SetReadOnlyAttribute(i); + } else { + cur.SetMethod(i); + } + cur.SetIndexInInterface(indexInInterface); + members.infallibleAppend(cur); + } + } + + for (unsigned int i = 0; i < constCount; i++) { + RootedValue constant(cx); + nsCString namestr; + if (NS_FAILED(aInfo->GetConstant(i, &constant, getter_Copies(namestr)))) { + return nullptr; + } + + RootedString str(cx, JS_AtomizeString(cx, namestr.get())); + if (!str) { + NS_ERROR("bad constant name"); + return nullptr; + } + jsid name = PropertyKey::NonIntAtom(str); + + // XXX need better way to find dups + // MOZ_ASSERT(!LookupMemberByID(name),"duplicate method/constant name"); + size_t indexInInterface = members.length(); + if (indexInInterface == XPCNativeMember::GetMaxIndexInInterface()) { + NS_WARNING("Too many members in interface"); + return nullptr; + } + XPCNativeMember cur; + cur.SetName(name); + cur.SetConstant(i); + cur.SetIndexInInterface(indexInInterface); + members.infallibleAppend(cur); + } + + const char* bytes = aInfo->Name(); + if (!bytes) { + return nullptr; + } + RootedString str(cx, JS_AtomizeString(cx, bytes)); + if (!str) { + return nullptr; + } + + RootedId interfaceName(cx, PropertyKey::NonIntAtom(str)); + + // Use placement new to create an object with the right amount of space + // to hold the members array + size_t size = sizeof(XPCNativeInterface); + if (members.length() > 1) { + size += (members.length() - 1) * sizeof(XPCNativeMember); + } + void* place = new char[size]; + if (!place) { + return nullptr; + } + + RefPtr<XPCNativeInterface> obj = + new (place) XPCNativeInterface(aInfo, interfaceName); + + obj->mMemberCount = members.length(); + // copy valid members + if (!members.empty()) { + memcpy(obj->mMembers, members.begin(), + members.length() * sizeof(XPCNativeMember)); + } + + if (!aMap->AddNew(obj)) { + NS_ERROR("failed to add our interface!"); + return nullptr; + } + + return obj.forget(); +} + +// static +void XPCNativeInterface::DestroyInstance(XPCNativeInterface* inst) { + inst->~XPCNativeInterface(); + delete[] (char*)inst; +} + +size_t XPCNativeInterface::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) { + return mallocSizeOf(this); +} + +void XPCNativeInterface::Trace(JSTracer* trc) { + JS::TraceRoot(trc, &mName, "XPCNativeInterface::mName"); + + for (size_t i = 0; i < mMemberCount; i++) { + JS::PropertyKey key = mMembers[i].GetName(); + JS::TraceRoot(trc, &key, "XPCNativeInterface::mMembers"); + MOZ_ASSERT(mMembers[i].GetName() == key); + } +} + +void IID2NativeInterfaceMap::Trace(JSTracer* trc) { + for (Map::Enum e(mMap); !e.empty(); e.popFront()) { + XPCNativeInterface* iface = e.front().value(); + iface->Trace(trc); + } +} + +void XPCNativeInterface::DebugDump(int16_t depth) { +#ifdef DEBUG + XPC_LOG_ALWAYS(("XPCNativeInterface @ %p", this)); + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("name is %s", GetNameString())); + XPC_LOG_ALWAYS(("mInfo @ %p", mInfo)); + XPC_LOG_OUTDENT(); +#endif +} + +/***************************************************************************/ +// XPCNativeSetKey + +HashNumber XPCNativeSetKey::Hash() const { + HashNumber h = 0; + + if (mBaseSet) { + // If we ever start using mCx here, adjust the constructors accordingly. + XPCNativeInterface** current = mBaseSet->GetInterfaceArray(); + uint16_t count = mBaseSet->GetInterfaceCount(); + for (uint16_t i = 0; i < count; i++) { + h = AddToHash(h, *(current++)); + } + } else { + // A newly created set will contain nsISupports first... + RefPtr<XPCNativeInterface> isupp = XPCNativeInterface::GetISupports(mCx); + h = AddToHash(h, isupp.get()); + + // ...but no more than once. + if (isupp == mAddition) { + return h; + } + } + + if (mAddition) { + h = AddToHash(h, mAddition.get()); + } + + return h; +} + +/***************************************************************************/ +// XPCNativeSet + +XPCNativeSet::~XPCNativeSet() { + // Remove |this| before we clear the interfaces to ensure that the + // hashtable look up is correct. + + XPCJSRuntime::Get()->GetNativeSetMap()->Remove(this); + + for (int i = 0; i < mInterfaceCount; i++) { + NS_RELEASE(mInterfaces[i]); + } +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed(JSContext* cx, + const nsIID* iid) { + RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(cx, iid); + if (!iface) { + return nullptr; + } + + XPCNativeSetKey key(cx, iface); + + XPCJSRuntime* xpcrt = XPCJSRuntime::Get(); + NativeSetMap* map = xpcrt->GetNativeSetMap(); + if (!map) { + return nullptr; + } + + RefPtr<XPCNativeSet> set = map->Find(&key); + + if (set) { + return set.forget(); + } + + set = NewInstance(cx, {std::move(iface)}); + if (!set) { + return nullptr; + } + + if (!map->AddNew(&key, set)) { + NS_ERROR("failed to add our set!"); + set = nullptr; + } + + return set.forget(); +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( + JSContext* cx, nsIClassInfo* classInfo) { + XPCJSRuntime* xpcrt = XPCJSRuntime::Get(); + ClassInfo2NativeSetMap* map = xpcrt->GetClassInfo2NativeSetMap(); + if (!map) { + return nullptr; + } + + RefPtr<XPCNativeSet> set = map->Find(classInfo); + + if (set) { + return set.forget(); + } + + AutoTArray<nsIID, 4> iids; + if (NS_FAILED(classInfo->GetInterfaces(iids))) { + // Note: I'm making it OK for this call to fail so that one can add + // nsIClassInfo to classes implemented in script without requiring this + // method to be implemented. + + // Make sure these are set correctly... + iids.Clear(); + } + + // Try to look up each IID's XPCNativeInterface object. + nsTArray<RefPtr<XPCNativeInterface>> interfaces(iids.Length()); + for (auto& iid : iids) { + RefPtr<XPCNativeInterface> iface = + XPCNativeInterface::GetNewOrUsed(cx, &iid); + if (iface) { + interfaces.AppendElement(iface.forget()); + } + } + + // Build a set from the interfaces specified here. + if (interfaces.Length() > 0) { + set = NewInstance(cx, std::move(interfaces)); + if (set) { + NativeSetMap* map2 = xpcrt->GetNativeSetMap(); + if (!map2) { + return set.forget(); + } + + XPCNativeSetKey key(set); + XPCNativeSet* set2 = map2->Add(&key, set); + if (!set2) { + NS_ERROR("failed to add our set"); + return nullptr; + } + + // It is okay to find an existing entry here because + // we did not look for one before we called Add(). + if (set2 != set) { + set = set2; + } + } + } else { + set = GetNewOrUsed(cx, &NS_GET_IID(nsISupports)); + } + + if (set) { +#ifdef DEBUG + XPCNativeSet* set2 = +#endif + map->Add(classInfo, set); + MOZ_ASSERT(set2, "failed to add our set!"); + MOZ_ASSERT(set2 == set, "hashtables inconsistent!"); + } + + return set.forget(); +} + +// static +void XPCNativeSet::ClearCacheEntryForClassInfo(nsIClassInfo* classInfo) { + XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance(); + ClassInfo2NativeSetMap* map = xpcrt->GetClassInfo2NativeSetMap(); + if (map) { + map->Remove(classInfo); + } +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( + JSContext* cx, XPCNativeSetKey* key) { + NativeSetMap* map = XPCJSRuntime::Get()->GetNativeSetMap(); + if (!map) { + return nullptr; + } + + RefPtr<XPCNativeSet> set = map->Find(key); + + if (set) { + return set.forget(); + } + + if (key->GetBaseSet()) { + set = NewInstanceMutate(key); + } else { + set = NewInstance(cx, {key->GetAddition()}); + } + + if (!set) { + return nullptr; + } + + if (!map->AddNew(key, set)) { + NS_ERROR("failed to add our set!"); + set = nullptr; + } + + return set.forget(); +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::GetNewOrUsed( + JSContext* cx, XPCNativeSet* firstSet, XPCNativeSet* secondSet, + bool preserveFirstSetOrder) { + // Figure out how many interfaces we'll need in the new set. + uint32_t uniqueCount = firstSet->mInterfaceCount; + for (uint32_t i = 0; i < secondSet->mInterfaceCount; ++i) { + if (!firstSet->HasInterface(secondSet->mInterfaces[i])) { + uniqueCount++; + } + } + + // If everything in secondSet was a duplicate, we can just use the first + // set. + if (uniqueCount == firstSet->mInterfaceCount) { + return RefPtr<XPCNativeSet>(firstSet).forget(); + } + + // If the secondSet is just a superset of the first, we can use it provided + // that the caller doesn't care about ordering. + if (!preserveFirstSetOrder && uniqueCount == secondSet->mInterfaceCount) { + return RefPtr<XPCNativeSet>(secondSet).forget(); + } + + // Ok, darn. Now we have to make a new set. + // + // It would be faster to just create the new set all at once, but that + // would involve wrangling with some pretty hairy code - especially since + // a lot of stuff assumes that sets are created by adding one interface to an + // existing set. So let's just do the slow and easy thing and hope that the + // above optimizations handle the common cases. + RefPtr<XPCNativeSet> currentSet = firstSet; + for (uint32_t i = 0; i < secondSet->mInterfaceCount; ++i) { + XPCNativeInterface* iface = secondSet->mInterfaces[i]; + if (!currentSet->HasInterface(iface)) { + // Create a new augmented set, inserting this interface at the end. + XPCNativeSetKey key(currentSet, iface); + currentSet = XPCNativeSet::GetNewOrUsed(cx, &key); + if (!currentSet) { + return nullptr; + } + } + } + + // We've got the union set. Hand it back to the caller. + MOZ_ASSERT(currentSet->mInterfaceCount == uniqueCount); + return currentSet.forget(); +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::NewInstance( + JSContext* cx, nsTArray<RefPtr<XPCNativeInterface>>&& array) { + if (array.Length() == 0) { + return nullptr; + } + + // We impose the invariant: + // "All sets have exactly one nsISupports interface and it comes first." + // This is the place where we impose that rule - even if given inputs + // that don't exactly follow the rule. + + RefPtr<XPCNativeInterface> isup = XPCNativeInterface::GetISupports(cx); + uint16_t slots = array.Length() + 1; + + for (auto key = array.begin(); key != array.end(); key++) { + if (*key == isup) { + slots--; + } + } + + // Use placement new to create an object with the right amount of space + // to hold the members array + int size = sizeof(XPCNativeSet); + if (slots > 1) { + size += (slots - 1) * sizeof(XPCNativeInterface*); + } + void* place = new char[size]; + RefPtr<XPCNativeSet> obj = new (place) XPCNativeSet(); + + // Stick the nsISupports in front and skip additional nsISupport(s) + XPCNativeInterface** outp = (XPCNativeInterface**)&obj->mInterfaces; + + NS_ADDREF(*(outp++) = isup); + + for (auto key = array.begin(); key != array.end(); key++) { + RefPtr<XPCNativeInterface> cur = std::move(*key); + if (isup == cur) { + continue; + } + *(outp++) = cur.forget().take(); + } + obj->mInterfaceCount = slots; + + return obj.forget(); +} + +// static +already_AddRefed<XPCNativeSet> XPCNativeSet::NewInstanceMutate( + XPCNativeSetKey* key) { + XPCNativeSet* otherSet = key->GetBaseSet(); + XPCNativeInterface* newInterface = key->GetAddition(); + + MOZ_ASSERT(otherSet); + + if (!newInterface) { + return nullptr; + } + + // Use placement new to create an object with the right amount of space + // to hold the members array + int size = sizeof(XPCNativeSet); + size += otherSet->mInterfaceCount * sizeof(XPCNativeInterface*); + void* place = new char[size]; + RefPtr<XPCNativeSet> obj = new (place) XPCNativeSet(); + + obj->mInterfaceCount = otherSet->mInterfaceCount + 1; + + XPCNativeInterface** src = otherSet->mInterfaces; + XPCNativeInterface** dest = obj->mInterfaces; + for (uint16_t i = 0; i < otherSet->mInterfaceCount; i++) { + NS_ADDREF(*dest++ = *src++); + } + NS_ADDREF(*dest++ = newInterface); + + return obj.forget(); +} + +// static +void XPCNativeSet::DestroyInstance(XPCNativeSet* inst) { + inst->~XPCNativeSet(); + delete[] (char*)inst; +} + +size_t XPCNativeSet::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) { + return mallocSizeOf(this); +} + +void XPCNativeSet::DebugDump(int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS(("XPCNativeSet @ %p", this)); + XPC_LOG_INDENT(); + + XPC_LOG_ALWAYS(("mInterfaceCount of %d", mInterfaceCount)); + if (depth) { + for (uint16_t i = 0; i < mInterfaceCount; i++) { + mInterfaces[i]->DebugDump(depth); + } + } + XPC_LOG_OUTDENT(); +#endif +} diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp new file mode 100644 index 0000000000..6de0e959fd --- /dev/null +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -0,0 +1,1236 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* JavaScript JSClasses and JSOps for our Wrapped Native JS Objects. */ + +#include "xpcprivate.h" +#include "xpc_make_class.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/Maybe.h" +#include "mozilla/Preferences.h" +#include "js/CharacterEncoding.h" +#include "js/Class.h" +#include "js/Object.h" // JS::GetClass +#include "js/Printf.h" +#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById, JS_GetProperty, JS_GetPropertyById +#include "js/Symbol.h" + +#include <string_view> + +using namespace mozilla; +using namespace JS; +using namespace xpc; + +/***************************************************************************/ + +// All of the exceptions thrown into JS from this file go through here. +// That makes this a nice place to set a breakpoint. + +static bool Throw(nsresult errNum, JSContext* cx) { + XPCThrower::Throw(errNum, cx); + return false; +} + +// Handy macro used in many callback stub below. + +#define THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper) \ + PR_BEGIN_MACRO \ + if (!wrapper) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); \ + if (!wrapper->IsValid()) return Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx); \ + PR_END_MACRO + +/***************************************************************************/ + +static bool ToStringGuts(XPCCallContext& ccx) { + UniqueChars sz; + XPCWrappedNative* wrapper = ccx.GetWrapper(); + + if (wrapper) { + sz.reset(wrapper->ToString(ccx.GetTearOff())); + } else { + sz = JS_smprintf("[xpconnect wrapped native prototype]"); + } + + if (!sz) { + JS_ReportOutOfMemory(ccx); + return false; + } + + JSString* str = JS_NewStringCopyZ(ccx, sz.get()); + if (!str) { + return false; + } + + ccx.SetRetVal(JS::StringValue(str)); + return true; +} + +/***************************************************************************/ + +static bool XPC_WN_Shared_ToString(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + RootedObject obj(cx); + if (!args.computeThis(cx, &obj)) { + return false; + } + + XPCCallContext ccx(cx, obj); + if (!ccx.IsValid()) { + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); + } + ccx.SetName(ccx.GetContext()->GetStringID(XPCJSContext::IDX_TO_STRING)); + ccx.SetArgsAndResultPtr(args.length(), args.array(), vp); + return ToStringGuts(ccx); +} + +static bool XPC_WN_Shared_ToSource(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + static constexpr std::string_view empty = "({})"; + JSString* str = JS_NewStringCopyN(cx, empty.data(), empty.length()); + if (!str) { + return false; + } + args.rval().setString(str); + + return true; +} + +static bool XPC_WN_Shared_toPrimitive(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + RootedObject obj(cx); + if (!JS_ValueToObject(cx, args.thisv(), &obj)) { + return false; + } + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + JSType hint; + if (!GetFirstArgumentAsTypeHint(cx, args, &hint)) { + return false; + } + + if (hint == JSTYPE_NUMBER) { + args.rval().set(NaNValue()); + return true; + } + + MOZ_ASSERT(hint == JSTYPE_STRING || hint == JSTYPE_UNDEFINED); + ccx.SetName(ccx.GetContext()->GetStringID(XPCJSContext::IDX_TO_STRING)); + ccx.SetArgsAndResultPtr(0, nullptr, args.rval().address()); + + XPCNativeMember* member = ccx.GetMember(); + if (member && member->IsMethod()) { + if (!XPCWrappedNative::CallMethod(ccx)) { + return false; + } + + if (args.rval().isPrimitive()) { + return true; + } + } + + // else... + return ToStringGuts(ccx); +} + +/***************************************************************************/ + +// A "double wrapped object" is a user JSObject that has been wrapped as a +// wrappedJS in order to be used by native code and then re-wrapped by a +// wrappedNative wrapper to be used by JS code. One might think of it as: +// wrappedNative(wrappedJS(underlying_JSObject)) +// This is done (as opposed to just unwrapping the wrapped JS and automatically +// returning the underlying JSObject) so that JS callers will see what looks +// Like any other xpcom object - and be limited to use its interfaces. +// + +/** + * When JavaScript code uses a component that is itself implemented in + * JavaScript then XPConnect will build a wrapper rather than directly + * expose the JSObject of the component. This allows components implemented + * in JavaScript to 'look' just like any other xpcom component (from the + * perspective of the JavaScript caller). This insulates the component from + * the caller and hides any properties or methods that are not part of the + * interface as declared in xpidl. Usually this is a good thing. + * + * However, in some cases it is useful to allow the JS caller access to the + * JS component's underlying implementation. In order to facilitate this + * XPConnect supports the 'wrappedJSObject' property. This 'wrappedJSObject' + * property is different than the XrayWrapper meaning. (The naming collision + * avoids having more than one magic XPConnect property name, but is + * confusing.) + * + * The caller code can do: + * + * // 'foo' is some xpcom component (that might be implemented in JS). + * var bar = foo.wrappedJSObject; + * if(bar) { + * // bar is the underlying JSObject. Do stuff with it here. + * } + * + * Recall that 'foo' above is an XPConnect wrapper, not the underlying JS + * object. The property get "foo.wrappedJSObject" will only succeed if three + * conditions are met: + * + * 1) 'foo' really is an XPConnect wrapper around a JSObject. + * 3) The caller must be system JS and not content. Double-wrapped XPCWJS should + * not be exposed to content except with a remote-XUL domain. + * + * Notes: + * + * a) If 'foo' above were the underlying JSObject and not a wrapper at all, + * then this all just works and XPConnect is not part of the picture at all. + * b) One might ask why 'foo' should not just implement an interface through + * which callers might get at the underlying object. There are two reasons: + * i) XPConnect would still have to do magic since JSObject is not a + * scriptable type. + * ii) Avoiding the explicit interface makes it easier for both the caller + * and the component. + */ + +static JSObject* GetDoubleWrappedJSObject(XPCCallContext& ccx, + XPCWrappedNative* wrapper) { + RootedObject obj(ccx); + { + nsCOMPtr<nsIXPConnectWrappedJS> underware = + do_QueryInterface(wrapper->GetIdentityObject()); + if (!underware) { + return nullptr; + } + RootedObject mainObj(ccx, underware->GetJSObject()); + if (mainObj) { + JSAutoRealm ar(ccx, underware->GetJSObjectGlobal()); + + // We don't have to root this ID, as it's already rooted by our context. + HandleId id = + ccx.GetContext()->GetStringID(XPCJSContext::IDX_WRAPPED_JSOBJECT); + + // If the `wrappedJSObject` property is defined, use the result of getting + // that property, otherwise fall back to the `mainObj` object which is + // directly being wrapped. + RootedValue val(ccx); + if (JS_GetPropertyById(ccx, mainObj, id, &val) && !val.isPrimitive()) { + obj = val.toObjectOrNull(); + } else { + obj = mainObj; + } + } + } + return obj; +} + +// This is the getter native function we use to handle 'wrappedJSObject' for +// double wrapped JSObjects. + +static bool XPC_WN_DoubleWrappedGetter(JSContext* cx, unsigned argc, + Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + if (!args.thisv().isObject()) { + JS_ReportErrorASCII( + cx, + "xpconnect double wrapped getter called on incompatible non-object"); + return false; + } + RootedObject obj(cx, &args.thisv().toObject()); + + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, + "bad function"); + + RootedObject realObject(cx, GetDoubleWrappedJSObject(ccx, wrapper)); + if (!realObject) { + // This is pretty unexpected at this point. The object originally + // responded to this get property call and now gives no object. + // XXX Should this throw something at the caller? + args.rval().setNull(); + return true; + } + + // It is a double wrapped object. This should really never appear in + // content these days, but addons still do it - see bug 965921. + if (MOZ_UNLIKELY(!nsContentUtils::IsSystemCaller(cx))) { + JS_ReportErrorASCII(cx, + "Attempt to use .wrappedJSObject in untrusted code"); + return false; + } + args.rval().setObject(*realObject); + return JS_WrapValue(cx, args.rval()); +} + +/***************************************************************************/ + +// This is our shared function to define properties on our JSObjects. + +/* + * NOTE: + * We *never* set the tearoff names (e.g. nsIFoo) as JS_ENUMERATE. + * We *never* set toString or toSource as JS_ENUMERATE. + */ + +static bool DefinePropertyIfFound( + XPCCallContext& ccx, HandleObject obj, HandleId idArg, XPCNativeSet* set, + XPCNativeInterface* ifaceArg, XPCNativeMember* member, + XPCWrappedNativeScope* scope, bool reflectToStringAndToSource, + XPCWrappedNative* wrapperToReflectInterfaceNames, + XPCWrappedNative* wrapperToReflectDoubleWrap, nsIXPCScriptable* scr, + unsigned propFlags, bool* resolved) { + RootedId id(ccx, idArg); + RefPtr<XPCNativeInterface> iface = ifaceArg; + XPCJSContext* xpccx = ccx.GetContext(); + bool found; + const char* name; + + propFlags |= JSPROP_RESOLVING; + + if (set) { + if (iface) { + found = true; + } else { + found = set->FindMember(id, &member, &iface); + } + } else + found = (nullptr != (member = iface->FindMember(id))); + + if (!found) { + if (reflectToStringAndToSource) { + JSNative call; + if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) { + call = XPC_WN_Shared_ToString; + name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING); + } else if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_SOURCE)) { + call = XPC_WN_Shared_ToSource; + name = xpccx->GetStringName(XPCJSContext::IDX_TO_SOURCE); + } else if (id.isWellKnownSymbol(JS::SymbolCode::toPrimitive)) { + call = XPC_WN_Shared_toPrimitive; + name = "[Symbol.toPrimitive]"; + } else { + call = nullptr; + } + + if (call) { + RootedFunction fun(ccx, JS_NewFunction(ccx, call, 0, 0, name)); + if (!fun) { + JS_ReportOutOfMemory(ccx); + return false; + } + + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + RootedObject value(ccx, JS_GetFunctionObject(fun)); + return JS_DefinePropertyById(ccx, obj, id, value, + propFlags & ~JSPROP_ENUMERATE); + } + } + // This *might* be a tearoff name that is not yet part of our + // set. Let's lookup the name and see if it is the name of an + // interface. Then we'll see if the object actually *does* this + // interface and add a tearoff as necessary. + + if (wrapperToReflectInterfaceNames) { + JS::UniqueChars name; + RefPtr<XPCNativeInterface> iface2; + XPCWrappedNativeTearOff* to; + RootedObject jso(ccx); + nsresult rv = NS_OK; + + bool defineProperty = false; + do { + if (!id.isString()) { + break; + } + + name = JS_EncodeStringToLatin1(ccx, id.toString()); + if (!name) { + break; + } + + iface2 = XPCNativeInterface::GetNewOrUsed(ccx, name.get()); + if (!iface2) { + break; + } + + to = + wrapperToReflectInterfaceNames->FindTearOff(ccx, iface2, true, &rv); + if (!to) { + break; + } + + jso = to->GetJSObject(); + if (!jso) { + break; + } + + defineProperty = true; + } while (false); + + if (defineProperty) { + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + return JS_DefinePropertyById(ccx, obj, id, jso, + propFlags & ~JSPROP_ENUMERATE); + } else if (NS_FAILED(rv) && rv != NS_ERROR_NO_INTERFACE) { + return Throw(rv, ccx); + } + } + + // This *might* be a double wrapped JSObject + if (wrapperToReflectDoubleWrap && + id == xpccx->GetStringID(XPCJSContext::IDX_WRAPPED_JSOBJECT) && + GetDoubleWrappedJSObject(ccx, wrapperToReflectDoubleWrap)) { + // We build and add a getter function. + // A security check is done on a per-get basis. + + JSFunction* fun; + + id = xpccx->GetStringID(XPCJSContext::IDX_WRAPPED_JSOBJECT); + name = xpccx->GetStringName(XPCJSContext::IDX_WRAPPED_JSOBJECT); + + fun = JS_NewFunction(ccx, XPC_WN_DoubleWrappedGetter, 0, 0, name); + + if (!fun) { + return false; + } + + RootedObject funobj(ccx, JS_GetFunctionObject(fun)); + if (!funobj) { + return false; + } + + propFlags &= ~JSPROP_ENUMERATE; + + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + return JS_DefinePropertyById(ccx, obj, id, funobj, nullptr, propFlags); + } + + if (resolved) { + *resolved = false; + } + return true; + } + + if (!member) { + if (wrapperToReflectInterfaceNames) { + XPCWrappedNativeTearOff* to = + wrapperToReflectInterfaceNames->FindTearOff(ccx, iface, true); + + if (!to) { + return false; + } + RootedObject jso(ccx, to->GetJSObject()); + if (!jso) { + return false; + } + + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + return JS_DefinePropertyById(ccx, obj, id, jso, + propFlags & ~JSPROP_ENUMERATE); + } + if (resolved) { + *resolved = false; + } + return true; + } + + if (member->IsConstant()) { + RootedValue val(ccx); + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + return member->GetConstantValue(ccx, iface, val.address()) && + JS_DefinePropertyById(ccx, obj, id, val, propFlags); + } + + if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING) || + id == xpccx->GetStringID(XPCJSContext::IDX_TO_SOURCE) || + (scr && scr->DontEnumQueryInterface() && + id == xpccx->GetStringID(XPCJSContext::IDX_QUERY_INTERFACE))) + propFlags &= ~JSPROP_ENUMERATE; + + RootedValue funval(ccx); + if (!member->NewFunctionObject(ccx, iface, obj, funval.address())) { + return false; + } + + if (member->IsMethod()) { + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + return JS_DefinePropertyById(ccx, obj, id, funval, propFlags); + } + + // else... + + MOZ_ASSERT(member->IsAttribute(), "way broken!"); + + propFlags &= ~JSPROP_READONLY; + RootedObject funobjGetter(ccx, funval.toObjectOrNull()); + RootedObject funobjSetter(ccx); + if (member->IsWritableAttribute()) { + funobjSetter = funobjGetter; + } + + AutoResolveName arn(ccx, id); + if (resolved) { + *resolved = true; + } + + return JS_DefinePropertyById(ccx, obj, id, funobjGetter, funobjSetter, + propFlags); +} + +/***************************************************************************/ +/***************************************************************************/ + +static bool XPC_WN_OnlyIWrite_AddPropertyStub(JSContext* cx, HandleObject obj, + HandleId id, HandleValue v) { + XPCCallContext ccx(cx, obj, nullptr, id); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + // Allow only XPConnect to add/set the property + if (ccx.GetResolveName() == id) { + return true; + } + + return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx); +} + +bool XPC_WN_CannotModifyPropertyStub(JSContext* cx, HandleObject obj, + HandleId id, HandleValue v) { + return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx); +} + +bool XPC_WN_CannotDeletePropertyStub(JSContext* cx, HandleObject obj, + HandleId id, ObjectOpResult& result) { + return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx); +} + +bool XPC_WN_Shared_Enumerate(JSContext* cx, HandleObject obj) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + // Since we aren't going to enumerate tearoff names and the prototype + // handles non-mutated members, we can do this potential short-circuit. + if (!wrapper->HasMutatedSet()) { + return true; + } + + XPCNativeSet* set = wrapper->GetSet(); + XPCNativeSet* protoSet = + wrapper->HasProto() ? wrapper->GetProto()->GetSet() : nullptr; + + uint16_t interface_count = set->GetInterfaceCount(); + XPCNativeInterface** interfaceArray = set->GetInterfaceArray(); + for (uint16_t i = 0; i < interface_count; i++) { + XPCNativeInterface* iface = interfaceArray[i]; + uint16_t member_count = iface->GetMemberCount(); + for (uint16_t k = 0; k < member_count; k++) { + XPCNativeMember* member = iface->GetMemberAt(k); + jsid name = member->GetName(); + + // Skip if this member is going to come from the proto. + uint16_t index; + if (protoSet && protoSet->FindMember(name, nullptr, &index) && index == i) + continue; + + JS_MarkCrossZoneId(cx, name); + if (!xpc_ForcePropertyResolve(cx, obj, name)) { + return false; + } + } + } + return true; +} + +/***************************************************************************/ + +enum WNHelperType { WN_NOHELPER, WN_HELPER }; + +static void WrappedNativeFinalize(JS::GCContext* gcx, JSObject* obj, + WNHelperType helperType) { + const JSClass* clazz = JS::GetClass(obj); + if (clazz->flags & JSCLASS_DOM_GLOBAL) { + mozilla::dom::DestroyProtoAndIfaceCache(obj); + } + XPCWrappedNative* wrapper = JS::GetObjectISupports<XPCWrappedNative>(obj); + if (!wrapper) { + return; + } + + if (helperType == WN_HELPER) { + wrapper->GetScriptable()->Finalize(wrapper, gcx, obj); + } + wrapper->FlatJSObjectFinalized(); +} + +static size_t WrappedNativeObjectMoved(JSObject* obj, JSObject* old) { + XPCWrappedNative* wrapper = JS::GetObjectISupports<XPCWrappedNative>(obj); + if (!wrapper) { + return 0; + } + + wrapper->FlatJSObjectMoved(obj, old); + return 0; +} + +void XPC_WN_NoHelper_Finalize(JS::GCContext* gcx, JSObject* obj) { + WrappedNativeFinalize(gcx, obj, WN_NOHELPER); +} + +/* + * General comment about XPConnect tracing: Given a C++ object |wrapper| and its + * corresponding JS object |obj|, calling |wrapper->TraceSelf| will ask the JS + * engine to mark |obj|. Eventually, this will lead to the trace hook being + * called for |obj|. The trace hook should call |wrapper->TraceInside|, which + * should mark any JS objects held by |wrapper| as members. + */ + +/* static */ +void XPCWrappedNative::Trace(JSTracer* trc, JSObject* obj) { + const JSClass* clazz = JS::GetClass(obj); + if (clazz->flags & JSCLASS_DOM_GLOBAL) { + mozilla::dom::TraceProtoAndIfaceCache(trc, obj); + } + MOZ_ASSERT(clazz->isWrappedNative()); + + XPCWrappedNative* wrapper = XPCWrappedNative::Get(obj); + if (wrapper && wrapper->IsValid()) { + wrapper->TraceInside(trc); + } +} + +void XPCWrappedNative_Trace(JSTracer* trc, JSObject* obj) { + XPCWrappedNative::Trace(trc, obj); +} + +static bool XPC_WN_NoHelper_Resolve(JSContext* cx, HandleObject obj, + HandleId id, bool* resolvedp) { + XPCCallContext ccx(cx, obj, nullptr, id); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + XPCNativeSet* set = ccx.GetSet(); + if (!set) { + return true; + } + + // Don't resolve properties that are on our prototype. + if (ccx.GetInterface() && !ccx.GetStaticMemberIsLocal()) { + return true; + } + + return DefinePropertyIfFound( + ccx, obj, id, set, nullptr, nullptr, wrapper->GetScope(), true, wrapper, + wrapper, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT, + resolvedp); +} + +static const JSClassOps XPC_WN_NoHelper_JSClassOps = { + XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty + XPC_WN_CannotDeletePropertyStub, // delProperty + XPC_WN_Shared_Enumerate, // enumerate + nullptr, // newEnumerate + XPC_WN_NoHelper_Resolve, // resolve + nullptr, // mayResolve + XPC_WN_NoHelper_Finalize, // finalize + nullptr, // call + nullptr, // construct + XPCWrappedNative::Trace, // trace +}; + +const js::ClassExtension XPC_WN_JSClassExtension = { + WrappedNativeObjectMoved, // objectMovedOp +}; + +const JSClass XPC_WN_NoHelper_JSClass = { + "XPCWrappedNative_NoHelper", + JSCLASS_IS_WRAPPED_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(1) | + JSCLASS_SLOT0_IS_NSISUPPORTS | JSCLASS_FOREGROUND_FINALIZE, + &XPC_WN_NoHelper_JSClassOps, + JS_NULL_CLASS_SPEC, + &XPC_WN_JSClassExtension, + JS_NULL_OBJECT_OPS}; + +/***************************************************************************/ + +bool XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, HandleObject obj, + HandleId id, HandleValue v) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + if (ccx.GetResolvingWrapper() == wrapper) { + return true; + } + return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx); +} + +bool XPC_WN_MaybeResolvingDeletePropertyStub(JSContext* cx, HandleObject obj, + HandleId id, + ObjectOpResult& result) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + if (ccx.GetResolvingWrapper() == wrapper) { + return result.succeed(); + } + return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx); +} + +// macro fun! +#define PRE_HELPER_STUB \ + /* It's very important for "unwrapped" to be rooted here. */ \ + RootedObject unwrapped(cx, js::CheckedUnwrapDynamic(obj, cx, false)); \ + if (!unwrapped) { \ + JS_ReportErrorASCII(cx, "Permission denied to operate on object."); \ + return false; \ + } \ + if (!IsWrappedNativeReflector(unwrapped)) { \ + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); \ + } \ + XPCWrappedNative* wrapper = XPCWrappedNative::Get(unwrapped); \ + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); \ + bool retval = true; \ + nsresult rv = wrapper->GetScriptable()-> + +#define POST_HELPER_STUB \ + if (NS_FAILED(rv)) return Throw(rv, cx); \ + return retval; + +bool XPC_WN_Helper_Call(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + // N.B. we want obj to be the callee, not JS_THIS(cx, vp) + RootedObject obj(cx, &args.callee()); + + XPCCallContext ccx(cx, obj, nullptr, JS::VoidHandlePropertyKey, args.length(), + args.array(), args.rval().address()); + if (!ccx.IsValid()) { + return false; + } + + PRE_HELPER_STUB + Call(wrapper, cx, obj, args, &retval); + POST_HELPER_STUB +} + +bool XPC_WN_Helper_Construct(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + RootedObject obj(cx, &args.callee()); + if (!obj) { + return false; + } + + XPCCallContext ccx(cx, obj, nullptr, JS::VoidHandlePropertyKey, args.length(), + args.array(), args.rval().address()); + if (!ccx.IsValid()) { + return false; + } + + PRE_HELPER_STUB + Construct(wrapper, cx, obj, args, &retval); + POST_HELPER_STUB +} + +static bool XPC_WN_Helper_HasInstance(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.requireAtLeast(cx, "WrappedNative[Symbol.hasInstance]", 1)) { + return false; + } + + if (!args.thisv().isObject()) { + JS_ReportErrorASCII( + cx, "WrappedNative[Symbol.hasInstance]: unexpected this value"); + return false; + } + + RootedObject obj(cx, &args.thisv().toObject()); + RootedValue val(cx, args.get(0)); + + bool retval2; + PRE_HELPER_STUB + HasInstance(wrapper, cx, obj, val, &retval2, &retval); + args.rval().setBoolean(retval2); + POST_HELPER_STUB +} + +void XPC_WN_Helper_Finalize(JS::GCContext* gcx, JSObject* obj) { + WrappedNativeFinalize(gcx, obj, WN_HELPER); +} + +// RAII class used to store the wrapper in the context when resolving a lazy +// property on its JS reflector. This is used by XPC_WN_MaybeResolving to allow +// adding properties while resolving. +class MOZ_RAII AutoSetResolvingWrapper { + public: + AutoSetResolvingWrapper(XPCCallContext& ccx, XPCWrappedNative* wrapper) + : mCcx(ccx), mOldResolvingWrapper(ccx.SetResolvingWrapper(wrapper)) {} + + ~AutoSetResolvingWrapper() { + (void)mCcx.SetResolvingWrapper(mOldResolvingWrapper); + } + + private: + XPCCallContext& mCcx; + XPCWrappedNative* mOldResolvingWrapper; +}; + +bool XPC_WN_Helper_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + nsresult rv = NS_OK; + bool retval = true; + bool resolved = false; + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + RootedId old(cx, ccx.SetResolveName(id)); + + nsCOMPtr<nsIXPCScriptable> scr = wrapper->GetScriptable(); + + // Resolve a Symbol.hasInstance property if we want custom `instanceof` + // behavior. + if (scr && scr->WantHasInstance() && + id.isWellKnownSymbol(SymbolCode::hasInstance)) { + mozilla::Maybe<AutoSetResolvingWrapper> asrw; + if (scr->AllowPropModsDuringResolve()) { + asrw.emplace(ccx, wrapper); + } + if (!JS_DefineFunctionById( + cx, obj, id, XPC_WN_Helper_HasInstance, 1, + JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING)) { + rv = NS_ERROR_FAILURE; + } else { + resolved = true; + } + } + + if (scr && scr->WantResolve()) { + mozilla::Maybe<AutoSetResolvingWrapper> asrw; + if (scr->AllowPropModsDuringResolve()) { + asrw.emplace(ccx, wrapper); + } + rv = scr->Resolve(wrapper, cx, obj, id, &resolved, &retval); + } + + old = ccx.SetResolveName(old); + MOZ_ASSERT(old == id, "bad nest"); + + if (NS_FAILED(rv)) { + return Throw(rv, cx); + } + + if (resolved) { + *resolvedp = true; + } else if (wrapper->HasMutatedSet()) { + // We are here if scriptable did not resolve this property and + // it *might* be in the instance set but not the proto set. + + XPCNativeSet* set = wrapper->GetSet(); + XPCNativeSet* protoSet = + wrapper->HasProto() ? wrapper->GetProto()->GetSet() : nullptr; + XPCNativeMember* member = nullptr; + RefPtr<XPCNativeInterface> iface; + bool IsLocal = false; + + if (set->FindMember(id, &member, &iface, protoSet, &IsLocal) && IsLocal) { + XPCWrappedNative* wrapperForInterfaceNames = + (scr && scr->DontReflectInterfaceNames()) ? nullptr : wrapper; + + AutoSetResolvingWrapper asrw(ccx, wrapper); + retval = DefinePropertyIfFound( + ccx, obj, id, set, iface, member, wrapper->GetScope(), false, + wrapperForInterfaceNames, nullptr, scr, JSPROP_ENUMERATE, resolvedp); + } + } + + return retval; +} + +/***************************************************************************/ + +bool XPC_WN_NewEnumerate(JSContext* cx, HandleObject obj, + MutableHandleIdVector properties, + bool enumerableOnly) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + nsCOMPtr<nsIXPCScriptable> scr = wrapper->GetScriptable(); + if (!scr || !scr->WantNewEnumerate()) { + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); + } + + if (!XPC_WN_Shared_Enumerate(cx, obj)) { + return false; + } + + bool retval = true; + nsresult rv = + scr->NewEnumerate(wrapper, cx, obj, properties, enumerableOnly, &retval); + if (NS_FAILED(rv)) { + return Throw(rv, cx); + } + return retval; +} + +/***************************************************************************/ +/***************************************************************************/ + +// Compatibility hack. +// +// XPConnect used to do all sorts of funny tricks to find the "correct" +// |this| object for a given method (often to the detriment of proper +// call/apply). When these tricks were removed, a fair amount of chrome +// code broke, because it was relying on being able to grab methods off +// some XPCOM object (like the nsITelemetry service) and invoke them without +// a proper |this|. So, if it's quite clear that we're in this situation and +// about to use a |this| argument that just won't work, fix things up. +// +// This hack is only useful for getters/setters if someone sets an XPCOM object +// as the prototype for a vanilla JS object and expects the XPCOM attributes to +// work on the derived object, which we really don't want to support. But we +// handle it anyway, for now, to minimize regression risk on an already-risky +// landing. +// +// This hack is mainly useful for the NoHelper JSClass. We also fix up +// Components.utils because it implements nsIXPCScriptable (giving it a custom +// JSClass) but not nsIClassInfo (which would put the methods on a prototype). + +#define IS_NOHELPER_CLASS(clasp) (clasp == &XPC_WN_NoHelper_JSClass) +#define IS_CU_CLASS(clasp) \ + (clasp->name[0] == 'n' && !strcmp(clasp->name, "nsXPCComponents_Utils")) + +MOZ_ALWAYS_INLINE JSObject* FixUpThisIfBroken(JSObject* obj, JSObject* funobj) { + if (funobj) { + JSObject* parentObj = + &js::GetFunctionNativeReserved(funobj, XPC_FUNCTION_PARENT_OBJECT_SLOT) + .toObject(); + const JSClass* parentClass = JS::GetClass(parentObj); + if (MOZ_UNLIKELY( + (IS_NOHELPER_CLASS(parentClass) || IS_CU_CLASS(parentClass)) && + (JS::GetClass(obj) != parentClass))) { + return parentObj; + } + } + return obj; +} + +bool XPC_WN_CallMethod(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, + "bad function"); + RootedObject funobj(cx, &args.callee()); + + RootedObject obj(cx); + if (!args.computeThis(cx, &obj)) { + return false; + } + + obj = FixUpThisIfBroken(obj, funobj); + XPCCallContext ccx(cx, obj, funobj, JS::VoidHandlePropertyKey, args.length(), + args.array(), vp); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + RefPtr<XPCNativeInterface> iface; + XPCNativeMember* member; + + if (!XPCNativeMember::GetCallInfo(funobj, &iface, &member)) { + return Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, cx); + } + ccx.SetCallInfo(iface, member, false); + return XPCWrappedNative::CallMethod(ccx); +} + +bool XPC_WN_GetterSetter(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + MOZ_ASSERT(JS_TypeOfValue(cx, args.calleev()) == JSTYPE_FUNCTION, + "bad function"); + RootedObject funobj(cx, &args.callee()); + + if (!args.thisv().isObject()) { + JS_ReportErrorASCII( + cx, "xpconnect getter/setter called on incompatible non-object"); + return false; + } + RootedObject obj(cx, &args.thisv().toObject()); + + obj = FixUpThisIfBroken(obj, funobj); + XPCCallContext ccx(cx, obj, funobj, JS::VoidHandlePropertyKey, args.length(), + args.array(), vp); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + RefPtr<XPCNativeInterface> iface; + XPCNativeMember* member; + + if (!XPCNativeMember::GetCallInfo(funobj, &iface, &member)) { + return Throw(NS_ERROR_XPC_CANT_GET_METHOD_INFO, cx); + } + + if (args.length() != 0 && member->IsWritableAttribute()) { + ccx.SetCallInfo(iface, member, true); + bool retval = XPCWrappedNative::SetAttribute(ccx); + if (retval) { + args.rval().set(args[0]); + } + return retval; + } + // else... + + ccx.SetCallInfo(iface, member, false); + return XPCWrappedNative::GetAttribute(ccx); +} + +/***************************************************************************/ + +/* static */ +XPCWrappedNativeProto* XPCWrappedNativeProto::Get(JSObject* obj) { + MOZ_ASSERT(JS::GetClass(obj) == &XPC_WN_Proto_JSClass); + return JS::GetMaybePtrFromReservedSlot<XPCWrappedNativeProto>(obj, ProtoSlot); +} + +/* static */ +XPCWrappedNativeTearOff* XPCWrappedNativeTearOff::Get(JSObject* obj) { + MOZ_ASSERT(JS::GetClass(obj) == &XPC_WN_Tearoff_JSClass); + return JS::GetMaybePtrFromReservedSlot<XPCWrappedNativeTearOff>(obj, + TearOffSlot); +} + +static bool XPC_WN_Proto_Enumerate(JSContext* cx, HandleObject obj) { + MOZ_ASSERT(JS::GetClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); + XPCWrappedNativeProto* self = XPCWrappedNativeProto::Get(obj); + if (!self) { + return false; + } + + XPCNativeSet* set = self->GetSet(); + if (!set) { + return false; + } + + XPCCallContext ccx(cx); + if (!ccx.IsValid()) { + return false; + } + + uint16_t interface_count = set->GetInterfaceCount(); + XPCNativeInterface** interfaceArray = set->GetInterfaceArray(); + for (uint16_t i = 0; i < interface_count; i++) { + XPCNativeInterface* iface = interfaceArray[i]; + uint16_t member_count = iface->GetMemberCount(); + + for (uint16_t k = 0; k < member_count; k++) { + jsid name = iface->GetMemberAt(k)->GetName(); + JS_MarkCrossZoneId(cx, name); + if (!xpc_ForcePropertyResolve(cx, obj, name)) { + return false; + } + } + } + + return true; +} + +static void XPC_WN_Proto_Finalize(JS::GCContext* gcx, JSObject* obj) { + // This can be null if xpc shutdown has already happened + XPCWrappedNativeProto* p = XPCWrappedNativeProto::Get(obj); + if (p) { + p->JSProtoObjectFinalized(gcx, obj); + } +} + +static size_t XPC_WN_Proto_ObjectMoved(JSObject* obj, JSObject* old) { + // This can be null if xpc shutdown has already happened + XPCWrappedNativeProto* p = XPCWrappedNativeProto::Get(obj); + if (!p) { + return 0; + } + + p->JSProtoObjectMoved(obj, old); + return 0; +} + +/*****************************************************/ + +static bool XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, + HandleObject obj, + HandleId id, + HandleValue v) { + MOZ_ASSERT(JS::GetClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); + + XPCWrappedNativeProto* self = XPCWrappedNativeProto::Get(obj); + if (!self) { + return false; + } + + XPCCallContext ccx(cx); + if (!ccx.IsValid()) { + return false; + } + + // Allow XPConnect to add the property only + if (ccx.GetResolveName() == id) { + return true; + } + + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); +} + +static bool XPC_WN_Proto_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + MOZ_ASSERT(JS::GetClass(obj) == &XPC_WN_Proto_JSClass, "bad proto"); + + XPCWrappedNativeProto* self = XPCWrappedNativeProto::Get(obj); + if (!self) { + return false; + } + + XPCCallContext ccx(cx); + if (!ccx.IsValid()) { + return false; + } + + nsCOMPtr<nsIXPCScriptable> scr = self->GetScriptable(); + + return DefinePropertyIfFound( + ccx, obj, id, self->GetSet(), nullptr, nullptr, self->GetScope(), true, + nullptr, nullptr, scr, + JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE, resolvedp); +} + +static const JSClassOps XPC_WN_Proto_JSClassOps = { + XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty + XPC_WN_CannotDeletePropertyStub, // delProperty + XPC_WN_Proto_Enumerate, // enumerate + nullptr, // newEnumerate + XPC_WN_Proto_Resolve, // resolve + nullptr, // mayResolve + XPC_WN_Proto_Finalize, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +static const js::ClassExtension XPC_WN_Proto_ClassExtension = { + XPC_WN_Proto_ObjectMoved, // objectMovedOp +}; + +const JSClass XPC_WN_Proto_JSClass = { + "XPC_WN_Proto_JSClass", + JSCLASS_HAS_RESERVED_SLOTS(XPCWrappedNativeProto::SlotCount) | + JSCLASS_FOREGROUND_FINALIZE, + &XPC_WN_Proto_JSClassOps, + JS_NULL_CLASS_SPEC, + &XPC_WN_Proto_ClassExtension, + JS_NULL_OBJECT_OPS}; + +/***************************************************************************/ + +static bool XPC_WN_TearOff_Enumerate(JSContext* cx, HandleObject obj) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + XPCWrappedNativeTearOff* to = ccx.GetTearOff(); + XPCNativeInterface* iface; + + if (!to || nullptr == (iface = to->GetInterface())) { + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); + } + + uint16_t member_count = iface->GetMemberCount(); + for (uint16_t k = 0; k < member_count; k++) { + jsid name = iface->GetMemberAt(k)->GetName(); + JS_MarkCrossZoneId(cx, name); + if (!xpc_ForcePropertyResolve(cx, obj, name)) { + return false; + } + } + + return true; +} + +static bool XPC_WN_TearOff_Resolve(JSContext* cx, HandleObject obj, HandleId id, + bool* resolvedp) { + XPCCallContext ccx(cx, obj); + XPCWrappedNative* wrapper = ccx.GetWrapper(); + THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); + + XPCWrappedNativeTearOff* to = ccx.GetTearOff(); + XPCNativeInterface* iface; + + if (!to || nullptr == (iface = to->GetInterface())) { + return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); + } + + return DefinePropertyIfFound( + ccx, obj, id, nullptr, iface, nullptr, wrapper->GetScope(), true, nullptr, + nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE, + resolvedp); +} + +static void XPC_WN_TearOff_Finalize(JS::GCContext* gcx, JSObject* obj) { + XPCWrappedNativeTearOff* p = XPCWrappedNativeTearOff::Get(obj); + if (!p) { + return; + } + p->JSObjectFinalized(); +} + +static size_t XPC_WN_TearOff_ObjectMoved(JSObject* obj, JSObject* old) { + XPCWrappedNativeTearOff* p = XPCWrappedNativeTearOff::Get(obj); + if (!p) { + return 0; + } + p->JSObjectMoved(obj, old); + return 0; +} + +static const JSClassOps XPC_WN_Tearoff_JSClassOps = { + XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty + XPC_WN_CannotDeletePropertyStub, // delProperty + XPC_WN_TearOff_Enumerate, // enumerate + nullptr, // newEnumerate + XPC_WN_TearOff_Resolve, // resolve + nullptr, // mayResolve + XPC_WN_TearOff_Finalize, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +static const js::ClassExtension XPC_WN_Tearoff_JSClassExtension = { + XPC_WN_TearOff_ObjectMoved, // objectMovedOp +}; + +const JSClass XPC_WN_Tearoff_JSClass = { + "WrappedNative_TearOff", + JSCLASS_HAS_RESERVED_SLOTS(XPCWrappedNativeTearOff::SlotCount) | + JSCLASS_FOREGROUND_FINALIZE, + &XPC_WN_Tearoff_JSClassOps, JS_NULL_CLASS_SPEC, + &XPC_WN_Tearoff_JSClassExtension}; diff --git a/js/xpconnect/src/XPCWrappedNativeProto.cpp b/js/xpconnect/src/XPCWrappedNativeProto.cpp new file mode 100644 index 0000000000..4b492bfa9e --- /dev/null +++ b/js/xpconnect/src/XPCWrappedNativeProto.cpp @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shared proto object for XPCWrappedNative. */ + +#include "xpcprivate.h" +#include "js/Object.h" // JS::SetReservedSlot +#include "pratom.h" +#include "XPCMaps.h" + +using namespace mozilla; + +#ifdef DEBUG +int32_t XPCWrappedNativeProto::gDEBUG_LiveProtoCount = 0; +#endif + +XPCWrappedNativeProto::XPCWrappedNativeProto(XPCWrappedNativeScope* Scope, + nsIClassInfo* ClassInfo, + RefPtr<XPCNativeSet>&& Set) + : mScope(Scope), + mJSProtoObject(nullptr), + mClassInfo(ClassInfo), + mSet(std::move(Set)) { + // This native object lives as long as its associated JSObject - killed + // by finalization of the JSObject (or explicitly if Init fails). + + MOZ_COUNT_CTOR(XPCWrappedNativeProto); + MOZ_ASSERT(mScope); + +#ifdef DEBUG + gDEBUG_LiveProtoCount++; +#endif +} + +XPCWrappedNativeProto::~XPCWrappedNativeProto() { + MOZ_ASSERT(!mJSProtoObject, "JSProtoObject still alive"); + + MOZ_COUNT_DTOR(XPCWrappedNativeProto); + +#ifdef DEBUG + gDEBUG_LiveProtoCount--; +#endif + + // Note that our weak ref to mScope is not to be trusted at this point. + + XPCNativeSet::ClearCacheEntryForClassInfo(mClassInfo); + + DeferredFinalize(mClassInfo.forget().take()); +} + +bool XPCWrappedNativeProto::Init(JSContext* cx, nsIXPCScriptable* scriptable) { + mScriptable = scriptable; + + JS::RootedObject proto(cx, JS::GetRealmObjectPrototype(cx)); + mJSProtoObject = JS_NewObjectWithGivenProto(cx, &XPC_WN_Proto_JSClass, proto); + + bool success = !!mJSProtoObject; + if (success) { + JS::SetReservedSlot(mJSProtoObject, ProtoSlot, JS::PrivateValue(this)); + } + + return success; +} + +void XPCWrappedNativeProto::JSProtoObjectFinalized(JS::GCContext* gcx, + JSObject* obj) { + MOZ_ASSERT(obj == mJSProtoObject, "huh?"); + +#ifdef DEBUG + // Check that this object has already been swept from the map. + ClassInfo2WrappedNativeProtoMap* map = GetScope()->GetWrappedNativeProtoMap(); + MOZ_ASSERT(map->Find(mClassInfo) != this); +#endif + + MOZ_ALWAYS_TRUE(GetRuntime()->GetDyingWrappedNativeProtos().append(this)); + mJSProtoObject = nullptr; +} + +void XPCWrappedNativeProto::JSProtoObjectMoved(JSObject* obj, + const JSObject* old) { + // Update without triggering barriers. + MOZ_ASSERT(mJSProtoObject == old); + mJSProtoObject.unbarrieredSet(obj); +} + +void XPCWrappedNativeProto::SystemIsBeingShutDown() { + // Note that the instance might receive this call multiple times + // as we walk to here from various places. + + if (mJSProtoObject) { + // short circuit future finalization + JS::SetReservedSlot(mJSProtoObject, ProtoSlot, JS::UndefinedValue()); + mJSProtoObject = nullptr; + } +} + +// static +XPCWrappedNativeProto* XPCWrappedNativeProto::GetNewOrUsed( + JSContext* cx, XPCWrappedNativeScope* scope, nsIClassInfo* classInfo, + nsIXPCScriptable* scriptable) { + MOZ_ASSERT(scope, "bad param"); + MOZ_ASSERT(classInfo, "bad param"); + + AutoMarkingWrappedNativeProtoPtr proto(cx); + ClassInfo2WrappedNativeProtoMap* map = nullptr; + + map = scope->GetWrappedNativeProtoMap(); + proto = map->Find(classInfo); + if (proto) { + return proto; + } + + RefPtr<XPCNativeSet> set = XPCNativeSet::GetNewOrUsed(cx, classInfo); + if (!set) { + return nullptr; + } + + proto = new XPCWrappedNativeProto(scope, classInfo, std::move(set)); + + if (!proto->Init(cx, scriptable)) { + delete proto.get(); + return nullptr; + } + + map->Add(classInfo, proto); + + return proto; +} + +void XPCWrappedNativeProto::DebugDump(int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS(("XPCWrappedNativeProto @ %p", this)); + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("gDEBUG_LiveProtoCount is %d", gDEBUG_LiveProtoCount)); + XPC_LOG_ALWAYS(("mScope @ %p", mScope)); + XPC_LOG_ALWAYS(("mJSProtoObject @ %p", mJSProtoObject.get())); + XPC_LOG_ALWAYS(("mSet @ %p", mSet.get())); + XPC_LOG_ALWAYS(("mScriptable @ %p", mScriptable.get())); + if (depth && mScriptable) { + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("mFlags of %x", mScriptable->GetScriptableFlags())); + XPC_LOG_ALWAYS(("mJSClass @ %p", mScriptable->GetJSClass())); + XPC_LOG_OUTDENT(); + } + XPC_LOG_OUTDENT(); +#endif +} diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp new file mode 100644 index 0000000000..c600760544 --- /dev/null +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -0,0 +1,497 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Class used to manage the wrapped native objects within a JS scope. */ + +#include "AccessCheck.h" +#include "xpcprivate.h" +#include "XPCWrapper.h" +#include "nsContentUtils.h" +#include "nsCycleCollectionNoteRootCallback.h" +#include "ExpandedPrincipal.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Preferences.h" +#include "XPCMaps.h" +#include "mozilla/Unused.h" +#include "js/Object.h" // JS::GetCompartment +#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById +#include "js/RealmIterators.h" +#include "mozJSModuleLoader.h" + +#include "mozilla/dom/BindingUtils.h" + +using namespace mozilla; +using namespace xpc; +using namespace JS; + +/***************************************************************************/ + +static XPCWrappedNativeScopeList& AllScopes() { + return XPCJSRuntime::Get()->GetWrappedNativeScopes(); +} + +static bool RemoteXULForbidsXBLScopeForPrincipal(nsIPrincipal* aPrincipal) { + // AllowXULXBLForPrincipal will return true for system principal, but we + // don't want that here. + MOZ_ASSERT(nsContentUtils::IsInitialized()); + if (aPrincipal->IsSystemPrincipal()) { + return false; + } + + // If this domain isn't whitelisted, we're done. + if (!nsContentUtils::AllowXULXBLForPrincipal(aPrincipal)) { + return false; + } + + // Check the pref to determine how we should behave. + return !Preferences::GetBool("dom.use_xbl_scopes_for_remote_xul", false); +} + +static bool RemoteXULForbidsXBLScope(HandleObject aFirstGlobal) { + MOZ_ASSERT(aFirstGlobal); + + // Certain singleton sandoxes are created very early in startup - too early + // to call into AllowXULXBLForPrincipal. We never create XBL scopes for + // sandboxes anway, and certainly not for these singleton scopes. So we just + // short-circuit here. + if (IsSandbox(aFirstGlobal)) { + return false; + } + + nsIPrincipal* principal = xpc::GetObjectPrincipal(aFirstGlobal); + return RemoteXULForbidsXBLScopeForPrincipal(principal); +} + +XPCWrappedNativeScope::XPCWrappedNativeScope(JS::Compartment* aCompartment, + JS::HandleObject aFirstGlobal) + : mWrappedNativeMap(mozilla::MakeUnique<Native2WrappedNativeMap>()), + mWrappedNativeProtoMap( + mozilla::MakeUnique<ClassInfo2WrappedNativeProtoMap>()), + mComponents(nullptr), + mCompartment(aCompartment) { +#ifdef DEBUG + for (XPCWrappedNativeScope* cur : AllScopes()) { + MOZ_ASSERT(aCompartment != cur->Compartment(), "dup object"); + } +#endif + + AllScopes().insertBack(this); + + MOZ_COUNT_CTOR(XPCWrappedNativeScope); + + // Determine whether we would allow an XBL scope in this situation. + // In addition to being pref-controlled, we also disable XBL scopes for + // remote XUL domains, _except_ if we have an additional pref override set. + // + // Note that we can't quite remove this yet, even though we never actually + // use XBL scopes, because the security manager uses this boolean to make + // decisions that we rely on in our test infrastructure. + // + // FIXME(emilio): Now that the security manager is the only caller probably + // should be renamed, but what's a good name for this? + mAllowContentXBLScope = !RemoteXULForbidsXBLScope(aFirstGlobal); +} + +bool XPCWrappedNativeScope::GetComponentsJSObject(JSContext* cx, + JS::MutableHandleObject obj) { + if (!mComponents) { + bool system = AccessCheck::isChrome(mCompartment); + MOZ_RELEASE_ASSERT(system, "How did we get a non-system Components?"); + mComponents = new nsXPCComponents(this); + } + + RootedValue val(cx); + xpcObjectHelper helper(mComponents); + bool ok = XPCConvert::NativeInterface2JSObject(cx, &val, helper, nullptr, + false, nullptr); + if (NS_WARN_IF(!ok)) { + return false; + } + + if (NS_WARN_IF(!val.isObject())) { + return false; + } + + obj.set(&val.toObject()); + return true; +} + +static bool DefineSubcomponentProperty(JSContext* aCx, HandleObject aGlobal, + nsISupports* aSubcomponent, + const nsID* aIID, + unsigned int aStringIndex) { + RootedValue subcompVal(aCx); + xpcObjectHelper helper(aSubcomponent); + if (!XPCConvert::NativeInterface2JSObject(aCx, &subcompVal, helper, aIID, + false, nullptr)) + return false; + if (NS_WARN_IF(!subcompVal.isObject())) { + return false; + } + RootedId id(aCx, XPCJSContext::Get()->GetStringID(aStringIndex)); + return JS_DefinePropertyById(aCx, aGlobal, id, subcompVal, 0); +} + +bool XPCWrappedNativeScope::AttachComponentsObject(JSContext* aCx) { + RootedObject components(aCx); + if (!GetComponentsJSObject(aCx, &components)) { + return false; + } + + RootedObject global(aCx, CurrentGlobalOrNull(aCx)); + + const unsigned attrs = JSPROP_READONLY | JSPROP_RESOLVING | JSPROP_PERMANENT; + + RootedId id(aCx, + XPCJSContext::Get()->GetStringID(XPCJSContext::IDX_COMPONENTS)); + if (!JS_DefinePropertyById(aCx, global, id, components, attrs)) { + return false; + } + +// _iid can be nullptr if the object implements classinfo. +#define DEFINE_SUBCOMPONENT_PROPERTY(_comp, _type, _iid, _id) \ + nsCOMPtr<nsIXPCComponents_##_type> obj##_type; \ + if (NS_FAILED(_comp->Get##_type(getter_AddRefs(obj##_type)))) return false; \ + if (!DefineSubcomponentProperty(aCx, global, obj##_type, _iid, \ + XPCJSContext::IDX_##_id)) \ + return false; + + DEFINE_SUBCOMPONENT_PROPERTY(mComponents, Interfaces, nullptr, CI) + DEFINE_SUBCOMPONENT_PROPERTY(mComponents, Results, nullptr, CR) + + DEFINE_SUBCOMPONENT_PROPERTY(mComponents, Classes, nullptr, CC) + DEFINE_SUBCOMPONENT_PROPERTY(mComponents, Utils, + &NS_GET_IID(nsIXPCComponents_Utils), CU) + +#undef DEFINE_SUBCOMPONENT_PROPERTY + + return true; +} + +bool XPCWrappedNativeScope::AttachJSServices(JSContext* aCx) { + RootedObject global(aCx, CurrentGlobalOrNull(aCx)); + return mozJSModuleLoader::Get()->DefineJSServices(aCx, global); +} + +bool XPCWrappedNativeScope::XBLScopeStateMatches(nsIPrincipal* aPrincipal) { + return mAllowContentXBLScope == + !RemoteXULForbidsXBLScopeForPrincipal(aPrincipal); +} + +bool XPCWrappedNativeScope::AllowContentXBLScope(Realm* aRealm) { + // We only disallow XBL scopes in remote XUL situations. + MOZ_ASSERT_IF(!mAllowContentXBLScope, nsContentUtils::AllowXULXBLForPrincipal( + xpc::GetRealmPrincipal(aRealm))); + return mAllowContentXBLScope; +} + +namespace xpc { +JSObject* GetUAWidgetScope(JSContext* cx, JSObject* contentScopeArg) { + JS::RootedObject contentScope(cx, contentScopeArg); + JSAutoRealm ar(cx, contentScope); + nsIPrincipal* principal = GetObjectPrincipal(contentScope); + + if (principal->IsSystemPrincipal()) { + return JS::GetNonCCWObjectGlobal(contentScope); + } + + return GetUAWidgetScope(cx, principal); +} + +JSObject* GetUAWidgetScope(JSContext* cx, nsIPrincipal* principal) { + RootedObject scope(cx, XPCJSRuntime::Get()->GetUAWidgetScope(cx, principal)); + NS_ENSURE_TRUE(scope, nullptr); // See bug 858642. + + scope = js::UncheckedUnwrap(scope); + JS::ExposeObjectToActiveJS(scope); + return scope; +} + +bool AllowContentXBLScope(JS::Realm* realm) { + JS::Compartment* comp = GetCompartmentForRealm(realm); + XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->GetScope(); + MOZ_ASSERT(scope); + return scope->AllowContentXBLScope(realm); +} + +} /* namespace xpc */ + +XPCWrappedNativeScope::~XPCWrappedNativeScope() { + MOZ_COUNT_DTOR(XPCWrappedNativeScope); + + // We can do additional cleanup assertions here... + + MOZ_ASSERT(0 == mWrappedNativeMap->Count(), "scope has non-empty map"); + + MOZ_ASSERT(0 == mWrappedNativeProtoMap->Count(), "scope has non-empty map"); + + // This should not be necessary, since the Components object should die + // with the scope but just in case. + if (mComponents) { + mComponents->mScope = nullptr; + } + + // XXX we should assert that we are dead or that xpconnect has shutdown + // XXX might not want to do this at xpconnect shutdown time??? + mComponents = nullptr; + + MOZ_RELEASE_ASSERT(!mXrayExpandos.initialized()); + + mCompartment = nullptr; +} + +// static +void XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(XPCJSRuntime* xpcrt, + JSTracer* trc) { + // Do JS::TraceEdge for all wrapped natives with external references, as + // well as any DOM expando objects. + // + // Note: the GC can call this from a JS helper thread. We don't use + // AllScopes() because that asserts we're on the main thread. + + for (XPCWrappedNativeScope* cur : xpcrt->GetWrappedNativeScopes()) { + for (auto i = cur->mWrappedNativeMap->Iter(); !i.done(); i.next()) { + XPCWrappedNative* wrapper = i.get().value(); + if (wrapper->HasExternalReference() && !wrapper->IsWrapperExpired()) { + wrapper->TraceSelf(trc); + } + } + } +} + +// static +void XPCWrappedNativeScope::SuspectAllWrappers( + nsCycleCollectionNoteRootCallback& cb) { + for (XPCWrappedNativeScope* cur : AllScopes()) { + for (auto i = cur->mWrappedNativeMap->Iter(); !i.done(); i.next()) { + i.get().value()->Suspect(cb); + } + } +} + +void XPCWrappedNativeScope::UpdateWeakPointersAfterGC(JSTracer* trc) { + // Sweep waivers. + if (mWaiverWrapperMap) { + mWaiverWrapperMap->UpdateWeakPointers(trc); + } + + if (!js::IsCompartmentZoneSweepingOrCompacting(mCompartment)) { + return; + } + + if (!js::CompartmentHasLiveGlobal(mCompartment)) { + GetWrappedNativeMap()->Clear(); + mWrappedNativeProtoMap->Clear(); + + // The fields below are traced only if there's a live global in the + // compartment, see TraceXPCGlobal. The compartment has no live globals so + // clear these pointers here. + if (mXrayExpandos.initialized()) { + mXrayExpandos.destroy(); + } + mIDProto = nullptr; + mIIDProto = nullptr; + mCIDProto = nullptr; + return; + } + + // Sweep mWrappedNativeMap for dying flat JS objects. Moving has already + // been handled by XPCWrappedNative::FlatJSObjectMoved. + for (auto iter = GetWrappedNativeMap()->ModIter(); !iter.done(); + iter.next()) { + XPCWrappedNative* wrapper = iter.get().value(); + JSObject* obj = wrapper->GetFlatJSObjectPreserveColor(); + if (JS_UpdateWeakPointerAfterGCUnbarriered(trc, &obj)) { + MOZ_ASSERT(obj == wrapper->GetFlatJSObjectPreserveColor()); + MOZ_ASSERT(JS::GetCompartment(obj) == mCompartment); + } else { + iter.remove(); + } + } + + // Sweep mWrappedNativeProtoMap for dying prototype JSObjects. Moving has + // already been handled by XPCWrappedNativeProto::JSProtoObjectMoved. + for (auto i = mWrappedNativeProtoMap->ModIter(); !i.done(); i.next()) { + XPCWrappedNativeProto* proto = i.get().value(); + JSObject* obj = proto->GetJSProtoObjectPreserveColor(); + if (JS_UpdateWeakPointerAfterGCUnbarriered(trc, &obj)) { + MOZ_ASSERT(JS::GetCompartment(obj) == mCompartment); + MOZ_ASSERT(obj == proto->GetJSProtoObjectPreserveColor()); + } else { + i.remove(); + } + } +} + +// static +void XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs() { + for (XPCWrappedNativeScope* cur : AllScopes()) { + for (auto i = cur->mWrappedNativeMap->Iter(); !i.done(); i.next()) { + i.get().value()->SweepTearOffs(); + } + } +} + +// static +void XPCWrappedNativeScope::SystemIsBeingShutDown() { + // We're forcibly killing scopes, rather than allowing them to go away + // when they're ready. As such, we need to do some cleanup before they + // can safely be destroyed. + + for (XPCWrappedNativeScope* cur : AllScopes()) { + // Give the Components object a chance to try to clean up. + if (cur->mComponents) { + cur->mComponents->SystemIsBeingShutDown(); + } + + // Null out these pointers to prevent ~ObjectPtr assertion failures if we + // leaked things at shutdown. + cur->mIDProto = nullptr; + cur->mIIDProto = nullptr; + cur->mCIDProto = nullptr; + + // Similarly, destroy mXrayExpandos to prevent assertion failures. + if (cur->mXrayExpandos.initialized()) { + cur->mXrayExpandos.destroy(); + } + + // Walk the protos first. Wrapper shutdown can leave dangling + // proto pointers in the proto map. + for (auto i = cur->mWrappedNativeProtoMap->ModIter(); !i.done(); i.next()) { + i.get().value()->SystemIsBeingShutDown(); + i.remove(); + } + for (auto i = cur->mWrappedNativeMap->ModIter(); !i.done(); i.next()) { + i.get().value()->SystemIsBeingShutDown(); + i.remove(); + } + + CompartmentPrivate* priv = CompartmentPrivate::Get(cur->Compartment()); + priv->SystemIsBeingShutDown(); + } +} + +/***************************************************************************/ + +JSObject* XPCWrappedNativeScope::GetExpandoChain(HandleObject target) { + MOZ_ASSERT(ObjectScope(target) == this); + if (!mXrayExpandos.initialized()) { + return nullptr; + } + return mXrayExpandos.lookup(target); +} + +JSObject* XPCWrappedNativeScope::DetachExpandoChain(HandleObject target) { + MOZ_ASSERT(ObjectScope(target) == this); + if (!mXrayExpandos.initialized()) { + return nullptr; + } + return mXrayExpandos.removeValue(target); +} + +bool XPCWrappedNativeScope::SetExpandoChain(JSContext* cx, HandleObject target, + HandleObject chain) { + MOZ_ASSERT(ObjectScope(target) == this); + MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx)); + MOZ_ASSERT_IF(chain, ObjectScope(chain) == this); + if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx)) { + return false; + } + return mXrayExpandos.put(cx, target, chain); +} + +/***************************************************************************/ + +// static +void XPCWrappedNativeScope::DebugDumpAllScopes(int16_t depth) { +#ifdef DEBUG + depth--; + + // get scope count. + int count = 0; + for (XPCWrappedNativeScope* cur : AllScopes()) { + mozilla::Unused << cur; + count++; + } + + XPC_LOG_ALWAYS(("chain of %d XPCWrappedNativeScope(s)", count)); + XPC_LOG_INDENT(); + if (depth) { + for (XPCWrappedNativeScope* cur : AllScopes()) { + cur->DebugDump(depth); + } + } + XPC_LOG_OUTDENT(); +#endif +} + +void XPCWrappedNativeScope::DebugDump(int16_t depth) { +#ifdef DEBUG + depth--; + XPC_LOG_ALWAYS(("XPCWrappedNativeScope @ %p", this)); + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("next @ %p", getNext())); + XPC_LOG_ALWAYS(("mComponents @ %p", mComponents.get())); + XPC_LOG_ALWAYS(("mCompartment @ %p", mCompartment)); + + XPC_LOG_ALWAYS(("mWrappedNativeMap @ %p with %d wrappers(s)", + mWrappedNativeMap.get(), mWrappedNativeMap->Count())); + // iterate contexts... + if (depth && mWrappedNativeMap->Count()) { + XPC_LOG_INDENT(); + for (auto i = mWrappedNativeMap->Iter(); !i.done(); i.next()) { + i.get().value()->DebugDump(depth); + } + XPC_LOG_OUTDENT(); + } + + XPC_LOG_ALWAYS(("mWrappedNativeProtoMap @ %p with %d protos(s)", + mWrappedNativeProtoMap.get(), + mWrappedNativeProtoMap->Count())); + // iterate contexts... + if (depth && mWrappedNativeProtoMap->Count()) { + XPC_LOG_INDENT(); + for (auto i = mWrappedNativeProtoMap->Iter(); !i.done(); i.next()) { + i.get().value()->DebugDump(depth); + } + XPC_LOG_OUTDENT(); + } + XPC_LOG_OUTDENT(); +#endif +} + +void XPCWrappedNativeScope::AddSizeOfAllScopesIncludingThis( + JSContext* cx, ScopeSizeInfo* scopeSizeInfo) { + for (XPCWrappedNativeScope* cur : AllScopes()) { + cur->AddSizeOfIncludingThis(cx, scopeSizeInfo); + } +} + +void XPCWrappedNativeScope::AddSizeOfIncludingThis( + JSContext* cx, ScopeSizeInfo* scopeSizeInfo) { + scopeSizeInfo->mScopeAndMapSize += scopeSizeInfo->mMallocSizeOf(this); + scopeSizeInfo->mScopeAndMapSize += + mWrappedNativeMap->SizeOfIncludingThis(scopeSizeInfo->mMallocSizeOf); + scopeSizeInfo->mScopeAndMapSize += + mWrappedNativeProtoMap->SizeOfIncludingThis(scopeSizeInfo->mMallocSizeOf); + + auto realmCb = [](JSContext*, void* aData, JS::Realm* aRealm, + const JS::AutoRequireNoGC& nogc) { + auto* scopeSizeInfo = static_cast<ScopeSizeInfo*>(aData); + JSObject* global = GetRealmGlobalOrNull(aRealm); + if (global && dom::HasProtoAndIfaceCache(global)) { + dom::ProtoAndIfaceCache* cache = dom::GetProtoAndIfaceCache(global); + scopeSizeInfo->mProtoAndIfaceCacheSize += + cache->SizeOfIncludingThis(scopeSizeInfo->mMallocSizeOf); + } + }; + IterateRealmsInCompartment(cx, Compartment(), scopeSizeInfo, realmCb); + + // There are other XPCWrappedNativeScope members that could be measured; + // the above ones have been seen by DMD to be worth measuring. More stuff + // may be added later. +} diff --git a/js/xpconnect/src/XPCWrapper.cpp b/js/xpconnect/src/XPCWrapper.cpp new file mode 100644 index 0000000000..7a4f689471 --- /dev/null +++ b/js/xpconnect/src/XPCWrapper.cpp @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcprivate.h" +#include "XPCWrapper.h" +#include "WrapperFactory.h" +#include "AccessCheck.h" + +#include "js/PropertyAndElement.h" // JS_DefineFunction + +using namespace xpc; +using namespace mozilla; +using namespace JS; + +namespace XPCNativeWrapper { + +static inline bool ThrowException(nsresult ex, JSContext* cx) { + XPCThrower::Throw(ex, cx); + + return false; +} + +static bool UnwrapNW(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (args.length() != 1) { + return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); + } + + JS::RootedValue v(cx, args[0]); + if (!v.isObject() || !js::IsCrossCompartmentWrapper(&v.toObject()) || + !WrapperFactory::AllowWaiver(&v.toObject())) { + args.rval().set(v); + return true; + } + + bool ok = xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v); + NS_ENSURE_TRUE(ok, false); + args.rval().set(v); + return true; +} + +static bool XrayWrapperConstructor(JSContext* cx, unsigned argc, Value* vp) { + JS::CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() == 0) { + return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); + } + + if (!args[0].isObject()) { + if (args.isConstructing()) { + return ThrowException(NS_ERROR_XPC_BAD_CONVERT_JS, cx); + } + + args.rval().set(args[0]); + return true; + } + + args.rval().setObject(*js::UncheckedUnwrap(&args[0].toObject())); + return JS_WrapValue(cx, args.rval()); +} +// static +bool AttachNewConstructorObject(JSContext* aCx, + JS::HandleObject aGlobalObject) { + JSAutoRealm ar(aCx, aGlobalObject); + JSFunction* xpcnativewrapper = JS_DefineFunction( + aCx, aGlobalObject, "XPCNativeWrapper", XrayWrapperConstructor, 1, + JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_CONSTRUCTOR); + if (!xpcnativewrapper) { + return false; + } + JS::RootedObject obj(aCx, JS_GetFunctionObject(xpcnativewrapper)); + return JS_DefineFunction(aCx, obj, "unwrap", UnwrapNW, 1, + JSPROP_READONLY | JSPROP_PERMANENT) != nullptr; +} + +} // namespace XPCNativeWrapper + +namespace XPCWrapper { + +JSObject* UnsafeUnwrapSecurityWrapper(JSObject* obj) { + if (js::IsProxy(obj)) { + return js::UncheckedUnwrap(obj); + } + + return obj; +} + +} // namespace XPCWrapper diff --git a/js/xpconnect/src/XPCWrapper.h b/js/xpconnect/src/XPCWrapper.h new file mode 100644 index 0000000000..3c95322918 --- /dev/null +++ b/js/xpconnect/src/XPCWrapper.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef XPC_WRAPPER_H +#define XPC_WRAPPER_H 1 + +#include "js/TypeDecls.h" + +namespace XPCNativeWrapper { + +bool AttachNewConstructorObject(JSContext* aCx, JS::HandleObject aGlobalObject); + +} // namespace XPCNativeWrapper + +// This namespace wraps some common functionality between the three existing +// wrappers. Its main purpose is to allow XPCCrossOriginWrapper to act both +// as an XPCSafeJSObjectWrapper and as an XPCNativeWrapper when required to +// do so (the decision is based on the principals of the wrapper and wrapped +// objects). +namespace XPCWrapper { + +JSObject* UnsafeUnwrapSecurityWrapper(JSObject* obj); + +} // namespace XPCWrapper + +#endif diff --git a/js/xpconnect/src/components.conf b/js/xpconnect/src/components.conf new file mode 100644 index 0000000000..5cccec28b2 --- /dev/null +++ b/js/xpconnect/src/components.conf @@ -0,0 +1,16 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Classes = [ + { + 'js_name': 'scriptloader', + 'cid': '{929814d6-1dd2-11b2-8e08-82fa0a339b00}', + 'contract_ids': ['@mozilla.org/moz/jssubscript-loader;1'], + 'interfaces': ['mozIJSSubScriptLoader'], + 'type': 'mozJSSubScriptLoader', + 'headers': ['/js/xpconnect/loader/mozJSSubScriptLoader.h'], + }, +] diff --git a/js/xpconnect/src/jsshell.msg b/js/xpconnect/src/jsshell.msg new file mode 100644 index 0000000000..2758c1276c --- /dev/null +++ b/js/xpconnect/src/jsshell.msg @@ -0,0 +1,12 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Error messages for JSShell. See js/public/friend/ErrorNumbers.msg for format. + */ + +MSG_DEF(JSSMSG_NOT_AN_ERROR, 0, 0, JSEXN_ERR, "<Error #0 is reserved>") +MSG_DEF(JSSMSG_CANT_OPEN, 1, 2, JSEXN_ERR, "can't open {0}: {1}") diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build new file mode 100644 index 0000000000..39d4baecec --- /dev/null +++ b/js/xpconnect/src/moz.build @@ -0,0 +1,79 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + "BackstagePass.h", + "JSServices.h", + "nsIXPConnect.h", + "XPCJSMemoryReporter.h", + "xpcObjectHelper.h", + "xpcpublic.h", + "XPCSelfHostedShmem.h", +] + +UNIFIED_SOURCES += [ + "ExportHelpers.cpp", + "JSServices.cpp", + "nsXPConnect.cpp", + "Sandbox.cpp", + "XPCCallContext.cpp", + "XPCComponents.cpp", + "XPCConvert.cpp", + "XPCDebug.cpp", + "XPCException.cpp", + "XPCJSContext.cpp", + "XPCJSID.cpp", + "XPCJSRuntime.cpp", + "XPCJSWeakReference.cpp", + "XPCLocale.cpp", + "XPCLog.cpp", + "XPCMaps.cpp", + "XPCModule.cpp", + "XPCRuntimeService.cpp", + "XPCSelfHostedShmem.cpp", + "XPCShellImpl.cpp", + "XPCString.cpp", + "XPCThrower.cpp", + "XPCVariant.cpp", + "XPCWrappedJS.cpp", + "XPCWrappedJSClass.cpp", + "XPCWrappedJSIterator.cpp", + "XPCWrappedNative.cpp", + "XPCWrappedNativeInfo.cpp", + "XPCWrappedNativeJSOps.cpp", + "XPCWrappedNativeProto.cpp", + "XPCWrappedNativeScope.cpp", + "XPCWrapper.cpp", +] + + +if CONFIG["LIBFUZZER"]: + UNIFIED_SOURCES += ["xpcrtfuzzing/xpcrtfuzzing.cpp"] + +XPCOM_MANIFESTS += [ + "components.conf", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" + +LOCAL_INCLUDES += [ + "!/xpcom/components", + "../loader", + "../wrappers", + "/caps", + "/dom/base", + "/dom/bindings", + "/dom/html", + "/layout/base", + "/layout/style", + "/netwerk/base", + "/xpcom/components", +] + +if CONFIG["CC_TYPE"] in ("clang", "gcc"): + CXXFLAGS += ["-Werror=format"] diff --git a/js/xpconnect/src/nsIXPConnect.h b/js/xpconnect/src/nsIXPConnect.h new file mode 100644 index 0000000000..07703182f4 --- /dev/null +++ b/js/xpconnect/src/nsIXPConnect.h @@ -0,0 +1,291 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsIXPConnect_h +#define nsIXPConnect_h + +/* The core XPConnect public interfaces. */ + +#include "nsISupports.h" + +#include "jspubtd.h" +#include "js/CompileOptions.h" +#include "js/TypeDecls.h" +#include "mozilla/Attributes.h" +#include "xptinfo.h" +#include "nsCOMPtr.h" + +class XPCWrappedNative; +class nsXPCWrappedJS; +class nsWrapperCache; + +// forward declarations... +class nsIPrincipal; +class nsIVariant; + +/***************************************************************************/ +#define NS_IXPCONNECTJSOBJECTHOLDER_IID_STR \ + "73e6ff4a-ab99-4d99-ac00-ba39ccb8e4d7" +#define NS_IXPCONNECTJSOBJECTHOLDER_IID \ + { \ + 0x73e6ff4a, 0xab99, 0x4d99, { \ + 0xac, 0x00, 0xba, 0x39, 0xcc, 0xb8, 0xe4, 0xd7 \ + } \ + } + +class NS_NO_VTABLE nsIXPConnectJSObjectHolder : public nsISupports { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECTJSOBJECTHOLDER_IID) + + virtual JSObject* GetJSObject() = 0; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPConnectJSObjectHolder, + NS_IXPCONNECTJSOBJECTHOLDER_IID) + +#define NS_IXPCONNECTWRAPPEDNATIVE_IID_STR \ + "e787be29-db5d-4a45-a3d6-1de1d6b85c30" +#define NS_IXPCONNECTWRAPPEDNATIVE_IID \ + { \ + 0xe787be29, 0xdb5d, 0x4a45, { \ + 0xa3, 0xd6, 0x1d, 0xe1, 0xd6, 0xb8, 0x5c, 0x30 \ + } \ + } + +class nsIXPConnectWrappedNative : public nsIXPConnectJSObjectHolder { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECTWRAPPEDNATIVE_IID) + + nsresult DebugDump(int16_t depth); + + nsISupports* Native() const { return mIdentity; } + + protected: + nsCOMPtr<nsISupports> mIdentity; + + private: + XPCWrappedNative* AsXPCWrappedNative(); +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPConnectWrappedNative, + NS_IXPCONNECTWRAPPEDNATIVE_IID) + +#define NS_IXPCONNECTWRAPPEDJS_IID_STR "3a01b0d6-074b-49ed-bac3-08c76366cae4" +#define NS_IXPCONNECTWRAPPEDJS_IID \ + { \ + 0x3a01b0d6, 0x074b, 0x49ed, { \ + 0xba, 0xc3, 0x08, 0xc7, 0x63, 0x66, 0xca, 0xe4 \ + } \ + } + +class nsIXPConnectWrappedJS : public nsIXPConnectJSObjectHolder { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECTWRAPPEDJS_IID) + + nsresult GetInterfaceIID(nsIID** aInterfaceIID); + + // Returns the global object for our JS object. If this object is a + // cross-compartment wrapper, returns the compartment's first global. + // The global we return is guaranteed to be same-compartment with the + // object. + // Note: this matches the GetJSObject() signature. + JSObject* GetJSObjectGlobal(); + + nsresult DebugDump(int16_t depth); + + nsresult AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); + + private: + nsXPCWrappedJS* AsXPCWrappedJS(); +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPConnectWrappedJS, NS_IXPCONNECTWRAPPEDJS_IID) + +#define NS_IXPCONNECTWRAPPEDJSUNMARKGRAY_IID_STR \ + "c02a0ce6-275f-4ea1-9c23-08494898b070" +#define NS_IXPCONNECTWRAPPEDJSUNMARKGRAY_IID \ + { \ + 0xc02a0ce6, 0x275f, 0x4ea1, { \ + 0x9c, 0x23, 0x08, 0x49, 0x48, 0x98, 0xb0, 0x70 \ + } \ + } + +// Special interface to unmark the internal JSObject. +// QIing to nsIXPConnectWrappedJSUnmarkGray does *not* addref, it only unmarks, +// and QIing to nsIXPConnectWrappedJSUnmarkGray is always supposed to fail. +class NS_NO_VTABLE nsIXPConnectWrappedJSUnmarkGray + : public nsIXPConnectWrappedJS { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECTWRAPPEDJSUNMARKGRAY_IID) +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPConnectWrappedJSUnmarkGray, + NS_IXPCONNECTWRAPPEDJSUNMARKGRAY_IID) + +/***************************************************************************/ + +#define NS_IXPCONNECT_IID_STR "768507b5-b981-40c7-8276-f6a1da502a24" +#define NS_IXPCONNECT_IID \ + { \ + 0x768507b5, 0xb981, 0x40c7, { \ + 0x82, 0x76, 0xf6, 0xa1, 0xda, 0x50, 0x2a, 0x24 \ + } \ + } + +class nsIXPConnect : public nsISupports { + public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECT_IID) + // This gets a non-addref'd pointer. + static nsIXPConnect* XPConnect(); + + /** + * wrapNative will create a new JSObject or return an existing one. + * + * This method now correctly deals with cases where the passed in xpcom + * object already has an associated JSObject for the cases: + * 1) The xpcom object has already been wrapped for use in the same scope + * as an nsIXPConnectWrappedNative. + * 2) The xpcom object is in fact a nsIXPConnectWrappedJS and thus already + * has an underlying JSObject. + * + * It *might* be possible to QueryInterface the nsIXPConnectJSObjectHolder + * returned by the method into a nsIXPConnectWrappedNative or a + * nsIXPConnectWrappedJS. + * + * This method will never wrap the JSObject involved in an + * XPCNativeWrapper before returning. + * + * Returns: + * success: + * NS_OK + * failure: + * NS_ERROR_XPC_BAD_CONVERT_NATIVE + * NS_ERROR_FAILURE + */ + nsresult WrapNative(JSContext* aJSContext, JSObject* aScopeArg, + nsISupports* aCOMObj, const nsIID& aIID, + JSObject** aRetVal); + + /** + * Same as wrapNative, but it returns the JSObject in aVal. C++ callers + * must ensure that aVal is rooted. + * aIID may be null, it means the same as passing in + * &NS_GET_IID(nsISupports) but when passing in null certain shortcuts + * can be taken because we know without comparing IIDs that the caller is + * asking for an nsISupports wrapper. + * If aAllowWrapper, then the returned value will be wrapped in the proper + * type of security wrapper on top of the XPCWrappedNative (if needed). + * This method doesn't push aJSContext on the context stack, so the caller + * is required to push it if the top of the context stack is not equal to + * aJSContext. + */ + nsresult WrapNativeToJSVal(JSContext* aJSContext, JSObject* aScopeArg, + nsISupports* aCOMObj, nsWrapperCache* aCache, + const nsIID* aIID, bool aAllowWrapping, + JS::MutableHandle<JS::Value> aVal); + + /** + * wrapJS will yield a new or previously existing xpcom interface pointer + * to represent the JSObject passed in. + * + * This method now correctly deals with cases where the passed in JSObject + * already has an associated xpcom interface for the cases: + * 1) The JSObject has already been wrapped as a nsIXPConnectWrappedJS. + * 2) The JSObject is in fact a nsIXPConnectWrappedNative and thus already + * has an underlying xpcom object. + * 3) The JSObject is of a jsclass which supports getting the nsISupports + * from the JSObject directly. This is used for idlc style objects + * (e.g. DOM objects). + * + * It *might* be possible to QueryInterface the resulting interface pointer + * to nsIXPConnectWrappedJS. + * + * Returns: + * success: + * NS_OK + * failure: + * NS_ERROR_XPC_BAD_CONVERT_JS + * NS_ERROR_FAILURE + */ + nsresult WrapJS(JSContext* aJSContext, JSObject* aJSObj, const nsIID& aIID, + void** result); + + /** + * Wraps the given jsval in a nsIVariant and returns the new variant. + */ + nsresult JSValToVariant(JSContext* cx, JS::Handle<JS::Value> aJSVal, + nsIVariant** aResult); + + /** + * This only succeeds if the JSObject is a nsIXPConnectWrappedNative. + * A new wrapper is *never* constructed. + */ + nsresult GetWrappedNativeOfJSObject(JSContext* aJSContext, JSObject* aJSObj, + nsIXPConnectWrappedNative** _retval); + + nsresult DebugDump(int16_t depth); + nsresult DebugDumpObject(nsISupports* aCOMObj, int16_t depth); + nsresult DebugDumpJSStack(bool showArgs, bool showLocals, bool showThisProps); + + /** + * wrapJSAggregatedToNative is just like wrapJS except it is used in cases + * where the JSObject is also aggregated to some native xpcom Object. + * At present XBL is the only system that might want to do this. + * + * XXX write more! + * + * Returns: + * success: + * NS_OK + * failure: + * NS_ERROR_XPC_BAD_CONVERT_JS + * NS_ERROR_FAILURE + */ + nsresult WrapJSAggregatedToNative(nsISupports* aOuter, JSContext* aJSContext, + JSObject* aJSObj, const nsIID& aIID, + void** result); + + // Methods added since mozilla 0.6.... + + nsresult VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, + JS::MutableHandle<JS::Value> _retval); + nsresult JSToVariant(JSContext* ctx, JS::Handle<JS::Value> value, + nsIVariant** _retval); + + /** + * Create a sandbox for evaluating code in isolation using + * evalInSandboxObject(). + * + * @param cx A context to use when creating the sandbox object. + * @param principal The principal (or NULL to use the null principal) + * to use when evaluating code in this sandbox. + */ + nsresult CreateSandbox(JSContext* cx, nsIPrincipal* principal, + JSObject** _retval); + + /** + * Evaluate script in a sandbox, completely isolated from all + * other running scripts. + * + * @param source The source of the script to evaluate. + * @param filename The filename of the script. May be null. + * @param cx The context to use when setting up the evaluation of + * the script. The actual evaluation will happen on a new + * temporary context. + * @param sandbox The sandbox object to evaluate the script in. + * @return The result of the evaluation as a jsval. If the caller + * intends to use the return value from this call the caller + * is responsible for rooting the jsval before making a call + * to this method. + */ + nsresult EvalInSandboxObject(const nsAString& source, const char* filename, + JSContext* cx, JSObject* sandboxArg, + JS::MutableHandle<JS::Value> rval); +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPConnect, NS_IXPCONNECT_IID) + +#endif // defined nsIXPConnect_h diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp new file mode 100644 index 0000000000..f1ee189f0b --- /dev/null +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -0,0 +1,1160 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* High level class and public functions implementation. */ + +#include "js/Transcoding.h" +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" +#include "mozilla/Likely.h" +#include "mozilla/Unused.h" + +#include "XPCWrapper.h" +#include "jsfriendapi.h" +#include "js/AllocationLogging.h" // JS::SetLogCtorDtorFunctions +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions +#include "js/Object.h" // JS::GetClass +#include "js/ProfilingStack.h" +#include "GeckoProfiler.h" +#include "mozJSModuleLoader.h" +#include "nsJSEnvironment.h" +#include "nsThreadUtils.h" +#include "nsDOMJSUtils.h" + +#include "WrapperFactory.h" +#include "AccessCheck.h" +#include "JSServices.h" + +#include "mozilla/BasePrincipal.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/DOMException.h" +#include "mozilla/dom/Exceptions.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/glean/bindings/Glean.h" +#include "mozilla/glean/bindings/GleanPings.h" +#include "mozilla/ScriptPreloader.h" + +#include "nsDOMMutationObserver.h" +#include "nsICycleCollectorListener.h" +#include "nsCycleCollector.h" +#include "nsIOService.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" +#include "nsScriptSecurityManager.h" +#include "nsContentUtils.h" +#include "nsScriptError.h" +#include "nsJSUtils.h" +#include "prsystem.h" + +#include "xpcprivate.h" + +#ifdef XP_WIN +# include "mozilla/WinHeaderOnlyUtils.h" +#else +# include <sys/mman.h> +#endif + +using namespace mozilla; +using namespace mozilla::dom; +using namespace xpc; +using namespace JS; + +NS_IMPL_ISUPPORTS(nsXPConnect, nsIXPConnect) + +nsXPConnect* nsXPConnect::gSelf = nullptr; +bool nsXPConnect::gOnceAliveNowDead = false; + +// Global cache of the default script security manager (QI'd to +// nsIScriptSecurityManager) and the system principal. +nsIScriptSecurityManager* nsXPConnect::gScriptSecurityManager = nullptr; +nsIPrincipal* nsXPConnect::gSystemPrincipal = nullptr; + +const char XPC_EXCEPTION_CONTRACTID[] = "@mozilla.org/js/xpc/Exception;1"; +const char XPC_CONSOLE_CONTRACTID[] = "@mozilla.org/consoleservice;1"; +const char XPC_SCRIPT_ERROR_CONTRACTID[] = "@mozilla.org/scripterror;1"; + +/***************************************************************************/ + +nsXPConnect::nsXPConnect() { +#ifdef MOZ_GECKO_PROFILER + JS::SetProfilingThreadCallbacks(profiler_register_thread, + profiler_unregister_thread); +#endif +} + +// static +void nsXPConnect::InitJSContext() { + MOZ_ASSERT(!gSelf->mContext); + + XPCJSContext* xpccx = XPCJSContext::NewXPCJSContext(); + if (!xpccx) { + MOZ_CRASH("Couldn't create XPCJSContext."); + } + gSelf->mContext = xpccx; + gSelf->mRuntime = xpccx->Runtime(); + + mozJSModuleLoader::InitStatics(); + + // Initialize the script preloader cache. + Unused << mozilla::ScriptPreloader::GetSingleton(); + + nsJSContext::EnsureStatics(); +} + +void xpc::InitializeJSContext() { nsXPConnect::InitJSContext(); } + +nsXPConnect::~nsXPConnect() { + MOZ_ASSERT(mRuntime); + + mRuntime->DeleteSingletonScopes(); + + // In order to clean up everything properly, we need to GC twice: once now, + // to clean anything that can go away on its own (like the Junk Scope, which + // we unrooted above), and once after forcing a bunch of shutdown in + // XPConnect, to clean the stuff we forcibly disconnected. The forced + // shutdown code defaults to leaking in a number of situations, so we can't + // get by with only the second GC. :-( + // + // Bug 1650075: These should really pass GCOptions::Shutdown but doing that + // seems to cause crashes. + mRuntime->GarbageCollect(JS::GCOptions::Normal, + JS::GCReason::XPCONNECT_SHUTDOWN); + + XPCWrappedNativeScope::SystemIsBeingShutDown(); + + // The above causes us to clean up a bunch of XPConnect data structures, + // after which point we need to GC to clean everything up. We need to do + // this before deleting the XPCJSContext, because doing so destroys the + // maps that our finalize callback depends on. + mRuntime->GarbageCollect(JS::GCOptions::Normal, + JS::GCReason::XPCONNECT_SHUTDOWN); + + NS_RELEASE(gSystemPrincipal); + gScriptSecurityManager = nullptr; + + // shutdown the logging system + XPC_LOG_FINISH(); + + delete mContext; + + MOZ_ASSERT(gSelf == this); + gSelf = nullptr; + gOnceAliveNowDead = true; +} + +// static +void nsXPConnect::InitStatics() { +#ifdef NS_BUILD_REFCNT_LOGGING + // These functions are used for reporting leaks, so we register them as early + // as possible to avoid missing any classes' creations. + JS::SetLogCtorDtorFunctions(NS_LogCtor, NS_LogDtor); +#endif + ReadOnlyPage::Init(); + + gSelf = new nsXPConnect(); + gOnceAliveNowDead = false; + + // Initial extra ref to keep the singleton alive + // balanced by explicit call to ReleaseXPConnectSingleton() + NS_ADDREF(gSelf); + + // Fire up the SSM. + nsScriptSecurityManager::InitStatics(); + gScriptSecurityManager = nsScriptSecurityManager::GetScriptSecurityManager(); + gScriptSecurityManager->GetSystemPrincipal(&gSystemPrincipal); + MOZ_RELEASE_ASSERT(gSystemPrincipal); +} + +// static +void nsXPConnect::ReleaseXPConnectSingleton() { + nsXPConnect* xpc = gSelf; + if (xpc) { + nsrefcnt cnt; + NS_RELEASE2(xpc, cnt); + } + + mozJSModuleLoader::ShutdownLoaders(); +} + +// static +XPCJSRuntime* nsXPConnect::GetRuntimeInstance() { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + return gSelf->mRuntime; +} + +void xpc::ErrorBase::Init(JSErrorBase* aReport) { + if (!aReport->filename) { + mFileName.SetIsVoid(true); + } else { + CopyUTF8toUTF16(mozilla::MakeStringSpan(aReport->filename), mFileName); + } + + mSourceId = aReport->sourceId; + mLineNumber = aReport->lineno; + mColumn = aReport->column; +} + +void xpc::ErrorNote::Init(JSErrorNotes::Note* aNote) { + xpc::ErrorBase::Init(aNote); + + ErrorNoteToMessageString(aNote, mErrorMsg); +} + +void xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult, + bool aIsChrome, uint64_t aWindowID) { + xpc::ErrorBase::Init(aReport); + mCategory = aIsChrome ? "chrome javascript"_ns : "content javascript"_ns; + mWindowID = aWindowID; + + if (aToStringResult) { + AppendUTF8toUTF16(mozilla::MakeStringSpan(aToStringResult), mErrorMsg); + } + if (mErrorMsg.IsEmpty()) { + ErrorReportToMessageString(aReport, mErrorMsg); + } + if (mErrorMsg.IsEmpty()) { + mErrorMsg.AssignLiteral("<unknown>"); + } + + mSourceLine.Assign(aReport->linebuf(), aReport->linebufLength()); + + if (aReport->errorMessageName) { + mErrorMsgName.AssignASCII(aReport->errorMessageName); + } else { + mErrorMsgName.Truncate(); + } + + mIsWarning = aReport->isWarning(); + mIsMuted = aReport->isMuted; + + if (aReport->notes) { + if (!mNotes.SetLength(aReport->notes->length(), fallible)) { + return; + } + + size_t i = 0; + for (auto&& note : *aReport->notes) { + mNotes.ElementAt(i).Init(note.get()); + i++; + } + } +} + +void xpc::ErrorReport::Init(JSContext* aCx, mozilla::dom::Exception* aException, + bool aIsChrome, uint64_t aWindowID) { + mCategory = aIsChrome ? "chrome javascript"_ns : "content javascript"_ns; + mWindowID = aWindowID; + + aException->GetErrorMessage(mErrorMsg); + + aException->GetFilename(aCx, mFileName); + if (mFileName.IsEmpty()) { + mFileName.SetIsVoid(true); + } + mSourceId = aException->SourceId(aCx); + mLineNumber = aException->LineNumber(aCx); + mColumn = aException->ColumnNumber(); +} + +static LazyLogModule gJSDiagnostics("JSDiagnostics"); + +void xpc::ErrorBase::AppendErrorDetailsTo(nsCString& error) { + AppendUTF16toUTF8(mFileName, error); + error.AppendLiteral(", line "); + error.AppendInt(mLineNumber, 10); + error.AppendLiteral(": "); + AppendUTF16toUTF8(mErrorMsg, error); +} + +void xpc::ErrorNote::LogToStderr() { + if (!nsJSUtils::DumpEnabled()) { + return; + } + + nsAutoCString error; + error.AssignLiteral("JavaScript note: "); + AppendErrorDetailsTo(error); + + fprintf(stderr, "%s\n", error.get()); + fflush(stderr); +} + +void xpc::ErrorReport::LogToStderr() { + if (!nsJSUtils::DumpEnabled()) { + return; + } + + nsAutoCString error; + error.AssignLiteral("JavaScript "); + if (IsWarning()) { + error.AppendLiteral("warning: "); + } else { + error.AppendLiteral("error: "); + } + AppendErrorDetailsTo(error); + + fprintf(stderr, "%s\n", error.get()); + fflush(stderr); + + for (size_t i = 0, len = mNotes.Length(); i < len; i++) { + ErrorNote& note = mNotes[i]; + note.LogToStderr(); + } +} + +void xpc::ErrorReport::LogToConsole() { + LogToConsoleWithStack(nullptr, JS::NothingHandleValue, nullptr, nullptr); +} + +void xpc::ErrorReport::LogToConsoleWithStack( + nsGlobalWindowInner* aWin, JS::Handle<mozilla::Maybe<JS::Value>> aException, + JS::HandleObject aStack, JS::HandleObject aStackGlobal) { + if (aStack) { + MOZ_ASSERT(aStackGlobal); + MOZ_ASSERT(JS_IsGlobalObject(aStackGlobal)); + js::AssertSameCompartment(aStack, aStackGlobal); + } else { + MOZ_ASSERT(!aStackGlobal); + } + + LogToStderr(); + + MOZ_LOG(gJSDiagnostics, IsWarning() ? LogLevel::Warning : LogLevel::Error, + ("file %s, line %u\n%s", NS_ConvertUTF16toUTF8(mFileName).get(), + mLineNumber, NS_ConvertUTF16toUTF8(mErrorMsg).get())); + + // Log to the console. We do this last so that we can simply return if + // there's no console service without affecting the other reporting + // mechanisms. + nsCOMPtr<nsIConsoleService> consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + NS_ENSURE_TRUE_VOID(consoleService); + + RefPtr<nsScriptErrorBase> errorObject = + CreateScriptError(aWin, aException, aStack, aStackGlobal); + errorObject->SetErrorMessageName(mErrorMsgName); + + uint32_t flags = + mIsWarning ? nsIScriptError::warningFlag : nsIScriptError::errorFlag; + nsresult rv = errorObject->InitWithWindowID( + mErrorMsg, mFileName, mSourceLine, mLineNumber, mColumn, flags, mCategory, + mWindowID, mCategory.Equals("chrome javascript"_ns)); + NS_ENSURE_SUCCESS_VOID(rv); + + rv = errorObject->InitSourceId(mSourceId); + NS_ENSURE_SUCCESS_VOID(rv); + + rv = errorObject->InitIsPromiseRejection(mIsPromiseRejection); + NS_ENSURE_SUCCESS_VOID(rv); + + for (size_t i = 0, len = mNotes.Length(); i < len; i++) { + ErrorNote& note = mNotes[i]; + + nsScriptErrorNote* noteObject = new nsScriptErrorNote(); + noteObject->Init(note.mErrorMsg, note.mFileName, note.mSourceId, + note.mLineNumber, note.mColumn); + errorObject->AddNote(noteObject); + } + + consoleService->LogMessage(errorObject); +} + +/* static */ +void xpc::ErrorNote::ErrorNoteToMessageString(JSErrorNotes::Note* aNote, + nsAString& aString) { + aString.Truncate(); + if (aNote->message()) { + aString.Append(NS_ConvertUTF8toUTF16(aNote->message().c_str())); + } +} + +/* static */ +void xpc::ErrorReport::ErrorReportToMessageString(JSErrorReport* aReport, + nsAString& aString) { + aString.Truncate(); + if (aReport->message()) { + // Don't prefix warnings with an often misleading name like "Error: ". + if (!aReport->isWarning()) { + JSLinearString* name = js::GetErrorTypeName( + CycleCollectedJSContext::Get()->Context(), aReport->exnType); + if (name) { + AssignJSLinearString(aString, name); + aString.AppendLiteral(": "); + } + } + aString.Append(NS_ConvertUTF8toUTF16(aReport->message().c_str())); + } +} + +/***************************************************************************/ + +void xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS) { + // QIing to nsIXPConnectWrappedJSUnmarkGray may have side effects! + nsCOMPtr<nsIXPConnectWrappedJSUnmarkGray> wjsug = + do_QueryInterface(aWrappedJS); + Unused << wjsug; + MOZ_ASSERT(!wjsug, + "One should never be able to QI to " + "nsIXPConnectWrappedJSUnmarkGray successfully!"); +} + +/***************************************************************************/ +/***************************************************************************/ +// nsIXPConnect interface methods... + +template <typename T> +static inline T UnexpectedFailure(T rv) { + NS_ERROR("This is not supposed to fail!"); + return rv; +} + +void xpc::TraceXPCGlobal(JSTracer* trc, JSObject* obj) { + if (JS::GetClass(obj)->flags & JSCLASS_DOM_GLOBAL) { + mozilla::dom::TraceProtoAndIfaceCache(trc, obj); + } + + // We might be called from a GC during the creation of a global, before we've + // been able to set up the compartment private. + if (xpc::CompartmentPrivate* priv = xpc::CompartmentPrivate::Get(obj)) { + MOZ_ASSERT(priv->GetScope()); + priv->GetScope()->TraceInside(trc); + } +} + +namespace xpc { + +JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp, + nsIPrincipal* principal, + JS::RealmOptions& aOptions) { + MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); + MOZ_ASSERT(principal); + + MOZ_RELEASE_ASSERT( + principal != nsContentUtils::GetNullSubjectPrincipal(), + "The null subject principal is getting inherited - fix that!"); + + RootedObject global(cx); + { + SiteIdentifier site; + nsresult rv = BasePrincipal::Cast(principal)->GetSiteIdentifier(site); + NS_ENSURE_SUCCESS(rv, nullptr); + + global = JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), + JS::DontFireOnNewGlobalHook, aOptions); + if (!global) { + return nullptr; + } + JSAutoRealm ar(cx, global); + + RealmPrivate::Init(global, site); + + if (clasp->flags & JSCLASS_DOM_GLOBAL) { +#ifdef DEBUG + // Verify that the right trace hook is called. Note that this doesn't + // work right for wrapped globals, since the tracing situation there is + // more complicated. Manual inspection shows that they do the right + // thing. Also note that we only check this for JSCLASS_DOM_GLOBAL + // classes because xpc::TraceXPCGlobal won't call TraceProtoAndIfaceCache + // unless that flag is set. + if (!((const JSClass*)clasp)->isWrappedNative()) { + VerifyTraceProtoAndIfaceCacheCalledTracer trc(cx); + TraceChildren(&trc, GCCellPtr(global.get())); + MOZ_ASSERT(trc.ok, + "Trace hook on global needs to call TraceXPCGlobal for " + "XPConnect compartments."); + } +#endif + + const char* className = clasp->name; + AllocateProtoAndIfaceCache(global, + (strcmp(className, "Window") == 0 || + strcmp(className, "ChromeWindow") == 0) + ? ProtoAndIfaceCache::WindowLike + : ProtoAndIfaceCache::NonWindowLike); + } + } + + return global; +} + +void InitGlobalObjectOptions(JS::RealmOptions& aOptions, + bool aIsSystemPrincipal, + bool aShouldResistFingerprinting) { + bool shouldDiscardSystemSource = ShouldDiscardSystemSource(); + + if (aIsSystemPrincipal) { + // Make toSource functions [ChromeOnly] + aOptions.creationOptions().setToSourceEnabled(true); + // Make sure [SecureContext] APIs are visible: + aOptions.creationOptions().setSecureContext(true); + aOptions.behaviors().setClampAndJitterTime(false); + } + aOptions.behaviors().setShouldResistFingerprinting( + aShouldResistFingerprinting); + + if (shouldDiscardSystemSource) { + aOptions.behaviors().setDiscardSource(aIsSystemPrincipal); + } +} + +bool InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal, + uint32_t aFlags) { + // Immediately enter the global's realm so that everything we create + // ends up there. + JSAutoRealm ar(aJSContext, aGlobal); + + // Stuff coming through this path always ends up as a DOM global. + MOZ_ASSERT(JS::GetClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL); + + if (!(aFlags & xpc::OMIT_COMPONENTS_OBJECT)) { + // XPCCallContext gives us an active request needed to save/restore. + if (!ObjectScope(aGlobal)->AttachComponentsObject(aJSContext) || + !XPCNativeWrapper::AttachNewConstructorObject(aJSContext, aGlobal)) { + return UnexpectedFailure(false); + } + + if (!mozJSModuleLoader::Get()->DefineJSServices(aJSContext, aGlobal)) { + return UnexpectedFailure(false); + } + } + + if (!(aFlags & xpc::DONT_FIRE_ONNEWGLOBALHOOK)) { + JS_FireOnNewGlobalObject(aJSContext, aGlobal); + } + + return true; +} + +nsresult InitClassesWithNewWrappedGlobal(JSContext* aJSContext, + nsISupports* aCOMObj, + nsIPrincipal* aPrincipal, + uint32_t aFlags, + JS::RealmOptions& aOptions, + MutableHandleObject aNewGlobal) { + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aCOMObj, "bad param"); + + // We pass null for the 'extra' pointer during global object creation, so + // we need to have a principal. + MOZ_ASSERT(aPrincipal); + // All uses (at time of writing) were System Principal, meaning + // aShouldResistFingerprinting can be hardcoded to false. + // If this changes, ShouldRFP needs to be updated accordingly. + MOZ_RELEASE_ASSERT(aPrincipal->IsSystemPrincipal()); + + InitGlobalObjectOptions(aOptions, /* aSystemPrincipal */ true, + /* aShouldResistFingerprinting */ false); + + // Call into XPCWrappedNative to make a new global object, scope, and global + // prototype. + xpcObjectHelper helper(aCOMObj); + MOZ_ASSERT(helper.GetScriptableFlags() & XPC_SCRIPTABLE_IS_GLOBAL_OBJECT); + RefPtr<XPCWrappedNative> wrappedGlobal; + nsresult rv = XPCWrappedNative::WrapNewGlobal( + aJSContext, helper, aPrincipal, aFlags & xpc::INIT_JS_STANDARD_CLASSES, + aOptions, getter_AddRefs(wrappedGlobal)); + NS_ENSURE_SUCCESS(rv, rv); + + // Grab a copy of the global and enter its compartment. + RootedObject global(aJSContext, wrappedGlobal->GetFlatJSObject()); + MOZ_ASSERT(JS_IsGlobalObject(global)); + + if (!InitGlobalObject(aJSContext, global, aFlags)) { + return UnexpectedFailure(NS_ERROR_FAILURE); + } + + { // Scope for JSAutoRealm + JSAutoRealm ar(aJSContext, global); + if (!JS_DefineProfilingFunctions(aJSContext, global)) { + return UnexpectedFailure(NS_ERROR_OUT_OF_MEMORY); + } + if (aPrincipal->IsSystemPrincipal()) { + if (!glean::Glean::DefineGlean(aJSContext, global) || + !glean::GleanPings::DefineGleanPings(aJSContext, global)) { + return UnexpectedFailure(NS_ERROR_FAILURE); + } + } + } + + aNewGlobal.set(global); + return NS_OK; +} + +nsCString GetFunctionName(JSContext* cx, HandleObject obj) { + RootedObject inner(cx, js::UncheckedUnwrap(obj)); + JSAutoRealm ar(cx, inner); + + RootedFunction fun(cx, JS_GetObjectFunction(inner)); + if (!fun) { + // If the object isn't a function, it's likely that it has a single + // function property (for things like nsITimerCallback). In this case, + // return the name of that function property. + + Rooted<IdVector> idArray(cx, IdVector(cx)); + if (!JS_Enumerate(cx, inner, &idArray)) { + JS_ClearPendingException(cx); + return nsCString("error"); + } + + if (idArray.length() != 1) { + return nsCString("nonfunction"); + } + + RootedId id(cx, idArray[0]); + RootedValue v(cx); + if (!JS_GetPropertyById(cx, inner, id, &v)) { + JS_ClearPendingException(cx); + return nsCString("nonfunction"); + } + + if (!v.isObject()) { + return nsCString("nonfunction"); + } + + RootedObject vobj(cx, &v.toObject()); + return GetFunctionName(cx, vobj); + } + + RootedString funName(cx, JS_GetFunctionDisplayId(fun)); + RootedScript script(cx, JS_GetFunctionScript(cx, fun)); + const char* filename = script ? JS_GetScriptFilename(script) : "anonymous"; + const char* filenameSuffix = strrchr(filename, '/'); + + if (filenameSuffix) { + filenameSuffix++; + } else { + filenameSuffix = filename; + } + + nsCString displayName("anonymous"); + if (funName) { + RootedValue funNameVal(cx, StringValue(funName)); + if (!XPCConvert::JSData2Native(cx, &displayName, funNameVal, + {nsXPTType::T_UTF8STRING}, nullptr, 0, + nullptr)) { + JS_ClearPendingException(cx); + return nsCString("anonymous"); + } + } + + displayName.Append('['); + displayName.Append(filenameSuffix, strlen(filenameSuffix)); + displayName.Append(']'); + return displayName; +} + +} // namespace xpc + +static nsresult NativeInterface2JSObject(JSContext* aCx, HandleObject aScope, + nsISupports* aCOMObj, + nsWrapperCache* aCache, + const nsIID* aIID, bool aAllowWrapping, + MutableHandleValue aVal) { + JSAutoRealm ar(aCx, aScope); + + nsresult rv; + xpcObjectHelper helper(aCOMObj, aCache); + if (!XPCConvert::NativeInterface2JSObject(aCx, aVal, helper, aIID, + aAllowWrapping, &rv)) { + return rv; + } + + MOZ_ASSERT( + aAllowWrapping || !xpc::WrapperFactory::IsXrayWrapper(&aVal.toObject()), + "Shouldn't be returning a xray wrapper here"); + + return NS_OK; +} + +nsresult nsIXPConnect::WrapNative(JSContext* aJSContext, JSObject* aScopeArg, + nsISupports* aCOMObj, const nsIID& aIID, + JSObject** aRetVal) { + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aScopeArg, "bad param"); + MOZ_ASSERT(aCOMObj, "bad param"); + + RootedObject aScope(aJSContext, aScopeArg); + RootedValue v(aJSContext); + nsresult rv = NativeInterface2JSObject(aJSContext, aScope, aCOMObj, nullptr, + &aIID, true, &v); + if (NS_FAILED(rv)) { + return rv; + } + + if (!v.isObjectOrNull()) { + return NS_ERROR_FAILURE; + } + + *aRetVal = v.toObjectOrNull(); + return NS_OK; +} + +nsresult nsIXPConnect::WrapNativeToJSVal(JSContext* aJSContext, + JSObject* aScopeArg, + nsISupports* aCOMObj, + nsWrapperCache* aCache, + const nsIID* aIID, bool aAllowWrapping, + MutableHandleValue aVal) { + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aScopeArg, "bad param"); + MOZ_ASSERT(aCOMObj, "bad param"); + + RootedObject aScope(aJSContext, aScopeArg); + return NativeInterface2JSObject(aJSContext, aScope, aCOMObj, aCache, aIID, + aAllowWrapping, aVal); +} + +nsresult nsIXPConnect::WrapJS(JSContext* aJSContext, JSObject* aJSObjArg, + const nsIID& aIID, void** result) { + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aJSObjArg, "bad param"); + MOZ_ASSERT(result, "bad param"); + + *result = nullptr; + + RootedObject aJSObj(aJSContext, aJSObjArg); + + nsresult rv = NS_ERROR_UNEXPECTED; + if (!XPCConvert::JSObject2NativeInterface(aJSContext, result, aJSObj, &aIID, + nullptr, &rv)) + return rv; + return NS_OK; +} + +nsresult nsIXPConnect::JSValToVariant(JSContext* cx, HandleValue aJSVal, + nsIVariant** aResult) { + MOZ_ASSERT(aResult, "bad param"); + + RefPtr<XPCVariant> variant = XPCVariant::newVariant(cx, aJSVal); + variant.forget(aResult); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + + return NS_OK; +} + +nsresult nsIXPConnect::WrapJSAggregatedToNative(nsISupports* aOuter, + JSContext* aJSContext, + JSObject* aJSObjArg, + const nsIID& aIID, + void** result) { + MOZ_ASSERT(aOuter, "bad param"); + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aJSObjArg, "bad param"); + MOZ_ASSERT(result, "bad param"); + + *result = nullptr; + + RootedObject aJSObj(aJSContext, aJSObjArg); + nsresult rv; + if (!XPCConvert::JSObject2NativeInterface(aJSContext, result, aJSObj, &aIID, + aOuter, &rv)) + return rv; + return NS_OK; +} + +nsresult nsIXPConnect::GetWrappedNativeOfJSObject( + JSContext* aJSContext, JSObject* aJSObjArg, + nsIXPConnectWrappedNative** _retval) { + MOZ_ASSERT(aJSContext, "bad param"); + MOZ_ASSERT(aJSObjArg, "bad param"); + MOZ_ASSERT(_retval, "bad param"); + + RootedObject aJSObj(aJSContext, aJSObjArg); + aJSObj = js::CheckedUnwrapDynamic(aJSObj, aJSContext, + /* stopAtWindowProxy = */ false); + if (!aJSObj || !IsWrappedNativeReflector(aJSObj)) { + *_retval = nullptr; + return NS_ERROR_FAILURE; + } + + RefPtr<XPCWrappedNative> temp = XPCWrappedNative::Get(aJSObj); + temp.forget(_retval); + return NS_OK; +} + +static already_AddRefed<nsISupports> ReflectorToISupports(JSObject* reflector) { + if (!reflector) { + return nullptr; + } + + // Try XPCWrappedNatives. + if (IsWrappedNativeReflector(reflector)) { + XPCWrappedNative* wn = XPCWrappedNative::Get(reflector); + if (!wn) { + return nullptr; + } + nsCOMPtr<nsISupports> native = wn->Native(); + return native.forget(); + } + + // Try DOM objects. This QI without taking a ref first is safe, because + // this if non-null our thing will definitely be a DOM object, and we know + // their QI to nsISupports doesn't do anything weird. + nsCOMPtr<nsISupports> canonical = + do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(reflector)); + return canonical.forget(); +} + +already_AddRefed<nsISupports> xpc::ReflectorToISupportsStatic( + JSObject* reflector) { + // Unwrap security wrappers, if allowed. + return ReflectorToISupports(js::CheckedUnwrapStatic(reflector)); +} + +already_AddRefed<nsISupports> xpc::ReflectorToISupportsDynamic( + JSObject* reflector, JSContext* cx) { + // Unwrap security wrappers, if allowed. + return ReflectorToISupports( + js::CheckedUnwrapDynamic(reflector, cx, + /* stopAtWindowProxy = */ false)); +} + +nsresult nsIXPConnect::CreateSandbox(JSContext* cx, nsIPrincipal* principal, + JSObject** _retval) { + *_retval = nullptr; + + RootedValue rval(cx); + SandboxOptions options; + nsresult rv = CreateSandboxObject(cx, &rval, principal, options); + MOZ_ASSERT(NS_FAILED(rv) || !rval.isPrimitive(), + "Bad return value from xpc_CreateSandboxObject()!"); + + if (NS_SUCCEEDED(rv) && !rval.isPrimitive()) { + *_retval = rval.toObjectOrNull(); + } + + return rv; +} + +nsresult nsIXPConnect::EvalInSandboxObject(const nsAString& source, + const char* filename, JSContext* cx, + JSObject* sandboxArg, + MutableHandleValue rval) { + if (!sandboxArg) { + return NS_ERROR_INVALID_ARG; + } + + RootedObject sandbox(cx, sandboxArg); + nsCString filenameStr; + if (filename) { + filenameStr.Assign(filename); + } else { + filenameStr = "x-bogus://XPConnect/Sandbox"_ns; + } + return EvalInSandbox(cx, sandbox, source, filenameStr, 1, + /* enforceFilenameRestrictions */ true, rval); +} + +nsresult nsIXPConnect::DebugDump(int16_t depth) { +#ifdef DEBUG + auto* self = static_cast<nsXPConnect*>(this); + + depth--; + XPC_LOG_ALWAYS( + ("nsXPConnect @ %p with mRefCnt = %" PRIuPTR, self, self->mRefCnt.get())); + XPC_LOG_INDENT(); + XPC_LOG_ALWAYS(("gSelf @ %p", self->gSelf)); + XPC_LOG_ALWAYS(("gOnceAliveNowDead is %d", (int)self->gOnceAliveNowDead)); + XPCWrappedNativeScope::DebugDumpAllScopes(depth); + XPC_LOG_OUTDENT(); +#endif + return NS_OK; +} + +nsresult nsIXPConnect::DebugDumpObject(nsISupports* aCOMObj, int16_t depth) { +#ifdef DEBUG + if (!depth) { + return NS_OK; + } + if (!aCOMObj) { + XPC_LOG_ALWAYS(("*** Cound not dump object with NULL address")); + return NS_OK; + } + + nsCOMPtr<nsIXPConnect> xpc; + nsCOMPtr<nsIXPConnectWrappedNative> wn; + nsCOMPtr<nsIXPConnectWrappedJS> wjs; + + if (NS_SUCCEEDED(aCOMObj->QueryInterface(NS_GET_IID(nsIXPConnect), + getter_AddRefs(xpc)))) { + XPC_LOG_ALWAYS(("Dumping a nsIXPConnect...")); + xpc->DebugDump(depth); + } else if (NS_SUCCEEDED(aCOMObj->QueryInterface( + NS_GET_IID(nsIXPConnectWrappedNative), getter_AddRefs(wn)))) { + XPC_LOG_ALWAYS(("Dumping a nsIXPConnectWrappedNative...")); + wn->DebugDump(depth); + } else if (NS_SUCCEEDED(aCOMObj->QueryInterface( + NS_GET_IID(nsIXPConnectWrappedJS), getter_AddRefs(wjs)))) { + XPC_LOG_ALWAYS(("Dumping a nsIXPConnectWrappedJS...")); + wjs->DebugDump(depth); + } else { + XPC_LOG_ALWAYS(("*** Could not dump the nsISupports @ %p", aCOMObj)); + } +#endif + return NS_OK; +} + +nsresult nsIXPConnect::DebugDumpJSStack(bool showArgs, bool showLocals, + bool showThisProps) { + xpc_DumpJSStack(showArgs, showLocals, showThisProps); + + return NS_OK; +} + +nsresult nsIXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, + nsIVariant* value, + MutableHandleValue _retval) { + MOZ_ASSERT(ctx, "bad param"); + MOZ_ASSERT(scopeArg, "bad param"); + MOZ_ASSERT(value, "bad param"); + + RootedObject scope(ctx, scopeArg); + MOZ_ASSERT(js::IsObjectInContextCompartment(scope, ctx)); + + nsresult rv = NS_OK; + if (!XPCVariant::VariantDataToJS(ctx, value, &rv, _retval)) { + if (NS_FAILED(rv)) { + return rv; + } + + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult nsIXPConnect::JSToVariant(JSContext* ctx, HandleValue value, + nsIVariant** _retval) { + MOZ_ASSERT(ctx, "bad param"); + MOZ_ASSERT(_retval, "bad param"); + + RefPtr<XPCVariant> variant = XPCVariant::newVariant(ctx, value); + variant.forget(_retval); + if (!(*_retval)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +namespace xpc { + +bool Base64Encode(JSContext* cx, HandleValue val, MutableHandleValue out) { + MOZ_ASSERT(cx); + + nsAutoCString encodedString; + BindingCallContext callCx(cx, "Base64Encode"); + if (!ConvertJSValueToByteString(callCx, val, false, "value", encodedString)) { + return false; + } + + nsAutoCString result; + if (NS_FAILED(mozilla::Base64Encode(encodedString, result))) { + JS_ReportErrorASCII(cx, "Failed to encode base64 data!"); + return false; + } + + JSString* str = JS_NewStringCopyN(cx, result.get(), result.Length()); + if (!str) { + return false; + } + + out.setString(str); + return true; +} + +bool Base64Decode(JSContext* cx, HandleValue val, MutableHandleValue out) { + MOZ_ASSERT(cx); + + nsAutoCString encodedString; + BindingCallContext callCx(cx, "Base64Decode"); + if (!ConvertJSValueToByteString(callCx, val, false, "value", encodedString)) { + return false; + } + + nsAutoCString result; + if (NS_FAILED(mozilla::Base64Decode(encodedString, result))) { + JS_ReportErrorASCII(cx, "Failed to decode base64 string!"); + return false; + } + + JSString* str = JS_NewStringCopyN(cx, result.get(), result.Length()); + if (!str) { + return false; + } + + out.setString(str); + return true; +} + +void SetLocationForGlobal(JSObject* global, const nsACString& location) { + MOZ_ASSERT(global); + RealmPrivate::Get(global)->SetLocation(location); +} + +void SetLocationForGlobal(JSObject* global, nsIURI* locationURI) { + MOZ_ASSERT(global); + RealmPrivate::Get(global)->SetLocationURI(locationURI); +} + +} // namespace xpc + +// static +nsIXPConnect* nsIXPConnect::XPConnect() { + // Do a release-mode assert that we're not doing anything significant in + // XPConnect off the main thread. If you're an extension developer hitting + // this, you need to change your code. See bug 716167. + if (!MOZ_LIKELY(NS_IsMainThread())) { + MOZ_CRASH(); + } + + return nsXPConnect::gSelf; +} + +/* These are here to be callable from a debugger */ +extern "C" { + +MOZ_EXPORT void DumpJSStack() { xpc_DumpJSStack(true, true, false); } + +MOZ_EXPORT void DumpCompleteHeap() { + nsCOMPtr<nsICycleCollectorListener> listener = + nsCycleCollector_createLogger(); + MOZ_ASSERT(listener); + + nsCOMPtr<nsICycleCollectorListener> alltracesListener; + listener->AllTraces(getter_AddRefs(alltracesListener)); + if (!alltracesListener) { + NS_WARNING("Failed to get all traces logger"); + return; + } + + nsJSContext::CycleCollectNow(CCReason::DUMP_HEAP, alltracesListener); +} + +} // extern "C" + +namespace xpc { + +bool Atob(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.length()) { + return true; + } + + return xpc::Base64Decode(cx, args[0], args.rval()); +} + +bool Btoa(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.length()) { + return true; + } + + return xpc::Base64Encode(cx, args[0], args.rval()); +} + +bool IsXrayWrapper(JSObject* obj) { return WrapperFactory::IsXrayWrapper(obj); } + +} // namespace xpc + +namespace mozilla { +namespace dom { + +bool IsChromeOrUAWidget(JSContext* cx, JSObject* /* unused */) { + MOZ_ASSERT(NS_IsMainThread()); + JS::Realm* realm = JS::GetCurrentRealmOrNull(cx); + MOZ_ASSERT(realm); + JS::Compartment* c = JS::GetCompartmentForRealm(realm); + + return AccessCheck::isChrome(c) || IsUAWidgetCompartment(c); +} + +bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */) { + MOZ_ASSERT(NS_IsMainThread()); + JS::Realm* realm = JS::GetCurrentRealmOrNull(cx); + MOZ_ASSERT(realm); + JS::Compartment* c = JS::GetCompartmentForRealm(realm); + + return !IsUAWidgetCompartment(c); +} + +extern bool IsCurrentThreadRunningChromeWorker(); + +bool ThreadSafeIsChromeOrUAWidget(JSContext* cx, JSObject* obj) { + if (NS_IsMainThread()) { + return IsChromeOrUAWidget(cx, obj); + } + return IsCurrentThreadRunningChromeWorker(); +} + +} // namespace dom +} // namespace mozilla + +#ifdef MOZ_TSAN +ReadOnlyPage ReadOnlyPage::sInstance; +#else +constexpr const volatile ReadOnlyPage ReadOnlyPage::sInstance; +#endif + +void xpc::ReadOnlyPage::Write(const volatile bool* aPtr, bool aValue) { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + if (*aPtr == aValue) return; + // Please modify the definition of kAutomationPageSize if a new platform + // is running in automation and hits this assertion. + MOZ_RELEASE_ASSERT(PR_GetPageSize() == alignof(ReadOnlyPage)); + MOZ_RELEASE_ASSERT( + reinterpret_cast<uintptr_t>(&sInstance) % alignof(ReadOnlyPage) == 0); +#ifdef XP_WIN + AutoVirtualProtect prot(const_cast<ReadOnlyPage*>(&sInstance), + alignof(ReadOnlyPage), PAGE_READWRITE); + MOZ_RELEASE_ASSERT(prot && (prot.PrevProt() & 0xFF) == PAGE_READONLY); +#else + int ret = mprotect(const_cast<ReadOnlyPage*>(&sInstance), + alignof(ReadOnlyPage), PROT_READ | PROT_WRITE); + MOZ_RELEASE_ASSERT(ret == 0); +#endif + MOZ_RELEASE_ASSERT(aPtr == &sInstance.mNonLocalConnectionsDisabled || + aPtr == &sInstance.mTurnOffAllSecurityPref); +#ifdef XP_WIN + BOOL ret = WriteProcessMemory(GetCurrentProcess(), const_cast<bool*>(aPtr), + &aValue, sizeof(bool), nullptr); + MOZ_RELEASE_ASSERT(ret); +#else + *const_cast<volatile bool*>(aPtr) = aValue; + ret = mprotect(const_cast<ReadOnlyPage*>(&sInstance), alignof(ReadOnlyPage), + PROT_READ); + MOZ_RELEASE_ASSERT(ret == 0); +#endif +} + +void xpc::ReadOnlyPage::Init() { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + static_assert(alignof(ReadOnlyPage) == kAutomationPageSize); + static_assert(sizeof(sInstance) == alignof(ReadOnlyPage)); + + // Make sure that initialization is not too late. + MOZ_DIAGNOSTIC_ASSERT(!net::gIOService); + char* s = getenv("MOZ_DISABLE_NONLOCAL_CONNECTIONS"); + const bool disabled = s && *s != '0'; + Write(&sInstance.mNonLocalConnectionsDisabled, disabled); + if (!disabled) { + // not bothered to check automation prefs. + return; + } + + // The obvious thing is to make this pref a static pref. But then it would + // always be defined and always show up in about:config, and users could flip + // it, which we don't want. Instead we roll our own callback so that if the + // pref is undefined (the normal case) then sAutomationPrefIsSet is false and + // nothing shows up in about:config. + nsresult rv = Preferences::RegisterCallbackAndCall( + [](const char* aPrefName, void* /* aClosure */) { + Write(&sInstance.mTurnOffAllSecurityPref, + Preferences::GetBool(aPrefName, /* aFallback */ false)); + }, + "security." + "turn_off_all_security_so_that_viruses_can_take_over_this_computer"); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); +} diff --git a/js/xpconnect/src/xpc.msg b/js/xpconnect/src/xpc.msg new file mode 100644 index 0000000000..473106d185 --- /dev/null +++ b/js/xpconnect/src/xpc.msg @@ -0,0 +1,255 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Error Message definitions. */ + + +/* xpconnect specific codes (from nsIXPConnect.h) */ + +XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ARGS , "Not enough arguments") +XPC_MSG_DEF(NS_ERROR_XPC_NEED_OUT_OBJECT , "'Out' argument must be an object") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_OUT_VAL , "Cannot set 'value' property of 'out' argument") +XPC_MSG_DEF(NS_ERROR_XPC_NATIVE_RETURNED_FAILURE , "Component returned failure code:") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_INTERFACE_INFO , "Cannot find interface information") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO , "Cannot find interface information for parameter") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_METHOD_INFO , "Cannot find method information") +XPC_MSG_DEF(NS_ERROR_XPC_UNEXPECTED , "Unexpected error in XPConnect") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS , "Could not convert JavaScript argument") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_NATIVE , "Could not convert Native argument") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF , "Could not convert JavaScript argument (NULL value cannot be used for a C++ reference type)") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO , "Illegal operation on WrappedNative prototype object") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN , "Cannot convert WrappedNative to function") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_DEFINE_PROP_ON_WN , "Cannot define new property in a WrappedNative") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_WATCH_WN_STATIC , "Cannot place watchpoints on WrappedNative object static properties") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_EXPORT_WN_STATIC , "Cannot export a WrappedNative object's static properties") +XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CALL_FAILED , "nsIXPCScriptable::Call failed") +XPC_MSG_DEF(NS_ERROR_XPC_SCRIPTABLE_CTOR_FAILED , "nsIXPCScriptable::Construct failed") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CALL_WO_SCRIPTABLE , "Cannot use wrapper as function unless it implements nsIXPCScriptable") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CTOR_WO_SCRIPTABLE , "Cannot use wrapper as constructor unless it implements nsIXPCScriptable") +XPC_MSG_DEF(NS_ERROR_XPC_CI_RETURNED_FAILURE , "ComponentManager::CreateInstance returned failure code:") +XPC_MSG_DEF(NS_ERROR_XPC_GS_RETURNED_FAILURE , "ServiceManager::GetService returned failure code:") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CID , "Invalid ClassID or ContractID") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_IID , "Invalid InterfaceID") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CREATE_WN , "Cannot create wrapper around native interface") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_EXCEPTION , "JavaScript component threw exception") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT , "JavaScript component threw a native object that is not an exception") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_JS_OBJECT , "JavaScript component threw a JavaScript object") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NULL , "JavaScript component threw a null value as an exception") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_STRING , "JavaScript component threw a string as an exception") +XPC_MSG_DEF(NS_ERROR_XPC_JS_THREW_NUMBER , "JavaScript component threw a number as an exception") +XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR , "JavaScript component caused a JavaScript error") +XPC_MSG_DEF(NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS , "JavaScript component caused a JavaScript error (detailed report attached)") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY, "Cannot convert primitive JavaScript value into an array") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_CONVERT_OBJECT_TO_ARRAY , "Cannot convert JavaScript object into an array") +XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY , "JavaScript Array does not have as many elements as indicated by size argument") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_GET_ARRAY_INFO , "Cannot find array information") +XPC_MSG_DEF(NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING , "JavaScript String does not have as many characters as indicated by size argument") +XPC_MSG_DEF(NS_ERROR_XPC_SECURITY_MANAGER_VETO , "Security Manager vetoed action") +XPC_MSG_DEF(NS_ERROR_XPC_INTERFACE_NOT_SCRIPTABLE , "Failed to build a wrapper because the interface that was not declared [scriptable]") +XPC_MSG_DEF(NS_ERROR_XPC_INTERFACE_NOT_FROM_NSISUPPORTS , "Failed to build a wrapper because the interface does not inherit from nsISupports") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_READ_ONLY_CONSTANT , "Property is a constant and cannot be changed") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_READ_ONLY_ATTRIBUTE , "Property is a read only attribute and cannot be changed") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_SET_READ_ONLY_METHOD , "Property is an interface method and cannot be changed") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_ADD_PROP_TO_WRAPPED_NATIVE, "Cannot add property to WrappedNative object") +XPC_MSG_DEF(NS_ERROR_XPC_CALL_TO_SCRIPTABLE_FAILED , "Call to nsIXPCScriptable interface for WrappedNative failed unexpecedly") +XPC_MSG_DEF(NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED , "JavaScript component does not have a method named:") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_ID_STRING , "Bad ID string") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_INITIALIZER_NAME , "Bad initializer name in Constructor - Component has no method with that name") +XPC_MSG_DEF(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN , "Operation failed because the XPConnect subsystem has been shutdown") +XPC_MSG_DEF(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN , "Cannot modify properties of a WrappedNative") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL , "Could not convert JavaScript argument - 0 was passed, expected object. Did you mean null?") + + +/* common global codes (from nsError.h) */ + +XPC_MSG_DEF(NS_OK , "Success") +XPC_MSG_DEF(NS_ERROR_NOT_INITIALIZED , "Component not initialized") +XPC_MSG_DEF(NS_ERROR_ALREADY_INITIALIZED , "Component already initialized") +XPC_MSG_DEF(NS_ERROR_NOT_IMPLEMENTED , "Method not implemented") +XPC_MSG_DEF(NS_NOINTERFACE , "Component does not have requested interface") +XPC_MSG_DEF(NS_ERROR_NO_INTERFACE , "Component does not have requested interface") +XPC_MSG_DEF(NS_ERROR_ILLEGAL_VALUE , "Illegal value") +XPC_MSG_DEF(NS_ERROR_INVALID_POINTER , "Invalid pointer") +XPC_MSG_DEF(NS_ERROR_NULL_POINTER , "Null pointer") +XPC_MSG_DEF(NS_ERROR_ABORT , "Abort") +XPC_MSG_DEF(NS_ERROR_FAILURE , "Failure") +XPC_MSG_DEF(NS_ERROR_UNEXPECTED , "Unexpected error") +XPC_MSG_DEF(NS_ERROR_OUT_OF_MEMORY , "Out of Memory") +XPC_MSG_DEF(NS_ERROR_INVALID_ARG , "Invalid argument") +XPC_MSG_DEF(NS_ERROR_NOT_AVAILABLE , "Component is not available") +XPC_MSG_DEF(NS_ERROR_FACTORY_NOT_REGISTERED , "Factory not registered") +XPC_MSG_DEF(NS_ERROR_FACTORY_REGISTER_AGAIN , "Factory not registered (may be tried again)") +XPC_MSG_DEF(NS_ERROR_FACTORY_NOT_LOADED , "Factory not loaded") +XPC_MSG_DEF(NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT , "Factory does not support signatures") +XPC_MSG_DEF(NS_ERROR_FACTORY_EXISTS , "Factory already exists") + +/* added from nsError.h on Feb 28 2001... */ + +XPC_MSG_DEF(NS_BASE_STREAM_CLOSED , "Stream closed") +XPC_MSG_DEF(NS_BASE_STREAM_OSERROR , "Error from the operating system") +XPC_MSG_DEF(NS_BASE_STREAM_ILLEGAL_ARGS , "Illegal arguments") +XPC_MSG_DEF(NS_BASE_STREAM_NO_CONVERTER , "No converter for unichar streams") +XPC_MSG_DEF(NS_BASE_STREAM_BAD_CONVERSION , "Bad converter for unichar streams") +XPC_MSG_DEF(NS_BASE_STREAM_WOULD_BLOCK , "Stream would block") + +XPC_MSG_DEF(NS_ERROR_FILE_UNRECOGNIZED_PATH , "File error: Unrecognized path") +XPC_MSG_DEF(NS_ERROR_FILE_UNRESOLVABLE_SYMLINK , "File error: Unresolvable symlink") +XPC_MSG_DEF(NS_ERROR_FILE_EXECUTION_FAILED , "File error: Execution failed") +XPC_MSG_DEF(NS_ERROR_FILE_UNKNOWN_TYPE , "File error: Unknown type") +XPC_MSG_DEF(NS_ERROR_FILE_DESTINATION_NOT_DIR , "File error: Destination not dir") +XPC_MSG_DEF(NS_ERROR_FILE_COPY_OR_MOVE_FAILED , "File error: Copy or move failed") +XPC_MSG_DEF(NS_ERROR_FILE_ALREADY_EXISTS , "File error: Already exists") +XPC_MSG_DEF(NS_ERROR_FILE_INVALID_PATH , "File error: Invalid path") +XPC_MSG_DEF(NS_ERROR_FILE_CORRUPTED , "File error: Corrupted") +XPC_MSG_DEF(NS_ERROR_FILE_NOT_DIRECTORY , "File error: Not directory") +XPC_MSG_DEF(NS_ERROR_FILE_IS_DIRECTORY , "File error: Is directory") +XPC_MSG_DEF(NS_ERROR_FILE_IS_LOCKED , "File error: Is locked") +XPC_MSG_DEF(NS_ERROR_FILE_TOO_BIG , "File error: Too big") +XPC_MSG_DEF(NS_ERROR_FILE_NO_DEVICE_SPACE , "File error: No device space") +XPC_MSG_DEF(NS_ERROR_FILE_NAME_TOO_LONG , "File error: Name too long") +XPC_MSG_DEF(NS_ERROR_FILE_NOT_FOUND , "File error: Not found") +XPC_MSG_DEF(NS_ERROR_FILE_READ_ONLY , "File error: Read only") +XPC_MSG_DEF(NS_ERROR_FILE_DIR_NOT_EMPTY , "File error: Dir not empty") +XPC_MSG_DEF(NS_ERROR_FILE_ACCESS_DENIED , "File error: Access denied") + +/* added from nsError.h on Sept 6 2001... */ + +XPC_MSG_DEF(NS_ERROR_CANNOT_CONVERT_DATA , "Data conversion error") +XPC_MSG_DEF(NS_ERROR_OBJECT_IS_IMMUTABLE , "Can not modify immutable data container") +XPC_MSG_DEF(NS_ERROR_LOSS_OF_SIGNIFICANT_DATA , "Data conversion failed because significant data would be lost") +XPC_MSG_DEF(NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA , "Data conversion succeeded but data was rounded to fit") + +/* network related codes (from nsNetError.h) */ + +XPC_MSG_DEF(NS_BINDING_FAILED , "The async request failed for some unknown reason") +XPC_MSG_DEF(NS_BINDING_ABORTED , "The async request failed because it was aborted by some user action") +XPC_MSG_DEF(NS_BINDING_REDIRECTED , "The async request has been redirected to a different async request") +XPC_MSG_DEF(NS_BINDING_RETARGETED , "The async request has been retargeted to a different handler") +XPC_MSG_DEF(NS_ERROR_MALFORMED_URI , "The URI is malformed") +XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROTOCOL , "The URI scheme corresponds to an unknown protocol handler") +XPC_MSG_DEF(NS_ERROR_NO_CONTENT , "Channel opened successfully but no data will be returned") +XPC_MSG_DEF(NS_ERROR_IN_PROGRESS , "The requested action could not be completed while the object is busy") +XPC_MSG_DEF(NS_ERROR_ALREADY_OPENED , "Channel is already open") +XPC_MSG_DEF(NS_ERROR_INVALID_CONTENT_ENCODING , "The content encoding of the source document is incorrect") +XPC_MSG_DEF(NS_ERROR_CORRUPTED_CONTENT , "Corrupted content received from server (potentially MIME type mismatch because of 'X-Content-Type-Options: nosniff')") +XPC_MSG_DEF(NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "Couldn't extract first component from potentially corrupted header field") +XPC_MSG_DEF(NS_ERROR_ALREADY_CONNECTED , "The connection is already established") +XPC_MSG_DEF(NS_ERROR_NOT_CONNECTED , "The connection does not exist") +XPC_MSG_DEF(NS_ERROR_CONNECTION_REFUSED , "The connection was refused") + +/* Error codes return from the proxy */ +XPC_MSG_DEF(NS_ERROR_PROXY_CONNECTION_REFUSED , "The connection to the proxy server was refused") +XPC_MSG_DEF(NS_ERROR_PROXY_AUTHENTICATION_FAILED , "The proxy requires authentication") +XPC_MSG_DEF(NS_ERROR_PROXY_BAD_GATEWAY , "The request failed on the proxy") +XPC_MSG_DEF(NS_ERROR_PROXY_GATEWAY_TIMEOUT , "The request timed out on the proxy") +XPC_MSG_DEF(NS_ERROR_PROXY_TOO_MANY_REQUESTS , "Sending too many requests to a proxy") +XPC_MSG_DEF(NS_ERROR_PROXY_VERSION_NOT_SUPPORTED , "The proxy does not support the version of the HTTP request") +XPC_MSG_DEF(NS_ERROR_PROXY_FORBIDDEN , "The user is banned from the proxy") +XPC_MSG_DEF(NS_ERROR_PROXY_SERVICE_UNAVAILABLE , "The proxy is not available") +XPC_MSG_DEF(NS_ERROR_PROXY_UNAVAILABLE_FOR_LEGAL_REASONS, "The desired destination is unavailable for legal reasons") + +XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT , "The connection has timed out") +XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT_EXTERNAL , "The request has been cancelled because of a timeout") +XPC_MSG_DEF(NS_ERROR_OFFLINE , "The requested action could not be completed in the offline state") +XPC_MSG_DEF(NS_ERROR_PORT_ACCESS_NOT_ALLOWED , "Establishing a connection to an unsafe or otherwise banned port was prohibited") +XPC_MSG_DEF(NS_ERROR_NET_RESET , "The connection was established, but no data was ever received") +XPC_MSG_DEF(NS_ERROR_NET_INTERRUPT , "The connection was established, but the data transfer was interrupted") +XPC_MSG_DEF(NS_ERROR_NET_PARTIAL_TRANSFER , "A transfer was only partially done when it completed") +XPC_MSG_DEF(NS_ERROR_NET_HTTP3_PROTOCOL_ERROR , "There has been a http3 protocol error") +XPC_MSG_DEF(NS_ERROR_NOT_RESUMABLE , "This request is not resumable, but it was tried to resume it, or to request resume-specific data") +XPC_MSG_DEF(NS_ERROR_ENTITY_CHANGED , "It was attempted to resume the request, but the entity has changed in the meantime") +XPC_MSG_DEF(NS_ERROR_REDIRECT_LOOP , "The request failed as a result of a detected redirection loop") +XPC_MSG_DEF(NS_ERROR_UNSAFE_CONTENT_TYPE , "The request failed because the content type returned by the server was not a type expected by the channel") +XPC_MSG_DEF(NS_ERROR_LOAD_SHOWED_ERRORPAGE , "The load caused an error page to be displayed.") +XPC_MSG_DEF(NS_ERROR_BLOCKED_BY_POLICY , "The request was blocked by a policy set by the system administrator.") + +XPC_MSG_DEF(NS_ERROR_UNKNOWN_HOST , "The lookup of the hostname failed") +XPC_MSG_DEF(NS_ERROR_DNS_LOOKUP_QUEUE_FULL , "The DNS lookup queue is full") +XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROXY_HOST , "The lookup of the proxy hostname failed") +XPC_MSG_DEF(NS_ERROR_UNKNOWN_SOCKET_TYPE , "The specified socket type does not exist") +XPC_MSG_DEF(NS_ERROR_SOCKET_CREATE_FAILED , "The specified socket type could not be created") +XPC_MSG_DEF(NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED , "The specified socket address type is not supported") +XPC_MSG_DEF(NS_ERROR_SOCKET_ADDRESS_IN_USE , "Some other socket is already using the specified address.") +XPC_MSG_DEF(NS_ERROR_CACHE_KEY_NOT_FOUND , "Cache key could not be found") +XPC_MSG_DEF(NS_ERROR_CACHE_DATA_IS_STREAM , "Cache data is a stream") +XPC_MSG_DEF(NS_ERROR_CACHE_DATA_IS_NOT_STREAM , "Cache data is not a stream") +XPC_MSG_DEF(NS_ERROR_CACHE_WAIT_FOR_VALIDATION , "Cache entry exists but needs to be validated first") +XPC_MSG_DEF(NS_ERROR_CACHE_ENTRY_DOOMED , "Cache entry has been doomed") +XPC_MSG_DEF(NS_ERROR_CACHE_READ_ACCESS_DENIED , "Read access to cache denied") +XPC_MSG_DEF(NS_ERROR_CACHE_WRITE_ACCESS_DENIED , "Write access to cache denied") +XPC_MSG_DEF(NS_ERROR_CACHE_IN_USE , "Cache is currently in use") +XPC_MSG_DEF(NS_ERROR_DOCUMENT_NOT_CACHED , "Document does not exist in cache") +XPC_MSG_DEF(NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS , "The requested number of domain levels exceeds those present in the host string") +XPC_MSG_DEF(NS_ERROR_HOST_IS_IP_ADDRESS , "The host string is an IP address") +XPC_MSG_DEF(NS_ERROR_NOT_SAME_THREAD , "Can't access a wrapped JS object from a different thread") + +/* storage related codes (from mozStorage.h) */ +XPC_MSG_DEF(NS_ERROR_STORAGE_BUSY , "SQLite database connection is busy") +XPC_MSG_DEF(NS_ERROR_STORAGE_IOERR , "SQLite encountered an IO error") +XPC_MSG_DEF(NS_ERROR_STORAGE_CONSTRAINT , "SQLite database operation failed because a constraint was violated") + +/* plugin related codes (from nsPluginError.h) */ +XPC_MSG_DEF(NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, "Clearing site data by time range not supported by plugin") + +/* character converter related codes */ +XPC_MSG_DEF(NS_ERROR_ILLEGAL_INPUT , "The input characters have illegal sequences") + +/* Codes related to signd jars */ +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_NOT_SIGNED , "The JAR is not signed.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY , "An entry in the JAR has been modified after the JAR was signed.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY , "An entry in the JAR has not been signed.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_ENTRY_MISSING , "An entry is missing from the JAR file.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE , "The JAR's signature is wrong.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE , "An entry in the JAR is too large.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_ENTRY_INVALID , "An entry in the JAR is invalid.") +XPC_MSG_DEF(NS_ERROR_SIGNED_JAR_MANIFEST_INVALID , "The JAR's manifest or signature file is invalid.") +XPC_MSG_DEF(NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO , "The PKCS#7 signature is malformed or invalid.") +XPC_MSG_DEF(NS_ERROR_CMS_VERIFY_NOT_SIGNED , "The PKCS#7 information is not signed.") + +/* Codes related to signed manifests */ +XPC_MSG_DEF(NS_ERROR_SIGNED_APP_MANIFEST_INVALID , "The signed app manifest or signature file is invalid.") + +/* Codes for printing-related errors. */ +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE , "No printers available.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND , "The selected printer could not be found.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE , "Failed to open output file for print to file.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_STARTDOC , "Printing failed while starting the print job.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_ENDDOC , "Printing failed while completing the print job.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_STARTPAGE , "Printing failed while starting a new page.") +XPC_MSG_DEF(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY , "Cannot print this document yet, it is still being loaded.") + +/* Codes related to content */ +XPC_MSG_DEF(NS_ERROR_CONTENT_CRASHED , "The process that hosted this content has crashed.") +XPC_MSG_DEF(NS_ERROR_FRAME_CRASHED , "The process that hosted this frame has crashed.") +XPC_MSG_DEF(NS_ERROR_BUILDID_MISMATCH , "The process that hosted this content did not have the same buildID as the parent.") +XPC_MSG_DEF(NS_ERROR_CONTENT_BLOCKED , "The load for this content was blocked.") + +/* Codes for the JS-implemented Push DOM API. These can be removed as part of bug 1252660. */ +XPC_MSG_DEF(NS_ERROR_DOM_PUSH_INVALID_KEY_ERR , "Invalid raw ECDSA P-256 public key.") +XPC_MSG_DEF(NS_ERROR_DOM_PUSH_MISMATCHED_KEY_ERR , "A subscription with a different application server key already exists.") + +/* Codes defined in WebIDL https://heycam.github.io/webidl/#idl-DOMException-error-names */ +XPC_MSG_DEF(NS_ERROR_DOM_NOT_FOUND_ERR , "The object can not be found here.") +XPC_MSG_DEF(NS_ERROR_DOM_NOT_ALLOWED_ERR , "The request is not allowed.") + +/* Codes related to the URIClassifier service */ +XPC_MSG_DEF(NS_ERROR_MALWARE_URI , "The URI is malware") +XPC_MSG_DEF(NS_ERROR_PHISHING_URI , "The URI is phishing") +XPC_MSG_DEF(NS_ERROR_TRACKING_URI , "The URI is tracking") +XPC_MSG_DEF(NS_ERROR_UNWANTED_URI , "The URI is unwanted") +XPC_MSG_DEF(NS_ERROR_BLOCKED_URI , "The URI is blocked") +XPC_MSG_DEF(NS_ERROR_HARMFUL_URI , "The URI is harmful") +XPC_MSG_DEF(NS_ERROR_FINGERPRINTING_URI , "The URI is fingerprinting") +XPC_MSG_DEF(NS_ERROR_CRYPTOMINING_URI , "The URI is cryptomining") +XPC_MSG_DEF(NS_ERROR_SOCIALTRACKING_URI , "The URI is social tracking") +XPC_MSG_DEF(NS_ERROR_EMAILTRACKING_URI , "The URI is email tracking") + +/* Profile manager error codes */ +XPC_MSG_DEF(NS_ERROR_DATABASE_CHANGED , "Flushing the profiles to disk would have overwritten changes made elsewhere.") + +/* Codes related to URILoader */ +XPC_MSG_DEF(NS_ERROR_PARSED_DATA_CACHED , "The data from a channel has already been parsed and cached so it doesn't need to be reparsed from the original source.") +XPC_MSG_DEF(NS_BINDING_CANCELLED_OLD_LOAD , "The async request has been cancelled by another async request") diff --git a/js/xpconnect/src/xpcObjectHelper.h b/js/xpconnect/src/xpcObjectHelper.h new file mode 100644 index 0000000000..1d83fdde15 --- /dev/null +++ b/js/xpconnect/src/xpcObjectHelper.h @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpcObjectHelper_h +#define xpcObjectHelper_h + +// Including 'windows.h' will #define GetClassInfo to something else. +#ifdef XP_WIN +# ifdef GetClassInfo +# undef GetClassInfo +# endif +#endif + +#include "mozilla/Attributes.h" +#include <stdint.h> +#include "nsCOMPtr.h" +#include "nsIClassInfo.h" +#include "nsISupports.h" +#include "nsIXPCScriptable.h" +#include "nsWrapperCache.h" + +class xpcObjectHelper { + public: + explicit xpcObjectHelper(nsISupports* aObject, + nsWrapperCache* aCache = nullptr) + : mObject(aObject), mCache(aCache) { + if (!mCache && aObject) { + CallQueryInterface(aObject, &mCache); + } + } + + nsISupports* Object() { return mObject; } + + nsIClassInfo* GetClassInfo() { + if (!mClassInfo) { + mClassInfo = do_QueryInterface(mObject); + } + return mClassInfo; + } + + // We assert that we can reach an nsIXPCScriptable somehow. + uint32_t GetScriptableFlags() { + nsCOMPtr<nsIXPCScriptable> sinfo = do_QueryInterface(mObject); + + // We should have something by now. + MOZ_ASSERT(sinfo); + + // Grab the flags. + return sinfo->GetScriptableFlags(); + } + + nsWrapperCache* GetWrapperCache() { return mCache; } + + private: + xpcObjectHelper(xpcObjectHelper& aOther) = delete; + + nsISupports* MOZ_UNSAFE_REF( + "xpcObjectHelper has been specifically optimized " + "to avoid unnecessary AddRefs and Releases. " + "(see bug 565742)") mObject; + nsWrapperCache* mCache; + nsCOMPtr<nsIClassInfo> mClassInfo; +}; + +#endif diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h new file mode 100644 index 0000000000..2c629e5bc2 --- /dev/null +++ b/js/xpconnect/src/xpcprivate.h @@ -0,0 +1,2842 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * XPConnect allows JS code to manipulate C++ object and C++ code to manipulate + * JS objects. JS manipulation of C++ objects tends to be significantly more + * complex. This comment explains how it is orchestrated by XPConnect. + * + * For each C++ object to be manipulated in JS, there is a corresponding JS + * object. This is called the "flattened JS object". By default, there is an + * additional C++ object involved of type XPCWrappedNative. The XPCWrappedNative + * holds pointers to the C++ object and the flat JS object. + * + * All XPCWrappedNative objects belong to an XPCWrappedNativeScope. These scopes + * are essentially in 1:1 correspondence with JS compartments. The + * XPCWrappedNativeScope has a pointer to the JS compartment. The global of a + * flattened JS object is one of the globals in this compartment (the exception + * to this rule is when a PreCreate hook asks for a different global; see + * nsIXPCScriptable below). + * + * Some C++ objects (notably DOM objects) have information associated with them + * that lists the interfaces implemented by these objects. A C++ object exposes + * this information by implementing nsIClassInfo. If a C++ object implements + * nsIClassInfo, then JS code can call its methods without needing to use + * QueryInterface first. Typically, all instances of a C++ class share the same + * nsIClassInfo instance. (That is, obj->QueryInterface(nsIClassInfo) returns + * the same result for every obj of a given class.) + * + * XPConnect tracks nsIClassInfo information in an XPCWrappedNativeProto object. + * A given XPCWrappedNativeScope will have one XPCWrappedNativeProto for each + * nsIClassInfo instance being used. The XPCWrappedNativeProto has an associated + * JS object, which is used as the prototype of all flattened JS objects created + * for C++ objects with the given nsIClassInfo. + * + * Each XPCWrappedNativeProto has a pointer to its XPCWrappedNativeScope. If an + * XPCWrappedNative wraps a C++ object with class info, then it points to its + * XPCWrappedNativeProto. Otherwise it points to its XPCWrappedNativeScope. (The + * pointers are smooshed together in a tagged union.) Either way it can reach + * its scope. + * + * An XPCWrappedNativeProto keeps track of the set of interfaces implemented by + * the C++ object in an XPCNativeSet. (The list of interfaces is obtained by + * calling a method on the nsIClassInfo.) An XPCNativeSet is a collection of + * XPCNativeInterfaces. Each interface stores the list of members, which can be + * methods, constants, getters, or setters. + * + * An XPCWrappedNative also points to an XPCNativeSet. Initially this starts out + * the same as the XPCWrappedNativeProto's set. If there is no proto, it starts + * out as a singleton set containing nsISupports. If JS code QI's new interfaces + * outside of the existing set, the set will grow. All QueryInterface results + * are cached in XPCWrappedNativeTearOff objects, which are linked off of the + * XPCWrappedNative. + * + * Besides having class info, a C++ object may be "scriptable" (i.e., implement + * nsIXPCScriptable). This allows it to implement a more DOM-like interface, + * besides just exposing XPCOM methods and constants. An nsIXPCScriptable + * instance has hooks that correspond to all the normal JSClass hooks. Each + * nsIXPCScriptable instance can have pointers from XPCWrappedNativeProto and + * XPCWrappedNative (since C++ objects can have scriptable info without having + * class info). + */ + +/* All the XPConnect private declarations - only include locally. */ + +#ifndef xpcprivate_h___ +#define xpcprivate_h___ + +#include "mozilla/Alignment.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" +#include "mozilla/Attributes.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/CycleCollectedJSContext.h" +#include "mozilla/CycleCollectedJSRuntime.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/DefineEnum.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/LinkedList.h" +#include "mozilla/Maybe.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/mozalloc.h" +#include "mozilla/Preferences.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Vector.h" + +#include "mozilla/dom/ScriptSettings.h" + +#include <math.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "xpcpublic.h" +#include "js/HashTable.h" +#include "js/GCHashTable.h" +#include "js/Object.h" // JS::GetClass, JS::GetCompartment +#include "js/PropertyAndElement.h" // JS_DefineProperty +#include "js/TracingAPI.h" +#include "js/WeakMapPtr.h" +#include "nscore.h" +#include "nsXPCOM.h" +#include "nsCycleCollectionParticipant.h" +#include "nsDebug.h" +#include "nsISupports.h" +#include "nsIServiceManager.h" +#include "nsIClassInfoImpl.h" +#include "nsIComponentManager.h" +#include "nsIComponentRegistrar.h" +#include "nsISupportsPrimitives.h" +#include "nsISimpleEnumerator.h" +#include "nsIXPConnect.h" +#include "nsIXPCScriptable.h" +#include "nsIObserver.h" +#include "nsWeakReference.h" +#include "nsCOMPtr.h" +#include "nsXPTCUtils.h" +#include "xptinfo.h" +#include "XPCForwards.h" +#include "XPCLog.h" +#include "xpccomponents.h" +#include "prenv.h" +#include "prcvar.h" +#include "nsString.h" +#include "nsReadableUtils.h" + +#include "MainThreadUtils.h" + +#include "nsIConsoleService.h" + +#include "nsVariant.h" +#include "nsCOMArray.h" +#include "nsTArray.h" +#include "nsBaseHashtable.h" +#include "nsHashKeys.h" +#include "nsWrapperCache.h" +#include "nsStringBuffer.h" +#include "nsDeque.h" + +#include "nsIScriptSecurityManager.h" + +#include "nsIPrincipal.h" +#include "nsJSPrincipals.h" +#include "nsIScriptObjectPrincipal.h" +#include "xpcObjectHelper.h" + +#include "SandboxPrivate.h" +#include "BackstagePass.h" + +#ifdef XP_WIN +// Nasty MS defines +# ifdef GetClassInfo +# undef GetClassInfo +# endif +# ifdef GetClassName +# undef GetClassName +# endif +#endif /* XP_WIN */ + +namespace mozilla { +namespace dom { +class AutoEntryScript; +class Exception; +} // namespace dom +} // namespace mozilla + +/***************************************************************************/ +// data declarations... +extern const char XPC_EXCEPTION_CONTRACTID[]; +extern const char XPC_CONSOLE_CONTRACTID[]; +extern const char XPC_SCRIPT_ERROR_CONTRACTID[]; +extern const char XPC_XPCONNECT_CONTRACTID[]; + +/***************************************************************************/ +// Helper function. + +namespace xpc { + +inline bool IsWrappedNativeReflector(JSObject* obj) { + return JS::GetClass(obj)->isWrappedNative(); +} + +} // namespace xpc + +/*************************************************************************** +**************************************************************************** +* +* Core runtime and context classes... +* +**************************************************************************** +***************************************************************************/ + +// We have a general rule internally that getters that return addref'd interface +// pointer generally do so using an 'out' parm. When interface pointers are +// returned as function call result values they are not addref'd. Exceptions +// to this rule are noted explicitly. + +class nsXPConnect final : public nsIXPConnect { + public: + // all the interface method declarations... + NS_DECL_ISUPPORTS + + // non-interface implementation + public: + static XPCJSRuntime* GetRuntimeInstance(); + XPCJSContext* GetContext() { return mContext; } + + static nsIScriptSecurityManager* SecurityManager() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(gScriptSecurityManager); + return gScriptSecurityManager; + } + + static nsIPrincipal* SystemPrincipal() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(gSystemPrincipal); + return gSystemPrincipal; + } + + // Called by module code in dll startup + static void InitStatics(); + // Called by module code on dll shutdown. + static void ReleaseXPConnectSingleton(); + + static void InitJSContext(); + + void RecordTraversal(void* p, nsISupports* s); + + protected: + virtual ~nsXPConnect(); + + nsXPConnect(); + + private: + // Singleton instance + static nsXPConnect* gSelf; + static bool gOnceAliveNowDead; + + XPCJSContext* mContext = nullptr; + XPCJSRuntime* mRuntime = nullptr; + + friend class nsIXPConnect; + + public: + static nsIScriptSecurityManager* gScriptSecurityManager; + static nsIPrincipal* gSystemPrincipal; +}; + +/***************************************************************************/ + +// In the current xpconnect system there can only be one XPCJSContext. +// So, xpconnect can only be used on one JSContext within the process. + +class WatchdogManager; + +// clang-format off +MOZ_DEFINE_ENUM(WatchdogTimestampCategory, ( + TimestampWatchdogWakeup, + TimestampWatchdogHibernateStart, + TimestampWatchdogHibernateStop, + TimestampContextStateChange +)); +// clang-format on + +class AsyncFreeSnowWhite; +class XPCWrappedNativeScope; + +using XPCWrappedNativeScopeList = mozilla::LinkedList<XPCWrappedNativeScope>; + +class XPCJSContext final : public mozilla::CycleCollectedJSContext, + public mozilla::LinkedListElement<XPCJSContext> { + public: + static XPCJSContext* NewXPCJSContext(); + static XPCJSContext* Get(); + + XPCJSRuntime* Runtime() const; + + virtual mozilla::CycleCollectedJSRuntime* CreateRuntime( + JSContext* aCx) override; + + XPCCallContext* GetCallContext() const { return mCallContext; } + XPCCallContext* SetCallContext(XPCCallContext* ccx) { + XPCCallContext* old = mCallContext; + mCallContext = ccx; + return old; + } + + jsid GetResolveName() const { return mResolveName; } + jsid SetResolveName(jsid name) { + jsid old = mResolveName; + mResolveName = name; + return old; + } + + XPCWrappedNative* GetResolvingWrapper() const { return mResolvingWrapper; } + XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w) { + XPCWrappedNative* old = mResolvingWrapper; + mResolvingWrapper = w; + return old; + } + + bool JSContextInitialized(JSContext* cx); + + virtual void BeforeProcessTask(bool aMightBlock) override; + virtual void AfterProcessTask(uint32_t aNewRecursionDepth) override; + + // Relay to the CCGCScheduler instead of queuing up an idle runnable + // (as is done for workers in CycleCollectedJSContext). + virtual void MaybePokeGC() override; + + ~XPCJSContext(); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + bool IsSystemCaller() const override; + + AutoMarkingPtr** GetAutoRootsAdr() { return &mAutoRoots; } + + nsresult GetPendingResult() { return mPendingResult; } + void SetPendingResult(nsresult rv) { mPendingResult = rv; } + + PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory); + + static bool RecordScriptActivity(bool aActive); + + bool SetHasScriptActivity(bool aActive) { + bool oldValue = mHasScriptActivity; + mHasScriptActivity = aActive; + return oldValue; + } + + static bool InterruptCallback(JSContext* cx); + + // Mapping of often used strings to jsid atoms that live 'forever'. + // + // To add a new string: add to this list and to XPCJSRuntime::mStrings + // at the top of XPCJSRuntime.cpp + enum { + IDX_CONSTRUCTOR = 0, + IDX_TO_STRING, + IDX_TO_SOURCE, + IDX_VALUE, + IDX_QUERY_INTERFACE, + IDX_COMPONENTS, + IDX_CC, + IDX_CI, + IDX_CR, + IDX_CU, + IDX_SERVICES, + IDX_WRAPPED_JSOBJECT, + IDX_PROTOTYPE, + IDX_EVAL, + IDX_CONTROLLERS, + IDX_CONTROLLERS_CLASS, + IDX_LENGTH, + IDX_NAME, + IDX_UNDEFINED, + IDX_EMPTYSTRING, + IDX_FILENAME, + IDX_LINENUMBER, + IDX_COLUMNNUMBER, + IDX_STACK, + IDX_MESSAGE, + IDX_CAUSE, + IDX_ERRORS, + IDX_LASTINDEX, + IDX_THEN, + IDX_ISINSTANCE, + IDX_INFINITY, + IDX_NAN, + IDX_CLASS_ID, + IDX_INTERFACE_ID, + IDX_INITIALIZER, + IDX_PRINT, + IDX_FETCH, + IDX_CRYPTO, + IDX_INDEXEDDB, + IDX_STRUCTUREDCLONE, + IDX_TOTAL_COUNT // just a count of the above + }; + + inline JS::HandleId GetStringID(unsigned index) const; + inline const char* GetStringName(unsigned index) const; + + private: + XPCJSContext(); + + MOZ_IS_CLASS_INIT + nsresult Initialize(); + + XPCCallContext* mCallContext; + AutoMarkingPtr* mAutoRoots; + jsid mResolveName; + XPCWrappedNative* mResolvingWrapper; + WatchdogManager* mWatchdogManager; + + // Number of XPCJSContexts currently alive. + static uint32_t sInstanceCount; + static mozilla::StaticAutoPtr<WatchdogManager> sWatchdogInstance; + static WatchdogManager* GetWatchdogManager(); + + // If we spend too much time running JS code in an event handler, then we + // want to show the slow script UI. The timeout T is controlled by prefs. We + // invoke the interrupt callback once after T/2 seconds and set + // mSlowScriptSecondHalf to true. After another T/2 seconds, we invoke the + // interrupt callback again. Since mSlowScriptSecondHalf is now true, it + // shows the slow script UI. The reason we invoke the callback twice is to + // ensure that putting the computer to sleep while running a script doesn't + // cause the UI to be shown. If the laptop goes to sleep during one of the + // timeout periods, the script still has the other T/2 seconds to complete + // before the slow script UI is shown. + bool mSlowScriptSecondHalf; + + // mSlowScriptCheckpoint is set to the time when: + // 1. We started processing the current event, or + // 2. mSlowScriptSecondHalf was set to true + // (whichever comes later). We use it to determine whether the interrupt + // callback needs to do anything. + mozilla::TimeStamp mSlowScriptCheckpoint; + // Accumulates total time we actually waited for telemetry + mozilla::TimeDuration mSlowScriptActualWait; + bool mTimeoutAccumulated; + bool mExecutedChromeScript; + + bool mHasScriptActivity; + + // mPendingResult is used to implement Components.returnCode. Only really + // meaningful while calling through XPCWrappedJS. + nsresult mPendingResult; + + // These members must be accessed via WatchdogManager. + enum { CONTEXT_ACTIVE, CONTEXT_INACTIVE } mActive; + PRTime mLastStateChange; + + friend class XPCJSRuntime; + friend class Watchdog; + friend class WatchdogManager; + friend class AutoLockWatchdog; +}; + +class XPCJSRuntime final : public mozilla::CycleCollectedJSRuntime { + public: + static XPCJSRuntime* Get(); + + void RemoveWrappedJS(nsXPCWrappedJS* wrapper); + void AssertInvalidWrappedJSNotInTable(nsXPCWrappedJS* wrapper) const; + + JSObject2WrappedJSMap* GetMultiCompartmentWrappedJSMap() const { + return mWrappedJSMap.get(); + } + + IID2NativeInterfaceMap* GetIID2NativeInterfaceMap() const { + return mIID2NativeInterfaceMap.get(); + } + + ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const { + return mClassInfo2NativeSetMap.get(); + } + + NativeSetMap* GetNativeSetMap() const { return mNativeSetMap.get(); } + + using WrappedNativeProtoVector = + mozilla::Vector<mozilla::UniquePtr<XPCWrappedNativeProto>, 0, + InfallibleAllocPolicy>; + WrappedNativeProtoVector& GetDyingWrappedNativeProtos() { + return mDyingWrappedNativeProtos; + } + + XPCWrappedNativeScopeList& GetWrappedNativeScopes() { + return mWrappedNativeScopes; + } + + bool InitializeStrings(JSContext* cx); + + virtual bool DescribeCustomObjects(JSObject* aObject, const JSClass* aClasp, + char (&aName)[72]) const override; + virtual bool NoteCustomGCThingXPCOMChildren( + const JSClass* aClasp, JSObject* aObj, + nsCycleCollectionTraversalCallback& aCb) const override; + + /** + * Infrastructure for classes that need to defer part of the finalization + * until after the GC has run, for example for objects that we don't want to + * destroy during the GC. + */ + + public: + bool GetDoingFinalization() const { return mDoingFinalization; } + + JS::HandleId GetStringID(unsigned index) const { + MOZ_ASSERT(index < XPCJSContext::IDX_TOTAL_COUNT, "index out of range"); + // fromMarkedLocation() is safe because the string is interned. + return JS::HandleId::fromMarkedLocation(&mStrIDs[index]); + } + const char* GetStringName(unsigned index) const { + MOZ_ASSERT(index < XPCJSContext::IDX_TOTAL_COUNT, "index out of range"); + return mStrings[index]; + } + + virtual bool UsefulToMergeZones() const override; + void TraceNativeBlackRoots(JSTracer* trc) override; + void TraceAdditionalNativeGrayRoots(JSTracer* aTracer) override; + void TraverseAdditionalNativeRoots( + nsCycleCollectionNoteRootCallback& cb) override; + void UnmarkSkippableJSHolders(); + void PrepareForForgetSkippable() override; + void BeginCycleCollectionCallback(mozilla::CCReason aReason) override; + void EndCycleCollectionCallback( + mozilla::CycleCollectorResults& aResults) override; + void DispatchDeferredDeletion(bool aContinuation, + bool aPurge = false) override; + + void CustomGCCallback(JSGCStatus status) override; + void CustomOutOfMemoryCallback() override; + void OnLargeAllocationFailure(); + static void GCSliceCallback(JSContext* cx, JS::GCProgress progress, + const JS::GCDescription& desc); + static void DoCycleCollectionCallback(JSContext* cx); + static void FinalizeCallback(JS::GCContext* gcx, JSFinalizeStatus status, + void* data); + static void WeakPointerZonesCallback(JSTracer* trc, void* data); + static void WeakPointerCompartmentCallback(JSTracer* trc, + JS::Compartment* comp, void* data); + + inline void AddSubjectToFinalizationWJS(nsXPCWrappedJS* wrappedJS); + + void DebugDump(int16_t depth); + + bool GCIsRunning() const { return mGCIsRunning; } + + ~XPCJSRuntime(); + + void AddGCCallback(xpcGCCallback cb); + void RemoveGCCallback(xpcGCCallback cb); + + JSObject* GetUAWidgetScope(JSContext* cx, nsIPrincipal* principal); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + /** + * The unprivileged junk scope is an unprivileged sandbox global used for + * convenience by certain operations which need an unprivileged global but + * don't have one immediately handy. It should generally be avoided when + * possible. + * + * The scope is created lazily when it is needed, and held weakly so that it + * is destroyed when there are no longer any remaining external references to + * it. This means that under low memory conditions, when the scope does not + * already exist, we may not be able to create one. In these circumstances, + * the infallible version of this API will abort, and the fallible version + * will return null. Callers should therefore prefer the fallible version when + * on a codepath which can already return failure, but may use the infallible + * one otherwise. + */ + JSObject* UnprivilegedJunkScope(); + JSObject* UnprivilegedJunkScope(const mozilla::fallible_t&); + + bool IsUnprivilegedJunkScope(JSObject*); + JSObject* LoaderGlobal(); + + void DeleteSingletonScopes(); + + private: + explicit XPCJSRuntime(JSContext* aCx); + + MOZ_IS_CLASS_INIT + void Initialize(JSContext* cx); + void Shutdown(JSContext* cx) override; + + static const char* const mStrings[XPCJSContext::IDX_TOTAL_COUNT]; + jsid mStrIDs[XPCJSContext::IDX_TOTAL_COUNT]; + + struct Hasher { + using Key = RefPtr<mozilla::BasePrincipal>; + using Lookup = Key; + static uint32_t hash(const Lookup& l) { return l->GetOriginNoSuffixHash(); } + static bool match(const Key& k, const Lookup& l) { + return k->FastEquals(l); + } + }; + + struct MapEntryGCPolicy { + static bool traceWeak(JSTracer* trc, + RefPtr<mozilla::BasePrincipal>* /* unused */, + JS::Heap<JSObject*>* value) { + return JS::GCPolicy<JS::Heap<JSObject*>>::traceWeak(trc, value); + } + }; + + typedef JS::GCHashMap<RefPtr<mozilla::BasePrincipal>, JS::Heap<JSObject*>, + Hasher, js::SystemAllocPolicy, MapEntryGCPolicy> + Principal2JSObjectMap; + + mozilla::UniquePtr<JSObject2WrappedJSMap> mWrappedJSMap; + mozilla::UniquePtr<IID2NativeInterfaceMap> mIID2NativeInterfaceMap; + mozilla::UniquePtr<ClassInfo2NativeSetMap> mClassInfo2NativeSetMap; + mozilla::UniquePtr<NativeSetMap> mNativeSetMap; + Principal2JSObjectMap mUAWidgetScopeMap; + XPCWrappedNativeScopeList mWrappedNativeScopes; + WrappedNativeProtoVector mDyingWrappedNativeProtos; + bool mGCIsRunning; + nsTArray<nsISupports*> mNativesToReleaseArray; + bool mDoingFinalization; + mozilla::LinkedList<nsXPCWrappedJS> mSubjectToFinalizationWJS; + nsTArray<xpcGCCallback> extraGCCallbacks; + JS::GCSliceCallback mPrevGCSliceCallback; + JS::DoCycleCollectionCallback mPrevDoCycleCollectionCallback; + mozilla::WeakPtr<SandboxPrivate> mUnprivilegedJunkScope; + JS::PersistentRootedObject mLoaderGlobal; + RefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer; + + friend class XPCJSContext; + friend class XPCIncrementalReleaseRunnable; +}; + +inline JS::HandleId XPCJSContext::GetStringID(unsigned index) const { + return Runtime()->GetStringID(index); +} + +inline const char* XPCJSContext::GetStringName(unsigned index) const { + return Runtime()->GetStringName(index); +} + +/***************************************************************************/ + +// No virtuals +// XPCCallContext is ALWAYS declared as a local variable in some function; +// i.e. instance lifetime is always controled by some C++ function returning. +// +// These things are created frequently in many places. We *intentionally* do +// not inialialize all members in order to save on construction overhead. +// Some constructor pass more valid params than others. We init what must be +// init'd and leave other members undefined. In debug builds the accessors +// use a CHECK_STATE macro to track whether or not the object is in a valid +// state to answer the question a caller might be asking. As long as this +// class is maintained correctly it can do its job without a bunch of added +// overhead from useless initializations and non-DEBUG error checking. +// +// Note that most accessors are inlined. + +class MOZ_STACK_CLASS XPCCallContext final { + public: + enum : unsigned { NO_ARGS = (unsigned)-1 }; + + explicit XPCCallContext(JSContext* cx, JS::HandleObject obj = nullptr, + JS::HandleObject funobj = nullptr, + JS::HandleId id = JS::VoidHandlePropertyKey, + unsigned argc = NO_ARGS, JS::Value* argv = nullptr, + JS::Value* rval = nullptr); + + virtual ~XPCCallContext(); + + inline bool IsValid() const; + + inline XPCJSContext* GetContext() const; + inline JSContext* GetJSContext() const; + inline bool GetContextPopRequired() const; + inline XPCCallContext* GetPrevCallContext() const; + + inline JSObject* GetFlattenedJSObject() const; + inline XPCWrappedNative* GetWrapper() const; + + inline bool CanGetTearOff() const; + inline XPCWrappedNativeTearOff* GetTearOff() const; + + inline nsIXPCScriptable* GetScriptable() const; + inline XPCNativeSet* GetSet() const; + inline bool CanGetInterface() const; + inline XPCNativeInterface* GetInterface() const; + inline XPCNativeMember* GetMember() const; + inline bool HasInterfaceAndMember() const; + inline bool GetStaticMemberIsLocal() const; + inline unsigned GetArgc() const; + inline JS::Value* GetArgv() const; + + inline uint16_t GetMethodIndex() const; + + inline jsid GetResolveName() const; + inline jsid SetResolveName(JS::HandleId name); + + inline XPCWrappedNative* GetResolvingWrapper() const; + inline XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w); + + inline void SetRetVal(const JS::Value& val); + + void SetName(jsid name); + void SetArgsAndResultPtr(unsigned argc, JS::Value* argv, JS::Value* rval); + void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member, + bool isSetter); + + nsresult CanCallNow(); + + void SystemIsBeingShutDown(); + + operator JSContext*() const { return GetJSContext(); } + + private: + // no copy ctor or assignment allowed + XPCCallContext(const XPCCallContext& r) = delete; + XPCCallContext& operator=(const XPCCallContext& r) = delete; + + private: + // posible values for mState + enum State { + INIT_FAILED, + SYSTEM_SHUTDOWN, + HAVE_CONTEXT, + HAVE_OBJECT, + HAVE_NAME, + HAVE_ARGS, + READY_TO_CALL, + CALL_DONE + }; + +#ifdef DEBUG + inline void CHECK_STATE(int s) const { MOZ_ASSERT(mState >= s, "bad state"); } +#else +# define CHECK_STATE(s) ((void)0) +#endif + + private: + State mState; + + nsCOMPtr<nsIXPConnect> mXPC; + + XPCJSContext* mXPCJSContext; + JSContext* mJSContext; + + // ctor does not necessarily init the following. BEWARE! + + XPCCallContext* mPrevCallContext; + + XPCWrappedNative* mWrapper; + XPCWrappedNativeTearOff* mTearOff; + + nsCOMPtr<nsIXPCScriptable> mScriptable; + + RefPtr<XPCNativeSet> mSet; + RefPtr<XPCNativeInterface> mInterface; + XPCNativeMember* mMember; + + JS::RootedId mName; + bool mStaticMemberIsLocal; + + unsigned mArgc; + JS::Value* mArgv; + JS::Value* mRetVal; + + uint16_t mMethodIndex; +}; + +/*************************************************************************** +**************************************************************************** +* +* Core classes for wrapped native objects for use from JavaScript... +* +**************************************************************************** +***************************************************************************/ + +// These are the various JSClasses and callbacks whose use that required +// visibility from more than one .cpp file. + +extern const JSClass XPC_WN_NoHelper_JSClass; +extern const JSClass XPC_WN_Proto_JSClass; +extern const JSClass XPC_WN_Tearoff_JSClass; +extern const JSClass XPC_WN_NoHelper_Proto_JSClass; + +extern bool XPC_WN_CallMethod(JSContext* cx, unsigned argc, JS::Value* vp); + +extern bool XPC_WN_GetterSetter(JSContext* cx, unsigned argc, JS::Value* vp); + +/***************************************************************************/ +// XPCWrappedNativeScope is one-to-one with a JS compartment. + +class XPCWrappedNativeScope final + : public mozilla::LinkedListElement<XPCWrappedNativeScope> { + public: + XPCJSRuntime* GetRuntime() const { return XPCJSRuntime::Get(); } + + Native2WrappedNativeMap* GetWrappedNativeMap() const { + return mWrappedNativeMap.get(); + } + + ClassInfo2WrappedNativeProtoMap* GetWrappedNativeProtoMap() const { + return mWrappedNativeProtoMap.get(); + } + + nsXPCComponents* GetComponents() const { return mComponents; } + + bool AttachComponentsObject(JSContext* aCx); + + bool AttachJSServices(JSContext* aCx); + + // Returns the JS object reflection of the Components object. + bool GetComponentsJSObject(JSContext* cx, JS::MutableHandleObject obj); + + JSObject* GetExpandoChain(JS::HandleObject target); + + JSObject* DetachExpandoChain(JS::HandleObject target); + + bool SetExpandoChain(JSContext* cx, JS::HandleObject target, + JS::HandleObject chain); + + static void SystemIsBeingShutDown(); + + static void TraceWrappedNativesInAllScopes(XPCJSRuntime* xpcrt, + JSTracer* trc); + + void TraceInside(JSTracer* trc) { + if (mXrayExpandos.initialized()) { + mXrayExpandos.trace(trc); + } + JS::TraceEdge(trc, &mIDProto, "XPCWrappedNativeScope::mIDProto"); + JS::TraceEdge(trc, &mIIDProto, "XPCWrappedNativeScope::mIIDProto"); + JS::TraceEdge(trc, &mCIDProto, "XPCWrappedNativeScope::mCIDProto"); + } + + static void SuspectAllWrappers(nsCycleCollectionNoteRootCallback& cb); + + static void SweepAllWrappedNativeTearOffs(); + + void UpdateWeakPointersAfterGC(JSTracer* trc); + + static void DebugDumpAllScopes(int16_t depth); + + void DebugDump(int16_t depth); + + struct ScopeSizeInfo { + explicit ScopeSizeInfo(mozilla::MallocSizeOf mallocSizeOf) + : mMallocSizeOf(mallocSizeOf), + mScopeAndMapSize(0), + mProtoAndIfaceCacheSize(0) {} + + mozilla::MallocSizeOf mMallocSizeOf; + size_t mScopeAndMapSize; + size_t mProtoAndIfaceCacheSize; + }; + + static void AddSizeOfAllScopesIncludingThis(JSContext* cx, + ScopeSizeInfo* scopeSizeInfo); + + void AddSizeOfIncludingThis(JSContext* cx, ScopeSizeInfo* scopeSizeInfo); + + // Check whether our mAllowContentXBLScope state matches the given + // principal. This is used to avoid sharing compartments on + // mismatch. + bool XBLScopeStateMatches(nsIPrincipal* aPrincipal); + + XPCWrappedNativeScope(JS::Compartment* aCompartment, + JS::HandleObject aFirstGlobal); + virtual ~XPCWrappedNativeScope(); + + mozilla::UniquePtr<JSObject2JSObjectMap> mWaiverWrapperMap; + + JS::Compartment* Compartment() const { return mCompartment; } + + // Returns the global to use for new WrappedNative objects allocated in this + // compartment. This is better than using arbitrary globals we happen to be in + // because it prevents leaks (objects keep their globals alive). + JSObject* GetGlobalForWrappedNatives() { + return js::GetFirstGlobalInCompartment(Compartment()); + } + + bool AllowContentXBLScope(JS::Realm* aRealm); + + // ID Object prototype caches. + JS::Heap<JSObject*> mIDProto; + JS::Heap<JSObject*> mIIDProto; + JS::Heap<JSObject*> mCIDProto; + + protected: + XPCWrappedNativeScope() = delete; + + private: + mozilla::UniquePtr<Native2WrappedNativeMap> mWrappedNativeMap; + mozilla::UniquePtr<ClassInfo2WrappedNativeProtoMap> mWrappedNativeProtoMap; + RefPtr<nsXPCComponents> mComponents; + JS::Compartment* mCompartment; + + JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos; + + // For remote XUL domains, we run all XBL in the content scope for compat + // reasons (though we sometimes pref this off for automation). We + // track the result of this decision (mAllowContentXBLScope) for now. + bool mAllowContentXBLScope; +}; + +/***************************************************************************/ +// Slots we use for our functions +#define XPC_FUNCTION_NATIVE_MEMBER_SLOT 0 +#define XPC_FUNCTION_PARENT_OBJECT_SLOT 1 + +/***************************************************************************/ +// XPCNativeMember represents a single idl declared method, attribute or +// constant. + +// Tight. No virtual methods. Can be bitwise copied (until any resolution done). + +class XPCNativeMember final { + public: + static bool GetCallInfo(JSObject* funobj, + RefPtr<XPCNativeInterface>* pInterface, + XPCNativeMember** pMember); + + jsid GetName() const { return mName; } + + uint16_t GetIndex() const { return mIndex; } + + bool GetConstantValue(XPCCallContext& ccx, XPCNativeInterface* iface, + JS::Value* pval) { + MOZ_ASSERT(IsConstant(), + "Only call this if you're sure this is a constant!"); + return Resolve(ccx, iface, nullptr, pval); + } + + bool NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface, + JS::HandleObject parent, JS::Value* pval); + + bool IsMethod() const { return 0 != (mFlags & METHOD); } + + bool IsConstant() const { return 0 != (mFlags & CONSTANT); } + + bool IsAttribute() const { return 0 != (mFlags & GETTER); } + + bool IsWritableAttribute() const { return 0 != (mFlags & SETTER_TOO); } + + bool IsReadOnlyAttribute() const { + return IsAttribute() && !IsWritableAttribute(); + } + + void SetName(jsid a) { mName = a; } + + void SetMethod(uint16_t index) { + mFlags = METHOD; + mIndex = index; + } + + void SetConstant(uint16_t index) { + mFlags = CONSTANT; + mIndex = index; + } + + void SetReadOnlyAttribute(uint16_t index) { + mFlags = GETTER; + mIndex = index; + } + + void SetWritableAttribute() { + MOZ_ASSERT(mFlags == GETTER, "bad"); + mFlags = GETTER | SETTER_TOO; + } + + static uint16_t GetMaxIndexInInterface() { return (1 << 12) - 1; } + + inline XPCNativeInterface* GetInterface() const; + + void SetIndexInInterface(uint16_t index) { mIndexInInterface = index; } + + /* default ctor - leave random contents */ + MOZ_COUNTED_DEFAULT_CTOR(XPCNativeMember) + MOZ_COUNTED_DTOR(XPCNativeMember) + + XPCNativeMember(const XPCNativeMember& other) + : mName(other.mName), + mIndex(other.mIndex), + mFlags(other.mFlags), + mIndexInInterface(other.mIndexInInterface) { + MOZ_COUNT_CTOR(XPCNativeMember); + } + + private: + bool Resolve(XPCCallContext& ccx, XPCNativeInterface* iface, + JS::HandleObject parent, JS::Value* vp); + + enum { + METHOD = 0x01, + CONSTANT = 0x02, + GETTER = 0x04, + SETTER_TOO = 0x08 + // If you add a flag here, you may need to make mFlags wider and either + // make mIndexInInterface narrower (and adjust + // XPCNativeInterface::NewInstance accordingly) or make this object + // bigger. + }; + + private: + // our only data... + jsid mName; + uint16_t mIndex; + // mFlags needs to be wide enough to hold the flags in the above enum. + uint16_t mFlags : 4; + // mIndexInInterface is the index of this in our XPCNativeInterface's + // mMembers. In theory our XPCNativeInterface could have as many as 2^15-1 + // members (since mMemberCount is 15-bit) but in practice we prevent + // creation of XPCNativeInterfaces which have more than 2^12 members. + // If the width of this field changes, update GetMaxIndexInInterface. + uint16_t mIndexInInterface : 12; +}; + +/***************************************************************************/ +// XPCNativeInterface represents a single idl declared interface. This is +// primarily the set of XPCNativeMembers. + +// Tight. No virtual methods. + +class XPCNativeInterface final { + public: + NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeInterface, + DestroyInstance(this)) + + static already_AddRefed<XPCNativeInterface> GetNewOrUsed(JSContext* cx, + const nsIID* iid); + static already_AddRefed<XPCNativeInterface> GetNewOrUsed( + JSContext* cx, const nsXPTInterfaceInfo* info); + static already_AddRefed<XPCNativeInterface> GetNewOrUsed(JSContext* cx, + const char* name); + static already_AddRefed<XPCNativeInterface> GetISupports(JSContext* cx); + + inline const nsXPTInterfaceInfo* GetInterfaceInfo() const { return mInfo; } + inline jsid GetName() const { return mName; } + + inline const nsIID* GetIID() const; + inline const char* GetNameString() const; + inline XPCNativeMember* FindMember(jsid name) const; + + static inline size_t OffsetOfMembers(); + + uint16_t GetMemberCount() const { return mMemberCount; } + XPCNativeMember* GetMemberAt(uint16_t i) { + MOZ_ASSERT(i < mMemberCount, "bad index"); + return &mMembers[i]; + } + + void DebugDump(int16_t depth); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + void Trace(JSTracer* trc); + + protected: + static already_AddRefed<XPCNativeInterface> NewInstance( + JSContext* cx, IID2NativeInterfaceMap* aMap, + const nsXPTInterfaceInfo* aInfo); + + XPCNativeInterface() = delete; + XPCNativeInterface(const nsXPTInterfaceInfo* aInfo, jsid aName) + : mInfo(aInfo), mName(aName), mMemberCount(0) {} + ~XPCNativeInterface(); + + void* operator new(size_t, void* p) noexcept(true) { return p; } + + XPCNativeInterface(const XPCNativeInterface& r) = delete; + XPCNativeInterface& operator=(const XPCNativeInterface& r) = delete; + + static void DestroyInstance(XPCNativeInterface* inst); + + private: + const nsXPTInterfaceInfo* mInfo; + jsid mName; + uint16_t mMemberCount; + XPCNativeMember mMembers[1]; // always last - object sized for array +}; + +/***************************************************************************/ +// XPCNativeSetKey is used to key a XPCNativeSet in a NativeSetMap. +// It represents a new XPCNativeSet we are considering constructing, without +// requiring that the set actually be built. + +class MOZ_STACK_CLASS XPCNativeSetKey final { + public: + // This represents an existing set |baseSet|. + explicit XPCNativeSetKey(XPCNativeSet* baseSet) + : mCx(nullptr), mBaseSet(baseSet), mAddition(nullptr) { + MOZ_ASSERT(baseSet); + } + + // This represents a new set containing only nsISupports and + // |addition|. This needs a JSContext because it may need to + // construct some data structures that need one to construct them. + explicit XPCNativeSetKey(JSContext* cx, XPCNativeInterface* addition) + : mCx(cx), mBaseSet(nullptr), mAddition(addition) { + MOZ_ASSERT(cx); + MOZ_ASSERT(addition); + } + + // This represents the existing set |baseSet| with the interface + // |addition| inserted after existing interfaces. |addition| must + // not already be present in |baseSet|. + explicit XPCNativeSetKey(XPCNativeSet* baseSet, XPCNativeInterface* addition); + ~XPCNativeSetKey() = default; + + XPCNativeSet* GetBaseSet() const { return mBaseSet; } + XPCNativeInterface* GetAddition() const { return mAddition; } + + mozilla::HashNumber Hash() const; + + // Allow shallow copy + + private: + JSContext* mCx; + RefPtr<XPCNativeSet> mBaseSet; + RefPtr<XPCNativeInterface> mAddition; +}; + +/***************************************************************************/ +// XPCNativeSet represents an ordered collection of XPCNativeInterface pointers. + +class XPCNativeSet final { + public: + NS_INLINE_DECL_REFCOUNTING_WITH_DESTROY(XPCNativeSet, DestroyInstance(this)) + + static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx, + const nsIID* iid); + static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx, + nsIClassInfo* classInfo); + static already_AddRefed<XPCNativeSet> GetNewOrUsed(JSContext* cx, + XPCNativeSetKey* key); + + // This generates a union set. + // + // If preserveFirstSetOrder is true, the elements from |firstSet| come first, + // followed by any non-duplicate items from |secondSet|. If false, the same + // algorithm is applied; but if we detect that |secondSet| is a superset of + // |firstSet|, we return |secondSet| without worrying about whether the + // ordering might differ from |firstSet|. + static already_AddRefed<XPCNativeSet> GetNewOrUsed( + JSContext* cx, XPCNativeSet* firstSet, XPCNativeSet* secondSet, + bool preserveFirstSetOrder); + + static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo); + + inline bool FindMember(jsid name, XPCNativeMember** pMember, + uint16_t* pInterfaceIndex) const; + + inline bool FindMember(jsid name, XPCNativeMember** pMember, + RefPtr<XPCNativeInterface>* pInterface) const; + + inline bool FindMember(JS::HandleId name, XPCNativeMember** pMember, + RefPtr<XPCNativeInterface>* pInterface, + XPCNativeSet* protoSet, bool* pIsLocal) const; + + inline bool HasInterface(XPCNativeInterface* aInterface) const; + + uint16_t GetInterfaceCount() const { return mInterfaceCount; } + XPCNativeInterface** GetInterfaceArray() { return mInterfaces; } + + XPCNativeInterface* GetInterfaceAt(uint16_t i) { + MOZ_ASSERT(i < mInterfaceCount, "bad index"); + return mInterfaces[i]; + } + + inline bool MatchesSetUpToInterface(const XPCNativeSet* other, + XPCNativeInterface* iface) const; + + void DebugDump(int16_t depth); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + protected: + static already_AddRefed<XPCNativeSet> NewInstance( + JSContext* cx, nsTArray<RefPtr<XPCNativeInterface>>&& array); + static already_AddRefed<XPCNativeSet> NewInstanceMutate(XPCNativeSetKey* key); + + XPCNativeSet() : mInterfaceCount(0) {} + ~XPCNativeSet(); + void* operator new(size_t, void* p) noexcept(true) { return p; } + + static void DestroyInstance(XPCNativeSet* inst); + + private: + uint16_t mInterfaceCount; + // Always last - object sized for array. + // These are strong references. + XPCNativeInterface* mInterfaces[1]; +}; + +/***********************************************/ +// XPCWrappedNativeProtos hold the additional shared wrapper data for +// XPCWrappedNative whose native objects expose nsIClassInfo. +// +// The XPCWrappedNativeProto is owned by its mJSProtoObject, until that object +// is finalized. After that, it is owned by XPCJSRuntime's +// mDyingWrappedNativeProtos. See XPCWrappedNativeProto::JSProtoObjectFinalized +// and XPCJSRuntime::FinalizeCallback. + +class XPCWrappedNativeProto final { + public: + enum Slots { ProtoSlot, SlotCount }; + + static XPCWrappedNativeProto* GetNewOrUsed(JSContext* cx, + XPCWrappedNativeScope* scope, + nsIClassInfo* classInfo, + nsIXPCScriptable* scriptable); + + XPCWrappedNativeScope* GetScope() const { return mScope; } + + XPCJSRuntime* GetRuntime() const { return mScope->GetRuntime(); } + + JSObject* GetJSProtoObject() const { return mJSProtoObject; } + + JSObject* GetJSProtoObjectPreserveColor() const { + return mJSProtoObject.unbarrieredGet(); + } + + nsIClassInfo* GetClassInfo() const { return mClassInfo; } + + XPCNativeSet* GetSet() const { return mSet; } + + nsIXPCScriptable* GetScriptable() const { return mScriptable; } + + void JSProtoObjectFinalized(JS::GCContext* gcx, JSObject* obj); + void JSProtoObjectMoved(JSObject* obj, const JSObject* old); + + static XPCWrappedNativeProto* Get(JSObject* obj); + + void SystemIsBeingShutDown(); + + void DebugDump(int16_t depth); + + void TraceSelf(JSTracer* trc) { + if (mJSProtoObject) { + TraceEdge(trc, &mJSProtoObject, "XPCWrappedNativeProto::mJSProtoObject"); + } + } + + void TraceJS(JSTracer* trc) { TraceSelf(trc); } + + // NOP. This is just here to make the AutoMarkingPtr code compile. + void Mark() const {} + inline void AutoTrace(JSTracer* trc) {} + + ~XPCWrappedNativeProto(); + + protected: + // disable copy ctor and assignment + XPCWrappedNativeProto(const XPCWrappedNativeProto& r) = delete; + XPCWrappedNativeProto& operator=(const XPCWrappedNativeProto& r) = delete; + + // hide ctor + XPCWrappedNativeProto(XPCWrappedNativeScope* Scope, nsIClassInfo* ClassInfo, + RefPtr<XPCNativeSet>&& Set); + + bool Init(JSContext* cx, nsIXPCScriptable* scriptable); + + private: +#ifdef DEBUG + static int32_t gDEBUG_LiveProtoCount; +#endif + + private: + XPCWrappedNativeScope* mScope; + JS::Heap<JSObject*> mJSProtoObject; + nsCOMPtr<nsIClassInfo> mClassInfo; + RefPtr<XPCNativeSet> mSet; + nsCOMPtr<nsIXPCScriptable> mScriptable; +}; + +/***********************************************/ +// XPCWrappedNativeTearOff represents the info needed to make calls to one +// interface on the underlying native object of a XPCWrappedNative. + +class XPCWrappedNativeTearOff final { + public: + enum Slots { FlatObjectSlot, TearOffSlot, SlotCount }; + + bool IsAvailable() const { return mInterface == nullptr; } + bool IsReserved() const { return mInterface == (XPCNativeInterface*)1; } + bool IsValid() const { return !IsAvailable() && !IsReserved(); } + void SetReserved() { mInterface = (XPCNativeInterface*)1; } + + XPCNativeInterface* GetInterface() const { return mInterface; } + nsISupports* GetNative() const { return mNative; } + JSObject* GetJSObject(); + JSObject* GetJSObjectPreserveColor() const; + void SetInterface(XPCNativeInterface* Interface) { mInterface = Interface; } + void SetNative(nsISupports* Native) { mNative = Native; } + already_AddRefed<nsISupports> TakeNative() { return mNative.forget(); } + void SetJSObject(JSObject* JSObj); + + void JSObjectFinalized() { SetJSObject(nullptr); } + void JSObjectMoved(JSObject* obj, const JSObject* old); + + static XPCWrappedNativeTearOff* Get(JSObject* obj); + + XPCWrappedNativeTearOff() : mInterface(nullptr), mJSObject(nullptr) { + MOZ_COUNT_CTOR(XPCWrappedNativeTearOff); + } + ~XPCWrappedNativeTearOff(); + + // NOP. This is just here to make the AutoMarkingPtr code compile. + inline void TraceJS(JSTracer* trc) {} + inline void AutoTrace(JSTracer* trc) {} + + void Mark() { mJSObject.setFlags(1); } + void Unmark() { mJSObject.unsetFlags(1); } + bool IsMarked() const { return mJSObject.hasFlag(1); } + + XPCWrappedNativeTearOff* AddTearOff() { + MOZ_ASSERT(!mNextTearOff); + mNextTearOff = mozilla::MakeUnique<XPCWrappedNativeTearOff>(); + return mNextTearOff.get(); + } + + XPCWrappedNativeTearOff* GetNextTearOff() { return mNextTearOff.get(); } + + private: + XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r) = delete; + XPCWrappedNativeTearOff& operator=(const XPCWrappedNativeTearOff& r) = delete; + + private: + XPCNativeInterface* mInterface; + // mNative is an nsRefPtr not an nsCOMPtr because it may not be the canonical + // nsISupports pointer. + RefPtr<nsISupports> mNative; + JS::TenuredHeap<JSObject*> mJSObject; + mozilla::UniquePtr<XPCWrappedNativeTearOff> mNextTearOff; +}; + +/***************************************************************************/ +// XPCWrappedNative the wrapper around one instance of a native xpcom object +// to be used from JavaScript. + +class XPCWrappedNative final : public nsIXPConnectWrappedNative { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + + NS_DECL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) + + JSObject* GetJSObject() override; + + bool IsValid() const { return mFlatJSObject.hasFlag(FLAT_JS_OBJECT_VALID); } + + nsresult DebugDump(int16_t depth); + +#define XPC_SCOPE_WORD(s) (intptr_t(s)) +#define XPC_SCOPE_MASK (intptr_t(0x3)) +#define XPC_SCOPE_TAG (intptr_t(0x1)) +#define XPC_WRAPPER_EXPIRED (intptr_t(0x2)) + + static inline bool IsTaggedScope(XPCWrappedNativeScope* s) { + return XPC_SCOPE_WORD(s) & XPC_SCOPE_TAG; + } + + static inline XPCWrappedNativeScope* TagScope(XPCWrappedNativeScope* s) { + MOZ_ASSERT(!IsTaggedScope(s), "bad pointer!"); + return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) | XPC_SCOPE_TAG); + } + + static inline XPCWrappedNativeScope* UnTagScope(XPCWrappedNativeScope* s) { + return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) & ~XPC_SCOPE_TAG); + } + + inline bool IsWrapperExpired() const { + return XPC_SCOPE_WORD(mMaybeScope) & XPC_WRAPPER_EXPIRED; + } + + bool HasProto() const { return !IsTaggedScope(mMaybeScope); } + + XPCWrappedNativeProto* GetProto() const { + return HasProto() ? (XPCWrappedNativeProto*)(XPC_SCOPE_WORD(mMaybeProto) & + ~XPC_SCOPE_MASK) + : nullptr; + } + + XPCWrappedNativeScope* GetScope() const { + return GetProto() ? GetProto()->GetScope() + : (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(mMaybeScope) & + ~XPC_SCOPE_MASK); + } + + nsISupports* GetIdentityObject() const { return mIdentity; } + + /** + * This getter clears the gray bit before handing out the JSObject which + * means that the object is guaranteed to be kept alive past the next CC. + */ + JSObject* GetFlatJSObject() const { return mFlatJSObject; } + + /** + * This getter does not change the color of the JSObject meaning that the + * object returned is not guaranteed to be kept alive past the next CC. + * + * This should only be called if you are certain that the return value won't + * be passed into a JS API function and that it won't be stored without + * being rooted (or otherwise signaling the stored value to the CC). + */ + JSObject* GetFlatJSObjectPreserveColor() const { + return mFlatJSObject.unbarrieredGetPtr(); + } + + XPCNativeSet* GetSet() const { return mSet; } + + void SetSet(already_AddRefed<XPCNativeSet> set) { mSet = set; } + + static XPCWrappedNative* Get(JSObject* obj) { + MOZ_ASSERT(xpc::IsWrappedNativeReflector(obj)); + return JS::GetObjectISupports<XPCWrappedNative>(obj); + } + + private: + void SetFlatJSObject(JSObject* object); + void UnsetFlatJSObject(); + + inline void ExpireWrapper() { + mMaybeScope = (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(mMaybeScope) | + XPC_WRAPPER_EXPIRED); + } + + public: + nsIXPCScriptable* GetScriptable() const { return mScriptable; } + + nsIClassInfo* GetClassInfo() const { + return IsValid() && HasProto() ? GetProto()->GetClassInfo() : nullptr; + } + + bool HasMutatedSet() const { + return IsValid() && (!HasProto() || GetSet() != GetProto()->GetSet()); + } + + XPCJSRuntime* GetRuntime() const { + XPCWrappedNativeScope* scope = GetScope(); + return scope ? scope->GetRuntime() : nullptr; + } + + static nsresult WrapNewGlobal(JSContext* cx, xpcObjectHelper& nativeHelper, + nsIPrincipal* principal, + bool initStandardClasses, + JS::RealmOptions& aOptions, + XPCWrappedNative** wrappedGlobal); + + static nsresult GetNewOrUsed(JSContext* cx, xpcObjectHelper& helper, + XPCWrappedNativeScope* Scope, + XPCNativeInterface* Interface, + XPCWrappedNative** wrapper); + + void FlatJSObjectFinalized(); + void FlatJSObjectMoved(JSObject* obj, const JSObject* old); + + void SystemIsBeingShutDown(); + + enum CallMode { CALL_METHOD, CALL_GETTER, CALL_SETTER }; + + static bool CallMethod(XPCCallContext& ccx, CallMode mode = CALL_METHOD); + + static bool GetAttribute(XPCCallContext& ccx) { + return CallMethod(ccx, CALL_GETTER); + } + + static bool SetAttribute(XPCCallContext& ccx) { + return CallMethod(ccx, CALL_SETTER); + } + + XPCWrappedNativeTearOff* FindTearOff(JSContext* cx, + XPCNativeInterface* aInterface, + bool needJSObject = false, + nsresult* pError = nullptr); + XPCWrappedNativeTearOff* FindTearOff(JSContext* cx, const nsIID& iid); + + void Mark() const {} + + inline void TraceInside(JSTracer* trc) { + if (HasProto()) { + GetProto()->TraceSelf(trc); + } + + JSObject* obj = mFlatJSObject.unbarrieredGetPtr(); + if (obj && JS_IsGlobalObject(obj)) { + xpc::TraceXPCGlobal(trc, obj); + } + } + + void TraceJS(JSTracer* trc) { TraceInside(trc); } + + void TraceSelf(JSTracer* trc) { + // If this got called, we're being kept alive by someone who really + // needs us alive and whole. Do not let our mFlatJSObject go away. + // This is the only time we should be tracing our mFlatJSObject, + // normally somebody else is doing that. + JS::TraceEdge(trc, &mFlatJSObject, "XPCWrappedNative::mFlatJSObject"); + } + + static void Trace(JSTracer* trc, JSObject* obj); + + void AutoTrace(JSTracer* trc) { TraceSelf(trc); } + + inline void SweepTearOffs(); + + // Returns a string that should be freed with js_free, or nullptr on + // failure. + char* ToString(XPCWrappedNativeTearOff* to = nullptr) const; + + static nsIXPCScriptable* GatherProtoScriptable(nsIClassInfo* classInfo); + + bool HasExternalReference() const { return mRefCnt > 1; } + + void Suspect(nsCycleCollectionNoteRootCallback& cb); + void NoteTearoffs(nsCycleCollectionTraversalCallback& cb); + + // Make ctor and dtor protected (rather than private) to placate nsCOMPtr. + protected: + XPCWrappedNative() = delete; + + // This ctor is used if this object will have a proto. + XPCWrappedNative(nsCOMPtr<nsISupports>&& aIdentity, + XPCWrappedNativeProto* aProto); + + // This ctor is used if this object will NOT have a proto. + XPCWrappedNative(nsCOMPtr<nsISupports>&& aIdentity, + XPCWrappedNativeScope* aScope, RefPtr<XPCNativeSet>&& aSet); + + virtual ~XPCWrappedNative(); + void Destroy(); + + private: + enum { + // Flags bits for mFlatJSObject: + FLAT_JS_OBJECT_VALID = js::Bit(0) + }; + + bool Init(JSContext* cx, nsIXPCScriptable* scriptable); + bool FinishInit(JSContext* cx); + + bool ExtendSet(JSContext* aCx, XPCNativeInterface* aInterface); + + nsresult InitTearOff(JSContext* cx, XPCWrappedNativeTearOff* aTearOff, + XPCNativeInterface* aInterface, bool needJSObject); + + bool InitTearOffJSObject(JSContext* cx, XPCWrappedNativeTearOff* to); + + public: + static void GatherScriptable(nsISupports* obj, nsIClassInfo* classInfo, + nsIXPCScriptable** scrProto, + nsIXPCScriptable** scrWrapper); + + private: + union { + XPCWrappedNativeScope* mMaybeScope; + XPCWrappedNativeProto* mMaybeProto; + }; + RefPtr<XPCNativeSet> mSet; + JS::TenuredHeap<JSObject*> mFlatJSObject; + nsCOMPtr<nsIXPCScriptable> mScriptable; + XPCWrappedNativeTearOff mFirstTearOff; +}; + +/*************************************************************************** +**************************************************************************** +* +* Core classes for wrapped JSObject for use from native code... +* +**************************************************************************** +***************************************************************************/ + +/*************************/ +// nsXPCWrappedJS is a wrapper for a single JSObject for use from native code. +// nsXPCWrappedJS objects are chained together to represent the various +// interface on the single underlying (possibly aggregate) JSObject. + +class nsXPCWrappedJS final : protected nsAutoXPTCStub, + public nsIXPConnectWrappedJSUnmarkGray, + public nsSupportsWeakReference, + public mozilla::LinkedListElement<nsXPCWrappedJS> { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSISUPPORTSWEAKREFERENCE + + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS( + nsXPCWrappedJS, nsIXPConnectWrappedJS) + + JSObject* GetJSObject() override; + + // This method is defined in XPCWrappedJSClass.cpp to preserve VCS blame. + NS_IMETHOD CallMethod(uint16_t methodIndex, const nsXPTMethodInfo* info, + nsXPTCMiniVariant* nativeParams) override; + + /* + * This is rarely called directly. Instead one usually calls + * XPCConvert::JSObject2NativeInterface which will handles cases where the + * JS object is already a wrapped native or a DOM object. + */ + + static nsresult GetNewOrUsed(JSContext* cx, JS::HandleObject aJSObj, + REFNSIID aIID, nsXPCWrappedJS** wrapper); + + nsISomeInterface* GetXPTCStub() { return mXPTCStub; } + + nsresult DebugDump(int16_t depth); + + /** + * This getter does not change the color of the JSObject meaning that the + * object returned is not guaranteed to be kept alive past the next CC. + * + * This should only be called if you are certain that the return value won't + * be passed into a JS API function and that it won't be stored without + * being rooted (or otherwise signaling the stored value to the CC). + */ + JSObject* GetJSObjectPreserveColor() const { return mJSObj.unbarrieredGet(); } + + // Returns true if the wrapper chain contains references to multiple + // compartments. If the wrapper chain contains references to multiple + // compartments, then it must be registered on the XPCJSContext. Otherwise, + // it should be registered in the CompartmentPrivate for the compartment of + // the root's JS object. This will only return correct results when called + // on the root wrapper and will assert if not called on a root wrapper. + bool IsMultiCompartment() const; + + const nsXPTInterfaceInfo* GetInfo() const { return mInfo; } + REFNSIID GetIID() const { return mInfo->IID(); } + nsXPCWrappedJS* GetRootWrapper() const { return mRoot; } + nsXPCWrappedJS* GetNextWrapper() const { return mNext; } + + nsXPCWrappedJS* Find(REFNSIID aIID); + nsXPCWrappedJS* FindInherited(REFNSIID aIID); + nsXPCWrappedJS* FindOrFindInherited(REFNSIID aIID) { + nsXPCWrappedJS* wrapper = Find(aIID); + if (wrapper) { + return wrapper; + } + return FindInherited(aIID); + } + + bool IsRootWrapper() const { return mRoot == this; } + bool IsValid() const { return bool(mJSObj); } + void SystemIsBeingShutDown(); + + // These two methods are used by JSObject2WrappedJSMap::FindDyingJSObjects + // to find non-rooting wrappers for dying JS objects. See the top of + // XPCWrappedJS.cpp for more details. + bool IsSubjectToFinalization() const { return IsValid() && mRefCnt == 1; } + + void UpdateObjectPointerAfterGC(JSTracer* trc) { + MOZ_ASSERT(IsRootWrapper()); + JS_UpdateWeakPointerAfterGC(trc, &mJSObj); + } + + bool IsAggregatedToNative() const { return mRoot->mOuter != nullptr; } + nsISupports* GetAggregatedNativeObject() const { return mRoot->mOuter; } + void SetAggregatedNativeObject(nsISupports* aNative) { + MOZ_ASSERT(aNative); + if (mRoot->mOuter) { + MOZ_ASSERT(mRoot->mOuter == aNative, + "Only one aggregated native can be set"); + return; + } + mRoot->mOuter = aNative; + } + + // This method is defined in XPCWrappedJSClass.cpp to preserve VCS blame. + static void DebugDumpInterfaceInfo(const nsXPTInterfaceInfo* aInfo, + int16_t depth); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + virtual ~nsXPCWrappedJS(); + + protected: + nsXPCWrappedJS() = delete; + nsXPCWrappedJS(JSContext* cx, JSObject* aJSObj, + const nsXPTInterfaceInfo* aInfo, nsXPCWrappedJS* root, + nsresult* rv); + + bool CanSkip(); + void Destroy(); + void Unlink(); + + private: + friend class nsIXPConnectWrappedJS; + + JS::Compartment* Compartment() const { + return JS::GetCompartment(mJSObj.unbarrieredGet()); + } + + // These methods are defined in XPCWrappedJSClass.cpp to preserve VCS blame. + static const nsXPTInterfaceInfo* GetInterfaceInfo(REFNSIID aIID); + + nsresult DelegatedQueryInterface(REFNSIID aIID, void** aInstancePtr); + + static JSObject* GetRootJSObject(JSContext* cx, JSObject* aJSObj); + + static JSObject* CallQueryInterfaceOnJSObject(JSContext* cx, JSObject* jsobj, + JS::HandleObject scope, + REFNSIID aIID); + + // aObj is the nsXPCWrappedJS's object. We used this as the callee (or |this| + // if getter or setter). + // aSyntheticException, if not null, is the exception we should be using. + // If null, look for an exception on the JSContext hanging off the + // XPCCallContext. + static nsresult CheckForException( + XPCCallContext& ccx, mozilla::dom::AutoEntryScript& aes, + JS::HandleObject aObj, const char* aPropertyName, + const char* anInterfaceName, + mozilla::dom::Exception* aSyntheticException = nullptr); + + static bool GetArraySizeFromParam(const nsXPTMethodInfo* method, + const nsXPTType& type, + nsXPTCMiniVariant* params, + uint32_t* result); + + static bool GetInterfaceTypeFromParam(const nsXPTMethodInfo* method, + const nsXPTType& type, + nsXPTCMiniVariant* params, + nsID* result); + + static void CleanupOutparams(const nsXPTMethodInfo* info, + nsXPTCMiniVariant* nativeParams, bool inOutOnly, + uint8_t count); + + JS::Heap<JSObject*> mJSObj; + const nsXPTInterfaceInfo* const mInfo; + nsXPCWrappedJS* mRoot; // If mRoot != this, it is an owning pointer. + nsXPCWrappedJS* mNext; + nsCOMPtr<nsISupports> mOuter; // only set in root +}; + +/*************************************************************************** +**************************************************************************** +* +* All manner of utility classes follow... +* +**************************************************************************** +***************************************************************************/ + +namespace xpc { + +// A wrapper around JS iterators which presents an equivalent +// nsISimpleEnumerator interface for their contents. +class XPCWrappedJSIterator final : public nsISimpleEnumerator { + public: + NS_DECL_CYCLE_COLLECTION_CLASS(XPCWrappedJSIterator) + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSISIMPLEENUMERATOR + NS_DECL_NSISIMPLEENUMERATORBASE + + explicit XPCWrappedJSIterator(nsIJSEnumerator* aEnum); + + private: + ~XPCWrappedJSIterator() = default; + + nsCOMPtr<nsIJSEnumerator> mEnum; + nsCOMPtr<nsIGlobalObject> mGlobal; + nsCOMPtr<nsISupports> mNext; + mozilla::Maybe<bool> mHasNext; +}; + +} // namespace xpc + +/***************************************************************************/ +// class here just for static methods +class XPCConvert { + public: + /** + * Convert a native object into a JS::Value. + * + * @param cx the JSContext representing the global we want the value in + * @param d [out] the resulting JS::Value + * @param s the native object we're working with + * @param type the type of object that s is + * @param iid the interface of s that we want + * @param scope the default scope to put on the new JSObject's parent + * chain + * @param pErr [out] relevant error code, if any. + */ + + static bool NativeData2JS(JSContext* cx, JS::MutableHandleValue d, + const void* s, const nsXPTType& type, + const nsID* iid, uint32_t arrlen, nsresult* pErr); + + static bool JSData2Native(JSContext* cx, void* d, JS::HandleValue s, + const nsXPTType& type, const nsID* iid, + uint32_t arrlen, nsresult* pErr); + + /** + * Convert a native nsISupports into a JSObject. + * + * @param cx the JSContext representing the global we want the object in. + * @param dest [out] the resulting JSObject + * @param src the native object we're working with + * @param iid the interface of src that we want (may be null) + * @param cache the wrapper cache for src (may be null, in which case src + * will be QI'ed to get the cache) + * @param allowNativeWrapper if true, this method may wrap the resulting + * JSObject in an XPCNativeWrapper and return that, as needed. + * @param pErr [out] relevant error code, if any. + * @param src_is_identity optional performance hint. Set to true only + * if src is the identity pointer. + */ + static bool NativeInterface2JSObject(JSContext* cx, + JS::MutableHandleValue dest, + xpcObjectHelper& aHelper, + const nsID* iid, bool allowNativeWrapper, + nsresult* pErr); + + static bool GetNativeInterfaceFromJSObject(void** dest, JSObject* src, + const nsID* iid, nsresult* pErr); + static bool JSObject2NativeInterface(JSContext* cx, void** dest, + JS::HandleObject src, const nsID* iid, + nsISupports* aOuter, nsresult* pErr); + + // Note - This return the XPCWrappedNative, rather than the native itself, + // for the WN case. You probably want UnwrapReflectorToISupports. + static bool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface); + + static nsresult JSValToXPCException(JSContext* cx, JS::MutableHandleValue s, + const char* ifaceName, + const char* methodName, + mozilla::dom::Exception** exception); + + static nsresult ConstructException(nsresult rv, const char* message, + const char* ifaceName, + const char* methodName, nsISupports* data, + mozilla::dom::Exception** exception, + JSContext* cx, JS::Value* jsExceptionPtr); + + private: + /** + * Convert a native array into a JS::Value. + * + * @param cx the JSContext we're working with and in whose global the array + * should be created. + * @param d [out] the resulting JS::Value + * @param buf the native buffer containing input values + * @param type the type of objects in the array + * @param iid the interface of each object in the array that we want + * @param count the number of items in the array + * @param scope the default scope to put on the new JSObjects' parent chain + * @param pErr [out] relevant error code, if any. + */ + static bool NativeArray2JS(JSContext* cx, JS::MutableHandleValue d, + const void* buf, const nsXPTType& type, + const nsID* iid, uint32_t count, nsresult* pErr); + + using ArrayAllocFixupLen = std::function<void*(uint32_t*)>; + + /** + * Convert a JS::Value into a native array. + * + * @param cx the JSContext we're working with + * @param aJSVal the JS::Value to convert + * @param aEltType the type of objects in the array + * @param aIID the interface of each object in the array + * @param pErr [out] relevant error code, if any + * @param aAllocFixupLen function called with the JS Array's length to + * allocate the backing buffer. This function may + * modify the length of array to be converted. + */ + static bool JSArray2Native(JSContext* cx, JS::HandleValue aJSVal, + const nsXPTType& aEltType, const nsIID* aIID, + nsresult* pErr, + const ArrayAllocFixupLen& aAllocFixupLen); + + XPCConvert() = delete; +}; + +/***************************************************************************/ +// code for throwing exceptions into JS + +class nsXPCException; + +class XPCThrower { + public: + static void Throw(nsresult rv, JSContext* cx); + static void Throw(nsresult rv, XPCCallContext& ccx); + static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx); + static void ThrowBadParam(nsresult rv, unsigned paramNum, + XPCCallContext& ccx); + static bool SetVerbosity(bool state) { + bool old = sVerbose; + sVerbose = state; + return old; + } + + static bool CheckForPendingException(nsresult result, JSContext* cx); + + private: + static void Verbosify(XPCCallContext& ccx, char** psz, bool own); + + private: + static bool sVerbose; +}; + +/***************************************************************************/ + +class nsXPCException { + public: + static bool NameAndFormatForNSResult(nsresult rv, const char** name, + const char** format); + + static const void* IterateNSResults(nsresult* rv, const char** name, + const char** format, const void** iterp); + + static uint32_t GetNSResultCount(); +}; + +/***************************************************************************/ +// 'Components' object implementation. + +class nsXPCComponents final : public nsIXPCComponents { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCCOMPONENTS + + public: + void SystemIsBeingShutDown() { ClearMembers(); } + + XPCWrappedNativeScope* GetScope() { return mScope; } + + protected: + ~nsXPCComponents(); + + explicit nsXPCComponents(XPCWrappedNativeScope* aScope); + void ClearMembers(); + + XPCWrappedNativeScope* mScope; + + RefPtr<nsXPCComponents_Interfaces> mInterfaces; + RefPtr<nsXPCComponents_Results> mResults; + RefPtr<nsXPCComponents_Classes> mClasses; + RefPtr<nsXPCComponents_ID> mID; + RefPtr<nsXPCComponents_Exception> mException; + RefPtr<nsXPCComponents_Constructor> mConstructor; + RefPtr<nsXPCComponents_Utils> mUtils; + + friend class XPCWrappedNativeScope; +}; + +/****************************************************************************** + * Handles pre/post script processing. + */ +class MOZ_RAII AutoScriptEvaluate { + public: + /** + * Saves the JSContext as well as initializing our state + * @param cx The JSContext, this can be null, we don't do anything then + */ + explicit AutoScriptEvaluate(JSContext* cx) + : mJSContext(cx), mEvaluated(false) {} + + /** + * Does the pre script evaluation. + * This function should only be called once, and will assert if called + * more than once + */ + + bool StartEvaluating(JS::HandleObject scope); + + /** + * Does the post script evaluation. + */ + ~AutoScriptEvaluate(); + + private: + JSContext* mJSContext; + mozilla::Maybe<JS::AutoSaveExceptionState> mState; + bool mEvaluated; + mozilla::Maybe<JSAutoRealm> mAutoRealm; + + // No copying or assignment allowed + AutoScriptEvaluate(const AutoScriptEvaluate&) = delete; + AutoScriptEvaluate& operator=(const AutoScriptEvaluate&) = delete; +}; + +/***************************************************************************/ +class MOZ_RAII AutoResolveName { + public: + AutoResolveName(XPCCallContext& ccx, JS::HandleId name) + : mContext(ccx.GetContext()), + mOld(ccx, mContext->SetResolveName(name)) +#ifdef DEBUG + , + mCheck(ccx, name) +#endif + { + } + + ~AutoResolveName() { + mozilla::DebugOnly<jsid> old = mContext->SetResolveName(mOld); + MOZ_ASSERT(old == mCheck, "Bad Nesting!"); + } + + private: + XPCJSContext* mContext; + JS::RootedId mOld; +#ifdef DEBUG + JS::RootedId mCheck; +#endif +}; + +/***************************************************************************/ +// AutoMarkingPtr is the base class for the various AutoMarking pointer types +// below. This system allows us to temporarily protect instances of our garbage +// collected types after they are constructed but before they are safely +// attached to other rooted objects. +// This base class has pure virtual support for marking. + +class AutoMarkingPtr { + public: + explicit AutoMarkingPtr(JSContext* cx) { + mRoot = XPCJSContext::Get()->GetAutoRootsAdr(); + mNext = *mRoot; + *mRoot = this; + } + + virtual ~AutoMarkingPtr() { + if (mRoot) { + MOZ_ASSERT(*mRoot == this); + *mRoot = mNext; + } + } + + void TraceJSAll(JSTracer* trc) { + for (AutoMarkingPtr* cur = this; cur; cur = cur->mNext) { + cur->TraceJS(trc); + } + } + + void MarkAfterJSFinalizeAll() { + for (AutoMarkingPtr* cur = this; cur; cur = cur->mNext) { + cur->MarkAfterJSFinalize(); + } + } + + protected: + virtual void TraceJS(JSTracer* trc) = 0; + virtual void MarkAfterJSFinalize() = 0; + + private: + AutoMarkingPtr** mRoot; + AutoMarkingPtr* mNext; +}; + +template <class T> +class TypedAutoMarkingPtr : public AutoMarkingPtr { + public: + explicit TypedAutoMarkingPtr(JSContext* cx) + : AutoMarkingPtr(cx), mPtr(nullptr) {} + TypedAutoMarkingPtr(JSContext* cx, T* ptr) : AutoMarkingPtr(cx), mPtr(ptr) {} + + T* get() const { return mPtr; } + operator T*() const { return mPtr; } + T* operator->() const { return mPtr; } + + TypedAutoMarkingPtr<T>& operator=(T* ptr) { + mPtr = ptr; + return *this; + } + + protected: + virtual void TraceJS(JSTracer* trc) override { + if (mPtr) { + mPtr->TraceJS(trc); + mPtr->AutoTrace(trc); + } + } + + virtual void MarkAfterJSFinalize() override { + if (mPtr) { + mPtr->Mark(); + } + } + + private: + T* mPtr; +}; + +using AutoMarkingWrappedNativePtr = TypedAutoMarkingPtr<XPCWrappedNative>; +using AutoMarkingWrappedNativeTearOffPtr = + TypedAutoMarkingPtr<XPCWrappedNativeTearOff>; +using AutoMarkingWrappedNativeProtoPtr = + TypedAutoMarkingPtr<XPCWrappedNativeProto>; + +/***************************************************************************/ +// Definitions in XPCVariant.cpp. + +// {1809FD50-91E8-11d5-90F9-0010A4E73D9A} +#define XPCVARIANT_IID \ + { \ + 0x1809fd50, 0x91e8, 0x11d5, { \ + 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a \ + } \ + } + +// {DC524540-487E-4501-9AC7-AAA784B17C1C} +#define XPCVARIANT_CID \ + { \ + 0xdc524540, 0x487e, 0x4501, { \ + 0x9a, 0xc7, 0xaa, 0xa7, 0x84, 0xb1, 0x7c, 0x1c \ + } \ + } + +class XPCVariant : public nsIVariant { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSIVARIANT + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(XPCVariant) + + // If this class ever implements nsIWritableVariant, take special care with + // the case when mJSVal is JSVAL_STRING, since we don't own the data in + // that case. + + // We #define and iid so that out module local code can use QI to detect + // if a given nsIVariant is in fact an XPCVariant. + NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID) + + static already_AddRefed<XPCVariant> newVariant(JSContext* cx, + const JS::Value& aJSVal); + + /** + * This getter clears the gray bit before handing out the Value if the Value + * represents a JSObject. That means that the object is guaranteed to be + * kept alive past the next CC. + */ + JS::Value GetJSVal() const { return mJSVal; } + + protected: + /** + * This getter does not change the color of the Value (if it represents a + * JSObject) meaning that the value returned is not guaranteed to be kept + * alive past the next CC. + * + * This should only be called if you are certain that the return value won't + * be passed into a JS API function and that it won't be stored without + * being rooted (or otherwise signaling the stored value to the CC). + */ + JS::Value GetJSValPreserveColor() const { return mJSVal.unbarrieredGet(); } + + XPCVariant(JSContext* cx, const JS::Value& aJSVal); + + public: + /** + * Convert a variant into a JS::Value. + * + * @param cx the context for the whole procedure + * @param variant the variant to convert + * @param scope the default scope to put on the new JSObject's parent chain + * @param pErr [out] relevant error code, if any. + * @param pJSVal [out] the resulting jsval. + */ + static bool VariantDataToJS(JSContext* cx, nsIVariant* variant, + nsresult* pErr, JS::MutableHandleValue pJSVal); + + protected: + virtual ~XPCVariant(); + + bool InitializeData(JSContext* cx); + + void Cleanup(); + + nsDiscriminatedUnion mData; + JS::Heap<JS::Value> mJSVal; + bool mReturnRawObject; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID) + +/***************************************************************************/ +// Utilities + +inline JSContext* xpc_GetSafeJSContext() { + return XPCJSContext::Get()->Context(); +} + +namespace xpc { + +// JSNatives to expose atob and btoa in various non-DOM XPConnect scopes. +bool Atob(JSContext* cx, unsigned argc, JS::Value* vp); + +bool Btoa(JSContext* cx, unsigned argc, JS::Value* vp); + +// Helper function that creates a JSFunction that wraps a native function that +// forwards the call to the original 'callable'. +class FunctionForwarderOptions; +bool NewFunctionForwarder(JSContext* cx, JS::HandleId id, + JS::HandleObject callable, + FunctionForwarderOptions& options, + JS::MutableHandleValue vp); + +// Old fashioned xpc error reporter. Try to use JS_ReportError instead. +nsresult ThrowAndFail(nsresult errNum, JSContext* cx, bool* retval); + +struct GlobalProperties { + GlobalProperties() { mozilla::PodZero(this); } + bool Parse(JSContext* cx, JS::HandleObject obj); + bool DefineInXPCComponents(JSContext* cx, JS::HandleObject obj); + bool DefineInSandbox(JSContext* cx, JS::HandleObject obj); + + // Interface objects we can expose. + bool AbortController : 1; + bool Blob : 1; + bool ChromeUtils : 1; + bool CSS : 1; + bool CSSRule : 1; + bool Directory : 1; + bool Document : 1; + bool DOMException : 1; + bool DOMParser : 1; + bool DOMTokenList : 1; + bool Element : 1; + bool Event : 1; + bool File : 1; + bool FileReader : 1; + bool FormData : 1; + bool Headers : 1; + bool IOUtils : 1; + bool InspectorUtils : 1; + bool MessageChannel : 1; + bool MIDIInputMap : 1; + bool MIDIOutputMap : 1; + bool Node : 1; + bool NodeFilter : 1; + bool PathUtils : 1; + bool Performance : 1; + bool PromiseDebugging : 1; + bool Range : 1; + bool Selection : 1; + bool TextDecoder : 1; + bool TextEncoder : 1; + bool URL : 1; + bool URLSearchParams : 1; + bool XMLHttpRequest : 1; + bool WebSocket : 1; + bool Window : 1; + bool XMLSerializer : 1; + bool ReadableStream : 1; + + // Ad-hoc property names we implement. + bool atob : 1; + bool btoa : 1; + bool caches : 1; + bool crypto : 1; + bool fetch : 1; + bool storage : 1; + bool structuredClone : 1; + bool indexedDB : 1; + bool isSecureContext : 1; + bool rtcIdentityProvider : 1; + + private: + bool Define(JSContext* cx, JS::HandleObject obj); +}; + +// Infallible. +already_AddRefed<nsIXPCComponents_utils_Sandbox> NewSandboxConstructor(); + +// Returns true if class of 'obj' is SandboxClass. +bool IsSandbox(JSObject* obj); + +class MOZ_STACK_CLASS OptionsBase { + public: + explicit OptionsBase(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : mCx(cx), mObject(cx, options) {} + + virtual bool Parse() = 0; + + protected: + bool ParseValue(const char* name, JS::MutableHandleValue prop, + bool* found = nullptr); + bool ParseBoolean(const char* name, bool* prop); + bool ParseObject(const char* name, JS::MutableHandleObject prop); + bool ParseJSString(const char* name, JS::MutableHandleString prop); + bool ParseString(const char* name, nsCString& prop); + bool ParseString(const char* name, nsString& prop); + bool ParseId(const char* name, JS::MutableHandleId id); + bool ParseUInt32(const char* name, uint32_t* prop); + + JSContext* mCx; + JS::RootedObject mObject; +}; + +class MOZ_STACK_CLASS SandboxOptions : public OptionsBase { + public: + explicit SandboxOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), + wantXrays(true), + allowWaivers(true), + wantComponents(true), + wantExportHelpers(false), + isWebExtensionContentScript(false), + proto(cx), + sameZoneAs(cx), + forceSecureContext(false), + freshCompartment(false), + freshZone(false), + isUAWidgetScope(false), + invisibleToDebugger(false), + discardSource(false), + metadata(cx), + userContextId(0), + originAttributes(cx) {} + + virtual bool Parse() override; + + bool wantXrays; + bool allowWaivers; + bool wantComponents; + bool wantExportHelpers; + bool isWebExtensionContentScript; + JS::RootedObject proto; + nsCString sandboxName; + JS::RootedObject sameZoneAs; + bool forceSecureContext; + bool freshCompartment; + bool freshZone; + bool isUAWidgetScope; + bool invisibleToDebugger; + bool discardSource; + GlobalProperties globalProperties; + JS::RootedValue metadata; + uint32_t userContextId; + JS::RootedObject originAttributes; + + protected: + bool ParseGlobalProperties(); +}; + +class MOZ_STACK_CLASS CreateObjectInOptions : public OptionsBase { + public: + explicit CreateObjectInOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), defineAs(cx, JS::PropertyKey::Void()) {} + + virtual bool Parse() override { return ParseId("defineAs", &defineAs); } + + JS::RootedId defineAs; +}; + +class MOZ_STACK_CLASS ExportFunctionOptions : public OptionsBase { + public: + explicit ExportFunctionOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), + defineAs(cx, JS::PropertyKey::Void()), + allowCrossOriginArguments(false) {} + + virtual bool Parse() override { + return ParseId("defineAs", &defineAs) && + ParseBoolean("allowCrossOriginArguments", + &allowCrossOriginArguments); + } + + JS::RootedId defineAs; + bool allowCrossOriginArguments; +}; + +class MOZ_STACK_CLASS FunctionForwarderOptions : public OptionsBase { + public: + explicit FunctionForwarderOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), allowCrossOriginArguments(false) {} + + JSObject* ToJSObject(JSContext* cx) { + JS::RootedObject obj(cx, JS_NewObjectWithGivenProto(cx, nullptr, nullptr)); + if (!obj) { + return nullptr; + } + + JS::RootedValue val(cx); + unsigned attrs = JSPROP_READONLY | JSPROP_PERMANENT; + val = JS::BooleanValue(allowCrossOriginArguments); + if (!JS_DefineProperty(cx, obj, "allowCrossOriginArguments", val, attrs)) { + return nullptr; + } + + return obj; + } + + virtual bool Parse() override { + return ParseBoolean("allowCrossOriginArguments", + &allowCrossOriginArguments); + } + + bool allowCrossOriginArguments; +}; + +class MOZ_STACK_CLASS StackScopedCloneOptions : public OptionsBase { + public: + explicit StackScopedCloneOptions(JSContext* cx = xpc_GetSafeJSContext(), + JSObject* options = nullptr) + : OptionsBase(cx, options), + wrapReflectors(false), + cloneFunctions(false), + deepFreeze(false) {} + + virtual bool Parse() override { + return ParseBoolean("wrapReflectors", &wrapReflectors) && + ParseBoolean("cloneFunctions", &cloneFunctions) && + ParseBoolean("deepFreeze", &deepFreeze); + } + + // When a reflector is encountered, wrap it rather than aborting the clone. + bool wrapReflectors; + + // When a function is encountered, clone it (exportFunction-style) rather than + // aborting the clone. + bool cloneFunctions; + + // If true, the resulting object is deep-frozen after being cloned. + bool deepFreeze; +}; + +JSObject* CreateGlobalObject(JSContext* cx, const JSClass* clasp, + nsIPrincipal* principal, + JS::RealmOptions& aOptions); + +// Modify the provided compartment options, consistent with |aPrincipal| and +// with globally-cached values of various preferences. +// +// Call this function *before* |aOptions| is used to create the corresponding +// global object, as not all of the options it sets can be modified on an +// existing global object. (The type system should make this obvious, because +// you can't get a *mutable* JS::RealmOptions& from an existing global +// object.) +void InitGlobalObjectOptions(JS::RealmOptions& aOptions, + bool aIsSystemPrincipal, + bool aShouldResistFingerprinting); + +// Finish initializing an already-created, not-yet-exposed-to-script global +// object. This will attach a Components object (if necessary) and call +// |JS_FireOnNewGlobalObject| (if necessary). +// +// If you must modify compartment options, see InitGlobalObjectOptions above. +bool InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal, + uint32_t aFlags); + +// Helper for creating a sandbox object to use for evaluating +// untrusted code completely separated from all other code in the +// system using EvalInSandbox(). Takes the JSContext on which to +// do setup etc on, puts the sandbox object in *vp (which must be +// rooted by the caller), and uses the principal that's either +// directly passed in prinOrSop or indirectly as an +// nsIScriptObjectPrincipal holding the principal. If no principal is +// reachable through prinOrSop, a new null principal will be created +// and used. +nsresult CreateSandboxObject(JSContext* cx, JS::MutableHandleValue vp, + nsISupports* prinOrSop, + xpc::SandboxOptions& options); +// Helper for evaluating scripts in a sandbox object created with +// CreateSandboxObject(). The caller is responsible of ensuring +// that *rval doesn't get collected during the call or usage after the +// call. This helper will use filename and lineNo for error reporting, +// and if no filename is provided it will use the codebase from the +// principal and line number 1 as a fallback. +nsresult EvalInSandbox(JSContext* cx, JS::HandleObject sandbox, + const nsAString& source, const nsACString& filename, + int32_t lineNo, bool enforceFilenameRestrictions, + JS::MutableHandleValue rval); + +// Helper for retrieving metadata stored in a reserved slot. The metadata +// is set during the sandbox creation using the "metadata" option. +nsresult GetSandboxMetadata(JSContext* cx, JS::HandleObject sandboxArg, + JS::MutableHandleValue rval); + +nsresult SetSandboxMetadata(JSContext* cx, JS::HandleObject sandboxArg, + JS::HandleValue metadata); + +bool CreateObjectIn(JSContext* cx, JS::HandleValue vobj, + CreateObjectInOptions& options, + JS::MutableHandleValue rval); + +bool EvalInWindow(JSContext* cx, const nsAString& source, + JS::HandleObject scope, JS::MutableHandleValue rval); + +bool ExportFunction(JSContext* cx, JS::HandleValue vscope, + JS::HandleValue vfunction, JS::HandleValue voptions, + JS::MutableHandleValue rval); + +bool CloneInto(JSContext* cx, JS::HandleValue vobj, JS::HandleValue vscope, + JS::HandleValue voptions, JS::MutableHandleValue rval); + +bool StackScopedClone(JSContext* cx, StackScopedCloneOptions& options, + JS::HandleObject sourceScope, JS::MutableHandleValue val); + +} /* namespace xpc */ + +/***************************************************************************/ +// Inlined utilities. + +inline bool xpc_ForcePropertyResolve(JSContext* cx, JS::HandleObject obj, + jsid id); + +inline jsid GetJSIDByIndex(JSContext* cx, unsigned index); + +namespace xpc { + +enum WrapperDenialType { + WrapperDenialForXray = 0, + WrapperDenialForCOW, + WrapperDenialTypeCount +}; +bool ReportWrapperDenial(JSContext* cx, JS::HandleId id, WrapperDenialType type, + const char* reason); + +class CompartmentOriginInfo { + public: + CompartmentOriginInfo(const CompartmentOriginInfo&) = delete; + + CompartmentOriginInfo(mozilla::BasePrincipal* aOrigin, + const mozilla::SiteIdentifier& aSite) + : mOrigin(aOrigin), mSite(aSite) { + MOZ_ASSERT(aOrigin); + MOZ_ASSERT(aSite.IsInitialized()); + } + + bool IsSameOrigin(nsIPrincipal* aOther) const; + + // Does the principal of compartment a subsume the principal of compartment b? + static bool Subsumes(JS::Compartment* aCompA, JS::Compartment* aCompB); + static bool SubsumesIgnoringFPD(JS::Compartment* aCompA, + JS::Compartment* aCompB); + + bool MightBeWebContent() const; + + // Note: this principal must not be used for subsumes/equality checks + // considering document.domain. See mOrigin. + mozilla::BasePrincipal* GetPrincipalIgnoringDocumentDomain() const { + return mOrigin; + } + + const mozilla::SiteIdentifier& SiteRef() const { return mSite; } + + bool HasChangedDocumentDomain() const { return mChangedDocumentDomain; } + void SetChangedDocumentDomain() { mChangedDocumentDomain = true; } + + private: + // All globals in the compartment must have this origin. Note that + // individual globals and principals can have their domain changed via + // document.domain, so this principal must not be used for things like + // subsumesConsideringDomain or equalsConsideringDomain. Use the realm's + // principal for that. + RefPtr<mozilla::BasePrincipal> mOrigin; + + // In addition to the origin we also store the SiteIdentifier. When realms + // in different compartments can become same-origin (via document.domain), + // these compartments must have equal SiteIdentifiers. (This is derived from + // mOrigin but we cache it here for performance reasons.) + mozilla::SiteIdentifier mSite; + + // True if any global in this compartment mutated document.domain. + bool mChangedDocumentDomain = false; +}; + +// The CompartmentPrivate contains XPConnect-specific stuff related to each JS +// compartment. Since compartments are trust domains, this means mostly +// information needed to select the right security policy for cross-compartment +// wrappers. +class CompartmentPrivate { + CompartmentPrivate() = delete; + CompartmentPrivate(const CompartmentPrivate&) = delete; + + public: + CompartmentPrivate(JS::Compartment* c, + mozilla::UniquePtr<XPCWrappedNativeScope> scope, + mozilla::BasePrincipal* origin, + const mozilla::SiteIdentifier& site); + + ~CompartmentPrivate(); + + static CompartmentPrivate* Get(JS::Compartment* compartment) { + MOZ_ASSERT(compartment); + void* priv = JS_GetCompartmentPrivate(compartment); + return static_cast<CompartmentPrivate*>(priv); + } + + static CompartmentPrivate* Get(JS::Realm* realm) { + MOZ_ASSERT(realm); + JS::Compartment* compartment = JS::GetCompartmentForRealm(realm); + return Get(compartment); + } + + static CompartmentPrivate* Get(JSObject* object) { + JS::Compartment* compartment = JS::GetCompartment(object); + return Get(compartment); + } + + bool CanShareCompartmentWith(nsIPrincipal* principal) { + // Only share if we're same-origin with the principal. + if (!originInfo.IsSameOrigin(principal)) { + return false; + } + + // Don't share if we have any weird state set. + return !wantXrays && !isWebExtensionContentScript && + !isUAWidgetCompartment && mScope->XBLScopeStateMatches(principal); + } + + CompartmentOriginInfo originInfo; + + // Controls whether this compartment gets Xrays to same-origin. This behavior + // is deprecated, but is still the default for sandboxes for compatibity + // reasons. + bool wantXrays; + + // Controls whether this compartment is allowed to waive Xrays to content + // that it subsumes. This should generally be true, except in cases where we + // want to prevent code from depending on Xray Waivers (which might make it + // more portable to other browser architectures). + bool allowWaivers; + + // This compartment corresponds to a WebExtension content script, and + // receives various bits of special compatibility behavior. + bool isWebExtensionContentScript; + + // True if this compartment is a UA widget compartment. + bool isUAWidgetCompartment; + + // See CompartmentHasExclusiveExpandos. + bool hasExclusiveExpandos; + + // Whether SystemIsBeingShutDown has been called on this compartment. + bool wasShutdown; + + JSObject2WrappedJSMap* GetWrappedJSMap() const { return mWrappedJSMap.get(); } + void UpdateWeakPointersAfterGC(JSTracer* trc); + + void SystemIsBeingShutDown(); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); + + struct MapEntryGCPolicy { + static bool traceWeak(JSTracer* trc, const void* /* unused */, + JS::Heap<JSObject*>* value) { + return JS::GCPolicy<JS::Heap<JSObject*>>::traceWeak(trc, value); + } + }; + + typedef JS::GCHashMap<const void*, JS::Heap<JSObject*>, + mozilla::PointerHasher<const void*>, + js::SystemAllocPolicy, MapEntryGCPolicy> + RemoteProxyMap; + RemoteProxyMap& GetRemoteProxyMap() { return mRemoteProxies; } + + XPCWrappedNativeScope* GetScope() { return mScope.get(); } + + private: + mozilla::UniquePtr<JSObject2WrappedJSMap> mWrappedJSMap; + + // Cache holding proxy objects for Window objects (and their Location object) + // that are loaded in a different process. + RemoteProxyMap mRemoteProxies; + + // Our XPCWrappedNativeScope. + mozilla::UniquePtr<XPCWrappedNativeScope> mScope; +}; + +inline void CrashIfNotInAutomation() { MOZ_RELEASE_ASSERT(IsInAutomation()); } + +// XPConnect-specific data associated with each JavaScript realm. Per-Window +// settings live here; security-wrapper-related settings live in the +// CompartmentPrivate. +// +// Following the ECMAScript spec, a realm contains a global (e.g. an inner +// Window) and its associated scripts and objects; a compartment may contain +// several same-origin realms. +class RealmPrivate { + RealmPrivate() = delete; + RealmPrivate(const RealmPrivate&) = delete; + + public: + enum LocationHint { LocationHintRegular, LocationHintAddon }; + + explicit RealmPrivate(JS::Realm* realm); + + // Creates the RealmPrivate and CompartmentPrivate (if needed) for a new + // global. + static void Init(JS::HandleObject aGlobal, + const mozilla::SiteIdentifier& aSite); + + static RealmPrivate* Get(JS::Realm* realm) { + MOZ_ASSERT(realm); + void* priv = JS::GetRealmPrivate(realm); + return static_cast<RealmPrivate*>(priv); + } + + // Get the RealmPrivate for a given object. `object` must not be a + // cross-compartment wrapper, as CCWs aren't dedicated to a particular + // realm. + static RealmPrivate* Get(JSObject* object) { + JS::Realm* realm = JS::GetObjectRealmOrNull(object); + return Get(realm); + } + + // The scriptability of this realm. + Scriptability scriptability; + + // Whether we've emitted a warning about a property that was filtered out + // by a security wrapper. See XrayWrapper.cpp. + bool wrapperDenialWarnings[WrapperDenialTypeCount]; + + const nsACString& GetLocation() { + if (location.IsEmpty() && locationURI) { + nsCOMPtr<nsIXPConnectWrappedJS> jsLocationURI = + do_QueryInterface(locationURI); + if (jsLocationURI) { + // We cannot call into JS-implemented nsIURI objects, because + // we are iterating over the JS heap at this point. + location = "<JS-implemented nsIURI location>"_ns; + } else if (NS_FAILED(locationURI->GetSpec(location))) { + location = "<unknown location>"_ns; + } + } + return location; + } + bool GetLocationURI(LocationHint aLocationHint, nsIURI** aURI) { + if (locationURI) { + nsCOMPtr<nsIURI> rval = locationURI; + rval.forget(aURI); + return true; + } + return TryParseLocationURI(aLocationHint, aURI); + } + bool GetLocationURI(nsIURI** aURI) { + return GetLocationURI(LocationHintRegular, aURI); + } + + void SetLocation(const nsACString& aLocation) { + if (aLocation.IsEmpty()) { + return; + } + if (!location.IsEmpty() || locationURI) { + return; + } + location = aLocation; + } + void SetLocationURI(nsIURI* aLocationURI) { + if (!aLocationURI) { + return; + } + if (locationURI) { + return; + } + locationURI = aLocationURI; + } + + // JSStackFrames are tracked on a per-realm basis so they + // can be cleared when the associated window goes away. + void RegisterStackFrame(JSStackFrameBase* aFrame); + void UnregisterStackFrame(JSStackFrameBase* aFrame); + void NukeJSStackFrames(); + + private: + nsCString location; + nsCOMPtr<nsIURI> locationURI; + + bool TryParseLocationURI(LocationHint aType, nsIURI** aURI); + + nsTHashtable<nsPtrHashKey<JSStackFrameBase>> mJSStackFrames; +}; + +inline XPCWrappedNativeScope* ObjectScope(JSObject* obj) { + return CompartmentPrivate::Get(obj)->GetScope(); +} + +JSObject* NewOutObject(JSContext* cx); +bool IsOutObject(JSContext* cx, JSObject* obj); + +nsresult HasInstance(JSContext* cx, JS::HandleObject objArg, const nsID* iid, + bool* bp); + +// Returns the principal associated with |obj|'s realm. The object must not be a +// cross-compartment wrapper. +nsIPrincipal* GetObjectPrincipal(JSObject* obj); + +// Attempt to clean up the passed in value pointer. The pointer `value` must be +// a pointer to a value described by the type `nsXPTType`. +// +// This method expects a value of the following types: +// TD_NSIDPTR +// value : nsID* (free) +// TD_ASTRING, TD_CSTRING, TD_UTF8STRING +// value : ns[C]String* (truncate) +// TD_PSTRING, TD_PWSTRING, TD_PSTRING_SIZE_IS, TD_PWSTRING_SIZE_IS +// value : char[16_t]** (free) +// TD_INTERFACE_TYPE, TD_INTERFACE_IS_TYPE +// value : nsISupports** (release) +// TD_LEGACY_ARRAY (NOTE: aArrayLen should be passed) +// value : void** (destroy elements & free) +// TD_ARRAY +// value : nsTArray<T>* (destroy elements & Clear) +// TD_DOMOBJECT +// value : T** (cleanup) +// TD_PROMISE +// value : dom::Promise** (release) +// +// Other types are ignored. +inline void CleanupValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen = 0); + +// Out-of-line internals for xpc::CleanupValue. Defined in XPCConvert.cpp. +void InnerCleanupValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen); + +// In order to be able to safely call CleanupValue on a generated value, the +// data behind it needs to be initialized to a safe value. This method handles +// initializing the backing data to a safe value to use as an argument to +// XPCConvert methods, or xpc::CleanupValue. +// +// The pointer `aValue` must point to a block of memory at least aType.Stride() +// bytes large, and correctly aligned. +// +// This method accepts the same types as xpc::CleanupValue. +void InitializeValue(const nsXPTType& aType, void* aValue); + +// If a value was initialized with InitializeValue, it should be destroyed with +// DestructValue. This method acts like CleanupValue, except that destructors +// for complex types are also invoked, leaving them in an invalid state. +// +// This method should be called when destroying types initialized with +// InitializeValue. +// +// The pointer 'aValue' must point to a valid value of type 'aType'. +void DestructValue(const nsXPTType& aType, void* aValue, + uint32_t aArrayLen = 0); + +bool SandboxCreateCrypto(JSContext* cx, JS::Handle<JSObject*> obj); +bool SandboxCreateFetch(JSContext* cx, JS::Handle<JSObject*> obj); +bool SandboxCreateStructuredClone(JSContext* cx, JS::Handle<JSObject*> obj); + +} // namespace xpc + +namespace mozilla { +namespace dom { +extern bool DefineStaticJSVals(JSContext* cx); +} // namespace dom +} // namespace mozilla + +bool xpc_LocalizeRuntime(JSRuntime* rt); +void xpc_DelocalizeRuntime(JSRuntime* rt); + +/***************************************************************************/ +// Inlines use the above - include last. + +#include "XPCInlines.h" + +/***************************************************************************/ + +#endif /* xpcprivate_h___ */ diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h new file mode 100644 index 0000000000..970912aad7 --- /dev/null +++ b/js/xpconnect/src/xpcpublic.h @@ -0,0 +1,835 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpcpublic_h +#define xpcpublic_h + +#include <cstddef> +#include <cstdint> +#include "ErrorList.h" +#include "js/BuildId.h" +#include "js/ErrorReport.h" +#include "js/GCAPI.h" +#include "js/Object.h" +#include "js/RootingAPI.h" +#include "js/String.h" +#include "js/TypeDecls.h" +#include "js/Utility.h" +#include "js/Value.h" +#include "jsapi.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/dom/DOMString.h" +#include "mozilla/fallible.h" +#include "nsAtom.h" +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsIURI.h" +#include "nsStringBuffer.h" +#include "nsStringFwd.h" +#include "nsTArray.h" +#include "nsWrapperCache.h" + +// XXX only for NukeAllWrappersForRealm, which is only used in +// dom/base/WindowDestroyedEvent.cpp outside of js +#include "jsfriendapi.h" + +class JSObject; +class JSString; +class JSTracer; +class nsGlobalWindowInner; +class nsIGlobalObject; +class nsIHandleReportCallback; +class nsIPrincipal; +class nsPIDOMWindowInner; +struct JSContext; +struct nsID; +struct nsXPTInterfaceInfo; + +namespace JS { +class Compartment; +class ContextOptions; +class Realm; +class RealmOptions; +class Value; +struct RuntimeStats; +} // namespace JS + +namespace mozilla { +class BasePrincipal; + +namespace dom { +class Exception; +} // namespace dom +} // namespace mozilla + +using xpcGCCallback = void (*)(JSGCStatus); + +namespace xpc { + +class Scriptability { + public: + explicit Scriptability(JS::Realm* realm); + bool Allowed(); + bool IsImmuneToScriptPolicy(); + + void Block(); + void Unblock(); + void SetWindowAllowsScript(bool aAllowed); + + static Scriptability& Get(JSObject* aScope); + + // Returns true if scripting is allowed, false otherwise (if no Scriptability + // exists, like for example inside a ShadowRealm global, then script execution + // is assumed to be allowed) + static bool AllowedIfExists(JSObject* aScope); + + private: + // Whenever a consumer wishes to prevent script from running on a global, + // it increments this value with a call to Block(). When it wishes to + // re-enable it (if ever), it decrements this value with a call to Unblock(). + // Script may not run if this value is non-zero. + uint32_t mScriptBlocks; + + // Whether the DOM window allows javascript in this scope. If this scope + // doesn't have a window, this value is always true. + bool mWindowAllowsScript; + + // Whether this scope is immune to user-defined or addon-defined script + // policy. + bool mImmuneToScriptPolicy; + + // Whether the new-style domain policy when this compartment was created + // forbids script execution. + bool mScriptBlockedByPolicy; +}; + +JSObject* TransplantObject(JSContext* cx, JS::Handle<JSObject*> origobj, + JS::Handle<JSObject*> target); + +JSObject* TransplantObjectRetainingXrayExpandos(JSContext* cx, + JS::Handle<JSObject*> origobj, + JS::Handle<JSObject*> target); + +// If origObj has an xray waiver, nuke it before transplant. +JSObject* TransplantObjectNukingXrayWaiver(JSContext* cx, + JS::Handle<JSObject*> origObj, + JS::Handle<JSObject*> target); + +bool IsUAWidgetCompartment(JS::Compartment* compartment); +bool IsUAWidgetScope(JS::Realm* realm); +bool IsInUAWidgetScope(JSObject* obj); + +bool MightBeWebContentCompartment(JS::Compartment* compartment); + +void SetCompartmentChangedDocumentDomain(JS::Compartment* compartment); + +JSObject* GetUAWidgetScope(JSContext* cx, nsIPrincipal* principal); + +JSObject* GetUAWidgetScope(JSContext* cx, JSObject* contentScope); + +// Returns whether XBL scopes have been explicitly disabled for code running +// in this compartment. See the comment around mAllowContentXBLScope. +bool AllowContentXBLScope(JS::Realm* realm); + +// Get the scope for creating reflectors for native anonymous content +// whose normal global would be the given global. +JSObject* NACScope(JSObject* global); + +bool IsSandboxPrototypeProxy(JSObject* obj); +bool IsWebExtensionContentScriptSandbox(JSObject* obj); + +// The JSContext argument represents the Realm that's asking the question. This +// is needed to properly answer without exposing information unnecessarily +// from behind security wrappers. There will be no exceptions thrown on this +// JSContext. +bool IsReflector(JSObject* obj, JSContext* cx); + +bool IsXrayWrapper(JSObject* obj); + +// If this function was created for a given XrayWrapper, returns the global of +// the Xrayed object. Otherwise, returns the global of the function. +// +// To emphasize the obvious: the return value here is not necessarily same- +// compartment with the argument. +JSObject* XrayAwareCalleeGlobal(JSObject* fun); + +void TraceXPCGlobal(JSTracer* trc, JSObject* obj); + +/** + * Creates a new global object using the given aCOMObj as the global + * object. The object will be set up according to the flags (defined + * below). If you do not pass INIT_JS_STANDARD_CLASSES, then aCOMObj + * must implement nsIXPCScriptable so it can resolve the standard + * classes when asked by the JS engine. + * + * @param aJSContext the context to use while creating the global object. + * @param aCOMObj the native object that represents the global object. + * @param aPrincipal the principal of the code that will run in this + * compartment. Can be null if not on the main thread. + * @param aFlags one of the flags below specifying what options this + * global object wants. + * @param aOptions JSAPI-specific options for the new compartment. + */ +nsresult InitClassesWithNewWrappedGlobal( + JSContext* aJSContext, nsISupports* aCOMObj, nsIPrincipal* aPrincipal, + uint32_t aFlags, JS::RealmOptions& aOptions, + JS::MutableHandle<JSObject*> aNewGlobal); + +enum InitClassesFlag { + INIT_JS_STANDARD_CLASSES = 1 << 0, + DONT_FIRE_ONNEWGLOBALHOOK = 1 << 1, + OMIT_COMPONENTS_OBJECT = 1 << 2, +}; + +} /* namespace xpc */ + +namespace JS { + +struct RuntimeStats; + +} // namespace JS + +static_assert(JSCLASS_GLOBAL_APPLICATION_SLOTS > 0, + "Need at least one slot for JSCLASS_SLOT0_IS_NSISUPPORTS"); + +#define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n) \ + JSCLASS_DOM_GLOBAL | JSCLASS_SLOT0_IS_NSISUPPORTS | \ + JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS + n) + +#define XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET \ + (JSCLASS_GLOBAL_SLOT_COUNT + DOM_GLOBAL_SLOTS) + +#define XPCONNECT_GLOBAL_FLAGS XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(0) + +inline JSObject* xpc_FastGetCachedWrapper(JSContext* cx, nsWrapperCache* cache, + JS::MutableHandle<JS::Value> vp) { + if (cache) { + JSObject* wrapper = cache->GetWrapper(); + if (wrapper && + JS::GetCompartment(wrapper) == js::GetContextCompartment(cx)) { + vp.setObject(*wrapper); + return wrapper; + } + } + + return nullptr; +} + +// If aWrappedJS is a JS wrapper, unmark its JSObject. +extern void xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS); + +extern void xpc_UnmarkSkippableJSHolders(); + +// Defined in XPCDebug.cpp. +extern bool xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps); + +// Return a newly-allocated string containing a representation of the +// current JS stack. Defined in XPCDebug.cpp. +extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs, + bool showLocals, bool showThisProps); + +// readable string conversions, static methods and members only +class XPCStringConvert { + public: + // If the string shares the readable's buffer, that buffer will + // get assigned to *sharedBuffer. Otherwise null will be + // assigned. + static bool ReadableToJSVal(JSContext* cx, const nsAString& readable, + nsStringBuffer** sharedBuffer, + JS::MutableHandle<JS::Value> vp); + + // Convert the given stringbuffer/length pair to a jsval + static MOZ_ALWAYS_INLINE bool StringBufferToJSVal( + JSContext* cx, nsStringBuffer* buf, uint32_t length, + JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) { + JSString* str = JS_NewMaybeExternalString( + cx, static_cast<char16_t*>(buf->Data()), length, + &sDOMStringExternalString, sharedBuffer); + if (!str) { + return false; + } + rval.setString(str); + return true; + } + + static inline bool StringLiteralToJSVal(JSContext* cx, + const char16_t* literal, + uint32_t length, + JS::MutableHandle<JS::Value> rval) { + bool ignored; + JSString* str = JS_NewMaybeExternalString( + cx, literal, length, &sLiteralExternalString, &ignored); + if (!str) { + return false; + } + rval.setString(str); + return true; + } + + static inline bool DynamicAtomToJSVal(JSContext* cx, nsDynamicAtom* atom, + JS::MutableHandle<JS::Value> rval) { + bool sharedAtom; + JSString* str = + JS_NewMaybeExternalString(cx, atom->GetUTF16String(), atom->GetLength(), + &sDynamicAtomExternalString, &sharedAtom); + if (!str) { + return false; + } + if (sharedAtom) { + // We only have non-owning atoms in DOMString for now. + // nsDynamicAtom::AddRef is always-inline and defined in a + // translation unit we can't get to here. So we need to go through + // nsAtom::AddRef to call it. + static_cast<nsAtom*>(atom)->AddRef(); + } + rval.setString(str); + return true; + } + + static MOZ_ALWAYS_INLINE bool MaybeGetExternalStringChars( + JSString* str, const JSExternalStringCallbacks* desiredCallbacks, + const char16_t** chars) { + const JSExternalStringCallbacks* callbacks; + return JS::IsExternalString(str, &callbacks, chars) && + callbacks == desiredCallbacks; + } + + // Returns non-null chars if the given string is a literal external string. + static MOZ_ALWAYS_INLINE bool MaybeGetLiteralStringChars( + JSString* str, const char16_t** chars) { + return MaybeGetExternalStringChars(str, &sLiteralExternalString, chars); + } + + // Returns non-null chars if the given string is a DOM external string. + static MOZ_ALWAYS_INLINE bool MaybeGetDOMStringChars(JSString* str, + const char16_t** chars) { + return MaybeGetExternalStringChars(str, &sDOMStringExternalString, chars); + } + + private: + struct LiteralExternalString : public JSExternalStringCallbacks { + void finalize(char16_t* aChars) const override; + size_t sizeOfBuffer(const char16_t* aChars, + mozilla::MallocSizeOf aMallocSizeOf) const override; + }; + struct DOMStringExternalString : public JSExternalStringCallbacks { + void finalize(char16_t* aChars) const override; + size_t sizeOfBuffer(const char16_t* aChars, + mozilla::MallocSizeOf aMallocSizeOf) const override; + }; + struct DynamicAtomExternalString : public JSExternalStringCallbacks { + void finalize(char16_t* aChars) const override; + size_t sizeOfBuffer(const char16_t* aChars, + mozilla::MallocSizeOf aMallocSizeOf) const override; + }; + static const LiteralExternalString sLiteralExternalString; + static const DOMStringExternalString sDOMStringExternalString; + static const DynamicAtomExternalString sDynamicAtomExternalString; + + XPCStringConvert() = delete; +}; + +namespace xpc { + +// If these functions return false, then an exception will be set on cx. +bool Base64Encode(JSContext* cx, JS::Handle<JS::Value> val, + JS::MutableHandle<JS::Value> out); +bool Base64Decode(JSContext* cx, JS::Handle<JS::Value> val, + JS::MutableHandle<JS::Value> out); + +/** + * Convert an nsString to jsval, returning true on success. + * Note, the ownership of the string buffer may be moved from str to rval. + * If that happens, str will point to an empty string after this call. + */ +bool NonVoidStringToJsval(JSContext* cx, nsAString& str, + JS::MutableHandle<JS::Value> rval); +inline bool StringToJsval(JSContext* cx, nsAString& str, + JS::MutableHandle<JS::Value> rval) { + // From the T_ASTRING case in XPCConvert::NativeData2JS. + if (str.IsVoid()) { + rval.setNull(); + return true; + } + return NonVoidStringToJsval(cx, str, rval); +} + +inline bool NonVoidStringToJsval(JSContext* cx, const nsAString& str, + JS::MutableHandle<JS::Value> rval) { + nsString mutableCopy; + if (!mutableCopy.Assign(str, mozilla::fallible)) { + JS_ReportOutOfMemory(cx); + return false; + } + return NonVoidStringToJsval(cx, mutableCopy, rval); +} + +inline bool StringToJsval(JSContext* cx, const nsAString& str, + JS::MutableHandle<JS::Value> rval) { + nsString mutableCopy; + if (!mutableCopy.Assign(str, mozilla::fallible)) { + JS_ReportOutOfMemory(cx); + return false; + } + return StringToJsval(cx, mutableCopy, rval); +} + +/** + * As above, but for mozilla::dom::DOMString. + */ +inline bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str, + JS::MutableHandle<JS::Value> rval) { + if (str.IsEmpty()) { + rval.set(JS_GetEmptyStringValue(cx)); + return true; + } + + if (str.HasStringBuffer()) { + uint32_t length = str.StringBufferLength(); + nsStringBuffer* buf = str.StringBuffer(); + bool shared; + if (!XPCStringConvert::StringBufferToJSVal(cx, buf, length, rval, + &shared)) { + return false; + } + if (shared) { + // JS now needs to hold a reference to the buffer + str.RelinquishBufferOwnership(); + } + return true; + } + + if (str.HasLiteral()) { + return XPCStringConvert::StringLiteralToJSVal(cx, str.Literal(), + str.LiteralLength(), rval); + } + + if (str.HasAtom()) { + return XPCStringConvert::DynamicAtomToJSVal(cx, str.Atom(), rval); + } + + // It's an actual XPCOM string + return NonVoidStringToJsval(cx, str.AsAString(), rval); +} + +MOZ_ALWAYS_INLINE +bool StringToJsval(JSContext* cx, mozilla::dom::DOMString& str, + JS::MutableHandle<JS::Value> rval) { + if (str.IsNull()) { + rval.setNull(); + return true; + } + return NonVoidStringToJsval(cx, str, rval); +} + +mozilla::BasePrincipal* GetRealmPrincipal(JS::Realm* realm); + +void NukeAllWrappersForRealm(JSContext* cx, JS::Realm* realm, + js::NukeReferencesToWindow nukeReferencesToWindow = + js::NukeWindowReferences); + +void SetLocationForGlobal(JSObject* global, const nsACString& location); +void SetLocationForGlobal(JSObject* global, nsIURI* locationURI); + +// ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member +// of JS::ZoneStats. +class ZoneStatsExtras { + public: + ZoneStatsExtras() = default; + + nsCString pathPrefix; + + private: + ZoneStatsExtras(const ZoneStatsExtras& other) = delete; + ZoneStatsExtras& operator=(const ZoneStatsExtras& other) = delete; +}; + +// ReportJSRuntimeExplicitTreeStats will expect this in the |extra| member +// of JS::RealmStats. +class RealmStatsExtras { + public: + RealmStatsExtras() = default; + + nsCString jsPathPrefix; + nsCString domPathPrefix; + nsCOMPtr<nsIURI> location; + + private: + RealmStatsExtras(const RealmStatsExtras& other) = delete; + RealmStatsExtras& operator=(const RealmStatsExtras& other) = delete; +}; + +// This reports all the stats in |rtStats| that belong in the "explicit" tree, +// (which isn't all of them). +// @see ZoneStatsExtras +// @see RealmStatsExtras +void ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats, + const nsACString& rtPath, + nsIHandleReportCallback* handleReport, + nsISupports* data, bool anonymize, + size_t* rtTotal = nullptr); + +/** + * Throws an exception on cx and returns false. + */ +bool Throw(JSContext* cx, nsresult rv); + +/** + * Returns the nsISupports native behind a given reflector (either DOM or + * XPCWN). If a non-reflector object is passed in, null will be returned. + * + * This function will not correctly handle Window or Location objects behind + * cross-compartment wrappers: it will return null. If you care about getting + * non-null for Window or Location, use ReflectorToISupportsDynamic. + */ +already_AddRefed<nsISupports> ReflectorToISupportsStatic(JSObject* reflector); + +/** + * Returns the nsISupports native behind a given reflector (either DOM or + * XPCWN). If a non-reflector object is passed in, null will be returned. + * + * The JSContext argument represents the Realm that's asking for the + * nsISupports. This is needed to properly handle Window and Location objects, + * which do dynamic security checks. + */ +already_AddRefed<nsISupports> ReflectorToISupportsDynamic(JSObject* reflector, + JSContext* cx); + +/** + * Singleton scopes for stuff that really doesn't fit anywhere else. + * + * If you find yourself wanting to use these compartments, you're probably doing + * something wrong. Callers MUST consult with the XPConnect module owner before + * using this compartment. If you don't, bholley will hunt you down. + */ +JSObject* UnprivilegedJunkScope(); + +JSObject* UnprivilegedJunkScope(const mozilla::fallible_t&); + +bool IsUnprivilegedJunkScope(JSObject*); + +/** + * This will generally be the shared JSM global, but callers should not depend + * on that fact. + */ +JSObject* PrivilegedJunkScope(); + +/** + * Shared compilation scope for XUL prototype documents and XBL + * precompilation. + */ +JSObject* CompilationScope(); + +/** + * Returns the nsIGlobalObject corresponding to |obj|'s JS global. |obj| must + * not be a cross-compartment wrapper: CCWs are not associated with a single + * global. + */ +nsIGlobalObject* NativeGlobal(JSObject* obj); + +/** + * Returns the nsIGlobalObject corresponding to |cx|'s JS global. Must not be + * called when |cx| is not in a Realm. + */ +nsIGlobalObject* CurrentNativeGlobal(JSContext* cx); + +/** + * If |aObj| is a window, returns the associated nsGlobalWindow. + * Otherwise, returns null. + */ +nsGlobalWindowInner* WindowOrNull(JSObject* aObj); + +/** + * If |aObj| has a window for a global, returns the associated nsGlobalWindow. + * Otherwise, returns null. Note: aObj must not be a cross-compartment wrapper + * because CCWs are not associated with a single global/realm. + */ +nsGlobalWindowInner* WindowGlobalOrNull(JSObject* aObj); + +/** + * If |aObj| is a Sandbox object associated with a DOMWindow via a + * sandboxPrototype, then return that DOMWindow. + * |aCx| is used for checked unwrapping of the Window. + */ +nsGlobalWindowInner* SandboxWindowOrNull(JSObject* aObj, JSContext* aCx); + +/** + * If |cx| is in a realm whose global is a window, returns the associated + * nsGlobalWindow. Otherwise, returns null. + */ +nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx); + +class MOZ_RAII AutoScriptActivity { + bool mActive; + bool mOldValue; + + public: + explicit AutoScriptActivity(bool aActive); + ~AutoScriptActivity(); +}; + +// This function may be used off-main-thread, in which case it is benignly +// racey. +bool ShouldDiscardSystemSource(); + +void SetPrefableRealmOptions(JS::RealmOptions& options); +void SetPrefableContextOptions(JS::ContextOptions& options); + +class ErrorBase { + public: + nsString mErrorMsg; + nsString mFileName; + uint32_t mSourceId; + uint32_t mLineNumber; + uint32_t mColumn; + + ErrorBase() : mSourceId(0), mLineNumber(0), mColumn(0) {} + + void Init(JSErrorBase* aReport); + + void AppendErrorDetailsTo(nsCString& error); +}; + +class ErrorNote : public ErrorBase { + public: + void Init(JSErrorNotes::Note* aNote); + + // Produce an error event message string from the given JSErrorNotes::Note. + // This may produce an empty string if aNote doesn't have a message + // attached. + static void ErrorNoteToMessageString(JSErrorNotes::Note* aNote, + nsAString& aString); + + // Log the error note to the stderr. + void LogToStderr(); +}; + +class ErrorReport : public ErrorBase { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport); + + nsTArray<ErrorNote> mNotes; + + nsCString mCategory; + nsString mSourceLine; + nsString mErrorMsgName; + uint64_t mWindowID; + bool mIsWarning; + bool mIsMuted; + bool mIsPromiseRejection; + + ErrorReport() + : mWindowID(0), + mIsWarning(false), + mIsMuted(false), + mIsPromiseRejection(false) {} + + void Init(JSErrorReport* aReport, const char* aToStringResult, bool aIsChrome, + uint64_t aWindowID); + void Init(JSContext* aCx, mozilla::dom::Exception* aException, bool aIsChrome, + uint64_t aWindowID); + + // Log the error report to the console. Which console will depend on the + // window id it was initialized with. + void LogToConsole(); + // Log to console, using the given stack object (which should be a stack of + // the sort that JS::CaptureCurrentStack produces). aStack is allowed to be + // null. If aStack is non-null, aStackGlobal must be a non-null global + // object that's same-compartment with aStack. Note that aStack might be a + // CCW. + void LogToConsoleWithStack(nsGlobalWindowInner* aWin, + JS::Handle<mozilla::Maybe<JS::Value>> aException, + JS::Handle<JSObject*> aStack, + JS::Handle<JSObject*> aStackGlobal); + + // Produce an error event message string from the given JSErrorReport. Note + // that this may produce an empty string if aReport doesn't have a + // message attached. + static void ErrorReportToMessageString(JSErrorReport* aReport, + nsAString& aString); + + // Log the error report to the stderr. + void LogToStderr(); + + bool IsWarning() const { return mIsWarning; }; + + private: + ~ErrorReport() = default; +}; + +void DispatchScriptErrorEvent(nsPIDOMWindowInner* win, + JS::RootingContext* rootingCx, + xpc::ErrorReport* xpcReport, + JS::Handle<JS::Value> exception, + JS::Handle<JSObject*> exceptionStack); + +// Get a stack (as stackObj outparam) of the sort that can be passed to +// xpc::ErrorReport::LogToConsoleWithStack from the given exception value. Can +// be nullptr if the exception value doesn't have an associated stack, and if +// there is no stack supplied by the JS engine in exceptionStack. The +// returned stack, if any, may also not be in the same compartment as +// exceptionValue. +// +// The "win" argument passed in here should be the same as the window whose +// WindowID() is used to initialize the xpc::ErrorReport. This may be null, of +// course. If it's not null, this function may return a null stack object if +// the window is far enough gone, because in those cases we don't want to have +// the stack in the console message keeping the window alive. +// +// If this function sets stackObj to a non-null value, stackGlobal is set to +// either the JS exception object's global or the global of the SavedFrame we +// got from a DOM or XPConnect exception. In all cases, stackGlobal is an +// unwrapped global object and is same-compartment with stackObj. +void FindExceptionStackForConsoleReport( + nsPIDOMWindowInner* win, JS::Handle<JS::Value> exceptionValue, + JS::Handle<JSObject*> exceptionStack, JS::MutableHandle<JSObject*> stackObj, + JS::MutableHandle<JSObject*> stackGlobal); + +// Return a name for the realm. +// This function makes reasonable efforts to make this name both mostly +// human-readable and unique. However, there are no guarantees of either +// property. +extern void GetCurrentRealmName(JSContext*, nsCString& name); + +nsCString GetFunctionName(JSContext* cx, JS::Handle<JSObject*> obj); + +void AddGCCallback(xpcGCCallback cb); +void RemoveGCCallback(xpcGCCallback cb); + +// We need an exact page size only if we run the binary in automation. +#if defined(XP_DARWIN) && defined(__aarch64__) +const size_t kAutomationPageSize = 16384; +#else +const size_t kAutomationPageSize = 4096; +#endif + +struct alignas(kAutomationPageSize) ReadOnlyPage final { + bool mNonLocalConnectionsDisabled = false; + bool mTurnOffAllSecurityPref = false; + + static void Init(); + +#ifdef MOZ_TSAN + // TSan is confused by write access to read-only section. + static ReadOnlyPage sInstance; +#else + static const volatile ReadOnlyPage sInstance; +#endif + + private: + constexpr ReadOnlyPage() = default; + ReadOnlyPage(const ReadOnlyPage&) = delete; + void operator=(const ReadOnlyPage&) = delete; + + static void Write(const volatile bool* aPtr, bool aValue); +}; + +inline bool AreNonLocalConnectionsDisabled() { + return ReadOnlyPage::sInstance.mNonLocalConnectionsDisabled; +} + +inline bool IsInAutomation() { + if (!ReadOnlyPage::sInstance.mTurnOffAllSecurityPref) { + return false; + } + MOZ_RELEASE_ASSERT(AreNonLocalConnectionsDisabled()); + return true; +} + +void InitializeJSContext(); + +/** + * Extract the native nsID object from a JS ID, IfaceID, ClassID, or ContractID + * value. + * + * Returns 'Nothing()' if 'aVal' does is not one of the supported ID types. + */ +mozilla::Maybe<nsID> JSValue2ID(JSContext* aCx, JS::Handle<JS::Value> aVal); + +/** + * Reflect an ID into JS + */ +bool ID2JSValue(JSContext* aCx, const nsID& aId, + JS::MutableHandle<JS::Value> aVal); + +/** + * Reflect an IfaceID into JS + * + * This object will expose constants from the selected interface, and support + * 'instanceof', in addition to the other methods available on JS ID objects. + * + * Use 'xpc::JSValue2ID' to unwrap JS::Values created with this function. + */ +bool IfaceID2JSValue(JSContext* aCx, const nsXPTInterfaceInfo& aInfo, + JS::MutableHandle<JS::Value> aVal); + +/** + * Reflect a ContractID into JS + * + * This object will expose 'getService' and 'createInstance' methods in addition + * to the other methods available on nsID objects. + * + * Use 'xpc::JSValue2ID' to unwrap JS::Values created with this function. + */ +bool ContractID2JSValue(JSContext* aCx, JSString* aContract, + JS::MutableHandle<JS::Value> aVal); + +class JSStackFrameBase { + public: + virtual void Clear() = 0; +}; + +void RegisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame); +void UnregisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame); +void NukeJSStackFrames(JS::Realm* aRealm); + +// Check whether the given jsid is a property name (string or symbol) whose +// value can be gotten cross-origin. Cross-origin gets always return undefined +// as the value, unless the Xray actually provides a different value. +bool IsCrossOriginWhitelistedProp(JSContext* cx, + JS::Handle<JS::PropertyKey> id); + +// Appends to props the jsids for property names (strings or symbols) whose +// value can be gotten cross-origin. +bool AppendCrossOriginWhitelistedPropNames( + JSContext* cx, JS::MutableHandle<JS::StackGCVector<JS::PropertyKey>> props); +} // namespace xpc + +namespace mozilla { +namespace dom { + +/** + * This is used to prevent UA widget code from directly creating and adopting + * nodes via the content document, since they should use the special + * create-and-insert apis instead. + */ +bool IsNotUAWidget(JSContext* cx, JSObject* /* unused */); + +/** + * A test for whether WebIDL methods that should only be visible to + * chrome, XBL scopes, or UA Widget scopes. + */ +bool IsChromeOrUAWidget(JSContext* cx, JSObject* /* unused */); + +/** + * Same as IsChromeOrUAWidget but can be used in worker threads as well. + */ +bool ThreadSafeIsChromeOrUAWidget(JSContext* cx, JSObject* obj); + +} // namespace dom + +/** + * Fill the given vector with the buildid. + */ +bool GetBuildId(JS::BuildIdCharVector* aBuildID); + +} // namespace mozilla + +#endif diff --git a/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp b/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp new file mode 100644 index 0000000000..95982733cd --- /dev/null +++ b/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp @@ -0,0 +1,162 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcrtfuzzing/xpcrtfuzzing.h" + +#include "mozilla/Assertions.h" // MOZ_CRASH +#include "mozilla/Utf8.h" // mozilla::Utf8Unit + +#include <stdio.h> // fflush, fprintf, fputs + +#include "FuzzingInterface.h" +#include "jsapi.h" + +#include "js/CompilationAndEvaluation.h" // JS::Evaluate +#include "js/CompileOptions.h" // JS::CompileOptions +#include "js/Conversions.h" // JS::Conversions +#include "js/ErrorReport.h" // JS::PrintError +#include "js/Exception.h" // JS::StealPendingExceptionStack +#include "js/experimental/TypedData.h" // JS_GetUint8ClampedArrayData, JS_NewUint8ClampedArray +#include "js/PropertyAndElement.h" // JS_SetProperty, JS_HasOwnProperty +#include "js/RootingAPI.h" // JS::Rooted +#include "js/SourceText.h" // JS::Source{Ownership,Text} +#include "js/Value.h" // JS::Value + +using mozilla::dom::AutoJSAPI; + +static AutoJSAPI* gJsapi = nullptr; +static std::string gFuzzModuleName; + +static void CrashOnPendingException() { + if (gJsapi->HasException()) { + gJsapi->ReportException(); + + MOZ_CRASH("Unhandled exception from JS runtime!"); + } +} + +int FuzzXPCRuntimeStart(AutoJSAPI* jsapi, int* argc, char*** argv, + LibFuzzerDriver fuzzerDriver) { + gFuzzModuleName = getenv("FUZZER"); + gJsapi = jsapi; + + int ret = FuzzXPCRuntimeInit(); + if (ret) { + fprintf(stderr, "Fuzzing Interface: Error: Initialize callback failed\n"); + return ret; + } + + ret = fuzzerDriver(argc, argv, FuzzXPCRuntimeFuzz); + if (!ret) { + fprintf(stdout, "Trying to shutdown!\n"); + int shutdown = FuzzXPCRuntimeShutdown(); + if (shutdown) { + fprintf(stderr, "Fuzzing Interface: Error: Shutdown callback failed\n"); + return shutdown; + } + } + + return ret; +} + +int FuzzXPCRuntimeInit() { + JSContext* cx = gJsapi->cx(); + JS::Rooted<JS::Value> v(cx); + JS::CompileOptions opts(cx); + + // Load the fuzzing module specified in the FUZZER environment variable + JS::EvaluateUtf8Path(cx, opts, gFuzzModuleName.c_str(), &v); + + // Any errors while loading the fuzzing module should be fatal + CrashOnPendingException(); + + return 0; +} + +int FuzzXPCRuntimeFuzz(const uint8_t* buf, size_t size) { + if (!size) { + return 0; + } + + JSContext* cx = gJsapi->cx(); + + JS::Rooted<JSObject*> arr(cx, JS_NewUint8ClampedArray(cx, size)); + if (!arr) { + MOZ_CRASH("OOM"); + } + + do { + JS::AutoCheckCannotGC nogc; + bool isShared; + uint8_t* data = JS_GetUint8ClampedArrayData(arr, &isShared, nogc); + MOZ_RELEASE_ASSERT(!isShared); + memcpy(data, buf, size); + } while (false); + + JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx)); + JS::RootedValue arrVal(cx, JS::ObjectValue(*arr)); + if (!JS_SetProperty(cx, global, "fuzzBuf", arrVal)) { + MOZ_CRASH("JS_SetProperty failed"); + } + + JS::Rooted<JS::Value> v(cx); + JS::CompileOptions opts(cx); + + static const char data[] = "JSFuzzIterate();"; + + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (!srcBuf.init(cx, data, strlen(data), JS::SourceOwnership::Borrowed)) { + return 1; + } + + if (!JS::Evaluate(cx, opts.setFileAndLine(__FILE__, __LINE__), srcBuf, &v) && + !JS_IsExceptionPending(cx)) { + // A return value of `false` without a pending exception indicates + // a timeout as triggered by the `timeout` shell function. + return 1; + } + + // The fuzzing module is required to handle any exceptions + CrashOnPendingException(); + + int32_t ret = 0; + if (!ToInt32(cx, v, &ret)) { + MOZ_CRASH("Must return an int32 compatible return value!"); + } + + return ret; +} + +int FuzzXPCRuntimeShutdown() { + JSContext* cx = gJsapi->cx(); + JS::Rooted<JS::Value> v(cx); + JS::CompileOptions opts(cx); + JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx)); + + bool found = false; + if (JS_HasOwnProperty(cx, global, "JSFuzzShutdown", &found)) { + if (found) { + static const char data[] = "JSFuzzShutdown();"; + JS::SourceText<mozilla::Utf8Unit> srcBuf; + if (!srcBuf.init(cx, data, strlen(data), JS::SourceOwnership::Borrowed)) { + return 1; + } + + if (!JS::Evaluate(cx, opts.setFileAndLine(__FILE__, __LINE__), srcBuf, + &v) && + !JS_IsExceptionPending(cx)) { + // A return value of `false` without a pending exception indicates + // a timeout as triggered by the `timeout` shell function. + return 1; + } + } + } + + // The fuzzing module is required to handle any exceptions + CrashOnPendingException(); + + return 0; +} diff --git a/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.h b/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.h new file mode 100644 index 0000000000..89cdf5996b --- /dev/null +++ b/js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// xpcrtfuzzing.h - Functionality for XPC runtime fuzzing + +#ifndef shell_xpcrtfuzzing_h +#define shell_xpcrtfuzzing_h + +#include "mozilla/dom/ScriptSettings.h" // mozilla::dom::AutoJSAPI +#include "FuzzerRegistry.h" // LibFuzzerDriver + +// This is the entry point of the XPC runtime fuzzing code from the XPC shell +int FuzzXPCRuntimeStart(mozilla::dom::AutoJSAPI* jsapi, int* argc, char*** argv, + LibFuzzerDriver); + +// These are the traditional libFuzzer-style functions for initialization +// and fuzzing iteration. +int FuzzXPCRuntimeInit(); +int FuzzXPCRuntimeFuzz(const uint8_t* buf, size_t size); +int FuzzXPCRuntimeShutdown(); + +#endif /* shell_xpcrtfuzzing_h */ diff --git a/js/xpconnect/tests/browser/browser.ini b/js/xpconnect/tests/browser/browser.ini new file mode 100644 index 0000000000..86c28d0ad8 --- /dev/null +++ b/js/xpconnect/tests/browser/browser.ini @@ -0,0 +1,17 @@ +[DEFAULT] +support-files = + browser_consoleStack.html + browser_deadObjectOnUnload.html + browser_realm_key_object_prototype_top.html + browser_realm_key_object_prototype_frame.html + browser_realm_key_promise_top.html + browser_realm_key_promise_frame.html + browser_promise_userInteractionHandling.html +[browser_dead_object.js] +[browser_exception_leak.js] +[browser_freeze_builtins.js] +[browser_parent_process_hang_telemetry.js] +[browser_realm_key_and_document_domain.js] +[browser_promise_userInteractionHandling.js] +[browser_import_mapped_jsm.js] +[browser_weak_xpcwjs.js] diff --git a/js/xpconnect/tests/browser/browser_consoleStack.html b/js/xpconnect/tests/browser/browser_consoleStack.html new file mode 100644 index 0000000000..37bfdb32f6 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_consoleStack.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1471989 +--> +<head> + <meta charset="utf-8"> + <title>Test page for Bug 1471989</title> +</head> +<body onUnload="onUnload();"> +<p><span id="samplepage">sample page</span></p> +<script type="application/javascript"> + // Get something sent to ConsoleStorageAPI that has a stack. + console.trace("whatever"); + + function onUnload() { + console.log('in unload'); + } +</script> +</body> +</html> diff --git a/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html b/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html new file mode 100644 index 0000000000..ceb40b20b6 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1242643 +--> +<head> + <meta charset="utf-8"> + <title>Test page for Bug 1242643</title> +</head> +<body onUnload="onUnload();"> +<p><span id="samplepage">sample page</span></p> +<script type="application/javascript"> + function onUnload() { + console.log('in unload'); + } +</script> +</body> +</html> diff --git a/js/xpconnect/tests/browser/browser_dead_object.js b/js/xpconnect/tests/browser/browser_dead_object.js new file mode 100644 index 0000000000..b8b2dd0688 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_dead_object.js @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +// For bug 773980, test that Components.utils.isDeadWrapper works as expected. + +add_task(async function test() { + const url = + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html"; + let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + let browser = gBrowser.selectedBrowser; + let innerWindowId = browser.innerWindowID; + let contentDocDead = await ContentTask.spawn( + browser, + { innerWindowId }, + async function (args) { + let doc = content.document; + let { TestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TestUtils.sys.mjs" + ); + let promise = TestUtils.topicObserved( + "inner-window-nuked", + (subject, data) => { + let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; + return id == args.innerWindowId; + } + ); + content.location = "http://mochi.test:8888/"; + await promise; + return Cu.isDeadWrapper(doc); + } + ); + is(contentDocDead, true, "wrapper is dead"); + BrowserTestUtils.removeTab(newTab); +}); diff --git a/js/xpconnect/tests/browser/browser_exception_leak.js b/js/xpconnect/tests/browser/browser_exception_leak.js new file mode 100644 index 0000000000..be860355bc --- /dev/null +++ b/js/xpconnect/tests/browser/browser_exception_leak.js @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +// For bug 1471989, test that an exception saved by chrome code can't leak the page. + +add_task(async function test() { + const url = + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_consoleStack.html"; + let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + let browser = gBrowser.selectedBrowser; + let innerWindowId = browser.innerWindowID; + + let stackTraceEmpty = await ContentTask.spawn( + browser, + { innerWindowId }, + async function (args) { + let { TestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TestUtils.sys.mjs" + ); + let { Assert } = ChromeUtils.importESModule( + "resource://testing-common/Assert.sys.mjs" + ); + + const ConsoleAPIStorage = Cc[ + "@mozilla.org/consoleAPI-storage;1" + ].getService(Ci.nsIConsoleAPIStorage); + let consoleEvents = ConsoleAPIStorage.getEvents(args.innerWindowId); + Assert.equal( + consoleEvents.length, + 1, + "Should only be one console event for the window" + ); + + // Intentionally hold a reference to the console event. + let leakedConsoleEvent = consoleEvents[0]; + + // XXX I think this is intentionally leaking |doc|. + // eslint-disable-next-line no-unused-vars + let doc = content.document; + + let promise = TestUtils.topicObserved( + "inner-window-nuked", + (subject, data) => { + let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; + return id == args.innerWindowId; + } + ); + content.location = "http://mochi.test:8888/"; + await promise; + + // This string should be empty. For that to happen, two things + // need to be true: + // + // a) ConsoleCallData::mStack is not null. This means that the + // stack trace was not reified before the page was nuked. If it + // was, then the correct |filename| value would be stored on the + // object. (This is not a problem, except that it stops us from + // testing the next condition.) + // + // b) ConsoleData::mStack.mStack is null. This means that the + // JSStackFrame is keeping alive the JS object in the page after + // the page was nuked, which leaks the page. + return leakedConsoleEvent.stacktrace[0].filename; + } + ); + + is( + stackTraceEmpty, + "", + "JSStackFrame shouldn't leak mStack after window nuking" + ); + + BrowserTestUtils.removeTab(newTab); +}); diff --git a/js/xpconnect/tests/browser/browser_freeze_builtins.js b/js/xpconnect/tests/browser/browser_freeze_builtins.js new file mode 100644 index 0000000000..905224094e --- /dev/null +++ b/js/xpconnect/tests/browser/browser_freeze_builtins.js @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +function checkCtor(global, name, description) { + ok(Object.isFrozen(global[name]), `${description} ${name} is frozen`); + ok( + Object.isSealed(global[name].prototype), + `${description} ${name}.prototype is sealed` + ); + + let descr = Object.getOwnPropertyDescriptor(global, name); + ok(!descr.configurable, `${description} ${name} should be non-configurable`); + ok(!descr.writable, `${description} ${name} should not be writable`); +} + +function checkGlobal(global, description) { + checkCtor(global, "Object", description); + checkCtor(global, "Array", description); + checkCtor(global, "Function", description); +} + +add_task(async function () { + let systemGlobal = Cu.getGlobalForObject(Services); + checkGlobal(systemGlobal, "system global"); +}); diff --git a/js/xpconnect/tests/browser/browser_import_mapped_jsm.js b/js/xpconnect/tests/browser/browser_import_mapped_jsm.js new file mode 100644 index 0000000000..385f4e33c0 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_import_mapped_jsm.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +"use strict"; + +// Verify Cu.import and ChromeUtils.import works for JSM URL even after +// ESM-ification, and any not-in-tree consumer doesn't break. +// +// This test modules that's commonly used by not-in-tree consumers, such as +// privilege extensions and AutoConfigs. + +const JSMs = [ + "resource:///modules/AboutNewTab.jsm", + "resource:///modules/CustomizableUI.jsm", + "resource:///modules/UITour.jsm", + "resource:///modules/distribution.js", + "resource://gre/modules/AddonManager.jsm", + "resource://gre/modules/AppConstants.jsm", + "resource://gre/modules/AsyncShutdown.jsm", + "resource://gre/modules/Console.jsm", + "resource://gre/modules/FileUtils.jsm", + "resource://gre/modules/LightweightThemeManager.jsm", + "resource://gre/modules/NetUtil.jsm", + "resource://gre/modules/PlacesUtils.jsm", + "resource://gre/modules/PluralForm.jsm", + "resource://gre/modules/PrivateBrowsingUtils.jsm", + "resource://gre/modules/Timer.jsm", + "resource://gre/modules/XPCOMUtils.jsm", + "resource://gre/modules/addons/XPIDatabase.jsm", + "resource://gre/modules/addons/XPIProvider.jsm", + "resource://gre/modules/addons/XPIInstall.jsm", + "resource:///modules/BrowserWindowTracker.jsm", +]; + +if (AppConstants.platform === "win") { + JSMs.push("resource:///modules/WindowsJumpLists.jsm"); +} + +add_task(async function test_chrome_utils_import() { + for (const file of JSMs) { + try { + ChromeUtils.import(file); + ok(true, `Imported ${file}`); + } catch (e) { + ok(false, `Failed to import ${file}`); + } + } +}); + +add_task(async function test_cu_import() { + for (const file of JSMs) { + try { + // eslint-disable-next-line mozilla/use-chromeutils-import + Cu.import(file, {}); + ok(true, `Imported ${file}`); + } catch (e) { + ok(false, `Failed to import ${file}`); + } + } +}); diff --git a/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js b/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js new file mode 100644 index 0000000000..f9b325c216 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js @@ -0,0 +1,60 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that we record hangs in the parent process in telemetry events. + * This test would be an xpcshell test except xpcshell does not think + * it is running e10s (see bug 1568333). + */ +add_task(async function test_browser_hang() { + // Trip some testing code to ensure we can test this. Sadly, this is a magic + // number corresponding to code in XPCJSContext.cpp + await SpecialPowers.pushPrefEnv({ + set: [["dom.max_chrome_script_run_time", 2]], + }); + await SpecialPowers.promiseTimeout(0); + + // Hang for 1.2 seconds. + let now = Date.now(); + let i = 0; + info("Start loop"); + while (Date.now() - now < 2500) { + // The system clock can go backwards. Don't time out the test: + if (Date.now() - now < 0) { + info("Yikes, the system clock changed while running this test."); + now = Date.now(); + } + i++; + } + let duration = (Date.now() - now) / 1000; + info("Looped " + i + " iterations."); + + let events; + await TestUtils.waitForCondition(() => { + events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_ALL_CHANNELS, + false + ); + return events.parent?.some(e => e[1] == "slow_script_warning"); + }, "Should find an event after doing this.").catch(e => ok(false, e)); + events = events.parent || []; + let event = events.find(e => e[1] == "slow_script_warning"); + ok(event, "Should have registered an event."); + if (event) { + is(event[3], "browser", "Should register as browser hang."); + let args = event[5]; + is(args.uri_type, "browser", "Should register browser uri type."); + Assert.greater( + duration + 1, + parseFloat(args.hang_duration), + "hang duration should not exaggerate." + ); + Assert.less( + duration - 1, + parseFloat(args.hang_duration), + "hang duration should not undersell." + ); + } +}); diff --git a/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html new file mode 100644 index 0000000000..72f8ef3ee1 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test UserInteractionHandling propagation</title> +</head> +<body> +<button id="button">Meow</button> +</body> +</html> diff --git a/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js new file mode 100644 index 0000000000..612471be53 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +"use strict"; + +add_task(async function test_explicit_object_prototype() { + const url = + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html"; + await BrowserTestUtils.withNewTab(url, async browser => { + await SpecialPowers.spawn(browser, [], async () => { + const DOMWindowUtils = EventUtils._getDOMWindowUtils(content.window); + is( + DOMWindowUtils.isHandlingUserInput, + false, + "not yet handling user input" + ); + const button = content.document.getElementById("button"); + + let resolve; + const p = new Promise(r => { + resolve = r; + }); + + button.addEventListener("click", () => { + is(DOMWindowUtils.isHandlingUserInput, true, "handling user input"); + content.document.hasStorageAccess().then(() => { + is( + DOMWindowUtils.isHandlingUserInput, + true, + "still handling user input" + ); + Promise.resolve().then(() => { + is( + DOMWindowUtils.isHandlingUserInput, + false, + "no more handling user input" + ); + resolve(); + }); + }); + }); + + EventUtils.synthesizeMouseAtCenter(button, {}, content.window); + + await p; + }); + }); +}); diff --git a/js/xpconnect/tests/browser/browser_realm_key_and_document_domain.js b/js/xpconnect/tests/browser/browser_realm_key_and_document_domain.js new file mode 100644 index 0000000000..2f6910cd5d --- /dev/null +++ b/js/xpconnect/tests/browser/browser_realm_key_and_document_domain.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +"use strict"; + +async function test_document(url) { + await BrowserTestUtils.withNewTab(url, async function (browser) { + let result = await ContentTask.spawn(browser, {}, async function () { + let result = content.document.getElementById("result"); + return result.innerText; + }); + is(result, "OK", "test succeeds"); + }); +} + +add_task(async function test_explicit_object_prototype() { + await test_document( + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_realm_key_object_prototype_top.html" + ); +}); + +add_task(async function test_implicit_object_prototype() { + await test_document( + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_realm_key_promise_top.html" + ); +}); diff --git a/js/xpconnect/tests/browser/browser_realm_key_object_prototype_frame.html b/js/xpconnect/tests/browser/browser_realm_key_object_prototype_frame.html new file mode 100644 index 0000000000..5f3c0b5c2c --- /dev/null +++ b/js/xpconnect/tests/browser/browser_realm_key_object_prototype_frame.html @@ -0,0 +1,11 @@ +<script type="text/javascript"> +// Access to the top-level window property before getting access. +// This will create an entry in cross-origin realm map. +try { + window.top.Object; +} catch (e) {} + +document.domain = "mochi.test"; + +window.top.check(); +</script> diff --git a/js/xpconnect/tests/browser/browser_realm_key_object_prototype_top.html b/js/xpconnect/tests/browser/browser_realm_key_object_prototype_top.html new file mode 100644 index 0000000000..fdd342ff59 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_realm_key_object_prototype_top.html @@ -0,0 +1,12 @@ +<script type="text/javascript"> +document.domain = "mochi.test"; +function check() { + // Ensure frame's Object.prototype is accessible. + if (document.getElementById("frame").contentWindow.Object.prototype.toString.call({}) == "[object Object]") { + document.getElementById("result").textContent = "OK"; + } +} +</script> +<iframe id="frame" src="http://test2.mochi.test:8888/browser/js/xpconnect/tests/browser/browser_realm_key_object_prototype_frame.html"> +</iframe> +<span id="result"></span> diff --git a/js/xpconnect/tests/browser/browser_realm_key_promise_frame.html b/js/xpconnect/tests/browser/browser_realm_key_promise_frame.html new file mode 100644 index 0000000000..dfb08085cf --- /dev/null +++ b/js/xpconnect/tests/browser/browser_realm_key_promise_frame.html @@ -0,0 +1,17 @@ +<script type="text/javascript"> +// Access to the top-level window property before getting access. +// This will create an entry in cross-origin realm map. +try { + window.top.P; +} catch (e) {} + +document.domain = "mochi.test"; + +// Ensure that frame's Object.prototype is accessible from top-level frame +// when getting incumbent global object inside Promise handling. +window.top.P.then(v => { + if (v == 10) { + window.top.document.getElementById("result").textContent = "OK"; + } +}); +</script> diff --git a/js/xpconnect/tests/browser/browser_realm_key_promise_top.html b/js/xpconnect/tests/browser/browser_realm_key_promise_top.html new file mode 100644 index 0000000000..fe31fb6182 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_realm_key_promise_top.html @@ -0,0 +1,7 @@ +<script type="text/javascript"> +document.domain = "mochi.test"; +window.P = new Promise(r => r(10)); +</script> +<iframe src="http://test2.mochi.test:8888/browser/js/xpconnect/tests/browser/browser_realm_key_promise_frame.html"> +</iframe> +<span id="result"></span> diff --git a/js/xpconnect/tests/browser/browser_weak_xpcwjs.js b/js/xpconnect/tests/browser/browser_weak_xpcwjs.js new file mode 100644 index 0000000000..b8c8c2f85d --- /dev/null +++ b/js/xpconnect/tests/browser/browser_weak_xpcwjs.js @@ -0,0 +1,238 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Some basic tests of the lifetime of an XPCWJS with a weak reference. + +// Create a weak reference, with a single-element weak map. +let make_weak_ref = function (obj) { + let m = new WeakMap(); + m.set(obj, {}); + return m; +}; + +// Check to see if a weak reference is dead. +let weak_ref_dead = function (r) { + return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length; +}; + +add_task(async function gc_wwjs() { + // This subtest checks that a WJS with only a weak reference to it gets + // cleaned up, if its JS object is garbage, after just a GC. + // For the browser, this probably isn't important, but tests seem to rely + // on it. + const TEST_PREF = "wjs.pref1"; + let wjs_weak_ref = null; + let observed_count = 0; + + { + Services.prefs.clearUserPref(TEST_PREF); + + // Create the observer object. + let observer1 = { + QueryInterface: ChromeUtils.generateQI(["nsISupportsWeakReference"]), + observe() { + observed_count += 1; + info(TEST_PREF + " pref observer."); + }, + }; + + // Register the weak observer. + Services.prefs.addObserver(TEST_PREF, observer1, true); + + // Invoke the observer to make sure it is doing something. + info("Flipping the pref " + TEST_PREF); + Services.prefs.setBoolPref(TEST_PREF, true); + is(observed_count, 1, "Ran observer1 once after first flip."); + + wjs_weak_ref = make_weak_ref(observer1); + + // Exit the scope, making observer1 garbage. + } + + // Run the GC. + info("Running the GC."); + SpecialPowers.forceGC(); + + // Flip the pref again to make sure that the observer doesn't run. + info("Flipping the pref " + TEST_PREF); + Services.prefs.setBoolPref(TEST_PREF, false); + + is(observed_count, 1, "After GC, don't run the observer."); + ok(weak_ref_dead(wjs_weak_ref), "WJS with weak ref should be freed."); + + Services.prefs.clearUserPref(TEST_PREF); +}); + +add_task(async function alive_wwjs() { + // This subtest checks that a WJS with only a weak reference should not get + // cleaned up if the underlying JS object is held alive (here, via the + // variable |observer2|). + const TEST_PREF = "wjs.pref2"; + let observed_count = 0; + + Services.prefs.clearUserPref(TEST_PREF); + let observer2 = { + QueryInterface: ChromeUtils.generateQI(["nsISupportsWeakReference"]), + observe() { + observed_count += 1; + info(TEST_PREF + " pref observer"); + }, + }; + Services.prefs.addObserver(TEST_PREF, observer2, true); + + Services.prefs.setBoolPref(TEST_PREF, true); + is(observed_count, 1, "Run observer2 once after first flip."); + + await new Promise(resolve => + SpecialPowers.exactGC(() => { + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + + Services.prefs.setBoolPref(TEST_PREF, false); + + is(observed_count, 2, "Run observer2 again after second flip."); + + Services.prefs.removeObserver(TEST_PREF, observer2); + Services.prefs.clearUserPref(TEST_PREF); + + resolve(); + }) + ); +}); + +add_task(async function cc_wwjs() { + // This subtest checks that a WJS with only a weak reference to it, where the + // underlying JS object is part of a garbage cycle, gets cleaned up after a + // cycle collection. It also checks that things held alive by the JS object + // don't end up in an unlinked state, although that's mostly for fun, because + // it is redundant with checking that the JS object gets cleaned up. + const TEST_PREF = "wjs.pref3"; + let wjs_weak_ref = null; + let observed_count = 0; + let canary_count; + + { + Services.prefs.clearUserPref(TEST_PREF); + + // Set up a canary object that lets us detect unlinking. + // (When an nsArrayCC is unlinked, all of the elements are removed.) + // This is needed to distinguish the case where the observer was unlinked + // without removing the weak reference from the case where we did not + // collect the observer at all. + let canary = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + let someString = Cc["@mozilla.org/supports-string;1"].createInstance( + Ci.nsISupportsString + ); + someString.data = "canary"; + canary.appendElement(someString); + canary.appendElement(someString); + is(canary.Count(), 2, "The canary array should have two elements"); + + // Create the observer object. + let observer3 = { + QueryInterface: ChromeUtils.generateQI(["nsISupportsWeakReference"]), + canary, + cycle: new DOMMatrix(), + observe() { + observed_count += 1; + canary_count = this.canary.Count(); + info(TEST_PREF + " pref observer. Canary count: " + canary_count); + }, + }; + + // Set up a cycle between C++ and JS that requires the CC to collect. + // |cycle| is a random WebIDL object that we can set an expando on to + // create a nice clean cycle that doesn't involve any weird XPConnect stuff. + observer3.cycle.backEdge = observer3; + + // Register the weak observer. + Services.prefs.addObserver(TEST_PREF, observer3, true); + + // Invoke the observer to make sure it is doing something. + info("Flipping the pref " + TEST_PREF); + canary_count = -1; + Services.prefs.setBoolPref(TEST_PREF, true); + is( + canary_count, + 2, + "Observer ran with expected value while observer3 is alive." + ); + is(observed_count, 1, "Ran observer3 once after first flip."); + + wjs_weak_ref = make_weak_ref(observer3); + + // Exit the scope, making observer3 and canary garbage. + } + + // Run the GC. This is necessary to mark observer3 gray so the CC + // might consider it to be garbage. This won't free it because it is held + // alive from C++ (namely the DOMMatrix via its expando). + info("Running the GC."); + SpecialPowers.forceGC(); + + // Note: Don't flip the pref here. Doing so will run the observer, which will + // cause it to get marked black again, preventing it from being freed. + // For the same reason, don't call weak_ref_dead(wjs_weak_ref) here. + + // Run the CC. This should detect that the cycle between observer3 and the + // DOMMatrix is garbage, unlinking the DOMMatrix and the canary. Also, the + // weak reference for the WJS for observer3 should get cleared because the + // underlying JS object has been identifed as garbage. You can add logging to + // nsArrayCC's unlink method to see the canary getting unlinked. + info("Running the CC."); + SpecialPowers.forceCC(); + + // Flip the pref again to make sure that the observer doesn't run. + info("Flipping the pref " + TEST_PREF); + canary_count = -1; + Services.prefs.setBoolPref(TEST_PREF, false); + + isnot( + canary_count, + 0, + "After CC, don't run the observer with an unlinked canary." + ); + isnot( + canary_count, + 2, + "After CC, don't run the observer after it is garbage." + ); + is(canary_count, -1, "After CC, don't run the observer."); + is(observed_count, 1, "After CC, don't run the observer."); + + ok( + !weak_ref_dead(wjs_weak_ref), + "WJS with weak ref shouldn't be freed by the CC." + ); + + // Now that the CC has identified observer3 as garbage, running the GC again + // should free it. + info("Running the GC again."); + SpecialPowers.forceGC(); + + ok(weak_ref_dead(wjs_weak_ref), "WJS with weak ref should be freed."); + + info("Flipping the pref " + TEST_PREF); + canary_count = -1; + Services.prefs.setBoolPref(TEST_PREF, true); + + // Note: the original implementation of weak references for WJS fails most of + // the prior canary_count tests, but passes these. + isnot( + canary_count, + 0, + "After GC, don't run the observer with an unlinked canary." + ); + isnot( + canary_count, + 2, + "After GC, don't run the observer after it is garbage." + ); + is(canary_count, -1, "After GC, don't run the observer."); + is(observed_count, 1, "After GC, don't run the observer."); + + Services.prefs.clearUserPref(TEST_PREF); +}); diff --git a/js/xpconnect/tests/browser/moz.build b/js/xpconnect/tests/browser/moz.build new file mode 100644 index 0000000000..67b1ac4bbb --- /dev/null +++ b/js/xpconnect/tests/browser/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +BROWSER_CHROME_MANIFESTS += ["browser.ini"] diff --git a/js/xpconnect/tests/chrome/bug503926.xhtml b/js/xpconnect/tests/chrome/bug503926.xhtml new file mode 100644 index 0000000000..d62a6b575f --- /dev/null +++ b/js/xpconnect/tests/chrome/bug503926.xhtml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=503926 +--> +<window title="Mozilla Bug 503926" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503926" + target="_blank">Mozilla Bug 503926</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + var gWindowUtils = window.windowUtils; + var passed = false; + // eslint-disable-next-line mozilla/use-chromeutils-generateqi + var obj = { QueryInterface() { passed = true; } } + gWindowUtils.xpconnectArgument(obj); + var isDialog = location.hash != '#iframe'; + var outer = Cu.waiveXrays(isDialog ? window.arguments[0] : parent); + outer.ok(passed, "chrome/chrome test passed: " + (isDialog ? "dialog" : "iframe")); + if (isDialog) + close(); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/chrome.ini b/js/xpconnect/tests/chrome/chrome.ini new file mode 100644 index 0000000000..0057d6e193 --- /dev/null +++ b/js/xpconnect/tests/chrome/chrome.ini @@ -0,0 +1,128 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + bug503926.xhtml + file_bug484459.html + file_bug618176.xhtml + file_bug996069.html + file_bug1281071.html + file_discardSystemSource.html + file_empty.html + file_evalInSandbox.html + file_expandosharing.jsm + outoflinexulscript.js + subscript.js + utf8_subscript.js + worker_discardSystemSource.js + !/js/xpconnect/tests/mochitest/bug500931_helper.html + !/js/xpconnect/tests/mochitest/bug571849_helper.html + !/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html + !/js/xpconnect/tests/mochitest/file_bug706301.html + !/js/xpconnect/tests/mochitest/file_bug738244.html + !/js/xpconnect/tests/mochitest/file_bug760131.html + !/js/xpconnect/tests/mochitest/file_bug795275.html + !/js/xpconnect/tests/mochitest/file_bug799348.html + !/js/xpconnect/tests/mochitest/file_bug860494.html + !/js/xpconnect/tests/mochitest/file_documentdomain.html + !/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html + !/js/xpconnect/tests/mochitest/file_empty.html + !/js/xpconnect/tests/mochitest/file_exnstack.html + !/js/xpconnect/tests/mochitest/file_expandosharing.html + !/js/xpconnect/tests/mochitest/file_nodelists.html + !/js/xpconnect/tests/mochitest/file_evalInSandbox.html + !/js/xpconnect/tests/mochitest/file_xrayic.html +prefs = + javascript.options.large_arraybuffers=true + javascript.options.experimental.enable_new_set_methods=false + +[test_APIExposer.xhtml] +[test_bug361111.xhtml] +[test_bug448587.xhtml] +[test_bug484459.xhtml] +skip-if = os == 'win' || os == 'mac' || (os == 'linux' && !debug) # bug 1131110, 1255284 +[test_bug500931.xhtml] +[test_bug503926.xhtml] +[test_bug533596.xhtml] +[test_bug571849.xhtml] +[test_bug610390.xhtml] +[test_bug614757.xhtml] +[test_bug616992.xhtml] +[test_bug618176.xhtml] +[test_bug654370.xhtml] +[test_bug658560.xhtml] +[test_bug658909.xhtml] +[test_bug664689.xhtml] +[test_bug679861.xhtml] +[test_bug706301.xhtml] +[test_bug726949.xhtml] +[test_bug732665.xhtml] +[test_bug738244.xhtml] +[test_bug743843.xhtml] +[test_bug760076.xhtml] +[test_bug760131.html] +[test_bug763343.xhtml] +[test_bug771429.xhtml] +[test_bug773962.xhtml] +[test_bug792280.xhtml] +[test_bug793433.xhtml] +[test_bug795275.xhtml] +[test_bug799348.xhtml] +[test_bug801241.xhtml] +[test_bug812415.xhtml] +[test_bug853283.xhtml] +[test_bug853571.xhtml] +[test_bug858101.xhtml] +[test_bug860494.xhtml] +[test_bug865948.xhtml] +[test_bug866823.xhtml] +[test_bug895340.xhtml] +[test_bug932906.xhtml] +allow_xul_xbl = true +[test_bug996069.xhtml] +[test_bug1041626.xhtml] +[test_bug1042436.xhtml] +[test_bug1065185.html] +[test_bug1074863.html] +[test_bug1092477.xhtml] +[test_bug1124898.html] +[test_bug1126911.html] +[test_bug1281071.xhtml] +[test_bug1390159.xhtml] +[test_bug1430164.html] +[test_bug1516237.html] +[test_chrometoSource.xhtml] +[test_cloneInto.xhtml] +[test_cows.xhtml] +[test_private_field_cows.xhtml] +[test_discardSystemSource.xhtml] +[test_documentdomain.xhtml] +[test_doublewrappedcompartments.xhtml] +[test_evalInSandbox.xhtml] +[test_evalInWindow.xhtml] +[test_exnstack.xhtml] +[test_expandosharing.xhtml] +[test_exposeInDerived.xhtml] +[test_inlineScripts.html] +[test_localstorage_with_nsEp.xhtml] +[test_matches.xhtml] +[test_nodelists.xhtml] +[test_nsScriptErrorWithStack.html] +[test_onGarbageCollection.html] +[test_precisegc.xhtml] +[test_sandboxImport.xhtml] +[test_secureContexts.html] +[test_scriptSettings.xhtml] +[test_scripterror.html] +[test_sharedChromeCompartment.html] +[test_weakmap_keys_preserved.xhtml] +[test_weakmap_keys_preserved2.xhtml] +[test_weakref.xhtml] +[test_windowProxyDeadWrapper.html] +[test_wrappers.xhtml] +[test_xrayic.xhtml] +[test_xrayLargeTypedArray.html] +skip-if = bits == 32 # Large ArrayBuffers not supported on 32-bit. +[test_xrayToJS.xhtml] +[test_bug1530146.html] +support-files = file_bug1530146.html file_bug1530146_inner.html +[test_envChain_event_handler.html] diff --git a/js/xpconnect/tests/chrome/file_bug1281071.html b/js/xpconnect/tests/chrome/file_bug1281071.html new file mode 100644 index 0000000000..2398ce4a57 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug1281071.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<script> + function tryLocationGet() { + var desc = Object.getOwnPropertyDescriptor(window, "location"); + try { + desc.get.call(parent); + return "get succeeded"; + } catch (e) { + return e.message; + } + } +</script> + diff --git a/js/xpconnect/tests/chrome/file_bug1530146.html b/js/xpconnect/tests/chrome/file_bug1530146.html new file mode 100644 index 0000000000..5414ea407d --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug1530146.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<script> + // eslint-disable-next-line no-self-assign + document.domain = document.domain; +</script> +<iframe></iframe> diff --git a/js/xpconnect/tests/chrome/file_bug1530146_inner.html b/js/xpconnect/tests/chrome/file_bug1530146_inner.html new file mode 100644 index 0000000000..db642cf81d --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug1530146_inner.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<script> + var obj = { a: "hello" } +</script> diff --git a/js/xpconnect/tests/chrome/file_bug484459.html b/js/xpconnect/tests/chrome/file_bug484459.html new file mode 100644 index 0000000000..27be5463a2 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug484459.html @@ -0,0 +1,10 @@ +<html> +<head> + <title>helper for bug 484459</title> +</head> +<body> + <script type="application/javascript"> + var x=3; + </script> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/file_bug618176.xhtml b/js/xpconnect/tests/chrome/file_bug618176.xhtml new file mode 100644 index 0000000000..3aea153159 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug618176.xhtml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=618176 +--> +<window title="Mozilla Bug 618176" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start()"> + <label value="Mozilla Bug 618176"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /* global messageManager */ + const TEST_PAGE = Services.io.newURI( + "data:text/html,<script>var a=[1,2,3];</script>Hi" + ); + + const FRAME_SCRIPT = +"data:,addEventListener('pageshow', function() { sendAsyncMessage('test', content.wrappedJSObject.a) }, false);"; + // s/content.wrappedJSObject.a/[ 1, 2, 3]/ and the test passes + + function recvTest(m) { + var a = m.json; + window.arguments[0].is(a.length, 3, "array was serialized and deserialized"); + + messageManager.removeMessageListener("test", recvTest); + finish(); + } + + function start() { + messageManager.addMessageListener("test", recvTest); + messageManager.loadFrameScript(FRAME_SCRIPT, true); + let triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); + setTimeout(function () { + document.getElementById("browser").loadURI(TEST_PAGE, {triggeringPrincipal}); + }, 0); + } + + function finish() { + window.arguments[0].setTimeout(function() { this.done(); }, 0); + window.close(); + } + + ]]></script> + + <browser id="browser" type="content" style="width: 200px; height: 200px;"/> +</window> diff --git a/js/xpconnect/tests/chrome/file_bug996069.html b/js/xpconnect/tests/chrome/file_bug996069.html new file mode 100644 index 0000000000..e4bed07806 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_bug996069.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head></head> +<body> + <script> + if (window.opener && window.opener.finishTest) { + window.opener.finishTest(); + } + </script> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/file_discardSystemSource.html b/js/xpconnect/tests/chrome/file_discardSystemSource.html new file mode 100644 index 0000000000..5dc9e9e7ba --- /dev/null +++ b/js/xpconnect/tests/chrome/file_discardSystemSource.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> +<head> +<script> + function canary() { + // eslint-disable-next-line no-unused-vars + var someBitOfSource = 42; + } + function inner() { + throw new Error("some error"); + } + function throwSomething() { + inner(); + } +</script> +</head> +<body onload="someBitOfSource = 42"> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/file_empty.html b/js/xpconnect/tests/chrome/file_empty.html new file mode 100644 index 0000000000..b3bfe19c0b --- /dev/null +++ b/js/xpconnect/tests/chrome/file_empty.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<html><head><title>test page</title></head><body>there is nothing to see</body></html> diff --git a/js/xpconnect/tests/chrome/file_evalInSandbox.html b/js/xpconnect/tests/chrome/file_evalInSandbox.html new file mode 100644 index 0000000000..fb58f2bb41 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_evalInSandbox.html @@ -0,0 +1 @@ +<html><body><script>document.foo = 'bar';</script></body></html> diff --git a/js/xpconnect/tests/chrome/file_expandosharing.jsm b/js/xpconnect/tests/chrome/file_expandosharing.jsm new file mode 100644 index 0000000000..f680ae20a9 --- /dev/null +++ b/js/xpconnect/tests/chrome/file_expandosharing.jsm @@ -0,0 +1,12 @@ +var EXPORTED_SYMBOLS = ["checkFromJSM"]; + +function checkFromJSM(target, is_op) { + is_op(target.numProp, 42, "Number expando works"); + is_op(target.strProp, "foo", "String expando works"); + // If is_op is todo_is, target.objProp will be undefined. + try { + is_op(target.objProp.bar, "baz", "Object expando works"); + } catch (e) { + is_op(0, 1, "No object expando"); + } +} diff --git a/js/xpconnect/tests/chrome/moz.build b/js/xpconnect/tests/chrome/moz.build new file mode 100644 index 0000000000..d371d3051f --- /dev/null +++ b/js/xpconnect/tests/chrome/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_CHROME_MANIFESTS += ["chrome.ini"] + +TEST_HARNESS_FILES.testing.mochitest.tests.js.xpconnect.tests.chrome += [ + "file_discardSystemSource.html", + "worker_discardSystemSource.js", +] diff --git a/js/xpconnect/tests/chrome/outoflinexulscript.js b/js/xpconnect/tests/chrome/outoflinexulscript.js new file mode 100644 index 0000000000..14b99048e9 --- /dev/null +++ b/js/xpconnect/tests/chrome/outoflinexulscript.js @@ -0,0 +1,5 @@ +// Some unicode characters that must be decoded: +// ……………………………………………………………………………………………………………………………… +function outoflinefunction() { + return 42; +} diff --git a/js/xpconnect/tests/chrome/subscript.js b/js/xpconnect/tests/chrome/subscript.js new file mode 100644 index 0000000000..c2708f6e9b --- /dev/null +++ b/js/xpconnect/tests/chrome/subscript.js @@ -0,0 +1,4 @@ +/* global base */ +var ns = {}; +Services.scriptloader.loadSubScript(base + "file_expandosharing.jsm", ns); +var checkFromJSM = ns.checkFromJSM; diff --git a/js/xpconnect/tests/chrome/test_APIExposer.xhtml b/js/xpconnect/tests/chrome/test_APIExposer.xhtml new file mode 100644 index 0000000000..b327abe44d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_APIExposer.xhtml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=634156 +--> +<window title="Testing API exposing capabilities" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=634156" + target="_blank">Mozilla Bug 634156</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var sandbox = new Cu.Sandbox("about:blank"); + sandbox.ok = ok; + sandbox.is = is; + Cu.evalInSandbox("Object.defineProperty(Object.prototype, 'getProp', { get: function() { throw 'FAIL: called getter' }, set: function() { throw 'FAIL: called setter'; } })", sandbox); + + var obj = Cu.createObjectIn(sandbox); + is(obj, Cu.waiveXrays(obj), "createObjectIn waives"); + is(Object.getPrototypeOf(obj), Cu.waiveXrays(Cu.evalInSandbox("Object.prototype", sandbox)), + "Object is a sandbox object"); + + function genPropDesc(value) { + return { enumerable: true, configurable: true, writable: true, + value }; + } + const props = { + 'getProp': genPropDesc(function() { ok(true, "called prop that shadowed a getter"); }), + 'argument': genPropDesc(function(arg) { is(arg, 42, "can pass arguments through"); }), + 'returnval': genPropDesc(function() { return 42; }) + }; + Object.defineProperties(obj, props); + Cu.makeObjectPropsNormal(obj); + + sandbox.api = obj; + Cu.evalInSandbox("ok(Object.getPrototypeOf(api) === Object.prototype, 'we have the object we expected'); \ + api.getProp(); api.argument(42); is(api.returnval(), 42, 'return value was correct');\ + ok(typeof api.getProp === 'function', 'functions are functions');\ + ok(Object.getPrototypeOf(api.getProp) === Function.prototype, 'functions come from our scope');", sandbox); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1041626.xhtml b/js/xpconnect/tests/chrome/test_bug1041626.xhtml new file mode 100644 index 0000000000..61d7630838 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1041626.xhtml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1041626 +--> +<window title="Mozilla Bug 1041626" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041626" + target="_blank">Mozilla Bug 1041626</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 1041626 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + + // + // Location + // + + ok(Cu.isXrayWrapper(window[0].location), "Location is Xrayed"); + let xrayOwnProperties = Object.getOwnPropertyNames(window[0].location); + + let realOwnProperties = Object.getOwnPropertyNames(window[0].wrappedJSObject.location); + ok(realOwnProperties.length > 2); + + is(xrayOwnProperties.sort().toSource(), realOwnProperties.sort().toSource(), + "Xray enumerates location properties properly"); + + // + // Document + // + + ok(Cu.isXrayWrapper(window[0].document), "Document is Xrayed"); + xrayOwnProperties = Object.getOwnPropertyNames(window[0].document); + + realOwnProperties = Object.getOwnPropertyNames(window[0].wrappedJSObject.document); + ok(!!realOwnProperties.length); + + is(xrayOwnProperties.sort().toSource(), realOwnProperties.sort().toSource(), + "Xray enumerates document properties properly"); + + + + SimpleTest.finish(); + } + + + + ]]> + </script> + <iframe onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1042436.xhtml b/js/xpconnect/tests/chrome/test_bug1042436.xhtml new file mode 100644 index 0000000000..4c86839fd9 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1042436.xhtml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1042436 +--> +<window title="Mozilla Bug 1042436" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1042436" + target="_blank">Mozilla Bug 1042436</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 1042436 **/ + SimpleTest.waitForExplicitFinish(); + + var contentSb = Cu.Sandbox("https://www.example.com"); + var nonXrayableObj = contentSb.eval("new Map()[Symbol.iterator]()"); + nonXrayableObj.wrappedJSObject.someExpandoProperty = 42; + nonXrayableObj.wrappedJSObject.someOtherExpandoProperty = 52; + + + SimpleTest.expectConsoleMessages(function() { + // Create sandboxes in fresh compartments, because the warning state is + // stored per compartment. + var chromeSb1 = Cu.Sandbox(this, {freshCompartment: true}); + chromeSb1.nonXrayableObj = nonXrayableObj; + Cu.evalInSandbox(` + nonXrayableObj.someExpandoProperty; + nonXrayableObj.someOtherExpandoProperty; + `, chromeSb1); + + var chromeSb2 = Cu.Sandbox(this, {freshCompartment: true}); + var contentObjWithGetter = contentSb.eval('({ get getterProp() {return 42;}, valueProp: 42 })'); + is(contentObjWithGetter.wrappedJSObject.getterProp, 42, "Getter prop set up correctly"); + is(contentObjWithGetter.getterProp, undefined, "Xrays work right"); + is(contentObjWithGetter.valueProp, 42, "Getter prop set up correctly"); + chromeSb2.contentObjWithGetter = contentObjWithGetter; + Cu.evalInSandbox('contentObjWithGetter.getterProp; contentObjWithGetter.valueProp; contentObjWithGetter.getterProp;', + chromeSb2, "1.7", "https://phony.example.com/file.js", 99); + }, + [{ errorMessage: /property "someExpandoProperty" \(reason: object is not safely Xrayable/, sourceName: /test_bug1042436/, isWarning: true }, + { errorMessage: /property "getterProp" \(reason: property has accessor/, sourceName: /phony/, lineNumber: 99, isWarning: true } ], + SimpleTest.finish.bind(SimpleTest)); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1065185.html b/js/xpconnect/tests/chrome/test_bug1065185.html new file mode 100644 index 0000000000..bc5b6027f2 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1065185.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1065185 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1065185</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1065185 **/ + SimpleTest.waitForExplicitFinish(); + + function doMonitor(rgxps) { + var messages = rgxps.map((x) => ({ errorMessage: x, isWarning: true })); + info("Expecting console messages: " + messages.toSource()); + SimpleTest.monitorConsole(() => SimpleTest.executeSoon(() => window[0].location.reload()), messages, /* forbidUnexpected = */ true); + } + function endMonitor() { + SimpleTest.executeSoon(SimpleTest.endMonitorConsole.bind(SimpleTest)); + } + + var gLoadCount = 0; + function loaded() { + switch(gLoadCount++) { + case 0: + doMonitor([/access to property "a"/i]); + window[0].wrappedJSObject.probe = { a: 2 }; + is(window[0].eval('probe.a'), undefined, "Accessed exposed prop"); + endMonitor(); + break; + case 1: + doMonitor([/access to property "a"/i]); + window[0].wrappedJSObject.probe = { a: 2 }; + is(window[0].eval('probe.a'), undefined, "Non-exposed prop undefined"); + is(window[0].eval('probe.a'), undefined, "Non-exposed prop undefined again"); + endMonitor(); + break; + case 2: + SimpleTest.finish(); + break; + default: + ok(false, "Unexpected load"); + SimpleTest.finish(); + break; + } + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1065185">Mozilla Bug 1065185</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<iframe onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1074863.html b/js/xpconnect/tests/chrome/test_bug1074863.html new file mode 100644 index 0000000000..2fbe69a547 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1074863.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1074863 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1074863</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1074863 **/ + var sb = new Cu.Sandbox("https://www.example.com"); + sb.namedCtor = Image; + ok(true, "Didn't assert"); + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1074863">Mozilla Bug 1074863</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1092477.xhtml b/js/xpconnect/tests/chrome/test_bug1092477.xhtml new file mode 100644 index 0000000000..d79cd6604d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1092477.xhtml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1092477 +--> +<window title="Mozilla Bug 1092477" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1092477" + target="_blank">Mozilla Bug 1092477</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + +var exn; +var url = "resource://non-existent/script.js"; +try { + Services.scriptloader.loadSubScript(url); + ok(false, "This line should never be reached!"); +} +catch (e) { + exn = String(e); +} +var msg = "loadSubScript should throw an exception for trying to load a non-existent script" +is(exn, "Error opening input stream (invalid filename?): " + url, msg); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1124898.html b/js/xpconnect/tests/chrome/test_bug1124898.html new file mode 100644 index 0000000000..0b6c2b7451 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1124898.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1124898 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1124898</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1124898 **/ + SimpleTest.waitForExplicitFinish(); + (async () => { + await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]}); + + SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023. + + var w = window.browsingContext.topChromeWindow.open("about:blank", "w", "chrome"); + is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window'); + is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window'); + var contentURL = "https://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + w.location = contentURL; + tryWindow(); + + function tryWindow() { + if (w.document.title != 'empty test page') { + info("Document not loaded yet - retrying"); + SimpleTest.executeSoon(tryWindow); + return; + } + is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window'); + is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window'); + w.close(); + SimpleTest.finish(); + } + })(); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1124898">Mozilla Bug 1124898</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1126911.html b/js/xpconnect/tests/chrome/test_bug1126911.html new file mode 100644 index 0000000000..bbb2a00f54 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1126911.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1126911 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1126911</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1126911 **/ + var sb = new Cu.Sandbox(null); + sb.win = window; + sb.loc = location; + function checkThrows(expr) { + try { + Cu.evalInSandbox(expr, sb); + ok(false, "Should have thrown: " + expr); + } catch (e) { + ok(/denied|insecure/.test(e), "should get security exception: " + e); + } + } + checkThrows('win.top'); + checkThrows('loc.replace'); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1126911">Mozilla Bug 1126911</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1281071.xhtml b/js/xpconnect/tests/chrome/test_bug1281071.xhtml new file mode 100644 index 0000000000..e1ab036d55 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1281071.xhtml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1281071 +--> +<window title="Mozilla Bug 1281071" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + function go() { + var w = $('ifr').contentWindow.wrappedJSObject; + is(w.tryLocationGet(), "Permission to call 'get location' denied.", + "Trying to get our location object should throw"); + SimpleTest.finish(); + } + ]]></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <iframe type="content" + src="http://mochi.test:8888/chrome/js/xpconnect/tests/chrome/file_bug1281071.html" + onload="go()" + id="ifr"> + </iframe> + </body> + +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1390159.xhtml b/js/xpconnect/tests/chrome/test_bug1390159.xhtml new file mode 100644 index 0000000000..7d5b917a27 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1390159.xhtml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1390159 +--> +<window title="Mozilla Bug 1390159" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + function test() { + var xulRuntime = Services.appinfo; + + // Make sure it has an inSafeMode property. This is just an arbitrary + // readonly property. + var oldValue = xulRuntime.inSafeMode; + is(typeof oldValue, "boolean", "Expected an inSafeMode property"); + + // Changing a readonly property doesn't throw, but shouldn't change + // the value. + xulRuntime.inSafeMode = !oldValue; + is(xulRuntime.inSafeMode, oldValue, "Should not have modified prop"); + + // Adding a new property should throw. + let ex = null; + try { + xulRuntime.foobar = 1; + } catch (e) { + ex = e; + } + is(ex.toString().includes("Cannot modify"), true, "Expected an error"); + is(xulRuntime.foobar, undefined, "Property not defined"); + } + test(); + ]]></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + +</window> diff --git a/js/xpconnect/tests/chrome/test_bug1430164.html b/js/xpconnect/tests/chrome/test_bug1430164.html new file mode 100644 index 0000000000..609e662ad5 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1430164.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1430164 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1430164</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + /** Test for Bug 1430164 **/ + var s = new Cu.Sandbox(window, { sandboxPrototype: window } ); + var t; + var desc; + try { + t = Cu.evalInSandbox('Node === Node', s); + ok(t, "Object identity should be sane"); + + t = Cu.evalInSandbox('Node === this.Node', s); + ok(t, "Node should match this.Node in toplevel"); + + t = Cu.evalInSandbox('Node === window.Node', s); + ok(t, "Node should match window.Node"); + } catch (e) { + ok(false, "Should not get an exception: " + e); + } + </script> +</head> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1516237.html b/js/xpconnect/tests/chrome/test_bug1516237.html new file mode 100644 index 0000000000..e7b92461bf --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1516237.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1516237 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1516237</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +/** Test for Bug 1516237 **/ +ChromeUtils.import("resource://testing-common/TestUtils.jsm"); + +function go() { + SimpleTest.waitForExplicitFinish(); + + var frame = $('subframe'); + frame.onload = null; + + // Get a CCW wrapping an Xray waiver wrapping a WindowProxy. + var w = frame.contentWindow; + var ccwToWaiver = w.wrappedJSObject; + ccwToWaiver.testProp = 1; + is(ccwToWaiver.testProp, 1, "Can set properties on content window"); + + // Load a chrome page in the content frame. This might create a realm in + // the current chrome compartment - in that case we nuke the CCW to the + // waiver. + frame.onload = function() { + is(Cu.getClassName(w.Math, /* unwrap = */ false), "Math", + "Window must be in same system compartment"); + ok(Cu.isDeadWrapper(ccwToWaiver), + "Nuked CCW to same-compartment window"); + SimpleTest.finish(); + }; + frame.src = "file_empty.html"; +} + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1516237">Mozilla Bug 1516237</a> + +<iframe id="subframe" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" onload="go()"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug1530146.html b/js/xpconnect/tests/chrome/test_bug1530146.html new file mode 100644 index 0000000000..59be912027 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug1530146.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1530146 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1530146</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1530146 **/ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(setupTest); + + var sb; + + function setupTest() { + // Create a sandbox with an expanded principal for our iframe. + sb = new Cu.Sandbox([frames[0].document.nodePrincipal], + {sandboxPrototype: frames[0]}); + // Grab a waiver for the subframe in the sandbox to make sure the waiver + // stays alive. It would be nice if we could just use waiveXray in the + // sandbox: https://bugzilla.mozilla.org/show_bug.cgi?id=1531614 + Cu.evalInSandbox('this.waiver = document.querySelector("iframe").contentWindow.wrappedJSObject', + sb); + var ifr = frames[0].document.querySelector("iframe"); + ifr.onload = doTest; + ifr.src = "file_bug1530146_inner.html"; + } + +function doTest() { + // Create a new sandbox for the iframe's subframe + var sb2 = new Cu.Sandbox([frames[0][0].document.nodePrincipal], + {sandboxPrototype: frames[0][0]}); + // Reget the waiver; this is where things can go awry. + Cu.evalInSandbox('this.waiver = window.wrappedJSObject', sb2); + is(Cu.evalInSandbox("this.waiver.obj.a", sb2), "hello", + "Should get the right value and not crash"); + is(Cu.evalInSandbox("(new this.waiver.Image()).localName", sb2), "img", + "Should create an image and not crash"); + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1530146">Mozilla Bug 1530146</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe src="http://mochi.test:8888/chrome/js/xpconnect/tests/chrome/file_bug1530146.html"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug361111.xhtml b/js/xpconnect/tests/chrome/test_bug361111.xhtml new file mode 100644 index 0000000000..4f1f89cf86 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug361111.xhtml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=361111 +--> +<window title="Mozilla Bug 361111" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=361111" + target="_blank">Mozilla Bug 361111</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 361111 **/ + window.onerror = null; + SimpleTest.waitForExplicitFinish(); + document.documentElement.setAttribute("onclick", "%"); + is(1, 1, "Good, setting a bogus onclick did not throw."); + + // Bonus test - make sure that flushPrefEnv is appropriately + // called at the end of the test. It would be nice if there were + // somewhere in the harness that this could live, but there isn't. + SpecialPowers.pushPrefEnv({set: [['testing.some_arbitrary_pref', true]]}, + function() { SimpleTest.finish(); }); + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug448587.xhtml b/js/xpconnect/tests/chrome/test_bug448587.xhtml new file mode 100644 index 0000000000..cedab9ebbd --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug448587.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=448587.xul +--> +<window title="Mozilla Bug 503926" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=448587" + target="_blank">Mozilla Bug 448587</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + // Bonus test - collaborate with test_bug361111.xhtml to make sure that + // flushPrefEnv is appropriately called. + ok(!SpecialPowers.Services.prefs.prefHasUserValue('testing.some_arbitrary_pref'), + "Pref shouldn't carry over from previous test!"); + + + /** Test for Bug 448587 **/ + var sandbox = new Cu.Sandbox("about:blank"); + var fwrapper = Cu.evalInSandbox("function f() {} f", sandbox); + is(Cu.unwaiveXrays(Cu.waiveXrays(fwrapper).prototype), Cu.evalInSandbox("f.prototype", sandbox), + ".prototype visible through .wrappedJSObject"); + is(fwrapper.prototype, undefined, ".prototype invisible through Xrays"); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug484459.xhtml b/js/xpconnect/tests/chrome/test_bug484459.xhtml new file mode 100644 index 0000000000..59f2f4ea60 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug484459.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=484459 +--> +<window title="Mozilla Bug 484459" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <iframe type="content" + src="./file_bug484459.html" + onload="go()" + id="ifr"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + var url = "chrome://mochitests/content/chrome/js/xpconnect/tests/chrome/test_bug484459.xhtml"; + function go() { + var w = $('ifr').contentWindow.wrappedJSObject; + var sandbox = new Cu.Sandbox(w); + sandbox.__proto__ = w; + is(location.href, url, "location.href is set properly"); + ok(w.location.href.endsWith("file_bug484459.html"), + "contents of w.location are correct"); + is(Cu.evalInSandbox("x * 4", sandbox), 12, + "Unexpected return from the sandbox"); + SimpleTest.finish(); + } + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug500931.xhtml b/js/xpconnect/tests/chrome/test_bug500931.xhtml new file mode 100644 index 0000000000..68effb7342 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug500931.xhtml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500931 +--> +<window title="Mozilla Bug 500931" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=500931" + target="_blank">Mozilla Bug 500931</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 500931 **/ + + function go() { + var ifr = document.getElementById("ifr"); + var doc = ifr.contentDocument; + ok(Cu.isXrayWrapper(doc), "doc is an XrayWrapper"); + var weak = Cu.getWeakReference(doc); + ok(Cu.isXrayWrapper(weak.get()), "weak reference returns a wrapper"); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" + src="http://example.org/tests/js/xpconnect/tests/mochitest/bug500931_helper.html" + onload="go()" + id="ifr"> + </iframe> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug503926.xhtml b/js/xpconnect/tests/chrome/test_bug503926.xhtml new file mode 100644 index 0000000000..cfe6315fd8 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug503926.xhtml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=503926 +--> +<window title="Mozilla Bug 503926" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503926" + target="_blank">Mozilla Bug 503926</a> + + <iframe id="ifr" type="content" onload="loaded()" src="bug503926.xhtml#iframe"/> + <iframe id="ifrContent" type="content" onload="loaded()" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"/> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + SimpleTest.expectAssertions(0, 1); + + var gLoadCount = 0; + function loaded() { + if (++gLoadCount == 2) + go(); + } + + /** Test for Bug 503926 **/ + function go() { + var gWindowUtils = window.windowUtils; + + // Try with a chrome object. + var passed = false; + // eslint-disable-next-line mozilla/use-chromeutils-generateqi + var obj = { QueryInterface() { passed = true; } }; + gWindowUtils.xpconnectArgument(obj); + ok(passed, "trusted QIs should be called"); + + // Try with a content object. + var contentWin = $('ifrContent').contentWindow.wrappedJSObject; + contentWin.passed = false; + var contentObj = contentWin.eval('({ QueryInterface: function() { passed = true; } })'); + gWindowUtils.xpconnectArgument(contentObj); + ok(!contentWin.passed, "untrusted QI should not be called"); + + // Try with a dialog. + window.browsingContext.topChromeWindow.openDialog("bug503926.xhtml", "chromeDialog", "modal", window); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug533596.xhtml b/js/xpconnect/tests/chrome/test_bug533596.xhtml new file mode 100644 index 0000000000..3c3e610e81 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug533596.xhtml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=533596" + target="_blank">Mozilla Bug 533596</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + // XPCNativeWrapper is not defined globally in ESLint as it may be going away. + // See bug 1481337. + /* global XPCNativeWrapper */ + + /** Test for Bug 533596 **/ + + function go() { + try { XPCNativeWrapper.unwrap(); } catch (e) {} + try { XPCNativeWrapper.unwrap(0); } catch (e) {} + try { XPCNativeWrapper.unwrap(null); } catch (e) {} + + var o = {}; + is(o, XPCNativeWrapper.unwrap(o), "unwrap on a random object returns it"); + + var win = $('ifr').contentWindow; + var utils = window.windowUtils; + is(utils.getClassName(win), "Proxy", "win is a Proxy"); + ok("x" in XPCNativeWrapper.unwrap(win), "actually unwrapped"); + is(utils.getClassName(XPCNativeWrapper.unwrap(win)), "Proxy", + "unwrap on an Proxy returns the same object"); + is(utils.getClassName(XPCNativeWrapper.unwrap(new XPCNativeWrapper(win))), "Proxy", + "unwrap on an explicit NW works too"); + + ok(utils.getClassName(window) !== "XPCNativeWrapper", "window is not a native wrapper"); + ok(utils.getClassName(XPCNativeWrapper.unwrap(new XPCNativeWrapper(window))) !== "XPCSafeJSObjectWrapper", + "unwrapping a chrome object returns the object itself"); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" + src="http://example.org/tests/js/xpconnect/tests/mochitest/bug500931_helper.html" + onload="go()" + id="ifr"> + </iframe> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug571849.xhtml b/js/xpconnect/tests/chrome/test_bug571849.xhtml new file mode 100644 index 0000000000..3e4f6d6cc1 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug571849.xhtml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500931 +--> +<window title="Mozilla Bug 500931" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=500931" + target="_blank">Mozilla Bug 500931</a> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 500931 **/ + + function go() { + var ifr = document.getElementById('ifr'); + var docnodes = ifr.contentDocument.body.childNodes; + var index, value; + for (let i of Object.entries(docnodes)) { + index = i[0]; + value = i[1]; + } + is(index, "0", "enumerated the 0th element"); + ok(Text.isInstance(value), "the 0th element was a text node"); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" + src="http://example.org/tests/js/xpconnect/tests/mochitest/bug571849_helper.html" + onload="go()" + id="ifr"> + </iframe> + </body> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug610390.xhtml b/js/xpconnect/tests/chrome/test_bug610390.xhtml new file mode 100644 index 0000000000..e4d8a48477 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug610390.xhtml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=610390 +--> +<window title="Mozilla Bug 610390" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <iframe type="content" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + src="data:text/html,<script>var x=3</script>" + onload="go()" + id="ifr"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + function go() { + var w = $('ifr').contentWindow; + is(w.wrappedJSObject, w.wrappedJSObject, "wrappedJSObject identity not maintained"); + SimpleTest.finish(); + } + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug614757.xhtml b/js/xpconnect/tests/chrome/test_bug614757.xhtml new file mode 100644 index 0000000000..34058e38a3 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug614757.xhtml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=614757 +--> +<window title="Mozilla Bug 601803" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=614757" + target="_blank">Mozilla Bug 614757</a> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 614757 **/ + + function go() { + is($('ifr').contentDocument.wrappedJSObject.getElementsByTagName('body')[0].toString().indexOf('Xray'), + -1, "Properly deep wrap"); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_evalInSandbox.html" onload="go()" id="ifr" /> + </body> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug616992.xhtml b/js/xpconnect/tests/chrome/test_bug616992.xhtml new file mode 100644 index 0000000000..52a97cee3d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug616992.xhtml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=616992 +--> +<window title="Mozilla Bug 601803" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=616992" + target="_blank">Mozilla Bug 616992</a> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 616992 **/ + + var sandbox = new Cu.Sandbox(window); + sandbox.w = window; + var actual = Cu.evalInSandbox("Object.keys(w.NodeFilter)", sandbox).sort().toString(); + var expected = Object.keys(NodeFilter).sort().toString(); + is(actual, expected, "interface constants are visible inside sandboxes"); + + ]]></script> + </body> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug618176.xhtml b/js/xpconnect/tests/chrome/test_bug618176.xhtml new file mode 100644 index 0000000000..63e93c9b56 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug618176.xhtml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=618176 +--> +<window title="Mozilla Bug 618176" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=618176" + target="_blank">Mozilla Bug 618176</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.openDialog("file_bug618176.xhtml", "", "chrome,noopener", window); + }); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug654370.xhtml b/js/xpconnect/tests/chrome/test_bug654370.xhtml new file mode 100644 index 0000000000..e1afc32e38 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug654370.xhtml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=654370 +--> +<window title="Mozilla Bug 654370" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=654370" + target="_blank">Mozilla Bug 654370</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + +var sandbox = new Cu.Sandbox(window); +var script = "(function (obj, type) { return obj instanceof type; })"; +var instanceOf = Cu.evalInSandbox(script, sandbox, "1.8", "Test", 1); +ok(!instanceOf({}, Window), "instanceOf from the sandbox gets the right result"); + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug658560.xhtml b/js/xpconnect/tests/chrome/test_bug658560.xhtml new file mode 100644 index 0000000000..78b623a828 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug658560.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=658560 +--> +<window title="Mozilla Bug 658560" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=658560" + target="_blank">Mozilla Bug 658560</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + SimpleTest.waitForExplicitFinish(); + function go() { + var win = $('ifr').contentWindow.wrappedJSObject; + let o = { prop: true }; + win.foo = o; + + is(win.foo, o, "should have === identity through a CrossOriginWrapper"); + SimpleTest.finish(); + } + + ]]></script> + + <iframe + src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug658560.html" + id="ifr" + type="content" + onload="go()" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug658909.xhtml b/js/xpconnect/tests/chrome/test_bug658909.xhtml new file mode 100644 index 0000000000..360b8045e2 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug658909.xhtml @@ -0,0 +1,92 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=658909 +--> +<window title="Mozilla Bug 658909" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=658909" + target="_blank">Mozilla Bug 658909</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for call/apply-ing Xray methods.**/ + SimpleTest.waitForExplicitFinish(); + + let gLoadCount = 0; + function frameLoaded() { + if (++gLoadCount == frames.length) + go(); + } + + function msg(a, b, testName) { + return "(" + a.name + ", " + b.name + "): " + testName; + } + + var testFunctions = { + testDocumentElement(a, b, name) { + var getter = Object.prototype.__lookupGetter__.call(a.document, 'documentElement'); + is(getter.call(b.document), b.document.documentElement, msg(a, b, name)); + }, + + testInvalidCall(a, b, name) { + var getter = Object.prototype.__lookupGetter__.call(a.document, 'documentElement'); + var threw = false; + try { getter.call(b.document.body); } catch (e) { threw = true; }; + ok(threw, msg(a, b, name)); + }, + + testStatus(a, b, name) { + var setter = Object.prototype.__lookupSetter__.call(a, 'status'); + is(b.status, "", "Empty status"); + setter.call(b, "foopy"); + is(b.status, "foopy", msg(a, b, name)); + b.status = ""; + }, + + testCreateElement(a, b, name) { + is(a.document.createElement.call(b.document, 'div').ownerDocument, b.document, msg(a, b, name)); + }, + + testWindowName(a, b, name) { + var getter = Object.prototype.__lookupGetter__.call(a, 'name'); + is(getter.call(b), b.name, msg(a, b, name)); + }, + + testCanvas(a, b, name) { + var canvasA = a.document.createElement('canvas'); + var canvasB = b.document.createElement('canvas'); + var contextA = canvasA.getContext('2d'); + var contextB = canvasB.getContext('2d'); + var getter = Object.prototype.__lookupGetter__.call(contextA, 'canvas'); + is(getter.call(contextB), canvasB, msg(a, b, name)); + } + }; + + function go() { + for (let i = 0; i < frames.length; ++i) + frames[i].name = 'frame' + i; + for (let i = 0; i < frames.length; ++i) { + for (let j = 0; j < frames.length; ++j) { + for (let k in testFunctions) + testFunctions[k](frames[i], frames[j], k); + } + } + + SimpleTest.finish(); + } + + + ]]> + </script> + <iframe id="frame1" onload="frameLoaded();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> + <iframe id="frame2" onload="frameLoaded();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> + <iframe id="frame3" onload="frameLoaded();" type="content" src="http://example.com/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug664689.xhtml b/js/xpconnect/tests/chrome/test_bug664689.xhtml new file mode 100644 index 0000000000..45a39b1be9 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug664689.xhtml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=658560 +--> +<window title="Mozilla Bug 658560" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=658560" + target="_blank">Mozilla Bug 658560</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var sandbox = new Cu.Sandbox("about:blank"); + var contentObj = Cu.evalInSandbox("({ get foo() { return 42 } })", sandbox); + var propdesc = Object.getOwnPropertyDescriptor(Cu.waiveXrays(contentObj), "foo"); + is(typeof propdesc, "object", "got a property descriptor back"); + ok("get" in propdesc, "getter exists"); + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug679861.xhtml b/js/xpconnect/tests/chrome/test_bug679861.xhtml new file mode 100644 index 0000000000..302b66c966 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug679861.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500931 +--> +<window title="Mozilla Bug 601803" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=601803" + target="_blank">Mozilla Bug 601803</a> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 601803 **/ + + function go() { + var doc = document.getElementById('ifr').contentDocument; + var list = doc.getElementsByTagName("body"); + var zeroAsString = "0"; + is(typeof list[zeroAsString], "object", + "can lookup nodelist items by string"); + is(typeof list[0], "object", + "can lookup nodelist items by integer after the lookup by string"); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" src="about:blank" onload="go()" id="ifr" /> + </body> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug706301.xhtml b/js/xpconnect/tests/chrome/test_bug706301.xhtml new file mode 100644 index 0000000000..867f9222d2 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug706301.xhtml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=706301 +--> +<window title="Mozilla Bug 706301" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=706301" + target="_blank">Mozilla Bug 706301</a> + <iframe id="ifr" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug706301.html" onload="doTest();" /> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 706301 **/ + + SimpleTest.waitForExplicitFinish(); + + function getLengthInChrome(nodelist) { + + // Make sure the object is Xray wrapped. + is(nodelist, Cu.unwaiveXrays(nodelist), + "object passed from content to chrome should be Xray-wrapped."); + + // Perform the operation. + Object.getOwnPropertyDescriptor(nodelist, 'length'); + return !nodelist.length; + } + + function finishTestInChrome() { + SimpleTest.finish(); + } + + function doTest() { + + // Set up the callbacks for content. + $('ifr').contentWindow.wrappedJSObject.getLengthInChrome = getLengthInChrome; + $('ifr').contentWindow.wrappedJSObject.finishTestInChrome = finishTestInChrome; + $('ifr').contentWindow.wrappedJSObject.ok = ok; + + // Kick off the test. + $('ifr').contentWindow.postMessage({}, '*'); + } + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug720619.xhtml b/js/xpconnect/tests/chrome/test_bug720619.xhtml new file mode 100644 index 0000000000..335218886b --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug720619.xhtml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=720619 +--> +<window title="Mozilla Bug 720619" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=720619" + target="_blank">Mozilla Bug 720619</a> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /** Test for Bug 720619 **/ + var obj = { + valueOf () { + return 42; + }, + toString () { + return 'str'; + } + }; + + var content = new Cu.Sandbox("about:blank"); + content.obj = obj; + + ok(Cu.evalInSandbox("obj + ''", content) == "[object Object]"); + ok(Cu.evalInSandbox("'' + obj", content) == "[object Object]"); + ok(isNaN(Cu.evalInSandbox("obj - 0", content))); + ok(Cu.evalInSandbox("String(obj)", content) == "[object Object]"); + + var chrome = new Cu.Sandbox(window); + chrome.obj = obj; + + ok(Cu.evalInSandbox("obj + ''", chrome) == "42"); + ok(Cu.evalInSandbox("'' + obj", chrome) == "42"); + ok(Cu.evalInSandbox("obj - 0", chrome) == 42); + ok(Cu.evalInSandbox("String(obj)", chrome) == "str"); + ]]></script> + </body> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug726949.xhtml b/js/xpconnect/tests/chrome/test_bug726949.xhtml new file mode 100644 index 0000000000..b02b200893 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug726949.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=726949 +--> +<window title="Mozilla Bug 726949" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + style="display: block;"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=726949" + target="_blank">Mozilla Bug 726949</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 726949 **/ + var s = new Cu.Sandbox(window, { sandboxPrototype: window } ); + var t; + var desc; + try { + t = Cu.evalInSandbox('top', s); + is(t, window.top, "Should have gotten the right thing back"); + desc = Cu.evalInSandbox('Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this), "Cu")', s); + isnot(desc, undefined, + "Should have an own 'Cu' property"); + is(desc.value, Cu, "Should have the right value"); + var loc = Cu.evalInSandbox('location', s); + is(loc.href, location.href, "Should have the right location"); + var display = Cu.evalInSandbox('getComputedStyle(document.documentElement, "").display', s); + is(display, "block", "Should be able to call getComputedStyle"); + } catch (e) { + ok(false, "Should not get an exception: " + e); + } + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug732665.xhtml b/js/xpconnect/tests/chrome/test_bug732665.xhtml new file mode 100644 index 0000000000..0ffba66ebc --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug732665.xhtml @@ -0,0 +1,92 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=732665 +--> +<window title="Mozilla Bug 732665" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=732665" + target="_blank">Mozilla Bug 732665</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + +add_task(async () => { + await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", + true]]}); + // + // Important! If this test starts failing after a tricky platform-y change, + // the stack quota numbers in XPCJSContext probably need twiddling. We want + // to maintain the invariants in this test (at least to some approximation) + // for security reasons. + // + + // Executes f() d steps from the probed native stack limit, and returns + // the number of steps to the recursion limit from the caller. + function nearNativeStackLimit(d, f) { + f = f || function() {}; + let failed = null; + function inner() { + try { + // eslint-disable-next-line no-eval + var stepsFromLimit = eval("inner()"); // Use eval to force a number of native stackframes to be created. + if (stepsFromLimit == d) { + try { + f(); + } catch(e) { + // If we didn't have enough stack space to call the (possibly + // trivial) test function above, we obviously can't expect to call + // into the test harness assertion code successfully. + failed = e; + } + } + return stepsFromLimit + 1; + } catch(e) { + // It would be nice to check here that the exception is actually an + // over-recursion here. But doing so would require toString()ing the + // exception, which we may not have the stack space to do. + return 0; + } + } + let result = inner(); + ok(!failed, `nearNativeStackLimit callback threw: ${failed}`); + return result; + } + + var contentSb = new Cu.Sandbox("https://www.example.com"); + var chromeSb = new Cu.Sandbox(window); + chromeSb.ok = contentSb.ok = ok; + Cu.evalInSandbox(nearNativeStackLimit.toSource(), chromeSb); + Cu.evalInSandbox(nearNativeStackLimit.toSource(), contentSb); + var chromeLimit = Cu.evalInSandbox("nearNativeStackLimit(0);", chromeSb); + var contentLimit = Cu.evalInSandbox("nearNativeStackLimit(0)", contentSb); + ok(chromeLimit >= contentLimit + 10, + "Chrome should be able to have at least 10 heavy frames more stack than content: " + chromeLimit + ", " + contentLimit); + + // Exhaust the stack space in content, and then make sure we can still get 10 + // heavy frames in chrome. + // + // Note that sometimes, if we pass |0| to nearNativeStackLimit, we can end up + // so close to the border in content that we can't even get ourselves together + // enough to make the cross-compartment call. So rather than exhausting the + // stack entirely and then checking for 10 chrome frames, we leave ourselves + // one frame's worth, and check for 11. + // + // If this assertion fails, the current work-around so far is to measure + // again the worst frame size, by using the JS Shell to run + // test_bug732665_meta.js . This script will output numbers to update + // XPCJSContext.cpp comment, as well as the kTrustedScriptBuffer constant. + contentSb.nnslChrome = chromeSb.nearNativeStackLimit; + var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb); + ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit); +}); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug732665_meta.js b/js/xpconnect/tests/chrome/test_bug732665_meta.js new file mode 100644 index 0000000000..92bf9066b3 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug732665_meta.js @@ -0,0 +1,34 @@ +/* globals stackPointerInfo */ + +var stackBottom = stackPointerInfo(); +var stackTop = stackBottom; + +function nearNativeStackLimit() { + function inner() { + try { + stackTop = stackPointerInfo(); + // eslint-disable-next-line no-eval + var stepsFromLimit = eval("inner()"); // Use eval to force a number of native stackframes to be created. + return stepsFromLimit + 1; + } catch (e) { + // It would be nice to check here that the exception is actually an + // over-recursion here. But doing so would require toString()ing the + // exception, which we may not have the stack space to do. + return 1; + } + } + return inner(); +} + +var nbFrames = nearNativeStackLimit(); +var frameSize = stackBottom - stackTop; +print( + "Max stack size:", + frameSize, + "bytes", + "\nMaximum number of frames:", + nbFrames, + "\nAverage frame size:", + Math.ceil(frameSize / nbFrames), + "bytes" +); diff --git a/js/xpconnect/tests/chrome/test_bug738244.xhtml b/js/xpconnect/tests/chrome/test_bug738244.xhtml new file mode 100644 index 0000000000..96d0d880e6 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug738244.xhtml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + + <iframe src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug738244.html" + onload="xrayTest(this)"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + function xrayTest(ifr) { + var win = ifr.contentWindow; + var doc = ifr.contentDocument; + + doc.getElementById = 42; + is(doc.getElementById, 42, + "Native property cannot be shadowed on the xray"); + + is(doc.form1.name, "form1", + "Form elements cannot be found by name on the document through xray"); + + is(doc.form1.input1.name, "input1", + "Input element cannot be found by name on a form element through xray"); + + is(typeof doc.form1.appendChild, "function", + "Input element shadows native property with its name through xray"); + + is(win.frame1, undefined, + "IFrames should not be found by name on the window through xray"); + + is(win[0].name, "frame1", + "IFrames should be found by index on the window through xray"); + + win["1000"] = "foopy"; + ok(!("1000" in win), "Shouldn't be able to add indexed expandos to xray"); + + win["1000a"] = "foopy"; + ok("1000a" in win, "Should be able to add named expandos to xray"); + + SimpleTest.finish(); + } + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug743843.xhtml b/js/xpconnect/tests/chrome/test_bug743843.xhtml new file mode 100644 index 0000000000..a80134ff9e --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug743843.xhtml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=743843 +--> +<window title="Mozilla Bug 743843" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=743843" + target="_blank">Mozilla Bug 743843</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Components.Exception options objects. **/ + + // Note: We pass |window| as the 'data' field here because Components.Exception + // doesn't handle JS Objects here all that nicely. See bug 743121. + + // Test the old interface. + var e1 = Components.Exception('foo', Cr.NS_BINDING_ABORTED, null, window); + is(e1.result, Cr.NS_BINDING_ABORTED, "Result should get set properly"); + is(e1.data, window, "User data should get set properly"); + + // Test the options object. + var e2 = Components.Exception('foo', { result: Cr.NS_BINDING_ABORTED, + data: window, + foobar: 2 }); + is(e2.result, Cr.NS_BINDING_ABORTED, "Result should get set properly"); + is(e2.data.window, window, "User data should get set properly"); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug760076.xhtml b/js/xpconnect/tests/chrome/test_bug760076.xhtml new file mode 100644 index 0000000000..9d56455024 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug760076.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=760076 +--> +<window title="Mozilla Bug 760076" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=760076" + target="_blank">Mozilla Bug 760076</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for constructing COW-ed functions in content. **/ + + // This gets decompiled and run in the sandbox. + function sandboxCode() { + /* globals chromeFunction */ + try { + is(chromeFunction(), 42, "Should call successfully"); + } catch(e) { ok(false, "Shouldn't throw when calling"); } + + try { + ok(typeof (new chromeFunction()) !== 'undefined', + "Should construct successfully"); + } catch(e) { ok(false, "Shouldn't throw when constructing"); } + } + + // Set up the sandbox. + var sb = new Cu.Sandbox("https://www.example.com"); + + // Import the functions it needs. + sb.ok = ok; + sb.is = is; + sb.chromeFunction = function() { ok(true, "Called chrome function"); return 42; } + Cu.evalInSandbox(sandboxCode.toSource(), sb); + + // Do the test. + Cu.evalInSandbox("sandboxCode();", sb); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug760131.html b/js/xpconnect/tests/chrome/test_bug760131.html new file mode 100644 index 0000000000..eca4467c8d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug760131.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=760131 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 760131</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=760131">Mozilla Bug 760131</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="frame"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 760131 **/ + +var frame = document.getElementById("frame"); +function runTest() +{ + var win = frame.contentWindow; + win.wrappedJSObject.ok = ok; + var doc = win.document; + var empty = doc.createTouchList(); + var event = doc.createEvent("touchevent"); + event.initTouchEvent("touchstart", true, true, win, 0, false, false, false, false, empty, empty, empty); + doc.getElementById("target").dispatchEvent(event); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv( + {"set": [["dom.w3c_touch_events.legacy_apis.enabled", true]]}, + function() { + frame.onload = runTest; + frame.src = "http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug760131.html"; + } +); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_bug763343.xhtml b/js/xpconnect/tests/chrome/test_bug763343.xhtml new file mode 100644 index 0000000000..db3acd37c0 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug763343.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=763343 +--> +<window title="Mozilla Bug 763343" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=763343" + target="_blank">Mozilla Bug 763343</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Cross-compartment nsIClassInfo singleton wrapping. **/ + // We need an object here that has singleton classinfo. For now, the console + // service works. + var singleton = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIClassInfo); + ok(singleton.flags & Ci.nsIClassInfo.SINGLETON_CLASSINFO, + "Should have singleton classinfo"); + var sb = new Cu.Sandbox(window); + + // Don't crash. + sb.singleton = singleton; + ok(true, "didn't crash"); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug771429.xhtml b/js/xpconnect/tests/chrome/test_bug771429.xhtml new file mode 100644 index 0000000000..c5846dd6ac --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug771429.xhtml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=771429 +--> +<window title="Mozilla Bug 771429" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=771429" + target="_blank">Mozilla Bug 771429</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 771429 **/ + function f() {} + function g() { return this; } + function h() { "use strict"; return this; } + function ctor() { this.x = 1; } + f.x = 2; + f.g = g; + function test(freshCompartment) { + var s = new Cu.Sandbox(window, { + sandboxPrototype: window, + freshCompartment, + }); + try { + is(Cu.evalInSandbox('g()', s), window, + "Should get window as this object of non-strict global function"); + is(Cu.evalInSandbox('h()', s), undefined, + "Should get undefined as this object of strict global function"); + is(Cu.evalInSandbox('f.x', s), 2, + "Should have gotten the right thing back"); + if (freshCompartment) { + is(Cu.evalInSandbox('f.g()', s), f, + "Should have the right function object"); + } else { + // In the same-compartment case we don't go through a compartment + // boundary so when we call f.g() we don't unwrap the "callable + // proxy" around f and the test above fails. We accept this slight + // difference in behavior and assert a weaker invariant. + is(Cu.evalInSandbox('f.g()', s).toString(), f.toString(), + "Should have the right function object"); + } + is(Cu.evalInSandbox('var x = { z: 7 }; g.call(x).z', s), 7, + "Should not rebind calls that are already bound"); + // And test what happens when we use the normal Function.prototype.call + // on g instead of whatever our proxies happen to return. + is(Cu.evalInSandbox('var x = { z: 7 }; Function.prototype.call.call(g, x).z', s), 7, + "Should not rebind calls that are already bound"); + is(Cu.evalInSandbox('new ctor();', s).x, 1, + "Should get a properly constructed object out of the sandbox"); + } catch (e) { + ok(false, "Should not get an exception: " + e); + } + } + test(false); + test(true); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug773962.xhtml b/js/xpconnect/tests/chrome/test_bug773962.xhtml new file mode 100644 index 0000000000..2bdb43f6fc --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug773962.xhtml @@ -0,0 +1,88 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=773962 +--> +<window title="Mozilla Bug 773962" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=773962" + target="_blank">Mozilla Bug 773962</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for remapping Xray waivers during brain transplant. **/ + SimpleTest.waitForExplicitFinish(); + + var gFramesLoaded = 0; + function frameLoaded() { + ++gFramesLoaded; + if (gFramesLoaded == 2) + startTest(); + if (gFramesLoaded == 3) + finishTest(); + } + + var win1; + var win2; + var node1; + var loc1; + var win1Waiver; + var node1Waiver; + var loc1Waiver; + + function startTest() { + // grab the windows and the node. + win1 = document.getElementById('frame1').contentWindow; + win2 = document.getElementById('frame2').contentWindow; + node1 = win1.document.getElementById('text'); + loc1 = win1.location; + + // Grab some Xray waivers. + win1Waiver = win1.wrappedJSObject; + node1Waiver = node1.wrappedJSObject; + loc1Waiver = win1Waiver.location; + + // Adopt node1 into win2. This causes node1 to be transplanted. + win2.document.adoptNode(node1); + + // Navigate win1. This causes win1 to be transplanted. + win1.location = "https://test2.example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + + // The above happens async. Our onload handler will call finishTest() when we're ready. + } + + function finishTest() { + // Now, recompute some wrappers. + Cu.recomputeWrappers(); + + // First, pat ourselves on the back for not asserting/crashing. That's most of + // what we're really testing here. + ok(true, "Didn't crash!"); + + // Now, make sure everything is set up how we expect. + ok(Cu.isDeadWrapper(win1Waiver), "window waiver should go away after navigation"); + ok(node1Waiver === node1.wrappedJSObject, "waivers still work"); + ok(Cu.unwaiveXrays(node1Waiver) === node1, "waivers still work"); + + // The semantics of location are tricky, because win1 now has a new location object. + // In fact, loc1 should be a dead object proxy. Let's make sure we get this right. + ok(loc1 !== win1.location, "navigation means different window.location"); + ok(loc1Waiver !== win1.location.wrappedJSObject, "navigation means different window.location"); + + // Whew. + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="frame1" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> + <iframe id="frame2" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug792280.xhtml b/js/xpconnect/tests/chrome/test_bug792280.xhtml new file mode 100644 index 0000000000..1e1a197e57 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug792280.xhtml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=792280 +--> +<window title="Mozilla Bug 792280" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=792280" + target="_blank">Mozilla Bug 792280</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 792280 **/ + function checkSb(sb, expect) { + var target = new Cu.Sandbox("https://www.example.com"); + Cu.evalInSandbox('function fun() { return arguments.callee.caller; };', target); + sb.fun = target.fun; + let allowed = false; + try { + allowed = Cu.evalInSandbox('function doTest() { return fun() == doTest; }; doTest()', sb); + isnot(expect, "throw", "Should have thrown"); + } catch (e) { + is(expect, "throw", "Should expect exception"); + ok(/denied|insecure/.test(e), "Should be a security exception: " + e); + } + is(allowed, expect == "allow", "should censor appropriately"); + } + + // Note that COWs are callable, but XOWs are not. + checkSb(new Cu.Sandbox("https://www.example.com"), "allow"); + checkSb(new Cu.Sandbox("https://www.example.org"), "throw"); + checkSb(new Cu.Sandbox(window), "censor"); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug793433.xhtml b/js/xpconnect/tests/chrome/test_bug793433.xhtml new file mode 100644 index 0000000000..eed7166efc --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug793433.xhtml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=793433 +--> +<window title="Mozilla Bug 793433" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=793433" + target="_blank">Mozilla Bug 793433</a> + <p id="display"></p> + <div id="content" style="display: none"/> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + +function shouldThrow(fun, args, msg) { + try { + fun.apply(this, args); + ok(false, msg); + } catch (e) { + ok(true, msg+" -- "+e); + } +} + +function do_registerTopLevelWindow(win) { + Services.appShell.registerTopLevelWindow(win); +} + +shouldThrow( + do_registerTopLevelWindow, [null], + "registering null as a top-level window should throw"); + +shouldThrow( + do_registerTopLevelWindow, [{}], + "registering a void object as a top-level window should throw"); + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug795275.xhtml b/js/xpconnect/tests/chrome/test_bug795275.xhtml new file mode 100644 index 0000000000..a151a1a2b7 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug795275.xhtml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=795275 +--> +<window title="Mozilla Bug 795275" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=795275" + target="_blank">Mozilla Bug 795275</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Warning in content scopes about Components. **/ + + SimpleTest.waitForExplicitFinish(); + SimpleTest.executeSoon(function() { + SpecialPowers.pushPrefEnv({set: [["dom.use_components_shim", true]]}, + startLoad) + }); + function startLoad() { + for (var i = 1; i <= document.getElementsByTagName('iframe').length; ++i) { + var frame = document.getElementById('frame' + i); + frame.contentWindow.location = 'http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html'; + frame.onload = frameLoaded; + } + } + + // Set up our console listener. + var gWarnings = 0; + function onWarning(consoleMessage) { + if (/soon be removed/.test(consoleMessage.message)) + gWarnings++; + } + var gListener = { + observe: onWarning, + QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]) + }; + Services.console.registerListener(gListener); + + // Wait for all four child frame to load. + var gLoadCount = 0; + function frameLoaded() { + if (++gLoadCount == document.getElementsByTagName('iframe').length) + go(); + } + + function getWin(id) { return document.getElementById(id).contentWindow.wrappedJSObject; } + function go() { + getWin('frame1').touchComponents(); + getWin('frame2').touchInterfaces(); + getWin('frame4').touchComponents(); + getWin('frame4').touchInterfaces(); + + // Warnings are dispatched async, so stick ourselves at the end of the event + // queue. + setTimeout(done, 0); + } + + function done() { + Services.console.unregisterListener(gListener); + is(gWarnings, 3, "Got the right number of warnings"); + SimpleTest.finish(); + } + + ]]> + + </script> + <iframe id="frame1"/> + <iframe id="frame2"/> + <iframe id="frame3"/> + <iframe id="frame4"/> + +</window> diff --git a/js/xpconnect/tests/chrome/test_bug799348.xhtml b/js/xpconnect/tests/chrome/test_bug799348.xhtml new file mode 100644 index 0000000000..91de48164f --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug799348.xhtml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=799348 +--> +<window title="Mozilla Bug 799348" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=799348" + target="_blank">Mozilla Bug 799348</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 799348 **/ + SimpleTest.waitForExplicitFinish(); + var gCalledOnload = false; + var myObserver = { + QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), + observe(win, topic, data) { + if (topic == "domwindowopened") { + ok(!gCalledOnload, "domwindowopened notification fired before onload"); + win.addEventListener("load", function(evt) { + gCalledOnload = true; + win.close(); + }); + } else if (topic == "domwindowclosed") { + ok(gCalledOnload, "should have called onload"); + Services.ww.unregisterNotification(myObserver); + SimpleTest.finish(); + } else { + ok(false, "unknown topic"); + } + } + }; + Services.ww.registerNotification(myObserver); + + + ]]> + </script> + <iframe id="frame" type="content" src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/file_bug799348.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug801241.xhtml b/js/xpconnect/tests/chrome/test_bug801241.xhtml new file mode 100644 index 0000000000..5c83429afa --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug801241.xhtml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=801241 +--> +<window title="Mozilla Bug 801241" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=801241" + target="_blank">Mozilla Bug 801241</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 801241 **/ + SimpleTest.waitForExplicitFinish(); + + /* globals win */ + + // This is decompiled and run inside the sandbox; + function sbCode() { + try { + // eslint-disable-next-line no-self-assign + win.location = win.location; + ok(true, "Didn't throw setting from location"); + } catch (e) { + ok(false, "Threw setting location from sandbox"); + } + } + + function go() { + document.getElementById('ifr').onload = null; + var sb = new Cu.Sandbox(this); + sb.win = document.getElementById('ifr').contentWindow; + sb.ok = ok; + Cu.evalInSandbox('(' + sbCode.toSource() + ')()', sb); + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug812415.xhtml b/js/xpconnect/tests/chrome/test_bug812415.xhtml new file mode 100644 index 0000000000..71dc23768e --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug812415.xhtml @@ -0,0 +1,90 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=812415 +--> +<window title="Mozilla Bug 812415" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=812415" + target="_blank">Mozilla Bug 812415</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 812415 and Bug 823348 **/ + + SimpleTest.waitForExplicitFinish(); + + function testWaiving(iwin, sb) { + sb.win = iwin; + is(Cu.evalInSandbox('win', sb), iwin, "Basic identity works"); + is(Cu.evalInSandbox('win.wrappedJSObject.expando', sb), 42, "Waivers work via .wrappedJSObject"); + is(Cu.evalInSandbox('XPCNativeWrapper.unwrap(win).expando', sb), 42, "Waivers work via XPCNativeWrapper.unwrap"); + is(Cu.evalInSandbox('win.wrappedJSObject.document.defaultView.expando', sb), 42, "Waivers are deep"); + } + + function checkThrows(expression, sb, msg) { + var result = Cu.evalInSandbox('(function() { try { ' + expression + '; return "allowed"; } catch (e) { return e.toString(); }})();', sb); + ok(!!/denied/.exec(result), msg); + } + + function testAsymmetric(regular, expanded) { + + // Set up objects. + expanded.regFun = Cu.evalInSandbox('function reg() { return 42; }; reg', regular); + expanded.regObj = Cu.evalInSandbox('new Object({foo: 2})', regular); + regular.expFun = Cu.evalInSandbox('function exp() { return 41; }; exp', expanded); + regular.expObj = Cu.evalInSandbox('new Object({bar: 3})', expanded); + + // Check objects. + is(Cu.evalInSandbox('regObj.foo', expanded), 2, "Expanded can see regular object prop"); + checkThrows('expObj.bar', regular, "Regular shouldn't read properties"); + Cu.evalInSandbox('regObj.foo = 20', expanded); + is(expanded.regObj.foo, 20, "Expanded can set properties"); + checkThrows('expFun.bar = 0', regular, "Regular shouldn't write properties"); + + // Check functions. + is(Cu.evalInSandbox('regFun()', expanded), 42, "Expanded can call regular function"); + checkThrows('expFun()', regular, "Regular cannot call expanded function"); + is(Cu.evalInSandbox('regFun.name', expanded), 'reg', "Expanded can see regular function's name"); + checkThrows('expFun.name', regular, "Regular can't see expanded function's name"); + Cu.evalInSandbox('regFun.expando = 30', expanded); + is(Cu.evalInSandbox('regFun.expando', expanded), 30, "Expanded can set expandos"); + checkThrows('expFun.expando = 29', regular, "Regular can't set expandos"); + + // Check __proto__ stuff. + is(Cu.evalInSandbox('regFun.__proto__', expanded), regular.Function.prototype, "expanded can get __proto__"); + checkThrows('expFun.__proto__', regular, "regular can't use __proto__"); + checkThrows('expFun.__proto__ = {}', regular, "regular can't mutate __proto__"); + } + + function go() { + var iwin = document.getElementById('ifr').contentWindow; + iwin.wrappedJSObject.expando = 42; + + // Make our sandboxes. We pass wantXrays=false for the nsEP to ensure that + // the Xrays we get are the result of being an nsEP, not from the wantXrays + // flag. + var regular = new Cu.Sandbox(iwin); + var expanded = new Cu.Sandbox([iwin], {wantXrays: false}); + + // Because of the crazy secret life of wantXrays, passing wantXrays=false + // has the side effect of waiving Xrays on the returned sandbox. Undo that. + expanded = Cu.unwaiveXrays(expanded); + + testWaiving(iwin, regular); + testWaiving(iwin, expanded); + testAsymmetric(regular, expanded); + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug853283.xhtml b/js/xpconnect/tests/chrome/test_bug853283.xhtml new file mode 100644 index 0000000000..6cdd5027b8 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug853283.xhtml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=853283 +--> +<window title="Mozilla Bug 853283" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=853283" + target="_blank">Mozilla Bug 853283</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test nsNavigatorSH::Resolve in conjunction with Xrays.**/ + SimpleTest.waitForExplicitFinish(); + + function go() { + // This chrome document already has Xrays to the content scope, but we use a + // a sandbox anyway to make sure that the global in play here isn't an + // nsIDOMWindow. Otherwise, the resolve hook might just end up squeaking by + // with the chrome window. + var iwin = $('ifr').contentWindow; + var sb = new Cu.Sandbox(window); + sb.iwin = iwin; + sb.ok = ok; + Cu.evalInSandbox('try {iwin.navigator.mozContacts; ok(true, "Didnt throw"); } catch (e) { ok(false, "Threw: " + e);}', sb); + SimpleTest.finish(); + } + + + ]]> + </script> + <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug853571.xhtml b/js/xpconnect/tests/chrome/test_bug853571.xhtml new file mode 100644 index 0000000000..2f16915666 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug853571.xhtml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=853571 +--> +<window title="Mozilla Bug 853571" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=853571" + target="_blank">Mozilla Bug 853571</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 853571 **/ + SimpleTest.waitForExplicitFinish(); + + function* mainTest() { + var iwin = $('ifr').contentWindow; + + // Test with a simple sandbox with no prototype. + checkSource(iwin, new Cu.Sandbox(iwin), null, "should get null source with no sandboxPrototype"); + yield; + + // Test with a sandboxPrototype. + checkSource(iwin, new Cu.Sandbox(iwin, { sandboxPrototype: iwin }), iwin, "should be able to impersonate the prototype"); + yield; + + SimpleTest.finish(); + yield; // Prevent StopIteration from being thrown. + } + + var gen; + function runTest() { + gen = mainTest(); + gen.next(); + } + + function checkSource(target, sb, expectedSource, message) { + target.addEventListener("message", function listener(event) { + is(event.source, expectedSource, message); + let {done} = gen.next(); + if (done) { + // We're done. + } + }, + { once: true}); + + sb.target = target; + Cu.evalInSandbox("target.postMessage('foo', '*');", sb); + } + + + ]]> + </script> + <iframe id="ifr" type="content" onload="runTest()" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug858101.xhtml b/js/xpconnect/tests/chrome/test_bug858101.xhtml new file mode 100644 index 0000000000..5ff9f28dc7 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug858101.xhtml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=858101 +--> +<window title="Mozilla Bug 858101" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=858101" + target="_blank">Mozilla Bug 858101</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for [[DefaultValue]] on XrayWrappers. **/ + SimpleTest.waitForExplicitFinish(); + + function muckWithToString() { + function tricky() { return "hah"; }; + + window.toString = document.toString = document.body.toString = tricky; + window.valueOf = document.valueOf = document.body.valueOf = tricky; + + Window.prototype.toString = Window.prototype.valueOf = tricky; + Document.prototype.toString = Document.prototype.valueOf = tricky; + HTMLBodyElement.toString = HTMLBodyElement.valueOf = tricky; + } + + function go() { + var iwin = $('ifr').contentWindow; + iwin.wrappedJSObject.eval('(' + muckWithToString.toSource() + ')()'); + + // Check behavior with vanilla CCWs. + ok(!!/hah/.exec(iwin.wrappedJSObject + ""), "Waivers should get content-defined window stringification"); + ok(!!/hah/.exec(iwin.document.wrappedJSObject + ""), "Waivers should get content-defined document stringification"); + ok(!!/hah/.exec(iwin.document.body.wrappedJSObject + ""), "Waivers should get content-defined body stringification"); + + // Check Xray behavior. + ok(!/hah/.exec(iwin + ""), "Xrays should not get content-defined window stringification"); + ok(!/hah/.exec(iwin.document + ""), "Xrays should not get content-defined document stringification"); + ok(!/hah/.exec(iwin.document.body + ""), "Xrays should not get content-defined body stringification"); + + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug860494.xhtml b/js/xpconnect/tests/chrome/test_bug860494.xhtml new file mode 100644 index 0000000000..26bd1e13bd --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug860494.xhtml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=860494 +--> +<window title="Mozilla Bug 860494" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=860494" + target="_blank">Mozilla Bug 860494</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 860494 **/ + + SimpleTest.waitForExplicitFinish(); + + function go() { + var iwin = $('ifr').contentWindow; + // NB: mochitest-chrome actually runs the test as a content docshell. + is(iwin.top, window.top, "iframe names shouldn't shadow |top| via Xray"); + is(iwin.parent, window, "iframe names shouldn't shadow |parent| via Xray"); + ok(!!/http/.exec(iwin.location), "iframe names shouldn't shadow |location| via Xray"); + is(iwin.length, 7, "iframe names shouldn't shadow |length| via Xray"); + is(iwin.window, iwin, "iframe names shouldn't shadow |window| via Xray"); + is(iwin.navigator, Cu.unwaiveXrays(iwin.wrappedJSObject.navigator), + "iframe names shouldn't shadow |navigator| via Xray"); + ok(iwin.alert instanceof Function, + "iframe names shouldn't shadow |alert| via Xray"); + + // Now test XOWs. + var sb = new Cu.Sandbox("https://www.example.com"); + sb.win = iwin; + sb.topWin = top; + sb.parentWin = window; + sb.is = is; + sb.ok = ok; + Cu.evalInSandbox('ok(win.top === topWin, "iframe names shouldnt shadow |top| via cross-origin Xray");', sb); + Cu.evalInSandbox('ok(win.parent === parentWin, "iframe names shouldnt shadow |parent| via cross-origin Xray");', sb); + Cu.evalInSandbox('is(win.length, 7, "iframe names shouldnt shadow |length| via cross-origin Xray");', sb); + Cu.evalInSandbox('ok(win.window === win, "iframe names shouldnt shadow |window| via cross-origin Xray");', sb); + Cu.evalInSandbox('ok(win.navigator === win[5], "iframe names that correspond to non-cross-origin-visible properties should expose the subframe: navigator");', sb); + Cu.evalInSandbox('ok(win.alert === win[6], "iframe names that correspond to non-cross-origin-visible properties should expose the subframe: alert");', sb); + + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" type="content" onload="go();" src="https://example.org/tests/js/xpconnect/tests/mochitest/file_bug860494.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug865948.xhtml b/js/xpconnect/tests/chrome/test_bug865948.xhtml new file mode 100644 index 0000000000..85fb86874d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug865948.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=865948 +--> +<window title="Mozilla Bug 865948" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=865948" + target="_blank">Mozilla Bug 865948</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 865948 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + $('ifr').onload = null; + var sb = Cu.Sandbox(["https://example.com", "https://example.org"]); + sb.iwin = $('ifr').contentWindow; + sb.ok = ok; + Cu.evalInSandbox('try { iwin.location = "about:mozilla"; ok(false, "didnt throw"); } catch (e) { ok(!!/denied/.exec(e), "threw: " + e); }', sb); + SimpleTest.finish(); + } + + ]]> + </script> +<iframe id="ifr" type="content" onload="go();" src="https://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug866823.xhtml b/js/xpconnect/tests/chrome/test_bug866823.xhtml new file mode 100644 index 0000000000..39a24fc14e --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug866823.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=866823 +--> +<window title="Mozilla Bug 866823" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=866823" + target="_blank">Mozilla Bug 866823</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 866823 **/ + SimpleTest.waitForExplicitFinish(); + + function go() { + var iwin = $('ifr').contentWindow; + + // Make sure that Xray waivers can't be transitively extended onto objects + // for whom the extender may not waive. + var sb = new Cu.Sandbox(iwin, { wantXrays: true }); + sb.iwin = iwin; + ok(Cu.evalInSandbox('iwin.wrappedJSObject.top == iwin.top', sb), "Waiver does not propagate"); + Cu.evalInSandbox('iwin.wrappedJSObject.waiver = iwin.wrappedJSObject', sb); + ok(iwin.wrappedJSObject.eval('waiver == window'), "Waivers disappear same-compartment"); + + // Make sure that standard prototypes don't get COWs. + sb.objProto = Object.prototype; + try { + sb.eval('objProto.toString;', sb); + ok(false, "Should have thrown"); + } catch (e) { + ok(/denied|insecure/, "No silent failure when accessing properties on forbidden prototype"); + } + + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug895340.xhtml b/js/xpconnect/tests/chrome/test_bug895340.xhtml new file mode 100644 index 0000000000..ded70e6dd4 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug895340.xhtml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=895340 +--> +<window title="Mozilla Bug 895340" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=895340 " + target="_blank">Mozilla Bug 895340 </a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + SimpleTest.waitForExplicitFinish(); + SimpleTest.expectUncaughtException(); + + var finished = false; + + let listener = { + QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]) + }; + + listener.observe = function(aMessage) { + if (aMessage.message.includes("Will you report me?") && !finished) { + finished = true; + ok(true, "exception reported"); + Services.console.unregisterListener(listener); + SimpleTest.finish(); + } + }; + + Services.console.registerListener(listener); + + /* Throw an exception and verify that it gets reported. */ + let foo_obs = function() { + throw new Error("Will you report me?"); + }; + + Services.obs.addObserver(foo_obs, "foo"); + Services.obs.notifyObservers(null, "foo", "foo"); + Services.obs.removeObserver(foo_obs, "foo"); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug932906.xhtml b/js/xpconnect/tests/chrome/test_bug932906.xhtml new file mode 100644 index 0000000000..f7e839d980 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug932906.xhtml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=932906 +--> +<window title="Mozilla Bug 932906" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=932906" + target="_blank">Mozilla Bug 932906</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 932906 **/ + SimpleTest.waitForExplicitFinish(); + + function passToContent(shouldThrow) { + try { + $('ifr').contentWindow.obs = Services.obs; + ok(!shouldThrow, "Didn't throw when passing non-DOM XPCWN to content"); + } catch (e) { + ok(shouldThrow, "Threw when passing non-DOM XPCWN to content"); + ok(/denied/.test(e), "Threw correct exception: " + e); + } + } + + var gLoadCount = 0; + function loaded() { + ++gLoadCount; + if (gLoadCount == 1) + part1(); + else if (gLoadCount == 2) + part2(); + else + ok(false, "Didn't expect three loads"); + } + + function part1() { + + // Make sure that the pref is what we expect for mochitests. + is(Services.prefs.getBoolPref('dom.use_xbl_scopes_for_remote_xul'), true, + "Test harness set up like we expect"); + + + // First, test that we can't normally pass non-DOM XPCWNs to content. + passToContent(/* shouldThrow = */ true); + + // Now, make sure we _can_ for the remote xul case. We use SpecialPowers + // for the pref munging because it cleans up after us. + SpecialPowers.pushPrefEnv({set: [['dom.use_xbl_scopes_for_remote_xul', false]]}, function() { + $('ifr').contentWindow.location.reload(); + }); + } + + function part2() { + passToContent(/* shouldThrow = */ false); + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="loaded();" type="content" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_bug996069.xhtml b/js/xpconnect/tests/chrome/test_bug996069.xhtml new file mode 100644 index 0000000000..5693fd3447 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_bug996069.xhtml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=996069 +--> +<window title="Mozilla Bug 996069" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=996069" + target="_blank">Mozilla Bug 996069</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 996069 **/ + SimpleTest.waitForExplicitFinish(); + + function loaded() { + var ifr = document.getElementById("ifr").contentWindow; + var sb = new Cu.Sandbox([ifr], + { sandboxPrototype: ifr }); + + ifr.wrappedJSObject.finishTest = function() { + // If we got here we did not hit the NS_ReleaseAssert... + ok(true, "ExpandedPrincipal should not be inherited by content windows"); + + // But let's be sure that the new window does not have nsEP + newWin.wrappedJSObject.obj = Cu.evalInSandbox("var obj = { foo: 'bar' }; obj", sb); + try { + newWin.eval("obj.foo"); + ok(false, "newWin should not have access to object from a scope with ExpandedPrincipal"); + } catch (e) { + ok(/Permission denied/.exec(e.message), "newWin should not have access to object from a scope with ExpandedPrincipal"); + } + newWin.close(); + SimpleTest.finish(); + }; + + var newWin = Cu.evalInSandbox( + "window.open('https://example.org/chrome/js/xpconnect/tests/chrome/file_bug996069.html');", + sb); + } + + ]]> + </script> + <iframe id="ifr" onload="loaded();" type="content" src="https://example.org/chrome/js/xpconnect/tests/chrome/file_bug996069.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_chrometoSource.xhtml b/js/xpconnect/tests/chrome/test_chrometoSource.xhtml new file mode 100644 index 0000000000..b9920603a0 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_chrometoSource.xhtml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Mozilla Bug 761723" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=761723" target="_blank">Mozilla Bug 761723</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript" src="outoflinexulscript.js"></script> + <script type="application/javascript"><![CDATA[ +const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +let base = /.*\//.exec(window.location.href)[0]; +const {checkFromJSM} = ChromeUtils.import(base + "file_expandosharing.jsm"); + +function inlinefunction() { + return 42; +} + +var src; +src = inlinefunction.toSource(); +isnot(src.indexOf("return 42"), -1, "inline XUL script should have source"); +is(src.charAt(src.length - 1), "}", "inline XUL source should end with '}'"); +src = outoflinefunction.toSource(); +isnot(src.indexOf("return 42"), -1, "out of line XUL script should have source") +is(src.charAt(src.length - 1), "}", "out of line XUL source should end with '}'"); +src = checkFromJSM.toSource(); +isnot(src.indexOf("catch"), -1, "JSM should have source"); +var ns = {}; +Services.scriptloader.loadSubScript(base + "file_expandosharing.jsm", ns); +src = ns.checkFromJSM.toSource(); +isnot(src.indexOf("catch"), -1, "subscript should have source"); + +var reg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); +var resolvedBase = reg.convertChromeURL(NetUtil.newURI(base)).spec; + +ns = { + base, +}; +Services.scriptloader.loadSubScript(resolvedBase + "subscript.js", ns); +src = ns.checkFromJSM.toSource(); +isnot(src.indexOf("catch"), -1, "subscript of a subscript should have source"); + +ns = {}; +Services.scriptloader.loadSubScript(resolvedBase + "utf8_subscript.js", ns); +src = ns.f.toSource(); +isnot(src.indexOf("return 42;"), -1, "encoded subscript should have correct source"); + +ns = {}; +Services.scriptloader.loadSubScriptWithOptions(resolvedBase + "utf8_subscript.js", + {target: ns, ignoreCache: true}); +src = ns.f.toSource(); +isnot(src.indexOf("return 42;"), -1, "encoded subscript should have correct source"); + +ns = {}; +let b = new Blob([ + "var Exported = 17;" +]); +var blobUrl = URL.createObjectURL(b); +Services.scriptloader.loadSubScript(blobUrl, ns); +is(ns.Exported, 17, "subscript from a blob URL should work"); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_cloneInto.xhtml b/js/xpconnect/tests/chrome/test_cloneInto.xhtml new file mode 100644 index 0000000000..aa874bda96 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_cloneInto.xhtml @@ -0,0 +1,194 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<window title="Mozilla Bug 503926" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=964293" + target="_blank">Cu.cloneInto()</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + const TypedArrayThings = [ + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array', + ]; + + function checkThrows(f, msg, rgxp) { + try { + f(); + ok(false, "Should have thrown: " + msg); + } catch (e) { + ok(true, "Threw correctly - " + msg + " - " + e); + if (rgxp) + ok(rgxp.test(e), "Should throw correct exception: " + e); + } + } + + function getType(a) { + if (a === null || a === undefined) + return 'null'; + + if (Array.isArray(a)) + return 'array'; + + if (File.isInstance(a)) + return 'file'; + + if (Blob.isInstance(a)) + return 'blob'; + + if (TypedArrayThings.includes(a.constructor.name)) + return a.constructor.name; + + if (typeof a == 'object') + return 'object'; + + if (typeof a == 'function') + return 'function'; + + return 'primitive'; + } + + function compare(a, b) { + is (getType(a), getType(b), 'Type matches'); + + var type = getType(a); + if (type == 'array') { + is (a.length, b.length, 'Array.length matches'); + for (var i = 0; i < a.length; ++i) { + compare(a[i], b[i]); + } + + return; + } + + if (type == 'file' || type == 'blob') { + ok ( a === b, 'They should match'); + return; + } + + if (type == 'object') { + ok ( a !== b, 'They should not match'); + + var aProps = []; + for (let p in a) aProps.push(p); + + var bProps = []; + for (let p in b) bProps.push(p); + + is (aProps.length, bProps.length, 'Props match'); + is (aProps.sort().toString(), bProps.sort().toString(), 'Props names match'); + + for (let p in a) { + compare(a[p], b[p]); + } + + return; + } + + if (type == 'function') { + ok ( a !== b, 'They should not match'); + return; + } + + if (type != 'null') { + is (a, b, 'Same value'); + } + } + + var sandboxOptions = { + wantXrays: true, + wantExportHelpers: true, + }; + var sandbox = new Cu.Sandbox(window, sandboxOptions); + // The second sandbox is for testing the exportHelper version of the cloneInto + var sandbox2 = new Cu.Sandbox("https://example.com", sandboxOptions); + sandbox.sandbox2 = sandbox2; + sandbox2.sandbox = sandbox; + + function cloneAndTest(test) { + var output = sandbox.test = Cu.cloneInto(test, sandbox); + compare(test, output); + + output = Cu.evalInSandbox('cloneInto(test, sandbox2)', sandbox); + compare(test, output); + } + + function cloneAndTestWithFunctions(test) { + var output = sandbox.test = Cu.cloneInto(test, sandbox, { cloneFunctions: true }); + compare(test, output); + + output = Cu.evalInSandbox('cloneInto(test, sandbox2, { cloneFunctions: true })', sandbox); + // Note - We need to waive here, because functions are filtered out by object Xrays. + compare(test, Cu.waiveXrays(output)); + } + + var tests = [ + 1, + null, + true, + 'hello world', + [1, 2, 3], + { a: 1, b: 2 }, + new Date(), + { a: 1, b: {}, c: [1, 2, 3, {} ], e: 'hello world' }, + ]; + + for (var i = 0; i < tests.length; ++i) { + cloneAndTest(tests[i]); + } + + checkThrows(function() { Cu.cloneInto({ a() {} }, sandbox); }, + 'Function should not be cloned by default'); + + checkThrows(function() { Cu.cloneInto({ a: document }, sandbox); }, + 'Reflectors should not be wrapped by default'); + + var withReflectors = Cu.cloneInto({ doc: document, win: window }, sandbox, + { wrapReflectors: true }); + is(Cu.unwaiveXrays(Cu.waiveXrays(withReflectors).doc), document, "Document passes"); + is(Cu.unwaiveXrays(Cu.waiveXrays(withReflectors).win), window, "Window passes"); + + + checkThrows(function() { Cu.evalInSandbox('cloneInto({}, sandbox)', sandbox2); }, + 'CloneInto should only work on less privileged target scopes.', + /denied|insecure/); + + var cloneTarget = new Cu.Sandbox("https://example.com"); + var sameOriginSB = new Cu.Sandbox("https://example.com", { wantGlobalProperties: ['XMLHttpRequest'] }); + var crossOriginSB = new Cu.Sandbox("https://example.net", { wantGlobalProperties: ['XMLHttpRequest'] }); + sandbox2.cloneTarget = cloneTarget; + sandbox2.soXHR = Cu.evalInSandbox('new XMLHttpRequest()', sameOriginSB); + sandbox2.xoXHR = Cu.evalInSandbox('new XMLHttpRequest()', crossOriginSB); + sandbox2.chromeDoc = document; + Cu.evalInSandbox('function tryToClone(x) { return cloneInto({val: x}, cloneTarget, { wrapReflectors: true }).val; }', sandbox2); + is(Cu.evalInSandbox('tryToClone(soXHR)', sandbox2), sandbox2.soXHR, 'Same-origin wrapReflectors works'); + checkThrows(function() { Cu.evalInSandbox('tryToClone(chromeDoc)', sandbox2); }, + 'wrapReflectors may not wrap cross-origin reflectors', /unsupported value type/); + + + var test = { a() { return 42; } }; + cloneAndTestWithFunctions(test); + + // Check that inputs are properly passed through cloned functions: + test = { a(obj) { return obj; } }; + var clonedTest = Cu.cloneInto(test, sandbox, {cloneFunctions: true}); + var testInput = {}; + is(clonedTest.a(testInput), testInput, "Objects should be identical"); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_cows.xhtml b/js/xpconnect/tests/chrome/test_cows.xhtml new file mode 100644 index 0000000000..69d7d3e9e6 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_cows.xhtml @@ -0,0 +1,207 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500931 +--> +<window title="Mozilla Bug 522764" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=522764 " + target="_blank">Mozilla Bug 522764 </a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ +add_task(async () => { +var sandbox = new Cu.Sandbox("about:blank"); + +await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", + true]]}); + +/* eslint-disable no-eval */ + +function getCOW(x) { + if (typeof x != 'object' && typeof x != 'function') + return x; + x = Cu.waiveXrays(x); + var rval = {}; + if (typeof x == "function") + rval = eval(`(${x.toString()})`); + for (var i in x) { + if (x.__lookupGetter__(i)) + rval.__defineGetter__(i, eval(`(${x.__lookupGetter__(i).toString()})`)) + else + rval[i] = getCOW(x[i]); + } + return rval; +} + +// Give the sandbox a way to create ChromeObjectWrapped objects. +sandbox.getCOW = getCOW; + +// Define test API functions in the sandbox. +const TEST_API = ['is', 'isnot', 'ok', 'todo_is', 'todo_isnot', 'todo']; +TEST_API.forEach(function(name) { sandbox[name] = window[name]; }); + +sandbox.chromeGet = function (obj, prop) { return obj[prop]; }; + +function COWTests() { + function getNames(cow) { + let names = []; + for (let name in cow) { + names.push(name); + } + return names; + } + + // This function is actually stringified and run inside a + // sandbox with content privileges. + + // TODO: This could use some refactoring; creating helper + // functions like assertIsWritable(myObj, 'someproperty') might + // be useful. + + function isPropHidden(obj, propName, desc) { + try { + is(obj[propName], undefined, + "getting " + propName + " on " + desc + " should return undefined"); + ok(!(propName in obj), + propName + " on " + desc + " should act as if it doesn't exist"); + ok(!Object.hasOwnProperty.call(obj, propName), + propName + " on " + desc + " should act as if it doesn't exist"); + } catch (e) { + ok(false, "getting " + propName + " on " + desc + " threw " + e); + } + } + + const PROPS_TO_TEST = ['foo', 'bar', 'prototype']; + + var empty = {}; + var nonempty = {foo: 42, bar: 33}; + is(getCOW(empty).foo, undefined, + "shouldn't throw when accessing exposed properties that don't exist"); + + PROPS_TO_TEST.forEach(function(name) { + isPropHidden(getCOW(nonempty), name, "object without exposedProps"); + }); + + // Test function objects. + var func = function(x) { return 42; }; + func.foo = "foo property"; + var funcCOW = getCOW(func); + try { + funcCOW.foo; + ok(false, 'Functions are no longer COWable'); + } catch (e) { + ok(/denied|insecure/.test(e), 'Functions are no longer COWable'); + } + is(funcCOW(), 42, "Chrome functions should be callable"); + + // Test writable property + var writable = getCOW({}); + try { + ok(!("foo" in writable), + "non-existing write-only property shouldn't exist"); + writable.foo = 5; + ok(false, "writing to a write-only exposed prop should throw"); + } catch (e) { + ok(/Permission denied/.test(e), + "writing to a write-only exposed prop should throw the right error"); + } + is(writable.foo, undefined, + "reading from a write-only exposed prop should return undefined"); + try { + delete writable.foo; + ok(false, "deleting a write-only exposed prop should throw"); + } catch (e) { + ok(true, "deleting a write-only exposed prop should throw " + e); + } + + // Test readable property + var readable = { foo: 5, + bar: 6 }; + try { + isPropHidden(getCOW(readable), "foo", undefined, + "reading from a readable exposed prop shouldn't work"); + } catch (e) { + ok(false, "reading from a readable exposed prop shouldn't throw " + e); + } + try { + getCOW(readable).foo = 1; + ok(false, "writing to a read-only exposed prop should fail"); + } catch (e) { + ok(/Permission denied/.test(e), + "writing to a read-only exposed prop should fail"); + } + try { + delete getCOW(readable).foo; + ok(false, "deleting a read-only exposed prop shouldn't work"); + } catch (e) { + ok(/Permission denied/.test(e), + "deleting a read-only exposed prop should throw error"); + } + + try { + var props = getNames(getCOW(readable)); + is(props.length, 0, "COW w/ one exposed prop should not enumerate"); + } catch (e) { + ok(false, "COW w/ a readable prop should not raise exc " + + "on enumeration: " + e); + } + + // Test read/write property + var readwrite = getCOW({}); + try { + ok(!("foo" in readwrite), + "non-existing readwrite property shouldn't exist"); + readwrite.foo = 5; + ok(false, "writing to a readwrite exposed prop should throw"); + } catch (e) { + ok(/Permission denied/.test(e), + "writing to a readwrite exposed prop should throw the right error"); + } + try { + delete readwrite.foo; + ok(false, "deleting a readwrite prop should throw"); + } catch (e) { + ok(/Permission denied/.test(e), + "deleting a readwrite exposed prop should throw the right error"); + } + + // Readables and functions + try { + var COWFunc = getCOW((function() { return 5; })); + is(COWFunc(), 5, "COWed functions should be callable"); + } catch (e) { + todo(false, "COWed functions should not raise " + e); + } +} + +// Stringify the COW test suite and directly evaluate it in the sandbox. +Cu.evalInSandbox('(' + COWTests.toString() + ')()', sandbox); + +// Test that COWed objects passing from content to chrome get unwrapped. +function returnCOW() { + return getCOW({bar: 6}); +} + +var unwrapped = Cu.evalInSandbox( + '(' + returnCOW.toString() + ')()', + sandbox +); + +try { + is(unwrapped.bar, 6, + "COWs should be unwrapped when entering chrome space"); +} catch (e) { + todo(false, "COWs should be unwrapped when entering chrome space, " + + "not raise " + e); +} +}); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_discardSystemSource.xhtml b/js/xpconnect/tests/chrome/test_discardSystemSource.xhtml new file mode 100644 index 0000000000..86a353e580 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_discardSystemSource.xhtml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990353 +--> +<window title="Mozilla Bug 990353" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=990353" + target="_blank">Mozilla Bug 990353</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 990353 **/ + SimpleTest.waitForExplicitFinish(); + + function canary() { + // eslint-disable-next-line no-unused-vars + var someBitOfSource = 42; + } + + var gLoadCount = 0; + function frameLoaded() { + switch (++gLoadCount) { + case 1: + ok(/native code/.test(window[0].canary.toString()), "System function should be sourceless: " + window[0].canary.toString()); + ok(/native code/.test(window[0].onload.toString()), "System event handler should be sourceless: " + window[0].onload.toString()); + var sb = new Cu.Sandbox("https://www.example.com", { discardSource: true }); + Cu.evalInSandbox('function canary() { var someBitOfSource = 42; }', sb); + ok(/native code/.test(sb.canary.toString()), "Function from sandbox with explicit discarding should be sourceless"); + try { + window[0].throwSomething(); + ok(false, "should have thrown"); + } catch (e) { + ok(/some error/.test(e), "Threw exception as expected: " + e); + ok(/throwSomething/.test(e.stack), "Exception stack trace works: " + e.stack); + } + window[0].location = "https://example.org/tests/js/xpconnect/tests/chrome/file_discardSystemSource.html"; + break; + case 2: + ok(/someBitOfSource/.test(Cu.waiveXrays(window[0]).canary.toString()), "Content function should have source"); + ok(/someBitOfSource/.test(Cu.waiveXrays(window[0]).onload.toString()), "Content event handler should have source"); + testWorker(); + break; + } + } + + function testWorker() { + var worker = new window[0].wrappedJSObject.Worker('worker_discardSystemSource.js'); + worker.onmessage = function(evt) { + ok(/someBitOfSource/.test(evt.data), "Non-chrome worker should have source: " + evt.data); + var chromeWorker = new Worker('worker_discardSystemSource.js'); + chromeWorker.onmessage = function(evt) { + ok(/native code/.test(evt.data), "Chrome worker should not have source: " + evt.data); + SimpleTest.finish(); + } + } + } + + function go() { + // We should have our own source, because the pref wasn't enabled when we + // were loaded. + ok(/someBitOfSource/.test(canary.toString()), "Should have own source"); + + window[0].frameElement.onload = frameLoaded; + window[0].location = "file_discardSystemSource.html"; + } + addLoadEvent(function() { + SpecialPowers.pushPrefEnv({set: [['javascript.options.discardSystemSource', true]]}, go); + }); + + ]]> + </script> + <iframe></iframe> +</window> diff --git a/js/xpconnect/tests/chrome/test_documentdomain.xhtml b/js/xpconnect/tests/chrome/test_documentdomain.xhtml new file mode 100644 index 0000000000..8cffdc8e46 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_documentdomain.xhtml @@ -0,0 +1,100 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=601277 +--> +<window title="Mozilla Bug 601277" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=601277" + target="_blank">Mozilla Bug 601277</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Tests for document.domain. **/ + + SimpleTest.waitForExplicitFinish(); + + // Wait for the frames to load. + var gFramesLoaded = 0; + function frameLoaded() { + gFramesLoaded++; + if (gFramesLoaded == document.getElementsByTagName('iframe').length) + startTest(); + } + + function startTest() { + + // Grab all the content windows and waive Xray. Xray waivers only apply to + // chrome, so we can pass these references directly to content. + var win1A = document.getElementById('test1A').contentWindow.wrappedJSObject; + var win1B = document.getElementById('test1B').contentWindow.wrappedJSObject; + var win2 = document.getElementById('test2').contentWindow.wrappedJSObject; + var winBase = document.getElementById('base').contentWindow.wrappedJSObject; + + // Check the basics. + ok(win1A.tryToAccess(win1B), + "Same-origin windows should grant access"); + ok(!win1A.tryToAccess(win2), + "Cross-origin windows should not grant access"); + ok(!win1A.tryToAccess(winBase), + "Subdomain windows should not receive access"); + + // Store references now, while test1A and test1B are same-origin. + win1A.storeReference(win1B); + win1B.storeReference(win1A); + ok(win1A.tryToAccessStored(), "Stored references work when same-origin"); + win1A.evalFromB = Cu.unwaiveXrays(win1B.eval); // Crashtest for bug 1040181. + win1B.functionFromA = Cu.unwaiveXrays(win1A.Function); // Crashtest for bug 1040181. + ok(!win1A.invokingFunctionThrowsSecurityException('evalFromB'), "Should allow before document.domain"); + ok(!win1B.invokingFunctionThrowsSecurityException('functionFromA'), "Should allow before document.domain"); + + // Set document.domain on test1A. This should grant no access, since nobody + // else set it. + win1A.setDomain('example.org'); + ok(!win1A.tryToAccess(winBase), "base must collaborate too"); + ok(!winBase.tryToAccess(win1A), "base must collaborate too"); + ok(!win1A.tryToAccess(win1B), "No longer same-origin"); + ok(win1A.tryToAccessStored(), "We don't revoke access except through Window and Location"); + ok(!win1B.tryToAccess(win1A), "No longer same-origin"); + ok(win1B.tryToAccessStored(), "We don't revoke access except through Window and Location"); + ok(!win1A.invokingFunctionThrowsSecurityException('evalFromB'), "We don't revoke access except through Window and Location"); + ok(!win1B.invokingFunctionThrowsSecurityException('functionFromA'), "We don't revoke access except through Window and Location"); + + // Set document.domain on test1B. Now we're cooking with gas. + win1B.setDomain('example.org'); + ok(!win1B.tryToAccess(winBase), "base must collaborate too"); + ok(!winBase.tryToAccess(win1B), "base must collaborate too"); + ok(win1A.tryToAccess(win1B), "same-origin"); + ok(win1A.tryToAccessStored(), "same-origin"); + ok(win1B.tryToAccess(win1A), "same-origin"); + ok(win1B.tryToAccessStored(), "same-origin"); + + // Explicitly collaborate with base. + winBase.setDomain('example.org'); + ok(winBase.tryToAccess(win1A), "base collaborates"); + ok(win1A.tryToAccess(winBase), "base collaborates"); + + // All done. + SimpleTest.finish(); + } + + + ]]> + </script> + + <iframe id="test1A" onload="frameLoaded();" type="content" + src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/file_documentdomain.html" /> + <iframe id="test1B" onload="frameLoaded();" type="content" + src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/file_documentdomain.html" /> + <iframe id="test2" onload="frameLoaded();" type="content" + src="http://test2.example.org/tests/js/xpconnect/tests/mochitest/file_documentdomain.html" /> + <iframe id="base" onload="frameLoaded();" type="content" + src="http://example.org/tests/js/xpconnect/tests/mochitest/file_documentdomain.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_doublewrappedcompartments.xhtml b/js/xpconnect/tests/chrome/test_doublewrappedcompartments.xhtml new file mode 100644 index 0000000000..dd8ddd1bef --- /dev/null +++ b/js/xpconnect/tests/chrome/test_doublewrappedcompartments.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + + <iframe type="content" + src="http://example.org/tests/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html" + onload="go()" + id="ifr"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + const utils = SpecialPowers.DOMWindowUtils; + + function go() { + var wrappedWin = $('ifr').contentWindow; + is(typeof wrappedWin.expando, 'undefined', "Shouldn't be able to see the expando"); + + var unwrapped = wrappedWin.wrappedJSObject; + + var expando = unwrapped.expando; + isnot(expando, 'undefined', 'properly wrapped'); + is(typeof expando.querySelector, 'function', 'double wrapped'); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_envChain_event_handler.html b/js/xpconnect/tests/chrome/test_envChain_event_handler.html new file mode 100644 index 0000000000..f492e11512 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_envChain_event_handler.html @@ -0,0 +1,137 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1782450 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1782450</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> +"use strict"; + +SimpleTest.waitForExplicitFinish(); + +// Verify the environment chain for DOM event handlers described in +// js/src/vm/EnvironmentObject.h. + +let count = 0; +function check(envs, hasEval) { + is(envs.length, hasEval ? 8 : 6); + + let i = 0, env; + + if (hasEval) { + env = envs[i]; i++; + is(env.type, "BlockLexicalEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, true, "lexical must live in the function lexical env"); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, false); + + env = envs[i]; i++; + is(env.type, "CallObject"); + is(env.qualified, true, "qualified var live in the function call object"); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, false); + } else { + // qualified var and lexical live in function's frame. + } + + env = envs[i]; i++; + is(env.type, "NonSyntacticLexicalEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, false); + + env = envs[i]; i++; + is(env.type, "WithEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, true, "this property must live in the with env for button"); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, true, "button property must live in the with env for button"); + + env = envs[i]; i++; + is(env.type, "WithEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, true, "form property must live in the with env for form"); + is(env.document_prop, false); + is(env.button_prop, false); + + env = envs[i]; i++; + is(env.type, "WithEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, true, "document property must live in the with env for document"); + is(env.button_prop, false); + + env = envs[i]; i++; + is(env.type, "GlobalLexicalEnvironmentObject"); + is(env.qualified, false); + is(env.unqualified, false); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, false); + + env = envs[i]; i++; + is(env.type, "*global*"); + is(env.qualified, false); + is(env.unqualified, true, "unqualified name must live in the global"); + is(env.lexical, false); + is(env.prop, false); + is(env.form_prop, false); + is(env.document_prop, false); + is(env.button_prop, false); + + count++; + if (count == 2) { + SimpleTest.finish(); + } +} + </script> +</head> +<body> +<form id="form"> +<button id="button_optimized" onclick="event.preventDefault(); var qualified = 10; unqualified = 20; let lexical = 30; this.prop = 40; const funcs = Cu.getJSTestingFunctions(); const envs = []; let env = funcs.getInnerMostEnvironmentObject(); while (env) { envs.push({ type: funcs.getEnvironmentObjectType(env) || '*global*', qualified: !!Object.getOwnPropertyDescriptor(env, 'qualified'), unqualified: !!Object.getOwnPropertyDescriptor(env, 'unqualified'), lexical: !!Object.getOwnPropertyDescriptor(env, 'lexical'), prop: !!Object.getOwnPropertyDescriptor(env, 'prop'), document_prop: !!Object.getOwnPropertyDescriptor(env, 'document_prop'), form_prop: !!Object.getOwnPropertyDescriptor(env, 'form_prop'), button_prop: !!Object.getOwnPropertyDescriptor(env, 'button_prop'), }); env = funcs.getEnclosingEnvironmentObject(env); } check(envs, false); return false;">Click Me!</button> +<!-- Put direct eval to de-optimize function scope --> +<button id="button_unoptimized" onclick="event.preventDefault(); eval(''); var qualified = 10; unqualified = 20; let lexical = 30; this.prop = 40; const funcs = Cu.getJSTestingFunctions(); const envs = []; let env = funcs.getInnerMostEnvironmentObject(); while (env) { envs.push({ type: funcs.getEnvironmentObjectType(env) || '*global*', qualified: !!Object.getOwnPropertyDescriptor(env, 'qualified'), unqualified: !!Object.getOwnPropertyDescriptor(env, 'unqualified'), lexical: !!Object.getOwnPropertyDescriptor(env, 'lexical'), prop: !!Object.getOwnPropertyDescriptor(env, 'prop'), document_prop: !!Object.getOwnPropertyDescriptor(env, 'document_prop'), form_prop: !!Object.getOwnPropertyDescriptor(env, 'form_prop'), button_prop: !!Object.getOwnPropertyDescriptor(env, 'button_prop'), }); env = funcs.getEnclosingEnvironmentObject(env); } check(envs, true);">Click Me!</button> +</form> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1782450">Mozilla Bug 1782450</a> +<script type="application/javascript"> +"use strict"; +document.document_prop = 50; +const form = document.getElementById("form"); +form.form_prop = 50; +const button_unoptimized = document.getElementById("button_unoptimized"); +button_unoptimized.button_prop = 60; +button_unoptimized.click(); +const button_optimized = document.getElementById("button_optimized"); +button_optimized.button_prop = 60; +button_optimized.click(); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_evalInSandbox.xhtml b/js/xpconnect/tests/chrome/test_evalInSandbox.xhtml new file mode 100644 index 0000000000..ac65151101 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_evalInSandbox.xhtml @@ -0,0 +1,205 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + + <iframe src="http://example.org/tests/js/xpconnect/tests/mochitest/file_evalInSandbox.html" + onload="checkCrossOrigin(this)"> + </iframe> + <iframe src="chrome://mochitests/content/chrome/js/xpconnect/tests/chrome/file_evalInSandbox.html" + onload="checkSameOrigin(this)"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + const utils = window.windowUtils; + + function checkCrossOriginSandbox(sandbox) + { + is(utils.getClassName(sandbox), + "Proxy", + "sandbox was wrapped correctly"); + + is(utils.getClassName(Cu.evalInSandbox("this.document", sandbox)), + "Proxy", + "return value was rewrapped correctly"); + } + + function checkCrossOriginXrayedSandbox(sandbox) + { + ok(Cu.evalInSandbox("!('windowfoo' in window);", sandbox), + "the window itself Xray is an XrayWrapper"); + ok(Cu.evalInSandbox("('wrappedJSObject' in this.document);", sandbox), + "wrappers inside eIS are Xrays"); + ok(Cu.evalInSandbox("!('foo' in this.document);", sandbox), + "must not see expandos"); + ok('wrappedJSObject' in Cu.evalInSandbox("this.document", sandbox), + "wrappers returned from the sandbox are Xrays"); + ok(!("foo" in Cu.evalInSandbox("this.document", sandbox)), + "must not see expandos in wrappers returned from the sandbox"); + + ok('wrappedJSObject' in sandbox.document, + "values obtained from the sandbox are Xrays"); + ok(!("foo" in sandbox.document), + "must not see expandos in wrappers obtained from the sandbox"); + + } + + function checkCrossOrigin(ifr) { + var win = ifr.contentWindow; + var sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win, wantXrays: true } ); + + checkCrossOriginSandbox(sandbox); + checkCrossOriginXrayedSandbox(sandbox); + + sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win } ); + + checkCrossOriginSandbox(sandbox); + checkCrossOriginXrayedSandbox(sandbox); + + sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win, wantXrays: false } ); + + checkCrossOriginSandbox(sandbox); + + ok(Cu.evalInSandbox("('foo' in this.document);", sandbox), + "can see expandos"); + ok(!("foo" in Cu.evalInSandbox("this.document", sandbox)), + "must not see expandos in wrappers returned from the sandbox"); + ok(("foo" in Cu.waiveXrays(Cu.evalInSandbox("this.document", sandbox))), + "must see expandos in waived wrappers returned from the sandbox"); + + ok(!("foo" in sandbox.document), + "must not see expandos in wrappers obtained from the sandbox"); + ok("foo" in Cu.waiveXrays(sandbox.document), + "must see expandos in wrappers obtained from the sandbox"); + + testDone(); + } + + function checkSameOrigin(ifr) { + var win = ifr.contentWindow; + var sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win, wantXrays: true } ); + + ok(Cu.evalInSandbox("('foo' in this.document);", sandbox), + "must see expandos for a chrome sandbox"); + + sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win } ); + + ok(Cu.evalInSandbox("('foo' in this.document);", sandbox), + "must see expandos for a chrome sandbox"); + + sandbox = + new Cu.Sandbox(win, { sandboxPrototype: win, wantXrays: false } ); + + ok(Cu.evalInSandbox("('foo' in this.document);", sandbox), + "can see expandos for a chrome sandbox"); + + testDone(); + } + + var testsRun = 0; + function testDone() { + if (++testsRun == 2) + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + + try { + var sandbox1 = new Cu.Sandbox(this, { sandboxPrototype: undefined } ); + ok(false, "undefined is not a valid prototype"); + } + catch (e) { + ok(true, "undefined is not a valid prototype"); + } + + try { + var sandbox2 = new Cu.Sandbox(this, { wantXrays: undefined } ); + ok(false, "undefined is not a valid value for wantXrays"); + } + catch (e) { + ok(true, "undefined is not a valid value for wantXrays"); + } + + // Crash test for bug 601829. + try { + Cu.evalInSandbox('', null); + } catch (e) { + ok(true, "didn't crash on a null sandbox object"); + } + + try { + var sandbox3 = new Cu.Sandbox(this, { sameZoneAs: this } ); + ok(true, "sameZoneAs works"); + } + catch (e) { + ok(false, "sameZoneAs works"); + } + + // The 'let' keyword only appears with JS 1.7 and above. We use this fact + // to make sure that sandboxes get explict JS versions and don't inherit + // them from the most recent scripted frame. + function checkExplicitVersions() { + // eslint-disable-next-line no-undef + var sb = new Cu.Sandbox(sop); + Cu.evalInSandbox('let someVariable = 42', sb, '1.7'); + ok(true, "Didn't throw with let"); + try { + Cu.evalInSandbox('let someVariable = 42', sb); + ok(false, "Should have thrown with let"); + } catch (e) { + ok(true, "Threw with let: " + e); + } + try { + Cu.evalInSandbox('let someVariable = 42', sb, '1.5'); + ok(false, "Should have thrown with let"); + } catch (e) { + ok(true, "Threw with let: " + e); + } + } + var outerSB = new Cu.Sandbox(this); + Cu.evalInSandbox(checkExplicitVersions.toSource(), outerSB, '1.7'); + outerSB.ok = ok; + outerSB.sop = this; + Cu.evalInSandbox('checkExplicitVersions();', outerSB); + + const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); + addDebuggerToGlobal(globalThis); + + try { + let dbg = new Debugger(); + let sandbox = new Cu.Sandbox(this, { + invisibleToDebugger: false, + freshCompartment: true, + }); + dbg.addDebuggee(sandbox); + ok(true, "debugger added visible value"); + } catch(e) { + ok(false, "debugger could not add visible value"); + } + + try { + let dbg = new Debugger(); + let sandbox = new Cu.Sandbox(this, { invisibleToDebugger: true }); + dbg.addDebuggee(sandbox); + ok(false, "debugger added invisible value"); + } catch(e) { + ok(true, "debugger did not add invisible value"); + } + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_evalInWindow.xhtml b/js/xpconnect/tests/chrome/test_evalInWindow.xhtml new file mode 100644 index 0000000000..00299266f2 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_evalInWindow.xhtml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=877673 +--> +<window title="Mozilla Bug 877673" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + var sb = new Cu.Sandbox("https://example.org", {wantExportHelpers: true}); + sb.ok = ok; + + function executeIn(frame, script, exceptionCb) { + sb.frame = frame; + sb.exceptionCb = exceptionCb; + if (exceptionCb) { + return Cu.evalInSandbox("try {frame.eval('" + script + "'); ok(false, 'Exception should have been thrown.')} catch(e) {exceptionCb(e)}", sb); + } + + return Cu.evalInSandbox("frame.eval('" + script + "')", sb); + } + + function testSameOrigin(frame) { + frame.contentWindow.document.wrappedJSObject.str = "foobar"; + is(executeIn(frame.contentWindow, "document.str"), "foobar", + "Same origin string property access."); + + executeIn(frame.contentWindow, 'document.obj = {prop: "foobar"}'); + is((executeIn(frame.contentWindow, "document.obj")).prop, "foobar", + "Same origin object property access (cloning)."); + isnot(executeIn(frame.contentWindow, "document.obj"), frame.contentWindow.document.wrappedJSObject.obj, + "Ensure cloning for js objects."); + is(executeIn(frame.contentWindow, "document"), frame.contentWindow.document, + "Xrayables should just pass without cloning."); + is( executeIn(frame.contentWindow, "({a:{doc: document}})").a.doc, frame.contentWindow.document, + "Deep cloning works."); + + executeIn(frame.contentWindow, "throw 42", function(e){is(e, 42, + "Exception was thrown from script.")}); + + testDone(); + } + + function testCrossOrigin(frame) { + executeIn(frame.contentWindow, "var a = 42;", function(e){ok(e.toString().indexOf("Permission denied") > -1, + "Executing script in a window from cross origin should throw.");}); + testDone(); + } + + var testsRun = 0; + function testDone() { + if (++testsRun == 2) + SimpleTest.finish(); + } + ]]></script> + <iframe src="https://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" + onload="testSameOrigin(this)"> + </iframe> + <iframe src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html" + onload="testCrossOrigin(this)"> + </iframe> +</window> diff --git a/js/xpconnect/tests/chrome/test_exnstack.xhtml b/js/xpconnect/tests/chrome/test_exnstack.xhtml new file mode 100644 index 0000000000..48bcac5243 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_exnstack.xhtml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=735544 +--> +<window title="Mozilla Bug 735544" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=735544" + target="_blank">Mozilla Bug 735544</a> + <iframe id='ifr0' onload="frameDone(0);" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_exnstack.html" /> + <iframe id='ifr1' onload="frameDone(1);" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_exnstack.html" /> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 735544 - Allow exception stacks to cross compartment boundaries **/ + + SimpleTest.waitForExplicitFinish(); + + var gFramesDone = [false, false]; + function frameDone(idx) { + gFramesDone[idx] = true; + if (gFramesDone[0] && gFramesDone[1]) + startTest(); + } + + function throwAsChrome() { + + // Grab the iframe content windows. + var cwin0 = document.getElementById('ifr0').contentWindow; + var cwin1 = document.getElementById('ifr1').contentWindow; + + // Have cwin0 call a function on cwin1 that throws. + cwin0.wrappedJSObject.doThrow(cwin1); + } + + function startTest() { + + try { + throwAsChrome(); + ok(false, "should throw"); + } catch (e) { + + let stackFrames = e.stack.split("\n"); + + ok(/throwAsInner/.exec(stackFrames[0]), + "The bottom frame should be thrown by the inner"); + + ok(/throwAsOuter/.exec(stackFrames[2]), + "The 3rd-from-bottom frame should be thrown by the other"); + + ok(!/throwAsChrome/.exec(e.stack), + "The entire stack should not cross into chrome."); + } + + SimpleTest.finish(); + } + + ]]> + </script> + +</window> diff --git a/js/xpconnect/tests/chrome/test_expandosharing.xhtml b/js/xpconnect/tests/chrome/test_expandosharing.xhtml new file mode 100644 index 0000000000..1dc95239f4 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_expandosharing.xhtml @@ -0,0 +1,147 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=758415 +--> +<window title="Mozilla Bug 758415" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758415" + target="_blank">Mozilla Bug 758415</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Cross-Origin Xray Expando Sharing. **/ + SimpleTest.waitForExplicitFinish(); + + // Import our test JSM. We first strip the filename off + // the chrome url, then append the jsm filename. + var base = /.*\//.exec(window.location.href)[0]; + const {checkFromJSM} = ChromeUtils.import(base + "file_expandosharing.jsm"); + + // Wait for all child frames to load. + var gLoadCount = 0; + function frameLoaded() { + if (++gLoadCount == window.frames.length) + go(); + } + + function go() { + + // Empower the content windows with some functions. + var wins = document.getElementsByTagName('iframe'); + for (var i = 0; i < wins.length; ++i) { + var win = wins[i].contentWindow.wrappedJSObject; + win.ok = ok; + win.is = is; + } + + // Grab references to the content windows. We abbreviate the origins as follows: + // A: test1.example.org + // B: test2.example.org + // C: sub1.test1.example.org + window.gWinA1 = document.getElementById('frameA1').contentWindow; + window.gWinA2 = document.getElementById('frameA2').contentWindow; + window.gWinA3 = document.getElementById('frameA3').contentWindow; + window.gWinB = document.getElementById('frameB').contentWindow; + window.gWinC = document.getElementById('frameC').contentWindow; + + /* globals gWinA1, gWinA2, gWinA3, gWinB, gWinC */ + + // Test expando sharing with a JSM for different types of Xrays. + testJSM(Cu.unwaiveXrays(gWinC.wrappedJSObject.targetWN)); + testJSM(Cu.unwaiveXrays(gWinC.wrappedJSObject.targetDOM)); + testJSM(Cu.unwaiveXrays(gWinC.wrappedJSObject.targetJS)); + + // Make sure sandboxes never share expandos with anyone else. + testSandbox(Cu.unwaiveXrays(gWinB.wrappedJSObject.targetWN)); + testSandbox(Cu.unwaiveXrays(gWinB.wrappedJSObject.targetDOM)); + testSandbox(Cu.unwaiveXrays(gWinB.wrappedJSObject.targetJS)); + + // Test Content Xrays. + testContentXrays(); + + SimpleTest.finish(); + } + + // Make sure that expandos are shared between us and a JSM. + function testJSM(target) { + target.numProp = 42; + target.strProp = "foo"; + target.objProp = { bar: "baz" }; + checkFromJSM(target, is); + } + + function testSandbox(target) { + + // This gets both run in this scope and the sandbox scope. + var name = "harness"; + function placeExpando() { + target.prop = name; + } + + // Set up the sandboxes. Use an expanded principal to get xrays with + // exclusive expandos. + let sb1 = Cu.Sandbox(["https://test1.example.org", "https://test2.example.org"]); + let sb2 = Cu.Sandbox(["https://test1.example.org", "https://test2.example.org"]); + sb1.target = target; + sb2.target = target; + sb1.name = "sandbox1"; + sb2.name = "sandbox2"; + placeExpando(); + Cu.evalInSandbox(placeExpando.toSource() + "placeExpando();", sb1); + Cu.evalInSandbox(placeExpando.toSource() + "placeExpando();", sb2); + + // Make sure everyone sees a different value. + is(target.prop, "harness", "Harness sees its own value"); + is(Cu.evalInSandbox("target.prop", sb1), "sandbox1", "Sandbox 1 sees its own value"); + is(Cu.evalInSandbox("target.prop", sb2), "sandbox2", "Sandbox 2 sees its own value"); + } + + // Make sure that the origin tagging machinery works correctly and that we don't + // mix up chrome and content expandos. + function testContentXrays() { + + // Give A1 and A3 xrays to (same-origin) A2. + Cu.setWantXrays(gWinA1); + Cu.setWantXrays(gWinA3); + + gWinA1.wrappedJSObject.placeExpando('A1_expando', 11, gWinA2.document); + gWinA3.wrappedJSObject.placeExpando('A3_expando', 33, gWinA2.document); + gWinA2.document.Chrome_expando = 33; + + is(gWinA2.document.Chrome_expando, 33, "Read chrome expando properly"); + is(typeof gWinA2.document.A1_expando, 'undefined', "Chrome doesn't see content expandos"); + is(typeof gWinA2.document.A3_expando, 'undefined', "Chrome doesn't see content expandos"); + gWinA1.wrappedJSObject.checkExpando('A1_expando', 11, gWinA2.document, "Content sees proper expandos"); + gWinA3.wrappedJSObject.checkExpando('A1_expando', 11, gWinA2.document, "Content sees proper expandos"); + gWinA1.wrappedJSObject.checkExpando('A3_expando', 33, gWinA2.document, "Content sees proper expandos"); + gWinA3.wrappedJSObject.checkExpando('A3_expando', 33, gWinA2.document, "Content sees proper expandos"); + gWinA1.wrappedJSObject.checkExpando('Chrome_expando', null, gWinA2.document, "Content doesn't see chrome expandos"); + gWinA3.wrappedJSObject.checkExpando('Chrome_expando', null, gWinA2.document, "Content doesn't see chrome expandos"); + + // We very explicitly do not support expando sharing via document.domain. + // A comment in the implementation explains why. + gWinA1.document.domain = 'test1.example.org'; + gWinA2.document.domain = 'test1.example.org'; + gWinA3.document.domain = 'test1.example.org'; + gWinC.document.domain = 'test1.example.org'; + gWinC.wrappedJSObject.checkExpando('A1_expando', null, gWinA2.document, "document.domain should have no effect here"); + gWinC.wrappedJSObject.checkExpando('A3_expando', null, gWinA2.document, "document.domain should have no effect here"); + } + + ]]> + </script> + <iframe id="frameA1" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_expandosharing.html" /> + <iframe id="frameA2" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_expandosharing.html" /> + <iframe id="frameA3" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_expandosharing.html" /> + <iframe id="frameB" onload="frameLoaded();" type="content" src="https://test2.example.org/tests/js/xpconnect/tests/mochitest/file_expandosharing.html" /> + <iframe id="frameC" onload="frameLoaded();" type="content" src="https://sub1.test1.example.org/tests/js/xpconnect/tests/mochitest/file_expandosharing.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_exposeInDerived.xhtml b/js/xpconnect/tests/chrome/test_exposeInDerived.xhtml new file mode 100644 index 0000000000..ee6ad2d229 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_exposeInDerived.xhtml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=804630 +--> +<window title="Mozilla Bug 804630" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=804630" + target="_blank">Mozilla Bug 804630</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test to make sure that COWed objects can't expose properties from their prototypes. **/ + // Set up the sandbox. + var sb = new Cu.Sandbox("https://www.example.com"); + sb.ok = ok; + sb.is = is; + + // Make a chrome object that tries to expose objects off its prototype. + sb.proto = { read: 42, readWrite: 32 }; + sb.obj = {}; + sb.obj.__proto__ = sb.proto; + + // Make sure we can't access any of the properties on the prototype directly. + Cu.evalInSandbox('is(proto.read, undefined, "proto.read inaccessible");', sb); + Cu.evalInSandbox('var wrote = false; ' + + 'try { proto.readWrite = 12; wrote = true; } catch(e) {} ' + + ' ok(!wrote, "Should not write proto property");', sb); + + // Make sure we can't access the exposed properties via the derived object. + Cu.evalInSandbox('is(obj.read, undefined, "obj.read inaccessible");', sb); + Cu.evalInSandbox('is(obj.readWrite, undefined, "obj.readWrite is not readable");', sb); + Cu.evalInSandbox('try { obj.readWrite = 8; ok(false, "obj.readWrite is not writable"); } catch (e) {};', + sb); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_inlineScripts.html b/js/xpconnect/tests/chrome/test_inlineScripts.html new file mode 100644 index 0000000000..cb5f5ed530 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_inlineScripts.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <meta charset=utf-8> + <title>Tests for nsIScriptError</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <div id="log"></div> + + <!-- Verify that column is correct, even for inline scripts with HTML on the same line --> + <span>some html</span> <script>var inlineScriptStack = new Error().stack;</script> + <script> + function waitForError (expectedMessage){ + return new Promise(resolve => { + const listener = { + QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]) + }; + + listener.observe = function(message) { + if (message.message.includes(expectedMessage)) { + message.QueryInterface(Ci.nsIScriptError); + resolve(message); + Services.console.unregisterListener(listener); + } + }; + + Services.console.registerListener(listener); + }); + } + + var onInlineScriptError = waitForError("doThrow"); + var onModuleError = waitForError("doThrowInModule"); + SimpleTest.expectUncaughtException(); + </script> + <span>some more html</span><script>doThrow() // eslint-disable-line no-undef</script> + <script>var b;</script><hr><script type="module">SimpleTest.expectUncaughtException();doThrowInModule() // eslint-disable-line no-undef</script> + <script> + add_task(async () => { + info("Check line and column information in Error#stack"); + const { groups } = inlineScriptStack.match(/(?<line>\d+):(?<column>\d+)/); + is(groups.line, "9", "line of Error#stack in inline script is correct"); + is(groups.column, "58", "column of Error#stack in inline script is correct"); + + info("Check line and column information Error message in inline script"); + const errorMessage = await onInlineScriptError; + is(errorMessage.lineNumber, 33, "The exception line is correct"); + is(errorMessage.columnNumber, 38, "The exception column is correct"); + + info("Check line and column information Error message in inline module"); + const errorMessageInModule = await onModuleError; + is(errorMessageInModule.lineNumber, 34, "The module exception line is correct"); + is(errorMessageInModule.columnNumber, 89, "The module exception column is correct"); + }); + </script> +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/chrome/test_localstorage_with_nsEp.xhtml b/js/xpconnect/tests/chrome/test_localstorage_with_nsEp.xhtml new file mode 100644 index 0000000000..dbc0ea6a61 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_localstorage_with_nsEp.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=980023 +--> +<window title="Mozilla Bug 980023 " + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=980023" + target="_blank">Mozilla Bug 980023 </a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for localstorage access with expanded principal. **/ + SimpleTest.waitForExplicitFinish(); + + function go() { + var iwin = document.getElementById('ifr').contentWindow; + var sb = new Cu.Sandbox([iwin], {sandboxPrototype: iwin}); + Cu.evalInSandbox("window.localStorage.test_localstorage_with_nsEp = 3",sb); + is(Cu.evalInSandbox("window.localStorage.test_localstorage_with_nsEp",sb), "3"); + is(iwin.localStorage.test_localstorage_with_nsEp, "3"); + iwin.localStorage.removeItem("test_localstorage_with_nsEp"); + SimpleTest.finish(); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_matches.xhtml b/js/xpconnect/tests/chrome/test_matches.xhtml new file mode 100644 index 0000000000..96472bc8ac --- /dev/null +++ b/js/xpconnect/tests/chrome/test_matches.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + + <iframe src="http://example.org/tests/js/xpconnect/tests/mochitest/file_matches.html" + onload="runTest(this)"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + function runTest(ifr) + { + var doc = ifr.contentDocument; + var docElem = doc.documentElement; + + var res = doc.createElement('div').matches('div'); + is(res, true, "matches call through xray, regular case"); + + res = docElem.matches.call( + doc.createElement('div'), 'div'); + is(res, true, "matches call through xray, with .call"); + + var sb = new Cu.Sandbox(ifr.contentWindow); + sb.doc = doc; + var str = "doc.documentElement.matches.call(doc.createElement( 'div' ),'div')"; + res = Cu.evalInSandbox(str, sb); + is(res, true, "matches call through xray (same origin), with .call"); + + docElem.matches = function(){return false}; + res = docElem.matches.call(doc.createElement( 'div' ),'div'); + is(res, false, "shadowing matches with an expando on the xray wrapper"); + + SimpleTest.finish(); + } + + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_nodelists.xhtml b/js/xpconnect/tests/chrome/test_nodelists.xhtml new file mode 100644 index 0000000000..d3d4dfc34e --- /dev/null +++ b/js/xpconnect/tests/chrome/test_nodelists.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Test nodelists from chrome" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + function go() { + var win = $('ifr').contentWindow; + var list = win.document.getElementsByTagName('p'); + is(list.length, 3, "can get the length"); + ok(HTMLParagraphElement.isInstance(list[0]), "can get list[0]"); + is(list[0], list.item(0), "list.item works"); + is(list.item, list.item, "don't recreate functions for each get"); + + var list2 = list[2]; + ok(HTMLParagraphElement.isInstance(list[2]), "list[2] exists"); + ok("2" in list, "in operator works"); + + is(win.document.body.removeChild(win.document.body.lastChild), list2, "remove last paragraph element"); + ok(!("2" in list), "in operator doesn't see phantom element"); + is(list[2], undefined, "no node there!"); + + var optionList = win.document.createElement("select").options; + var option = win.document.createElement("option"); + optionList[0] = option; + is(optionList.item(0), option, "Creators work"); + + option = win.document.createElement("option"); + optionList[0] = option; + is(optionList.item(0), option, "Setters work"); + + SimpleTest.finish(); + } + ]]></script> + + <iframe id="ifr" + src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_nodelists.html" + onload="go()" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_nsScriptErrorWithStack.html b/js/xpconnect/tests/chrome/test_nsScriptErrorWithStack.html new file mode 100644 index 0000000000..99a4727756 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_nsScriptErrorWithStack.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for 814497</title> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<div id="log"></div> +<script> + var c = Cc; + + SimpleTest.waitForExplicitFinish(); + SimpleTest.expectUncaughtException(); + + // /!\ Line number is important in this test, + // we are asserting the following functions line # + function failingStack() { + nestedFunction(); + } + function nestedFunction() { + // eslint-disable-next-line no-undef + doesntExistsAndThrow(); + } + + var TestObserver = { + QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), + + observe: function test_observe(aSubject) + { + if (!(aSubject instanceof Ci.nsIScriptError)) { + return; + } + dump("stack: "+aSubject.stack+"\n"); + + // Main assertions + var s = aSubject.stack; + ok(!!s, "has first frame"); + ok(s.source.includes("test_nsScriptErrorWithStack.html"), "source is correct"); + is(s.line, 19, "line is correct"); + is(s.column, 5, "column is correct"); + is(s.functionDisplayName, "nestedFunction"); + s = s.parent; + ok(!!s, "has second frame"); + ok(s.source.includes("test_nsScriptErrorWithStack.html"), "source is correct"); + is(s.line, 15, "line is correct"); + is(s.column, 5, "column is correct"); + is(s.functionDisplayName, "failingStack"); + // We shouldn't have any more frame as we used setTimeout + ok(!s.parent, "has no more frames"); + + // Cleanup + Services.console.unregisterListener(TestObserver); + SimpleTest.finish(); + } + }; + + Services.console.registerListener(TestObserver); + + // use setTimeout in order to prevent throwing from test frame + // and so have a clean stack frame with just our method calls + setTimeout(failingStack, 0); +</script> diff --git a/js/xpconnect/tests/chrome/test_onGarbageCollection.html b/js/xpconnect/tests/chrome/test_onGarbageCollection.html new file mode 100644 index 0000000000..ce056ed354 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_onGarbageCollection.html @@ -0,0 +1,48 @@ +<!doctype html> +<html> + <head> + <title>Bug 1150253 - Sanity test for the SpiderMonkey Debugger API's onGarbageCollection hook</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"> + </script> + </head> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1150253" + target="_blank">Mozilla Bug 1150253</a> + + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + const { gc } = Cu.getJSTestingFunctions(); + + // Instantiate `Debugger` in a sandbox as Debugger requires to be created + // in a compartment different than the debuggee. + let sandbox = Cu.Sandbox( + Components.Constructor("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), + { + freshCompartment: true, + wantGlobalProperties: ["ChromeUtils"], + } + ); + Cu.evalInSandbox(` +const { addDebuggerToGlobal } = ChromeUtils.importESModule( + 'resource://gre/modules/jsdebugger.sys.mjs' +); +addDebuggerToGlobal(globalThis); +`, sandbox + ); + + const dbg = new sandbox.Debugger(this); + + dbg.memory.onGarbageCollection = function (data) { + // Don't keep calling this hook after we finish. + dbg.memory.onGarbageCollection = undefined; + dbg.removeAllDebuggees(); + + ok(data, "The onGarbageCollection hook was fired."); + SimpleTest.finish(); + }; + + gc(); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/chrome/test_precisegc.xhtml b/js/xpconnect/tests/chrome/test_precisegc.xhtml new file mode 100644 index 0000000000..56f047843e --- /dev/null +++ b/js/xpconnect/tests/chrome/test_precisegc.xhtml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 661927" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + Cu.schedulePreciseGC( + function() { + ok(true, "callback executed"); + SimpleTest.finish(); + }); + SimpleTest.waitForExplicitFinish(); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_private_field_cows.xhtml b/js/xpconnect/tests/chrome/test_private_field_cows.xhtml new file mode 100644 index 0000000000..24fe9d5e0a --- /dev/null +++ b/js/xpconnect/tests/chrome/test_private_field_cows.xhtml @@ -0,0 +1,131 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window title="Mozilla Bug ????" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=>?????" target="_blank">Mozilla Bug ???? </a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /* eslint-disable no-eval */ + + add_task(async () => { + var sandbox = new Cu.Sandbox("about:blank"); + + await SpecialPowers.pushPrefEnv({ + "set": [["security.allow_eval_with_system_principal", + true]] + }); + + function getCOW(x) { + if (typeof x != 'object' && typeof x != 'function') + return x; + x = Cu.waiveXrays(x); + var rval = {}; + if (typeof x == "function") + rval = eval(`(${x.toString()})`); + for (var i in x) { + if (x.__lookupGetter__(i)) + rval.__defineGetter__(i, eval(`(${x.__lookupGetter__(i).toString()})`)) + else + rval[i] = getCOW(x[i]); + } + return rval; + } + + // Give the sandbox a way to create ChromeObjectWrapped objects. + sandbox.getCOW = getCOW; + + // Define test API functions in the sandbox. + const TEST_API = ['is', 'ok', 'info']; + TEST_API.forEach(function (name) { sandbox[name] = window[name]; }); + + + function COWTests() { + + var empty = {}; + var cow = getCOW(empty); + + // Because private fields may not be enabled, we construct A via the below eval of an IFFE, + // and return early if it syntax errors. + var A; + try { + A = eval(`(function(){ + class Base { + constructor(o) { + return o; + } + }; + + class A extends Base { + #x = 12; + static gx(o) { + return o.#x; + } + + static sx(o, v) { + o.#x = v; + } + }; + return A; + })();`); + } catch (e) { + is(e instanceof SyntaxError, true, "Syntax error: Private fields not enabled"); + is(/private fields are not currently supported/.test(e.message), true, "correct message"); + return; + } + + new A(empty); + is(A.gx(empty), 12, "Correct value read"); + A.sx(empty, 'wrapped'); + + function assertThrewInstance(f, error) { + var threw = true; + try { + f(); + threw = false; + } catch (e) { + is(e instanceof error, true, "Correct Error"); + } + is(threw, true, "Threw!"); + } + + // Note: These throw warnings: + // + // WARNING: Silently denied access to property ##x: Access to privileged JS object not permitted (@chrome://mochitests/content/chrome/js/xpconnect/tests/chrome/test_private_field_cows.xhtml:108:27): file /js/xpconnect/wrappers/XrayWrapper.cpp, line 226 + // + // It's not clear to me if we ougth to wire this up to -not-? I suspect this is a result of invoking + // the has + assertThrewInstance(() => A.gx(cow), TypeError); + assertThrewInstance(() => A.sx(cow, 'unwrapped'), TypeError); + assertThrewInstance(() => new A(cow), Error); + assertThrewInstance(() => A.gx(cow), TypeError); + } + + // Stringify the COW test suite and directly evaluate it in the sandbox. + Cu.evalInSandbox('(' + COWTests.toString() + ')()', sandbox); + + // Test that COWed objects passing from content to chrome get unwrapped. + function returnCOW() { + return getCOW({ + bar: 6 + }); + } + + // eslint-disable-next-line no-unused-vars + var unwrapped = Cu.evalInSandbox( + '(' + returnCOW.toString() + ')()', + sandbox + ); + + ok(true, "passed"); + }); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_sandboxImport.xhtml b/js/xpconnect/tests/chrome/test_sandboxImport.xhtml new file mode 100644 index 0000000000..1ae1f02ad7 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_sandboxImport.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=533596 +--> +<window title="Mozilla Bug 533596" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + function checkWrapped(obj) { + var utils = window.windowUtils; + is(utils.getClassName(obj), "Proxy", "right type of wrapper"); + } + + var sandbox = new Cu.Sandbox("about:blank"); + sandbox.importFunction(function() { return "PASS"; }, "foo"); + sandbox.importFunction(function bar() { return "PASS"; }); + sandbox.importFunction(checkWrapped); + is(Cu.evalInSandbox("foo()", sandbox), "PASS", "importFunction works"); + is(Cu.evalInSandbox("bar()", sandbox), "PASS", "importFunction works"); + Cu.evalInSandbox("checkWrapped({})", sandbox); + + var importer = sandbox.importFunction; + importer(function() { return "PASS"; }, "bar"); + is(Cu.evalInSandbox("bar()", sandbox), "PASS", "unbound importFunction works"); + is(typeof this.bar, "undefined", "didn't import into our global"); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_scriptSettings.xhtml b/js/xpconnect/tests/chrome/test_scriptSettings.xhtml new file mode 100644 index 0000000000..f78b921466 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_scriptSettings.xhtml @@ -0,0 +1,128 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=937317 +--> +<window title="Mozilla Bug 937317" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=937317" + target="_blank">Mozilla Bug 937317</a> + </body> + + <!-- test code goes here --> + <iframe src="./file_empty.html"></iframe> + <script type="application/javascript"> + <![CDATA[ + + /** Test for the script settings stack. **/ + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", + true]]}); + addLoadEvent(function() { + const {PromiseUtils} = ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm"); + let iwin = window[0]; + + // Smoketest. + is(Cu.getIncumbentGlobal(), window, "smoketest"); + + // Calling a cross-compartment non-scripted function changes the + // compartment, but not the incumbent script settings object. + var sb = new Cu.Sandbox(window, { wantComponents: true }); + is(sb.Components.utils.getIncumbentGlobal(), window, "cross-compartment sb non-scripted"); + is(iwin.Components.utils.getIncumbentGlobal(), window, "cross-compartment win non-scripted"); + + // If we call a scripted function in the other compartment, that becomes + // the incumbent script. + function gib() { return Cu.getIncumbentGlobal(); }; + Cu.evalInSandbox(gib.toSource(), sb); + iwin.eval(gib.toSource()); + is(sb.gib(), sb, "cross-compartment sb scripted"); + is(iwin.gib(), iwin, "cross-compartment win scripted"); + + // Eval-ing top-level script in another component makes that compartment the + // incumbent script. + is(Cu.evalInSandbox('Components.utils.getIncumbentGlobal()', sb), sb, 'eval sb'); + is(iwin.eval('Components.utils.getIncumbentGlobal()'), iwin, 'eval iwin'); + + // Make sure that the callback mechanism works. + function makeCallback(expectedGlobal, deferred, kind) { + function cb(incumbentGlobal) { + is(incumbentGlobal, expectedGlobal, "Callback got the right incumbent global: " + kind); + if (deferred) + deferred.resolve(); + } + info("Generated callback: " + kind); + return cb; + } + + var bound = Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, undefined, "simple bound")); + is(bound(), window, "Bound method returns the right global"); + + // Callbacks grab the incumbent script at the time of invocation. + // + // Note - We avoid calling the initial defer |d| so that it's not in-scope for everything below. + let initialDefer = PromiseUtils.defer(); + setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, initialDefer, "same-global setTimeout")), 0); + initialDefer.promise.then(function() { + + // Try cross-global setTimeout where |window| is the incumbent script when the callback is created. + let d = PromiseUtils.defer(); + iwin.setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global setTimeout by |window|")), 0); + return d.promise; + }).then(function() { + + // Try cross-global setTimeout where |iwin| is the incumbent script when the callback is created. + let d = PromiseUtils.defer(); + iwin.wrappedJSObject.timeoutFun = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout by |iwin|")); + iwin.eval('setTimeout(timeoutFun, 0);'); + return d.promise; + }).then(function() { + + // The incumbent script override doesn't take effect if the callback is scripted. + let d = PromiseUtils.defer(); + iwin.wrappedJSObject.timeoutFun2 = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout of scripted function")); + iwin.eval('var timeoutFun2Wrapper = function() { timeoutFun2(); }'); + setTimeout(iwin.wrappedJSObject.timeoutFun2Wrapper, 0); + return d.promise; + }).then(function() { + + // Try event listeners. + let d = PromiseUtils.defer(); + let body = iwin.document.body; + body.addEventListener('click', Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global event listener"))); + body.dispatchEvent(new iwin.MouseEvent('click')); + return d.promise; + + }).then(function() { + + // Try an event handler set by |iwin|. + let d = PromiseUtils.defer(); + let body = iwin.document.body; + iwin.wrappedJSObject.handler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global event handler")); + iwin.eval('document.body.onmousemove = handler'); + body.dispatchEvent(new iwin.MouseEvent('mousemove')); + return d.promise; + + }).then(function() { + + // Try an event handler compiled by a content attribute. + let d = PromiseUtils.defer(); + let body = iwin.document.body; + iwin.wrappedJSObject.innerHandler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global compiled event handler")); + iwin.eval("document.body.setAttribute('onmouseout', 'innerHandler()')"); + body.dispatchEvent(new iwin.MouseEvent('mouseout')); + return d.promise; + }).then(function() { + + SimpleTest.finish(); + }); + }); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_scripterror.html b/js/xpconnect/tests/chrome/test_scripterror.html new file mode 100644 index 0000000000..38cb316467 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_scripterror.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Tests for nsIScriptError</title> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<div id="log"></div> +<script> +function awaitScriptError(fun) { + // Use setTimeout in order to prevent throwing from test frame + // and to have a clean stack frame. + setTimeout(fun, 0) + + return new Promise(resolve => { + const observer = { + QueryInterface: ChromeUtils.generateQI(["nsIObserver"]), + observe(message) { + if (!(message instanceof Ci.nsIScriptError)) { + return; + } + + Services.console.unregisterListener(observer); + resolve(message); + } + }; + + Services.console.registerListener(observer); + }); +} + +function hasExpectedProperties(message, exception) { + is(message.hasException, true, "has exception"); + is(message.exception, exception, "has correct exception"); + + ok(message.stack != null, "has stack"); + is(message.stack?.source, location.href, "correct stack source") + + is(message.sourceName, location.href, "has correct sourceName/filename"); + ok(message.lineNumber > 0, "has lineNumber"); + + is(message.innerWindowID, window.windowGlobalChild.innerWindowId, + "correct innerWindowID"); +} + +add_task(async () => { + await SpecialPowers.pushPrefEnv({"set": [ + ["javascript.options.asyncstack_capture_debuggee_only", false], + ]}); + + const TESTS = [ + "abc", + new Error("foobar"), + {foo: "bar"} + ]; + + for (let test of TESTS) { + // First test as regular throw + SimpleTest.expectUncaughtException(); + let message = await awaitScriptError(function testName() { + throw test; + }); + hasExpectedProperties(message, test); + is(message.isPromiseRejection, false, "not a rejected promise"); + + // Now test as uncaught promise rejection + message = await awaitScriptError(function testName() { + Promise.reject(test); + }); + hasExpectedProperties(message, test); + is(message.isPromiseRejection, true, "is a rejected promise"); + + // Uncaught rejection from async function + message = await awaitScriptError(async function testName() { + throw test; + }); + hasExpectedProperties(message, test); + is(message.isPromiseRejection, true, "is a rejected promise"); + + // Uncaught rejection from then callback + message = await awaitScriptError(async function testName() { + Promise.resolve().then(() => { + throw test; + }); + }); + hasExpectedProperties(message, test); + is(message.isPromiseRejection, true, "is a rejected promise"); + } +}); +</script> diff --git a/js/xpconnect/tests/chrome/test_secureContexts.html b/js/xpconnect/tests/chrome/test_secureContexts.html new file mode 100644 index 0000000000..956e609d5f --- /dev/null +++ b/js/xpconnect/tests/chrome/test_secureContexts.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1273687 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1430164</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <iframe id="t" src="https://example.com"></iframe> + <iframe id="i" src="http://example.com"></iframe> + <script type="application/javascript"> + /** Test for Bug 1273687 **/ + SimpleTest.waitForExplicitFinish(); + + window.onload = () => { + /* globals t, i */ + runTest(t, true); + runTest(i, false); + + // Check we can inherit the system principal + var s = new Cu.Sandbox(window, { wantGlobalProperties: ["isSecureContext"] } ); + s.ok = ok; + Cu.evalInSandbox('ok(isSecureContext)', s); + + // Check options insecure works + let sb = new Cu.Sandbox('https://www.example.com', + { forceSecureContext: false, + wantGlobalProperties: + ["isSecureContext"] + }); + ok(!Cu.evalInSandbox('isSecureContext', sb)); + + // Check options secure works + let sb2 = new Cu.Sandbox('https://www.example.com', + { forceSecureContext: true, + wantGlobalProperties: + ["isSecureContext"] + }); + ok(Cu.evalInSandbox('isSecureContext', sb2)); + SimpleTest.finish(); + }; + + // Check dom window inheritance works + function runTest(ifr, expectIsSecureContext) { + let frameWin = ifr.contentWindow; + let s = new Cu.Sandbox(frameWin, { wantGlobalProperties: ["isSecureContext"] }); + is(expectIsSecureContext, Cu.evalInSandbox('isSecureContext', s)); + + // Ensure the implementation of 'wantGlobalProperties' matches the DOM window prototype + let s2 = new Cu.Sandbox(frameWin, { sandboxPrototype: frameWin }); + is(expectIsSecureContext, Cu.evalInSandbox('isSecureContext', s2)); + } + </script> +</head> +</html> diff --git a/js/xpconnect/tests/chrome/test_sharedChromeCompartment.html b/js/xpconnect/tests/chrome/test_sharedChromeCompartment.html new file mode 100644 index 0000000000..b653f19751 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_sharedChromeCompartment.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1517694 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1517694</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> +"use strict"; + +/** Test for Bug 1517694 **/ +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +SimpleTest.waitForExplicitFinish(); + +function go() { + var frame = $('subframe'); + frame.onload = null; + + var isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment; + + ok(isSameCompartment(window, frame.contentWindow), + "System window is in same compartment"); + + var sameCompSb = Cu.Sandbox(window); + ok(isSameCompartment(window, sameCompSb), + "System sandbox is in same compartment"); + + var ownCompSb = Cu.Sandbox(window, {freshCompartment: true}); + ok(!isSameCompartment(window, ownCompSb), + "Sandbox created with freshCompartment is in separate compartment"); + + // Sandbox created in fresh-compartment sandbox must be in shared + // compartment. + var sb = Cu.evalInSandbox(` + let principal = + Cc["@mozilla.org/systemprincipal;1"].getService(Ci.nsIPrincipal); + Cu.Sandbox(principal) + `, ownCompSb); + ok(isSameCompartment(window, sb), + "System sandbox created in different compartment is in system compartment"); + + ok(isSameCompartment(window, XPCOMUtils), + "Object defined in JSM is in same compartment"); + + SimpleTest.finish(); +} + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1517694">Mozilla Bug 1517694</a> + +<iframe id="subframe" src="file_empty.html" onload="go()"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_weakmap_keys_preserved.xhtml b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved.xhtml new file mode 100644 index 0000000000..c7c5d4369d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved.xhtml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=673468 +--> +<window title="Mozilla Bug " + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=" + target="_blank">Mozilla Bug 673468</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 673468 **/ + + let system = Cc["@mozilla.org/systemprincipal;1"].createInstance(); + let sandbox = Cu.Sandbox(system); + let map = new sandbox.WeakMap(); + let obj = {}; + map.set(obj, {}); + + Cu.forceGC(); + + ok(map.has(obj), "Weakmap still contains our wrapper!"); + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xhtml b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xhtml new file mode 100644 index 0000000000..faaaa8b9ac --- /dev/null +++ b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xhtml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=673468 +--> +<window title="Mozilla Bug " + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a id="testelem" href="https://bugzilla.mozilla.org/show_bug.cgi?id=" + target="_blank">Mozilla Bug 673468</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 673468 **/ + SimpleTest.waitForExplicitFinish(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + let get_live_dom = function () { + return document.getElementById("testelem"); + }; + + let wrappers_as_keys_test = function () { + let e = new MessageEvent("foo", { bubbles: false, cancellable: false, + data: { dummy: document.createXULElement("foo") }}); + window.eeeevent = e; + + let live_dom = e.data.dummy; + let dead_dom = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + let dead_child = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + dead_dom.appendChild(dead_child); + is(dead_dom.children.length, 1, "children have wrong length"); + let wrappee = {}; + + dead_dom.abcxyz = wrappee; + + let system = Cc["@mozilla.org/systemprincipal;1"].createInstance(); + let sandbox = Cu.Sandbox(system); + + sandbox.wrapper = wrappee; + sandbox.value = dead_dom; + let map = Cu.evalInSandbox("wm = new WeakMap(); wm.set(wrapper, value); wm", sandbox); + sandbox.wrapper = null; + sandbox.value = null; + + live_dom.xyzabc = {wrappee, m: map, sb: sandbox}; + + let key = ChromeUtils.nondeterministicGetWeakMapKeys(map)[0]; + let value = map.get(key); + is(value.children.length, 1, "children have wrong length"); + } + + wrappers_as_keys_test(); + + let check_wrappers_as_keys = function () { + let live_dom = window.eeeevent.data.dummy; + let live_map = live_dom.xyzabc.m; + is(ChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1, + "Map should not be empty."); + let key = ChromeUtils.nondeterministicGetWeakMapKeys(live_map)[0]; + let value = live_map.get(key); + is(value.children.length, 1, "children have wrong length"); + } + + Cu.schedulePreciseGC(function () { + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + check_wrappers_as_keys(); + SimpleTest.finish(); + }); + + ]]> + </script> +</window> diff --git a/js/xpconnect/tests/chrome/test_weakref.xhtml b/js/xpconnect/tests/chrome/test_weakref.xhtml new file mode 100644 index 0000000000..21986cbf34 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_weakref.xhtml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=484459 +--> +<window title="Weakrefs" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <iframe type="content" id="ifr"> + </iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + var util = window.windowUtils; + var weakUtil = Cu.getWeakReference(util); + util = null; + + function callback() { + ok(weakUtil.get(), "Should still be alive here"); + SimpleTest.finish(); + } + + SpecialPowers.exactGC(callback); + ]]></script> +</window> diff --git a/js/xpconnect/tests/chrome/test_windowProxyDeadWrapper.html b/js/xpconnect/tests/chrome/test_windowProxyDeadWrapper.html new file mode 100644 index 0000000000..7970c1ae70 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_windowProxyDeadWrapper.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1223372 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1223372</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +/** Test for Bug 1223372 **/ +const {TestUtils} = ChromeUtils.import("resource://testing-common/TestUtils.jsm"); + +async function go() { + SimpleTest.waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", + true]]}); + + var frame = $('subframe'); + frame.onload = null; + + var w = frame.contentWindow; + + w.eval("checkDead = function() { return Components.utils.isDeadWrapper(this); };"); + var checkDead = w.checkDead; + + w.eval("getObject = function() { return {}; }"); + var getObject = w.getObject; + + ok(!checkDead(), "WindowProxy shouldn't be dead yet"); + + // Load a content page in the chrome frame. + w.location = "https://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + tryWindow(); + + function tryWindow() { + if (w.document.title != 'empty test page') { + info("Document not loaded yet - retrying"); + SimpleTest.executeSoon(tryWindow); + return; + } + + let winID = w.docShell.outerWindowID; + // Remove the frame. This will nuke the WindowProxy wrapper from our chrome + // document's global, so evaluating 'this' in it will return a dead wrapper + // once the window is destroyed. + frame.remove(); + + TestUtils.topicObserved("outer-window-nuked", (subject, data) => { + let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; + return id == winID; + }).then(() => { + ok(checkDead(), "Expected a dead object wrapper"); + + // Wrapping the Window should return a dead wrapper now. + var global = Cu.getGlobalForObject(getObject()); + ok(Cu.isDeadWrapper(global), + "Expected a dead wrapper when requesting the window's global"); + + SimpleTest.finish(); + }); + } +} + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1223372">Mozilla Bug 1223372</a> + +<iframe id="subframe" src="./file_empty.html" onload="go()"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_wrappers.xhtml b/js/xpconnect/tests/chrome/test_wrappers.xhtml new file mode 100644 index 0000000000..73c808a9df --- /dev/null +++ b/js/xpconnect/tests/chrome/test_wrappers.xhtml @@ -0,0 +1,85 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500931 +--> +<window title="Mozilla Bug 500931" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=533596" + target="_blank">Mozilla Bug 533596</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 533596 **/ + + function go() { + var win = $('ifr').contentWindow; + var utils = window.windowUtils; + is(utils.getClassName(window), "Proxy", "our window is wrapped correctly") + is(utils.getClassName(location), "Location", "chrome doesn't have location wrappers") + is(utils.getClassName(win), "Proxy", "win is an Proxy"); + is(utils.getClassName(win.location), "Proxy", "deep wrapping works"); + is(win.location.href, "https://example.org/tests/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html", + "can still get strings out"); + + var unsafeWin = win.wrappedJSObject; + is(utils.getClassName(unsafeWin), "Proxy", "can get a Proxy"); + is(utils.getClassName(unsafeWin.location), "Proxy", "deep wrapping works"); + + Object.defineProperty(unsafeWin, "defprop1", { value: 1, writable: true, enumerable: true, configurable: true }); + /* TODO (bug 552854): the getter isn't visible in content. + function checkWrapper(val) { + ok(utils.getClassName(val) == "Proxy", "wrapped properly"); + } + Object.defineProperty(unsafeWin, "defprop2", { set: checkWrapper, enumerable: true, configurable: true }); + */ + unsafeWin.run_test(ok, win, unsafeWin); + + win.setTimeout(function() { + is(utils.getClassName(this), "Proxy", + "this is wrapped correctly"); + SimpleTest.finish(); + }, 0) + + var saw0 = false; + for (let i in $('ifr').contentDocument.getElementsByTagName('body')) { + if (i === "0") + saw0 = true; + } + ok(saw0, "properly enumerated the 0 value"); + + ok(win.XPathEvaluator.toString().includes("XPathEvaluator"), + "Can access content window.XPathEvaluator"); + + var nativeToString = + ("" + Math.sin).replace("sin", "EventTarget"); + var eventTargetToString = "" + win.EventTarget; + ok(eventTargetToString.indexOf(nativeToString) > -1, + "Stringifying a DOM interface object should return the same string as " + + "stringifying a native function. " + eventTargetToString + " " + nativeToString); + + is(win.XPathResult.NUMBER_TYPE, 1, "can access constants on constructors"); + is(typeof win.IDBKeyRange.bound, "function", "can access crazy IDBKeyRange static functions"); + + // Test getter/setter lookup on Xray wrappers. + ok(Object.prototype.__lookupGetter__.call(win.document, 'title'), 'found getter on document'); + ok(Object.prototype.__lookupGetter__.call(win.document, 'title'), 'found getter on document'); + } + + SimpleTest.waitForExplicitFinish(); + + ]]></script> + <iframe type="content" + src="https://example.org/tests/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html" + onload="go()" + id="ifr"> + </iframe> +</window> diff --git a/js/xpconnect/tests/chrome/test_xrayLargeTypedArray.html b/js/xpconnect/tests/chrome/test_xrayLargeTypedArray.html new file mode 100644 index 0000000000..dcb0b87380 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_xrayLargeTypedArray.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1674777 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1674777</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + +/** Test for Bug 1674777 **/ + +function go() { + SimpleTest.waitForExplicitFinish(); + + let win = document.getElementById('ifr').contentWindow; + + const nbytes = 3 * 1024 * 1024 * 1024; // 3 GB. + let tarray = new win.Int8Array(nbytes); + ok(Cu.isXrayWrapper(tarray), "Should be Xray"); + is(tarray.length, nbytes, "Length should match"); + is(tarray.byteLength, nbytes, "byteLength should match"); + + // Expect OOM when getting all property names. + let ex; + try { + Object.getOwnPropertyNames(tarray); + } catch (e) { + ex = e; + } + is(ex, "out of memory", "Expected OOM"); + + SimpleTest.finish(); +} + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1674777">Mozilla Bug 1674777</a> + +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> + +</body> +</html> diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xhtml b/js/xpconnect/tests/chrome/test_xrayToJS.xhtml new file mode 100644 index 0000000000..fbfa67e61d --- /dev/null +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xhtml @@ -0,0 +1,1191 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=933681 +--> +<window title="Mozilla Bug 933681" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=933681" + target="_blank">Mozilla Bug 933681</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for ES constructors on Xrayed globals. **/ + SimpleTest.waitForExplicitFinish(); + let global = Cu.getGlobalForObject.bind(Cu); + + function checkThrows(f, rgxp, msg) { + try { + f(); + ok(false, "Should have thrown: " + msg); + } catch (e) { + ok(true, "Threw as expected: " + msg); + ok(rgxp.test(e), "Message correct: " + e); + } + } + + var { AppConstants } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" + ); + var isNightlyBuild = AppConstants.NIGHTLY_BUILD; + var isReleaseOrBeta = AppConstants.RELEASE_OR_BETA; + + let typedArrayClasses = ['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', + 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array', + 'Uint8ClampedArray']; + let errorObjectClasses = ['Error', 'InternalError', 'EvalError', 'RangeError', 'ReferenceError', + 'SyntaxError', 'TypeError', 'URIError', 'AggregateError']; + + // A simpleConstructors entry can either be the name of a constructor as a + // string, or an object containing the properties `name`, and `args`. + // In the former case, the constructor is invoked without any args; in the + // latter case, it is invoked with `args` as the arguments list. + let simpleConstructors = ['Object', 'Function', 'Array', 'Boolean', 'Date', 'Number', + 'String', 'RegExp', 'ArrayBuffer', 'WeakMap', 'WeakSet', 'Map', 'Set', + {name: 'Promise', args: [function(){}]}]; + + // All TypedArray constructors can be called with zero arguments. + simpleConstructors = simpleConstructors.concat(typedArrayClasses); + + // All Error constructors except AggregateError can be called with zero arguments. + simpleConstructors = simpleConstructors.concat(errorObjectClasses.filter(name => { + return name !== 'AggregateError'; + })); + + function go() { + window.iwin = document.getElementById('ifr').contentWindow; + /* global iwin */ + + // Test constructors that can be instantiated with zero arguments, or with + // a fixed set of arguments provided using `...rest`. + for (let c of simpleConstructors) { + var args = []; + if (typeof c === 'object') { + args = c.args; + c = c.name; + } + ok(iwin[c], "Constructors appear: " + c); + is(iwin[c], Cu.unwaiveXrays(iwin.wrappedJSObject[c]), + "we end up with the appropriate constructor: " + c); + is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin[c](...args)).constructor), iwin[c], + "constructor property is set up right: " + c); + let expectedProto = Cu.isOpaqueWrapper(new iwin[c](...args)) ? + iwin.Object.prototype : iwin[c].prototype; + is(Object.getPrototypeOf(new iwin[c](...args)), expectedProto, + "prototype is correct: " + c); + is(global(new iwin[c](...args)), iwin, "Got the right global: " + c); + } + + // Test Object in more detail. + var num = new iwin.Object(4); + is(Cu.waiveXrays(num).valueOf(), 4, "primitive object construction works"); + is(global(num), iwin, "correct global for num"); + var obj = new iwin.Object(); + obj.foo = 2; + var withProto = Cu.unwaiveXrays(Cu.waiveXrays(iwin).Object.create(obj)); + is(global(withProto), iwin, "correct global for withProto"); + is(Cu.waiveXrays(withProto).foo, 2, "Inherits properly"); + + // Test Function. + var primitiveFun = new iwin.Function('return 2'); + is(global(primitiveFun), iwin, "function construction works"); + is(primitiveFun(), 2, "basic function works"); + var doSetFoo = new iwin.Function('arg', 'arg.foo = 2;'); + is(global(doSetFoo), iwin, "function with args works"); + try { + doSetFoo({}); + ok(false, "should have thrown while setting property on object"); + } catch (e) { + ok(!!/denied/.test(e), "Threw correctly: " + e); + } + var factoryFun = new iwin.Function('return {foo: 32}'); + is(global(factoryFun), iwin, "proper global for factoryFun"); + is(factoryFun().foo, 32, "factoryFun invokable"); + is(global(factoryFun()), iwin, "minted objects live in the content scope"); + testXray('Function', factoryFun, new iwin.Function(), ['length', 'name']); + var echoThis = new iwin.Function('return this;'); + echoThis.wrappedJSObject.bind = 42; + var boundEchoThis = echoThis.bind(document); + is(boundEchoThis(), document, "bind() works correctly over Xrays"); + is(global(boundEchoThis), window, "bound functions live in the caller's scope"); + ok(/return this/.test(echoThis.toSource()), 'toSource works: ' + echoThis.toSource()); + ok(/return this/.test(echoThis.toString()), 'toString works: ' + echoThis.toString()); + is(iwin.Function.prototype, Object.getPrototypeOf(echoThis), "Function.prototype works for standard classes"); + is(echoThis.prototype, undefined, "Function.prototype not visible for non standard constructors"); + iwin.eval('var foopyFunction = function namedFoopyFunction(a, b, c) {}'); + var foopyFunction = Cu.unwaiveXrays(Cu.waiveXrays(iwin).foopyFunction); + ok(Cu.isXrayWrapper(foopyFunction), "Should be Xrays"); + is(foopyFunction.name, "namedFoopyFunction", ".name works over Xrays"); + is(foopyFunction.length, 3, ".length works over Xrays"); + ok(Object.getOwnPropertyNames(foopyFunction).includes('length'), "Should list length"); + ok(Object.getOwnPropertyNames(foopyFunction).includes('name'), "Should list name"); + ok(!Object.getOwnPropertyNames(foopyFunction).includes('prototype'), "Should not list prototype"); + ok(Object.getOwnPropertyNames(iwin.Array).includes('prototype'), "Should list prototype for standard constructor"); + + // Test BoundFunction. + iwin.eval('var boundFoopyFunction = foopyFunction.bind(null, 1)'); + var boundFoopyFunction = Cu.unwaiveXrays(Cu.waiveXrays(iwin).boundFoopyFunction); + is(boundFoopyFunction.name, "bound namedFoopyFunction", "bound .name works over Xrays"); + is(boundFoopyFunction.length, 2, "bound .length works over Xrays"); + is(JSON.stringify(Object.getOwnPropertyNames(boundFoopyFunction).sort()), '["length","name"]', "Should list length and name"); + // Mutate .name, it's just a data property. + iwin.eval('Object.defineProperty(boundFoopyFunction, "name", {value: "foobar", configurable: true, writable: true});'); + is(boundFoopyFunction.name, "foobar", "mutated .name works over Xrays"); + iwin.eval('boundFoopyFunction.name = 123;'); + is(boundFoopyFunction.name, undefined, "only support string for .name"); + iwin.eval('delete boundFoopyFunction.name'); + is(boundFoopyFunction.name, undefined, "deleted .name works over Xrays"); + // Mutate .length. + iwin.eval('Object.defineProperty(boundFoopyFunction, "length", {value: 456, configurable: true, writable: true});'); + is(boundFoopyFunction.length, 456, "mutated .length works over Xrays"); + iwin.eval('boundFoopyFunction.length = "bar";'); + is(boundFoopyFunction.length, undefined, "only support number for .length"); + + // Test proxies. + var targetObject = new iwin.Object(); + targetObject.foo = 9; + var forwardingProxy = new iwin.Proxy(targetObject, new iwin.Object()); + is(global(forwardingProxy), iwin, "proxy global correct"); + is(Cu.waiveXrays(forwardingProxy).foo, 9, "forwards correctly"); + + // Test AggregateError. + { + // AggregateError throws when called without an iterable object as its first argument. + let args = [new iwin.Array()]; + + ok(iwin.AggregateError, "AggregateError constructor is present"); + is(iwin.AggregateError, Cu.unwaiveXrays(iwin.wrappedJSObject.AggregateError), + "we end up with the appropriate AggregateError constructor"); + is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin.AggregateError(...args)).constructor), iwin.AggregateError, + "AggregateError constructor property is set up right"); + let expectedProto = Cu.isOpaqueWrapper(new iwin.AggregateError(...args)) ? + iwin.Object.prototype : iwin.AggregateError.prototype; + is(Object.getPrototypeOf(new iwin.AggregateError(...args)), expectedProto, + "AggregateError prototype is correct"); + is(global(new iwin.AggregateError(...args)), iwin, "Got the right global for AggregateError"); + } + + // Test eval. + var toEval = "({a: 2, b: {foo: 'bar'}, f: function() { return window; }})"; + is(global(iwin.eval(toEval)), iwin, "eval creates objects in the correct global"); + is(iwin.eval(toEval).b.foo, 'bar', "eval-ed object looks right"); + is(Cu.waiveXrays(iwin.eval(toEval)).f(), Cu.waiveXrays(iwin), "evaled function works right"); + + testDate(); + + testObject(); + + testArray(); + + testTypedArrays(); + + testErrorObjects(); + + testRegExp(); + + testPromise(); + + testArrayBuffer(); + + testMap(); + + testSet(); + + testWeakMap(); + + testWeakSet(); + + testProxy(); + + testDataView(); + + testNumber(); + + SimpleTest.finish(); + } + + // Maintain a static list of the properties that are available on each standard + // prototype, so that we make sure to audit any new ones to make sure they're + // Xray-safe. + // + // DO NOT CHANGE WTIHOUT REVIEW FROM AN XPCONNECT PEER. + var gPrototypeProperties = {}; + var gConstructorProperties = {}; + function constructorProps(arr) { + // Some props live on all constructors + return arr.concat(["prototype", "length", "name"]); + } + gPrototypeProperties.Date = + ["getTime", "getTimezoneOffset", "getYear", "getFullYear", "getUTCFullYear", + "getMonth", "getUTCMonth", "getDate", "getUTCDate", "getDay", "getUTCDay", + "getHours", "getUTCHours", "getMinutes", "getUTCMinutes", "getSeconds", + "getUTCSeconds", "getMilliseconds", "getUTCMilliseconds", "setTime", + "setYear", "setFullYear", "setUTCFullYear", "setMonth", "setUTCMonth", + "setDate", "setUTCDate", "setHours", "setUTCHours", "setMinutes", + "setUTCMinutes", "setSeconds", "setUTCSeconds", "setMilliseconds", + "setUTCMilliseconds", "toUTCString", "toLocaleString", + "toLocaleDateString", "toLocaleTimeString", "toDateString", "toTimeString", + "toISOString", "toJSON", "toSource", "toString", "valueOf", "constructor", + "toGMTString", Symbol.toPrimitive]; + gConstructorProperties.Date = constructorProps(["UTC", "parse", "now"]); + gPrototypeProperties.Object = + ["constructor", "toSource", "toString", "toLocaleString", "valueOf", + "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", + "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", + "__proto__"]; + gConstructorProperties.Object = + constructorProps(["setPrototypeOf", "getOwnPropertyDescriptor", "getOwnPropertyDescriptors", + "keys", "is", "defineProperty", "defineProperties", "create", + "getOwnPropertyNames", "getOwnPropertySymbols", + "preventExtensions", "freeze", "fromEntries", "isFrozen", "seal", + "isSealed", "assign", "getPrototypeOf", "values", + "entries", "isExtensible", "hasOwn"]); + gPrototypeProperties.Array = + ["length", "toSource", "toString", "toLocaleString", "join", "reverse", "sort", "push", + "pop", "shift", "unshift", "splice", "concat", "slice", "lastIndexOf", "indexOf", + "includes", "forEach", "map", "reduce", "reduceRight", "filter", "some", "every", "find", + "findIndex", "copyWithin", "fill", Symbol.iterator, Symbol.unscopables, "entries", "keys", + "values", "constructor", "flat", "flatMap", "at", "findLast", "findLastIndex", + "toReversed", "toSorted", "toSpliced", "with"]; + gConstructorProperties.Array = + constructorProps(["isArray", "from", "fromAsync", "of", Symbol.species]); + for (let c of typedArrayClasses) { + gPrototypeProperties[c] = ["constructor", "BYTES_PER_ELEMENT"]; + gConstructorProperties[c] = constructorProps(["BYTES_PER_ELEMENT"]); + } + // There is no TypedArray constructor, looks like. + is(window.TypedArray, undefined, "If this ever changes, add to this test!"); + for (let c of errorObjectClasses) { + gPrototypeProperties[c] = ["constructor", "name", "message", "stack"]; + gConstructorProperties[c] = constructorProps([]); + } + // toString and toSource only live on the parent proto (Error.prototype). + gPrototypeProperties.Error.push('toString'); + gPrototypeProperties.Error.push('toSource'); + + gPrototypeProperties.Function = + ["constructor", "toSource", "toString", "apply", "call", "bind", + "length", "name", "arguments", "caller", Symbol.hasInstance]; + gConstructorProperties.Function = constructorProps([]) + + gPrototypeProperties.RegExp = + ["constructor", "toSource", "toString", "compile", "exec", "test", + Symbol.match, Symbol.matchAll, Symbol.replace, Symbol.search, Symbol.split, + "flags", "dotAll", "global", "hasIndices", "ignoreCase", "multiline", "source", "sticky", + "unicode"]; + gConstructorProperties.RegExp = + constructorProps(["input", "lastMatch", "lastParen", + "leftContext", "rightContext", "$1", "$2", "$3", "$4", + "$5", "$6", "$7", "$8", "$9", "$_", "$&", "$+", + "$`", "$'", Symbol.species]) + + gPrototypeProperties.Promise = + ["constructor", "catch", "then", "finally", Symbol.toStringTag]; + gConstructorProperties.Promise = + constructorProps(["resolve", "reject", "all", "allSettled", "any", "race", Symbol.species]); + + gPrototypeProperties.ArrayBuffer = + ["constructor", "byteLength", "slice", Symbol.toStringTag]; + gConstructorProperties.ArrayBuffer = + constructorProps(["isView", Symbol.species]); + + gPrototypeProperties.SharedArrayBuffer = ["constructor", "slice", "byteLength", Symbol.toStringTag]; + gConstructorProperties.SharedArrayBuffer = constructorProps([Symbol.species]); + + gPrototypeProperties.Map = + ["constructor", "size", Symbol.toStringTag, "get", "has", "set", "delete", + "keys", "values", "clear", "forEach", "entries", Symbol.iterator]; + gConstructorProperties.Map = + constructorProps([Symbol.species]); + + gPrototypeProperties.Set = + ["constructor", "size", Symbol.toStringTag, "has", "add", "delete", + "keys", "values", "clear", "forEach", "entries", Symbol.iterator]; + gConstructorProperties.Set = + constructorProps([Symbol.species]); + + gPrototypeProperties.WeakMap = + ["constructor", Symbol.toStringTag, "get", "has", "set", "delete"]; + gConstructorProperties.WeakMap = + constructorProps([]); + + gPrototypeProperties.WeakSet = + ["constructor", Symbol.toStringTag, "has", "add", "delete"]; + gConstructorProperties.WeakSet = + constructorProps([]); + + gPrototypeProperties.DataView = + ["constructor", "buffer", "byteLength", "byteOffset", Symbol.toStringTag, + "getInt8", "getUint8", "getInt16", "getUint16", + "getInt32", "getUint32", "getFloat32", "getFloat64", + "setInt8", "setUint8", "setInt16", "setUint16", + "setInt32", "setUint32", "setFloat32", "setFloat64", + "getBigInt64", "getBigUint64", "setBigInt64", "setBigUint64"] + gConstructorProperties.DataView = constructorProps([]); + + // Sort an array that may contain symbols as well as strings. + function sortProperties(arr) { + function sortKey(prop) { + return typeof prop + ":" + prop.toString(); + } + arr.sort((a, b) => sortKey(a) < sortKey(b) ? -1 : +1); + } + + // Sort all the lists so we don't need to mutate them later (or copy them + // again to sort them). + for (let c of Object.keys(gPrototypeProperties)) + sortProperties(gPrototypeProperties[c]); + for (let c of Object.keys(gConstructorProperties)) + sortProperties(gConstructorProperties[c]); + + function filterOut(array, props) { + return array.filter(p => !props.includes(p)); + } + + function isTypedArrayClass(classname) { + return typedArrayClasses.includes(classname); + } + + function propertyIsGetter(obj, name, classname) { + return !!Object.getOwnPropertyDescriptor(obj, name).get; + } + + function testProtoCallables(protoCallables, xray, xrayProto, localProto) { + for (let name of protoCallables) { + info("Running tests for property: " + name); + // Test both methods and getter properties. + function lookupCallable(obj) { + let desc = null; + do { + desc = Object.getOwnPropertyDescriptor(obj, name); + if (desc) { + break; + } + obj = Object.getPrototypeOf(obj); + } while (obj); + return desc ? (desc.get || desc.value) : undefined; + }; + ok(xrayProto.hasOwnProperty(name), `proto should have the property '${name}' as own`); + ok(!xray.hasOwnProperty(name), `instance should not have the property '${name}' as own`); + let method = lookupCallable(xrayProto); + is(typeof method, 'function', "Methods from Xrays are functions"); + is(global(method), window, "Methods from Xrays are local"); + ok(method instanceof Function, "instanceof works on methods from Xrays"); + is(lookupCallable(xrayProto), method, "Holder caching works properly"); + is(lookupCallable(xray), method, "Proto props resolve on the instance"); + let local = lookupCallable(localProto); + is(method.length, local.length, "Function.length identical"); + if (!method.length) { + is(method.call(xray) + "", local.call(xray) + "", + "Xray and local method results stringify identically"); + + // If invoking this method returns something non-Xrayable (opaque), the + // stringification is going to return [object Object]. + // This happens for set[@@iterator] and other Iterator objects. + let callable = lookupCallable(xray.wrappedJSObject); + if (!Cu.isOpaqueWrapper(method.call(xray)) && callable) { + is(method.call(xray) + "", + callable.call(xray.wrappedJSObject) + "", + "Xray and waived method results stringify identically"); + } + } + } + } + + function testCtorCallables(ctorCallables, xrayCtor, localCtor) { + for (let name of ctorCallables) { + // Don't try to test Function.prototype, since that is in fact a callable + // but doesn't really do the things we expect callables to do here + // (e.g. it's in the wrong global, since it gets Xrayed itself). + if (name == "prototype" && localCtor.name == "Function") { + continue; + } + info(`Running tests for property: ${localCtor.name}.${name}`); + // Test both methods and getter properties. + function lookupCallable(obj) { + let desc = null; + do { + desc = Object.getOwnPropertyDescriptor(obj, name); + obj = Object.getPrototypeOf(obj); + } while (!desc); + return desc.get || desc.value; + }; + + ok(xrayCtor.hasOwnProperty(name), "ctor should have the property as own"); + let method = lookupCallable(xrayCtor); + is(typeof method, 'function', "Methods from ctor Xrays are functions"); + is(global(method), window, "Methods from ctor Xrays are local"); + ok(method instanceof Function, + "instanceof works on methods from ctor Xrays"); + is(lookupCallable(xrayCtor), method, + "Holder caching works properly on ctors"); + let local = lookupCallable(localCtor); + is(method.length, local.length, + "Function.length identical for method from ctor"); + // Don't try to do the return-value check on Date.now(), since there is + // absolutely no reason it should return the same value each time. + // + // Also don't try to do the return-value check on Regexp.lastMatch and + // Regexp["$&"] (which are aliases), because they get state off the global + // they live in, as far as I can tell, so testing them over Xrays will be + // wrong: on the Xray they will actaully get the lastMatch of _our_ + // global, not the Xrayed one. + if (!method.length && + !(localCtor.name == "Date" && name == "now") && + !(localCtor.name == "RegExp" && (name == "lastMatch" || name == "$&"))) { + is(method.call(xrayCtor) + "", local.call(xrayCtor) + "", + "Xray and local method results stringify identically on constructors"); + is(method.call(xrayCtor) + "", + lookupCallable(xrayCtor.wrappedJSObject).call(xrayCtor.wrappedJSObject) + "", + "Xray and waived method results stringify identically"); + } + } + } + + function testXray(classname, xray, xray2, propsToSkip, ctorPropsToSkip = []) { + propsToSkip = propsToSkip || []; + let xrayProto = Object.getPrototypeOf(xray); + let localProto = window[classname].prototype; + let desiredProtoProps = Object.getOwnPropertyNames(localProto).sort(); + + is(desiredProtoProps.toSource(), + gPrototypeProperties[classname].filter(id => typeof id === "string").toSource(), + "A property on the " + classname + + " prototype has changed! You need a security audit from an XPConnect peer"); + is(Object.getOwnPropertySymbols(localProto).map(uneval).sort().toSource(), + gPrototypeProperties[classname].filter(id => typeof id !== "string").map(uneval).sort().toSource(), + "A symbol-keyed property on the " + classname + + " prototype has been changed! You need a security audit from an XPConnect peer"); + + let protoProps = filterOut(desiredProtoProps, propsToSkip); + let protoCallables = protoProps.filter(name => propertyIsGetter(localProto, name, classname) || + typeof localProto[name] == 'function' && + name != 'constructor'); + ok(!!protoCallables.length, "Need something to test"); + is(xrayProto, iwin[classname].prototype, "Xray proto is correct"); + is(xrayProto, xray.__proto__, "Proto accessors agree"); + var protoProto = classname == "Object" ? null : iwin.Object.prototype; + is(Object.getPrototypeOf(xrayProto), protoProto, "proto proto is correct"); + testProtoCallables(protoCallables, xray, xrayProto, localProto); + is(Object.getOwnPropertyNames(xrayProto).sort().toSource(), + protoProps.toSource(), "getOwnPropertyNames works"); + is(Object.getOwnPropertySymbols(xrayProto).map(uneval).sort().toSource(), + gPrototypeProperties[classname].filter(id => typeof id !== "string" && !propsToSkip.includes(id)) + .map(uneval).sort().toSource(), + "getOwnPropertySymbols works"); + + is(xrayProto.constructor, iwin[classname], "constructor property works"); + + xrayProto.expando = 42; + is(xray.expando, 42, "Xrayed instances see proto expandos"); + is(xray2.expando, 42, "Xrayed instances see proto expandos"); + + // Now test constructors + let localCtor = window[classname]; + let xrayCtor = xrayProto.constructor; + // We already checked that this is the same as iwin[classname] + + let desiredCtorProps = + Object.getOwnPropertyNames(localCtor).sort(); + is(desiredCtorProps.toSource(), + gConstructorProperties[classname].filter(id => typeof id === "string").toSource(), + "A property on the " + classname + + " constructor has changed! You need a security audit from an XPConnect peer"); + let desiredCtorSymbols = + Object.getOwnPropertySymbols(localCtor).map(uneval).sort() + is(desiredCtorSymbols.toSource(), + gConstructorProperties[classname].filter(id => typeof id !== "string").map(uneval).sort().toSource(), + "A symbol-keyed property on the " + classname + + " constructor has been changed! You need a security audit from an XPConnect peer"); + + let ctorProps = filterOut(desiredCtorProps, ctorPropsToSkip); + let ctorSymbols = filterOut(desiredCtorSymbols, ctorPropsToSkip.map(uneval)); + let ctorCallables = ctorProps.filter(name => propertyIsGetter(localCtor, name, classname) || + typeof localCtor[name] == 'function'); + testCtorCallables(ctorCallables, xrayCtor, localCtor); + is(Object.getOwnPropertyNames(xrayCtor).sort().toSource(), + ctorProps.toSource(), "getOwnPropertyNames works on Xrayed ctors"); + is(Object.getOwnPropertySymbols(xrayCtor).map(uneval).sort().toSource(), + ctorSymbols.toSource(), "getOwnPropertySymbols works on Xrayed ctors"); + } + + // We will need arraysEqual and testArrayIterators both in this global scope + // and in sandboxes. + function arraysEqual(arr1, arr2, reason) { + is(arr1.length, arr2.length, `${reason}; lengths should be equal`) + for (var i = 0; i < arr1.length; ++i) { + if (Array.isArray(arr2[i])) { + arraysEqual(arr1[i], arr2[i], `${reason}; item at index ${i}`); + } else { + is(arr1[i], arr2[i], `${reason}; item at index ${i} should be equal`); + } + } + } + + function testArrayIterators(arrayLike, equivalentArray, reason) { + arraysEqual([...arrayLike], equivalentArray, `${reason}; spread operator`); + arraysEqual([...arrayLike.entries()], [...equivalentArray.entries()], + `${reason}; entries`); + arraysEqual([...arrayLike.keys()], [...equivalentArray.keys()], + `${reason}; keys`); + if (arrayLike.values) { + arraysEqual([...arrayLike.values()], equivalentArray, + `${reason}; values`); + } + + var forEachCopy = []; + arrayLike.forEach(function(arg) { forEachCopy.push(arg); }); + arraysEqual(forEachCopy, equivalentArray, `${reason}; forEach copy`); + + var everyCopy = []; + arrayLike.every(function(arg) { everyCopy.push(arg); return true; }); + arraysEqual(everyCopy, equivalentArray, `${reason}; every() copy`); + + var filterCopy = []; + var filterResult = arrayLike.filter(function(arg) { + filterCopy.push(arg); + return true; + }); + arraysEqual(filterCopy, equivalentArray, `${reason}; filter copy`); + arraysEqual([...filterResult], equivalentArray, `${reason}; filter result`); + + var findCopy = []; + arrayLike.find(function(arg) { findCopy.push(arg); return false; }); + arraysEqual(findCopy, equivalentArray, `${reason}; find() copy`); + + var findIndexCopy = []; + arrayLike.findIndex(function(arg) { findIndexCopy.push(arg); return false; }); + arraysEqual(findIndexCopy, equivalentArray, `${reason}; findIndex() copy`); + + var mapCopy = []; + var mapResult = arrayLike.map(function(arg) { mapCopy.push(arg); return arg}); + arraysEqual(mapCopy, equivalentArray, `${reason}; map() copy`); + arraysEqual([...mapResult], equivalentArray, `${reason}; map() result`); + + var reduceCopy = []; + arrayLike.reduce(function(_, arg) { reduceCopy.push(arg); }, 0); + arraysEqual(reduceCopy, equivalentArray, `${reason}; reduce() copy`); + + var reduceRightCopy = []; + arrayLike.reduceRight(function(_, arg) { reduceRightCopy.unshift(arg); }, 0); + arraysEqual(reduceRightCopy, equivalentArray, `${reason}; reduceRight() copy`); + + var someCopy = []; + arrayLike.some(function(arg) { someCopy.push(arg); return false; }); + arraysEqual(someCopy, equivalentArray, `${reason}; some() copy`); + } + + function testDate() { + // toGMTString is handled oddly in the engine. We don't bother to support + // it over Xrays. + let propsToSkip = ['toGMTString']; + + testXray('Date', new iwin.Date(), new iwin.Date(), propsToSkip); + + // Test the self-hosted toLocaleString. + var d = new iwin.Date(); + isnot(d.toLocaleString, Cu.unwaiveXrays(d.wrappedJSObject.toLocaleString), "Different function identities"); + is(Cu.getGlobalForObject(d.toLocaleString), window, "Xray global is correct"); + is(Cu.getGlobalForObject(d.wrappedJSObject.toLocaleString), iwin, "Underlying global is correct"); + is(d.toLocaleString('de-DE'), d.wrappedJSObject.toLocaleString('de-DE'), "Results match"); + } + + var uniqueSymbol; + + function testObject() { + testXray('Object', Cu.unwaiveXrays(Cu.waiveXrays(iwin).Object.create(new iwin.Object())), + new iwin.Object(), []); + + // Construct an object full of tricky things. + let symbolProps = ''; + uniqueSymbol = iwin.eval('var uniqueSymbol = Symbol("uniqueSymbol"); uniqueSymbol'); + symbolProps = `, [uniqueSymbol]: 43, + [Symbol.for("registrySymbolProp")]: 44`; + var trickyObject = + iwin.eval(`(function() { + var o = new Object({ + primitiveProp: 42, objectProp: { foo: 2 }, + xoProp: top, hasOwnProperty: 10, + get getterProp() { return 2; }, + set setterProp(x) { }, + get getterSetterProp() { return 3; }, + set getterSetterProp(x) { }, + callableProp: function() { }, + nonXrayableProp: new Map()[Symbol.iterator]() + ${symbolProps} + }); + Object.defineProperty(o, "nonConfigurableGetterSetterProp", + { get: function() { return 5; }, set: function() {} }); + return o; + })()`); + testTrickyObject(trickyObject); + } + + function testArray() { + // The |length| property is generally very weird, especially with respect + // to its behavior on the prototype. Array.prototype is actually an Array + // instance, and therefore has a vestigial .length. But we don't want to + // show that over Xrays, and generally want .length to just appear as an + // |own| data property. So we add it to the ignore list here, and check it + // separately. + // + // |Symbol.unscopables| should in principle be exposed, but it is + // inconvenient (as it's a data property, unsupported by ClassSpec) and + // low value. + let propsToSkip = ['length', Symbol.unscopables]; + + testXray('Array', new iwin.Array(20), new iwin.Array(), propsToSkip); + + let symbolProps = ''; + uniqueSymbol = iwin.eval('var uniqueSymbol = Symbol("uniqueSymbol"); uniqueSymbol'); + symbolProps = `trickyArray[uniqueSymbol] = 43; + trickyArray[Symbol.for("registrySymbolProp")] = 44;`; + var trickyArray = + iwin.eval(`var trickyArray = []; + trickyArray.primitiveProp = 42; + trickyArray.objectProp = { foo: 2 }; + trickyArray.xoProp = top; + trickyArray.hasOwnProperty = 10; + Object.defineProperty(trickyArray, 'getterProp', { get: function() { return 2; }}); + Object.defineProperty(trickyArray, 'setterProp', { set: function(x) {}}); + Object.defineProperty(trickyArray, 'getterSetterProp', { get: function() { return 3; }, set: function(x) {}, configurable: true}); + Object.defineProperty(trickyArray, 'nonConfigurableGetterSetterProp', { get: function() { return 5; }, set: function(x) {}}); + trickyArray.callableProp = function() {}; + trickyArray.nonXrayableProp = new Map()[Symbol.iterator](); + ${symbolProps} + trickyArray;`); + + // Test indexed access. + trickyArray.wrappedJSObject[9] = "some indexed property"; + is(trickyArray[9], "some indexed property", "indexed properties work correctly over Xrays"); + is(trickyArray.length, 10, "Length works correctly over Xrays"); + checkThrows(function() { "use strict"; delete trickyArray.length; }, /config/, "Can't delete non-configurable 'length' property"); + delete trickyArray[9]; + is(trickyArray[9], undefined, "Delete works correctly over Xrays"); + is(trickyArray.wrappedJSObject[9], undefined, "Delete works correctly over Xrays (viewed via waiver)"); + is(trickyArray.length, 10, "length doesn't change"); + trickyArray[11] = "some other indexed property"; + is(trickyArray.length, 12, "length now changes"); + is(trickyArray.wrappedJSObject[11], "some other indexed property"); + trickyArray.length = 0; + is(trickyArray.length, 0, "Setting length works over Xray"); + is(trickyArray[11], undefined, "Setting length truncates over Xray"); + Object.defineProperty(trickyArray, 'length', { configurable: false, enumerable: false, writable: false, value: 0 }); + trickyArray[1] = "hi"; + is(trickyArray.length, 0, "Length remains non-writable"); + is(trickyArray[1], undefined, "Frozen length forbids new properties"); + is(trickyArray instanceof iwin.Array, true, "instanceof should work across xray wrappers."); + testTrickyObject(trickyArray); + + testArrayIterators(new iwin.Array(1, 1, 2, 3, 5), [1, 1, 2, 3, 5]); + } + + // Parts of this function are kind of specific to testing Object, but we factor + // it out so that we can re-use the trickyObject stuff on Arrays. + function testTrickyObject(trickyObject) { + + // Make sure it looks right under the hood. + is(trickyObject.wrappedJSObject.getterProp, 2, "Underlying object has getter"); + is(Cu.unwaiveXrays(trickyObject.wrappedJSObject.xoProp), top, "Underlying object has xo property"); + + // Test getOwnPropertyNames. + var expectedNames = ['objectProp', 'primitiveProp']; + if (trickyObject instanceof iwin.Array) + expectedNames.push('length'); + is(Object.getOwnPropertyNames(trickyObject).sort().toSource(), + expectedNames.sort().toSource(), "getOwnPropertyNames should be filtered correctly"); + var expectedSymbols = [Symbol.for("registrySymbolProp"), uniqueSymbol]; + is(Object.getOwnPropertySymbols(trickyObject).map(uneval).sort().toSource(), + expectedSymbols.map(uneval).sort().toSource(), + "getOwnPropertySymbols should be filtered correctly"); + + // Test that cloning uses the Xray view. + var cloned = Cu.cloneInto(trickyObject, this); + is(Object.getOwnPropertyNames(cloned).sort().toSource(), + expectedNames.sort().toSource(), "structured clone should use the Xray view"); + is(Object.getOwnPropertySymbols(cloned).map(uneval).sort().toSource(), + "[]", "structured cloning doesn't clone symbol-keyed properties yet"); + + // Test iteration and in-place modification. Beware of 'expando', which is the property + // we placed on the xray proto. + var propCount = 0; + for (let prop in trickyObject) { + if (prop == 'primitiveProp') + trickyObject[prop] = trickyObject[prop] - 10; + if (prop != 'expando') { + // eslint-disable-next-line no-self-assign + trickyObject[prop] = trickyObject[prop]; + } + ++propCount; + } + is(propCount, 3, "Should iterate the correct number of times"); + + // Test Object.keys. + is(Object.keys(trickyObject).sort().toSource(), + ['objectProp', 'primitiveProp'].toSource(), "Object.keys should be filtered correctly"); + + // Test getOwnPropertyDescriptor. + is(trickyObject.primitiveProp, 32, "primitive prop works"); + is(trickyObject.objectProp.foo, 2, "object prop works"); + is(typeof trickyObject.callableProp, 'undefined', "filtering works correctly"); + is(Object.getOwnPropertyDescriptor(trickyObject, 'primitiveProp').value, 32, "getOwnPropertyDescriptor works"); + is(Object.getOwnPropertyDescriptor(trickyObject, 'xoProp'), undefined, "filtering works with getOwnPropertyDescriptor"); + + // Test defineProperty. + + trickyObject.primitiveSetByXray = 'fourty two'; + is(trickyObject.primitiveSetByXray, 'fourty two', "Can set primitive correctly over Xray (ready via Xray)"); + is(trickyObject.wrappedJSObject.primitiveSetByXray, 'fourty two', "Can set primitive correctly over Xray (ready via Waiver)"); + + var newContentObject = iwin.eval('new Object({prop: 99, get getterProp() { return 2; }})'); + trickyObject.objectSetByXray = newContentObject; + is(trickyObject.objectSetByXray.prop, 99, "Can set object correctly over Xray (ready via Xray)"); + is(trickyObject.wrappedJSObject.objectSetByXray.prop, 99, "Can set object correctly over Xray (ready via Waiver)"); + checkThrows(function() { trickyObject.rejectedProp = {foo: 33}}, /cross-origin object/, + "Should reject privileged object property definition"); + + // Test JSON.stringify. + var jsonStr = JSON.stringify(newContentObject); + ok(/prop/.test(jsonStr), "JSON stringification should work: " + jsonStr); + + // Test deletion. + delete newContentObject.prop; + ok(!newContentObject.hasOwnProperty('prop'), "Deletion should work"); + ok(!newContentObject.wrappedJSObject.hasOwnProperty('prop'), "Deletion should forward"); + delete newContentObject.getterProp; + ok(newContentObject.wrappedJSObject.hasOwnProperty('getterProp'), "Deletion be no-op for filtered property"); + + // We should be able to overwrite an existing accessor prop and convert it + // to a value prop. + is(trickyObject.wrappedJSObject.getterSetterProp, 3, "Underlying object has getter"); + is(trickyObject.getterSetterProp, undefined, "Filtering properly over Xray"); + trickyObject.getterSetterProp = 'redefined'; + is(trickyObject.getterSetterProp, 'redefined', "Redefinition works"); + is(trickyObject.wrappedJSObject.getterSetterProp, 'redefined', "Redefinition forwards"); + + // We should NOT be able to overwrite an existing non-configurable accessor + // prop, though. + is(trickyObject.wrappedJSObject.nonConfigurableGetterSetterProp, 5, + "Underlying object has getter"); + is(trickyObject.nonConfigurableGetterSetterProp, undefined, + "Filtering properly over Xray here too"); + is((trickyObject.nonConfigurableGetterSetterProp = 'redefined'), 'redefined', + "Assigning to non-configurable prop should fail silently in non-strict mode"); + checkThrows(function() { + "use strict"; + trickyObject.nonConfigurableGetterSetterProp = 'redefined'; + }, /config/, "Should throw when redefining non-configurable prop in strict mode"); + is(trickyObject.nonConfigurableGetterSetterProp, undefined, + "Redefinition should have failed"); + is(trickyObject.wrappedJSObject.nonConfigurableGetterSetterProp, 5, + "Redefinition really should have failed"); + + checkThrows(function() { trickyObject.hasOwnProperty = 33; }, /shadow/, + "Should reject shadowing of pre-existing inherited properties over Xrays"); + + checkThrows(function() { Object.defineProperty(trickyObject, 'rejectedProp', { get() {}}); }, + /accessor property/, "Should reject accessor property definition"); + } + + function testTypedArrays() { + // We don't invoke testXray with %TypedArray%, because that function isn't + // set up to deal with "anonymous" dependent classes (that is, classes not + // visible as a global property, which %TypedArray% is not), and fixing it + // up is more trouble than it's worth. + + var typedArrayProto = Object.getPrototypeOf(Int8Array.prototype); + + var desiredInheritedProps = Object.getOwnPropertyNames(typedArrayProto).sort(); + var inheritedProps = + filterOut(desiredInheritedProps, ["BYTES_PER_ELEMENT", "constructor"]); + + var inheritedCallables = + inheritedProps.filter(name => (propertyIsGetter(typedArrayProto, name) || + typeof typedArrayProto[name] === "function") && + name !== "constructor"); + + for (let c of typedArrayClasses) { + var t = new iwin[c](10); + checkThrows(function() { t[2]; }, /performant/, "direct property-wise reading of typed arrays forbidden over Xrays"); + checkThrows(function() { t[2] = 3; }, /performant/, "direct property-wise writing of typed arrays forbidden over Xrays"); + var wesb = new Cu.Sandbox([iwin], {isWebExtensionContentScript: true}); + wesb.t = t; + wesb.eval('t[2] = 3'); + is(wesb.eval('t.wrappedJSObject[2]'), 3, "direct property-wise writing of typed arrays allowed for WebExtension content scripts"); + is(wesb.eval('t[2]'), 3, "direct property-wise reading and writing of typed arrays allowed for WebExtensions content scripts"); + + t.wrappedJSObject[2] = 3; + is(t.wrappedJSObject[2], 3, "accessing elements over waivers works"); + t.wrappedJSObject.expando = 'hi'; + is(t.wrappedJSObject.expando, 'hi', "access expandos over waivers works"); + is(Cu.cloneInto(t, window)[2], 3, "cloneInto works"); + is(Cu.cloneInto(t, window).expando, undefined, "cloneInto does not copy expandos"); + is(Object.getOwnPropertyNames(t).sort().toSource(), + '["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]', + "Only indexed properties visible over Xrays"); + Object.defineProperty(t.wrappedJSObject, 'length', {value: 42}); + is(t.wrappedJSObject.length, 42, "Set tricky expando") + is(t.length, 10, "Length accessor works over Xrays") + is(t.byteLength, t.length * window[c].prototype.BYTES_PER_ELEMENT, "byteLength accessor works over Xrays") + + // Can create TypedArray from content ArrayBuffer + var buffer = new iwin.ArrayBuffer(8); + new window[c](buffer); + + var xray = new iwin[c](0); + var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray)); + testProtoCallables(inheritedCallables, new iwin[c](0), xrayTypedArrayProto, typedArrayProto); + + // When testing iterators, make sure to do so from inside our web + // extension sandbox, since from chrome we can't poke their indices. Note + // that we have to actually recreate our functions that touch typed array + // indices inside the sandbox, not just export them, because otherwise + // they'll just run with our principal anyway. + // + // But we do want to export is(), since we want ours called. + wesb.eval(String(arraysEqual)); + wesb.eval(String(testArrayIterators)); + Cu.exportFunction(is, wesb, + { defineAs: "is" }); + wesb.eval('testArrayIterators(t, [0, 0, 3, 0, 0, 0, 0, 0, 0, 0])'); + } + } + + function testErrorObjects() { + // We only invoke testXray with Error, because that function isn't set up + // to deal with dependent classes and fixing it up is more trouble than + // it's worth. + testXray('Error', new iwin.Error('some error message'), new iwin.Error()); + + // Make sure that the dependent classes have their prototypes set up correctly. + for (let c of errorObjectClasses.filter(x => x != "Error")) { + var args = ['some message']; + if (c === 'AggregateError') { + // AggregateError's first argument is the list of aggregated errors. + args.unshift(new iwin.Array('error 1', 'error 2')); + } + var e = new iwin[c](...args); + is(Object.getPrototypeOf(e).name, c, "Prototype has correct name"); + is(Object.getPrototypeOf(Object.getPrototypeOf(e)), iwin.Error.prototype, "Dependent prototype set up correctly"); + is(e.name, c, "Exception name inherited correctly"); + + function testProperty(name, criterion, goodReplacement, faultyReplacement) { + ok(criterion(e[name]), name + " property is correct: " + e[name]); + e.wrappedJSObject[name] = goodReplacement; + is(e[name], goodReplacement, name + " property ok after replacement: " + goodReplacement); + e.wrappedJSObject[name] = faultyReplacement; + is(e[name], name == 'message' ? "" : undefined, name + " property skipped after suspicious replacement"); + } + testProperty('message', x => x == 'some message', 'some other message', 42); + testProperty('fileName', x => x == '', 'otherFilename.html', new iwin.Object()); + testProperty('columnNumber', x => x == 1, 99, 99.5); + testProperty('lineNumber', x => x == 0, 50, 'foo'); + + if (c === 'AggregateError') { + let {errors} = e; + is(errors.length, 2, "errors property has the correct length"); + is(errors[0], 'error 1', "errors[0] has the correct value"); + is(errors[1], 'error 2', "errors[1] has the correct value"); + + e.wrappedJSObject.errors = 42; + is(e.wrappedJSObject.errors, 42, "errors is a plain data property"); + is(e.errors, 42, "visible over Xrays"); + } + + // Note - an Exception newed via Xrays is going to have an empty stack given the + // current semantics and implementation. This tests the current behavior, but that + // may change in bug 1036527 or similar. + // + // Furthermore, xrays should always return an error's original stack, and + // not overwrite it. + var stack = e.stack; + ok(/^\s*$/.test(stack), "stack property should be correct"); + e.wrappedJSObject.stack = "not a stack"; + is(e.stack, stack, "Xrays should never get an overwritten stack property."); + + // Test the .cause property is correctly handled, too. + if (isNightlyBuild) { + let cause = 'error cause'; + let options = new iwin.Object(); + options.cause = cause; + args.push(options); + + let e = new iwin[c](...args); + is(e.cause, cause); + + e.wrappedJSObject.cause = 42; + is(e.wrappedJSObject.cause, 42, "cause is a plain data property"); + is(e.cause, 42, "visible over Xrays"); + } + } + } + + function testRegExp() { + // RegExp statics are very weird, and in particular RegExp has static + // properties that have to do with the last regexp execution in the global. + // Xraying those makes no sense, so we just skip constructor properties for + // RegExp xrays. + // RegExp[@@species] is affected by above skip, but we don't fix it until + // compelling use-case appears, as supporting RegExp[@@species] while + // skipping other static properties makes things complicated. + let ctorPropsToSkip = ["input", "lastMatch", "lastParen", + "leftContext", "rightContext", "$1", "$2", "$3", + "$4", "$5", "$6", "$7", "$8", "$9", "$_", "$&", + "$+", "$`", "$'", Symbol.species]; + testXray('RegExp', new iwin.RegExp('foo'), new iwin.RegExp(), [], + ctorPropsToSkip); + + // Test the self-hosted |flags| property, toString, and toSource. + for (var flags of ["", "g", "i", "m", "y", "gimy"]) { + var re = new iwin.RegExp("foo", flags); + is(re.flags, re.wrappedJSObject.flags, "Results match"); + + isnot(re.toString, Cu.unwaiveXrays(re.wrappedJSObject.toString), "Different function identities"); + is(Cu.getGlobalForObject(re.toString), window, "Xray global is correct"); + is(Cu.getGlobalForObject(re.wrappedJSObject.toString), iwin, "Underlying global is correct"); + is(re.toString(), re.wrappedJSObject.toString(), "Results match"); + + isnot(re.toSource, Cu.unwaiveXrays(re.wrappedJSObject.toSource), "Different function identities"); + is(Cu.getGlobalForObject(re.toSource), window, "Xray global is correct"); + if (re.wrappedJSObject.toSource) { + is(Cu.getGlobalForObject(re.wrappedJSObject.toSource), iwin, "Underlying global is correct"); + is(re.toSource(), re.wrappedJSObject.toSource(), "Results match"); + } + + // Test with modified flags accessors + iwin.eval(` +var props = ["global", "ignoreCase", "multiline", "sticky", "source", "unicode"]; +var origDescs = {}; +for (var prop of props) { + origDescs[prop] = Object.getOwnPropertyDescriptor(RegExp.prototype, prop); + Object.defineProperty(RegExp.prototype, prop, { + get: function() { + throw new Error("modified accessor is called"); + } + }); +} +`); + try { + is(re.flags, flags, "Unmodified flags accessors are called"); + is(re.toString(), "/foo/" + flags, "Unmodified flags and source accessors are called"); + is(re.toSource(), "/foo/" + flags, "Unmodified flags and source accessors are called"); + } finally { + iwin.eval(` +for (var prop of props) { + Object.defineProperty(RegExp.prototype, prop, origDescs[prop]); +} +`); + } + } + } + + // Note: this is a small set of basic tests. More in-depth tests are located + // in test_promise_xrays.html. + function testPromise() { + testXray('Promise', new iwin.Promise(function(){}), new iwin.Promise(function(){})); + + // Test catch and then. + var pr = new iwin.Promise(function(){}); + isnot(pr.catch, Cu.unwaiveXrays(pr.wrappedJSObject.catch), "Different function identities"); + is(Cu.getGlobalForObject(pr.catch), window, "Xray global is correct"); + is(Cu.getGlobalForObject(pr.wrappedJSObject.catch), iwin, "Underlying global is correct"); + + isnot(pr.then, Cu.unwaiveXrays(pr.wrappedJSObject.then), "Different function identities"); + is(Cu.getGlobalForObject(pr.then), window, "Xray global is correct"); + is(Cu.getGlobalForObject(pr.wrappedJSObject.then), iwin, "Underlying global is correct"); + } + + function testArrayBuffer() { + let constructors = ['ArrayBuffer']; + + for (const c of constructors) { + testXray(c, new iwin[c](0), new iwin[c](12)); + + var t = new iwin[c](12); + is(t.byteLength, 12, `${c} byteLength is correct`); + + is(t.slice(4).byteLength, 8, `${c} byteLength is correct after slicing`); + is(Cu.getGlobalForObject(t.slice(4)), iwin, "Slice results lives in the target compartment"); + is(Object.getPrototypeOf(t.slice(4)), iwin[c].prototype, "Slice results proto lives in target compartment") + + var i32Array = new Int32Array(t); + // i32Array is going to be created in the buffer's target compartment, + // but usually this is unobservable, because the proto is set to + // the current compartment's prototype. + // However Xrays ignore the object's proto and claim its proto is + // the default proto for that class in the relevant compartment, + // so see through this proto hack. + todo_is(Object.getPrototypeOf(i32Array), Int32Array.prototype, "Int32Array has correct proto"); + is(i32Array.length, 3, `Int32Array created from Xray ${c} has the correct length`); + is(i32Array.buffer, t, "Int32Array has the correct buffer that we passed in"); + + i32Array = new iwin.Int32Array(t); + is(Object.getPrototypeOf(i32Array), iwin.Int32Array.prototype, "Xray Int32Array has correct proto"); + is(i32Array.length, 3, `Xray Int32Array created from Xray ${c} has the correct length`); + is(i32Array.buffer, t, "Xray Int32Array has the correct buffer that we passed in"); + + t = (new iwin.Int32Array(2)).buffer; + is(t.byteLength, 8, `Can access ${c} returned by buffer property`); + } + } + + function testMap() { + testXray('Map', new iwin.Map(), new iwin.Map()); + + var t = iwin.eval(`new Map([[1, "a"], [null, "b"]])`); + is(t.size, 2, "Map size is correct"); + is(t.get(1), "a", "Key 1 has the correct value"); + is(t.get(null), "b", "Key null has the correct value"); + is(t.has(1), true, "Has Key 1"); + is(t.set(3, 5).get(3), 5, "Correctly sets key"); + is(t.delete(null), true, "Key null can be deleted"); + + let values = []; + t.forEach((value, key) => values.push(value)); + is(values.toString(), "a,5", "forEach enumerates values correctly"); + + t.clear(); + is(t.size, 0, "Map is empty after calling clear"); + } + + function testSet() { + testXray('Set', new iwin.Set(), new iwin.Set()); + + var t = iwin.eval(`new Set([1, null])`); + is(t.size, 2, "Set size is correct"); + is(t.has(1), true, "Contains 1"); + is(t.has(null), true, "Contains null"); + is(t.add(5).has(5), true, "Can add value to set"); + is(t.delete(null), true, "Value null can be deleted"); + + let values = []; + t.forEach(value => values.push(value)); + is(values.toString(), "1,5", "forEach enumerates values correctly"); + + t.clear(); + is(t.size, 0, "Set is empty after calling clear"); + } + + function testWeakMap() { + testXray('WeakMap', new iwin.WeakMap(), new iwin.WeakMap()); + + var key1 = iwin.eval(`var key1 = {}; key1`); + var key2 = iwin.eval(`var key2 = []; key2`); + var key3 = iwin.eval(`var key3 = /a/; key3`); + var key4 = {}; + var key5 = []; + var t = iwin.eval(`new WeakMap([[key1, "a"], [key2, "b"]])`); + is(t.get(key1), "a", "key1 has the correct value"); + is(t.get(key2), "b", "key2 has the correct value"); + is(t.has(key1), true, "Has key1"); + is(t.has(key3), false, "Doesn't have key3"); + is(t.has(key5), false, "Doesn't have key5"); + is(t.set(key4, 5).get(key4), 5, "Correctly sets key"); + is(t.get(key1), "a", "key1 has the correct value after modification"); + is(t.get(key2), "b", "key2 has the correct value after modification"); + is(t.delete(key1), true, "key1 can be deleted"); + is(t.delete(key2), true, "key2 can be deleted"); + is(t.delete(key3), false, "key3 cannot be deleted"); + is(t.delete(key4), true, "key4 can be deleted"); + is(t.delete(key5), false, "key5 cannot be deleted"); + } + + function testWeakSet() { + testXray('WeakSet', new iwin.WeakSet(), new iwin.WeakSet()); + + var key1 = iwin.eval(`var key1 = {}; key1`); + var key2 = iwin.eval(`var key2 = []; key2`); + var key3 = iwin.eval(`var key3 = /a/; key3`); + var key4 = {}; + var key5 = []; + var t = iwin.eval(`new WeakSet([key1, key2])`); + is(t.has(key1), true, "Has key1"); + is(t.has(key2), true, "Has key2"); + is(t.has(key3), false, "Doesn't have key3"); + is(t.has(key5), false, "Doesn't have key5"); + is(t.add(key4, 5).has(key4), true, "Can add value to set"); + is(t.delete(key1), true, "key1 can be deleted"); + is(t.delete(key2), true, "key2 can be deleted"); + is(t.delete(key3), false, "key3 cannot be deleted"); + is(t.delete(key4), true, "key4 can be deleted"); + is(t.delete(key5), false, "key5 cannot be deleted"); + } + + function testProxy() { + let ProxyCtor = iwin.Proxy; + is(Object.getOwnPropertyNames(ProxyCtor).sort().toSource(), + ["length", "name"].sort().toSource(), + "Xrayed Proxy constructor should not have any properties"); + is(ProxyCtor.prototype, undefined, "Proxy.prototype should not be set"); + // Proxy.revocable can safely be exposed, but it is not. + // Until it is supported, check that the property is not set. + is(ProxyCtor.revocable, undefined, "Proxy.reflect is not set"); + } + + function testDataView() { + testXray('DataView', new iwin.DataView(new iwin.ArrayBuffer(4)), + new iwin.DataView(new iwin.ArrayBuffer(8))); + + const versions = [() => iwin.eval(`new DataView(new ArrayBuffer(8))`), + () => new DataView(new iwin.ArrayBuffer(8))]; + + for (const constructor of versions) { + let t = constructor(); + is(t.byteLength, 8, `byteLength correct for "${constructor}"`); + is(t.byteOffset, 0, `byteOffset correct for "${constructor}"`); + is(t.buffer.byteLength, 8, `buffer works for "${constructor}"`); + + const get = ["getInt8", "getUint8", "getInt16", "getUint16", + "getInt32", "getUint32", "getFloat32", "getFloat64"]; + + const set = ["setInt8", "setUint8", "setInt16", "setUint16", + "setInt32", "setUint32", "setFloat32", "setFloat64"]; + + for (const f of get) { + let x = t[f](0); + is(x, 0, `${f} is 0 for "${constructor}"`); + is(typeof x, 'number', `typeof ${f} is number for "${constructor}"`); + } + + for (const f of ["getBigInt64", "getBigUint64"]) { + let x = t[f](0); + is(x, BigInt(0), `${f} is 0n for "${constructor}"`); + is(typeof x, 'bigint', `typeof ${f} is bigint for "${constructor}"`); + } + + for (let i = 0; i < set.length; i++) { + t[set[i]](0, 13); + is(t[get[i]](0), 13, `${get[i]}(0) afer ${set[i]}(0, 13) is 13 for "${constructor}"`); + } + + for (const k of ["BigInt64", "BigUint64"]) { + t["set" + k](0, BigInt(13)); + is(t["get" + k](0), BigInt(13), `get${k}(0) afer set${k}(0, 13n) is 13n for "${constructor}"`); + } + } + } + + function testNumber() { + // We don't actually support Xrays to Number yet. This is testing + // that case. If we add such support, we might have to start + // using a different non-Xrayed class here, if we can find one. + let xrayCtor = iwin.Number; + is(Object.getOwnPropertyNames(xrayCtor).sort().toSource(), + Object.getOwnPropertyNames(function() {}).sort().toSource(), + "We should not have any static properties on a non-Xrayable constructor"); + is(xrayCtor.noSuchProperty, undefined, + "Where did our noSuchProperty property come from?"); + } + + ]]> + </script> + <iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/test_xrayic.xhtml b/js/xpconnect/tests/chrome/test_xrayic.xhtml new file mode 100644 index 0000000000..fd9ab8f7b3 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_xrayic.xhtml @@ -0,0 +1,81 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1355109 +--> +<window title="Mozilla Bug 1355109" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758415" + target="_blank">Mozilla Bug 758415</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + // Import our test JSM. We first strip the filename off + // the chrome url, then append the jsm filename. + var base = /.*\//.exec(window.location.href)[0]; + ChromeUtils.import(base + "file_expandosharing.jsm"); + + // Wait for all child frames to load. + var gLoadCount = 0; + function frameLoaded() { + if (++gLoadCount == window.frames.length) + go(); + } + + function go() { + testSandbox(1); + testSandbox(100); + testSandbox(1000); + SimpleTest.finish(); + } + + function testSandbox(iterations) { + // Create an expanded principal sandbox to get xrays with exclusive + // expandos. + var sandbox = new Cu.Sandbox(["https://test1.example.org", + "https://test2.example.org"]); + sandbox.iframeWindows = new sandbox.Array(); + for (let iframe of document.getElementsByTagName('iframe')) { + sandbox.iframeWindows.push(iframe.contentWindow); + } + Cu.evalInSandbox(testClassName.toSource(), sandbox); + Cu.evalInSandbox(testIC.toSource(), sandbox); + is(Cu.evalInSandbox("testIC(" + iterations + ");", sandbox), true, "sandbox test"); + } + + // This is in a separate function to provide a common source location for ICs. + function testClassName(obj, expected) { + var className = obj.className; + if (className != expected) + throw new Error("Got " + className + ", expected " + expected); + } + + function testIC(iterations) { + for (var i = 0; i < this.iframeWindows.length; i++) { + var win = this.iframeWindows[i]; + var spans = win.document.getElementsByTagName('span'); + for (var j = 0; j < spans.length; j++) { + var span = spans[j]; + for (var k = 0; k < iterations; k++) + testClassName(span, "iamaspan"); + Object.defineProperty(span, "className", { value: "what" }); + testClassName(span, "what"); + } + } + return true; + } + ]]> + </script> + <iframe id="inlineFrame1" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_xrayic.html" /> + <iframe id="inlineFrame2" onload="frameLoaded();" type="content" src="https://test1.example.org/tests/js/xpconnect/tests/mochitest/file_xrayic.html" /> +</window> diff --git a/js/xpconnect/tests/chrome/utf8_subscript.js b/js/xpconnect/tests/chrome/utf8_subscript.js new file mode 100644 index 0000000000..6444273c9d --- /dev/null +++ b/js/xpconnect/tests/chrome/utf8_subscript.js @@ -0,0 +1,5 @@ +// -*- coding: utf-8; indent-tabs-mode: nil -*- +var str = "𝔘𝔫𝔦𝔠𝔬𝔡𝔢"; +function f() { + return 42; +} diff --git a/js/xpconnect/tests/chrome/worker_discardSystemSource.js b/js/xpconnect/tests/chrome/worker_discardSystemSource.js new file mode 100644 index 0000000000..5da32511fa --- /dev/null +++ b/js/xpconnect/tests/chrome/worker_discardSystemSource.js @@ -0,0 +1,6 @@ +function canary() { + // eslint-disable-next-line no-unused-vars + var someBitOfSource = 42; +} + +postMessage(canary.toString()); diff --git a/js/xpconnect/tests/components/native/moz.build b/js/xpconnect/tests/components/native/moz.build new file mode 100644 index 0000000000..ba3d227c5b --- /dev/null +++ b/js/xpconnect/tests/components/native/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + "xpctest_private.h", +] + +UNIFIED_SOURCES += [ + "xpctest_attributes.cpp", + "xpctest_cenums.cpp", + "xpctest_esmreturncode.cpp", + "xpctest_module.cpp", + "xpctest_params.cpp", + "xpctest_returncode.cpp", +] + +LOCAL_INCLUDES += [ + "/xpcom/components", +] + +FINAL_LIBRARY = "xul" diff --git a/js/xpconnect/tests/components/native/xpctest_attributes.cpp b/js/xpconnect/tests/components/native/xpctest_attributes.cpp new file mode 100644 index 0000000000..180c1f7606 --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_attributes.cpp @@ -0,0 +1,136 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpctest_private.h" + +NS_IMPL_ISUPPORTS(xpcTestObjectReadOnly, nsIXPCTestObjectReadOnly) + +xpcTestObjectReadOnly ::xpcTestObjectReadOnly() { + boolProperty = true; + shortProperty = 32767; + longProperty = 2147483647; + floatProperty = 5.5f; + charProperty = 'X'; + // timeProperty is PRTime and signed type. + // So it has to allow negative value. + timeProperty = -1; +} + +NS_IMETHODIMP xpcTestObjectReadOnly ::GetStrReadOnly(char** aStrReadOnly) { + if (!aStrReadOnly) return NS_ERROR_NULL_POINTER; + *aStrReadOnly = moz_xstrdup("XPConnect Read-Only String"); + return NS_OK; +} + +NS_IMETHODIMP xpcTestObjectReadOnly ::GetBoolReadOnly(bool* aBoolReadOnly) { + *aBoolReadOnly = boolProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadOnly ::GetShortReadOnly( + int16_t* aShortReadOnly) { + *aShortReadOnly = shortProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadOnly ::GetLongReadOnly(int32_t* aLongReadOnly) { + *aLongReadOnly = longProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadOnly ::GetFloatReadOnly(float* aFloatReadOnly) { + *aFloatReadOnly = floatProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadOnly ::GetCharReadOnly(char* aCharReadOnly) { + *aCharReadOnly = charProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadOnly ::GetTimeReadOnly(PRTime* aTimeReadOnly) { + *aTimeReadOnly = timeProperty; + return NS_OK; +} + +NS_IMPL_ISUPPORTS(xpcTestObjectReadWrite, nsIXPCTestObjectReadWrite) + +xpcTestObjectReadWrite ::xpcTestObjectReadWrite() { + stringProperty = moz_xstrdup("XPConnect Read-Writable String"); + boolProperty = true; + shortProperty = 32767; + longProperty = 2147483647; + floatProperty = 5.5f; + charProperty = 'X'; + // timeProperty is PRTime and signed type. + // So it has to allow negative value. + timeProperty = -1; +} + +xpcTestObjectReadWrite ::~xpcTestObjectReadWrite() { free(stringProperty); } + +NS_IMETHODIMP xpcTestObjectReadWrite ::GetStringProperty( + char** aStringProperty) { + if (!aStringProperty) { + return NS_ERROR_NULL_POINTER; + } + *aStringProperty = moz_xstrdup(stringProperty); + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetStringProperty( + const char* aStringProperty) { + free(stringProperty); + stringProperty = moz_xstrdup(aStringProperty); + return NS_OK; +} + +NS_IMETHODIMP xpcTestObjectReadWrite ::GetBooleanProperty( + bool* aBooleanProperty) { + *aBooleanProperty = boolProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetBooleanProperty( + bool aBooleanProperty) { + boolProperty = aBooleanProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::GetShortProperty( + int16_t* aShortProperty) { + *aShortProperty = shortProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetShortProperty( + int16_t aShortProperty) { + shortProperty = aShortProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::GetLongProperty(int32_t* aLongProperty) { + *aLongProperty = longProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetLongProperty(int32_t aLongProperty) { + longProperty = aLongProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::GetFloatProperty(float* aFloatProperty) { + *aFloatProperty = floatProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetFloatProperty(float aFloatProperty) { + floatProperty = aFloatProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::GetCharProperty(char* aCharProperty) { + *aCharProperty = charProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetCharProperty(char aCharProperty) { + charProperty = aCharProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::GetTimeProperty(PRTime* aTimeProperty) { + *aTimeProperty = timeProperty; + return NS_OK; +} +NS_IMETHODIMP xpcTestObjectReadWrite ::SetTimeProperty(PRTime aTimeProperty) { + timeProperty = aTimeProperty; + return NS_OK; +} diff --git a/js/xpconnect/tests/components/native/xpctest_cenums.cpp b/js/xpconnect/tests/components/native/xpctest_cenums.cpp new file mode 100644 index 0000000000..ae72351b77 --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_cenums.cpp @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* local header for xpconnect tests components */ + +#include "xpctest_private.h" + +NS_IMPL_ISUPPORTS(xpcTestCEnums, nsIXPCTestCEnums) + +// If this compiles, we pass. Otherwise, this means that XPIDL bitflag +// generation is broken. +xpcTestCEnums::xpcTestCEnums() { + static_assert( + 0 == static_cast<uint32_t>(shouldBe0Implicit), + "XPIDL bitflag generation did not create correct shouldBe0Implicit flag"); + static_assert( + 1 == static_cast<uint32_t>(shouldBe1Implicit), + "XPIDL bitflag generation did not create correct shouldBe1Implicit flag"); + static_assert( + 2 == static_cast<uint32_t>(shouldBe2Implicit), + "XPIDL bitflag generation did not create correct shouldBe2Implicit flag"); + static_assert( + 3 == static_cast<uint32_t>(shouldBe3Implicit), + "XPIDL bitflag generation did not create correct shouldBe3Implicit flag"); + static_assert( + 5 == static_cast<uint32_t>(shouldBe5Implicit), + "XPIDL bitflag generation did not create correct shouldBe5Implicit flag"); + static_assert( + 6 == static_cast<uint32_t>(shouldBe6Implicit), + "XPIDL bitflag generation did not create correct shouldBe6Implicit flag"); + static_assert(2 == static_cast<uint32_t>(shouldBe2AgainImplicit), + "XPIDL bitflag generation did not create correct " + "shouldBe2AgainImplicit flag"); + static_assert(3 == static_cast<uint32_t>(shouldBe3AgainImplicit), + "XPIDL bitflag generation did not create correct " + "shouldBe3AgainImplicit flag"); + static_assert( + 1 == static_cast<uint32_t>(shouldBe1Explicit), + "XPIDL bitflag generation did not create correct shouldBe1Explicit flag"); + static_assert( + 2 == static_cast<uint32_t>(shouldBe2Explicit), + "XPIDL bitflag generation did not create correct shouldBe2Explicit flag"); + static_assert( + 4 == static_cast<uint32_t>(shouldBe4Explicit), + "XPIDL bitflag generation did not create correct shouldBe4Explicit flag"); + static_assert( + 8 == static_cast<uint32_t>(shouldBe8Explicit), + "XPIDL bitflag generation did not create correct shouldBe8Explicit flag"); + static_assert(12 == static_cast<uint32_t>(shouldBe12Explicit), + "XPIDL bitflag generation did not create correct " + "shouldBe12Explicit flag"); +} + +nsresult xpcTestCEnums::TestCEnumInput(testFlagsExplicit a) { + if (a != shouldBe12Explicit) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult xpcTestCEnums::TestCEnumOutput(testFlagsExplicit* a) { + *a = shouldBe8Explicit; + return NS_OK; +} diff --git a/js/xpconnect/tests/components/native/xpctest_esmreturncode.cpp b/js/xpconnect/tests/components/native/xpctest_esmreturncode.cpp new file mode 100644 index 0000000000..758cab65da --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_esmreturncode.cpp @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpctest_private.h" +#include "nsComponentManagerUtils.h" +#include "nsImportModule.h" + +NS_IMPL_ISUPPORTS(nsXPCTestESMReturnCodeParent, nsIXPCTestReturnCodeParent) + +NS_IMETHODIMP nsXPCTestESMReturnCodeParent::CallChild(int32_t childBehavior, + nsresult* _retval) { + nsresult rv; + nsCOMPtr<nsIXPCTestReturnCodeChild> child(do_ImportESModule( + "resource://test/ReturnCodeChild.sys.mjs", "ReturnCodeChild", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = child->DoIt(childBehavior); + *_retval = rv; + return NS_OK; +} diff --git a/js/xpconnect/tests/components/native/xpctest_module.cpp b/js/xpconnect/tests/components/native/xpctest_module.cpp new file mode 100644 index 0000000000..98ee300e48 --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_module.cpp @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* module registration and factory code. */ + +#include "mozilla/GenericFactory.h" +#include "mozilla/ResultExtensions.h" +#include "nsComponentManager.h" +#include "xpctest_private.h" + +template <typename T> +nsresult RegisterFactory(const char* aContractID) { + auto constructor = [](REFNSIID aIID, void** aResult) { + RefPtr inst = new T(); + return inst->QueryInterface(aIID, aResult); + }; + + nsCOMPtr<nsIFactory> factory = new mozilla::GenericFactory(constructor); + + nsID cid; + MOZ_TRY(nsID::GenerateUUIDInPlace(cid)); + + return nsComponentManagerImpl::gComponentManager->RegisterFactory( + cid, aContractID, aContractID, factory); +} + +nsresult xpcTestRegisterComponents() { + MOZ_TRY(RegisterFactory<xpcTestObjectReadOnly>( + "@mozilla.org/js/xpc/test/native/ObjectReadOnly;1")); + MOZ_TRY(RegisterFactory<xpcTestObjectReadWrite>( + "@mozilla.org/js/xpc/test/native/ObjectReadWrite;1")); + MOZ_TRY(RegisterFactory<nsXPCTestParams>( + "@mozilla.org/js/xpc/test/native/Params;1")); + MOZ_TRY(RegisterFactory<nsXPCTestReturnCodeParent>( + "@mozilla.org/js/xpc/test/native/ReturnCodeParent;1")); + MOZ_TRY(RegisterFactory<nsXPCTestESMReturnCodeParent>( + "@mozilla.org/js/xpc/test/native/ESMReturnCodeParent;1")); + MOZ_TRY(RegisterFactory<xpcTestCEnums>( + "@mozilla.org/js/xpc/test/native/CEnums;1")); + + return NS_OK; +} diff --git a/js/xpconnect/tests/components/native/xpctest_params.cpp b/js/xpconnect/tests/components/native/xpctest_params.cpp new file mode 100644 index 0000000000..4d1924de05 --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_params.cpp @@ -0,0 +1,413 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpctest_private.h" +#include "xpctest_interfaces.h" +#include "mozilla/Casting.h" +#include "js/Value.h" + +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsIURI.h" + +using namespace mozilla; + +NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams) + +#define GENERIC_METHOD_IMPL \ + { \ + *_retval = *b; \ + *b = a; \ + return NS_OK; \ + } + +#define STRING_METHOD_IMPL \ + { \ + _retval.Assign(b); \ + b.Assign(a); \ + return NS_OK; \ + } + +#define SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP) \ + { \ + _retval = std::move(b); \ + b = a.Clone(); \ + for (uint32_t i = 0; i < b.Length(); ++i) TAKE_OWNERSHIP(b[i]); \ + return NS_OK; \ + } + +#define TAKE_OWNERSHIP_NOOP(val) \ + {} +#define TAKE_OWNERSHIP_INTERFACE(val) \ + { static_cast<nsISupports*>(val)->AddRef(); } +#define TAKE_OWNERSHIP_STRING(val) \ + { \ + nsDependentCString vprime(val); \ + val = ToNewCString(vprime); \ + } +#define TAKE_OWNERSHIP_WSTRING(val) \ + { \ + nsDependentString vprime(val); \ + val = ToNewUnicode(vprime); \ + } + +// Macro for our buffer-oriented types: +// 'type' is the type of element that the buffer contains. +// 'padding' is an offset added to length, allowing us to handle +// null-terminated strings. +// 'TAKE_OWNERSHIP' is one of the macros above. +#define BUFFER_METHOD_IMPL(type, padding, TAKE_OWNERSHIP) \ + { \ + uint32_t elemSize = sizeof(type); \ + \ + /* Copy b into rv. */ \ + *rvLength = *bLength; \ + *rv = static_cast<type*>(moz_xmalloc(elemSize * (*bLength + padding))); \ + memcpy(*rv, *b, elemSize*(*bLength + padding)); \ + \ + /* Copy a into b. */ \ + *bLength = aLength; \ + free(*b); \ + *b = static_cast<type*>(moz_xmalloc(elemSize * (aLength + padding))); \ + memcpy(*b, a, elemSize*(aLength + padding)); \ + \ + /* We need to take ownership of the data we got from a, \ + since the caller owns it. */ \ + for (unsigned i = 0; i < *bLength + padding; ++i) TAKE_OWNERSHIP((*b)[i]); \ + \ + return NS_OK; \ + } + +NS_IMETHODIMP nsXPCTestParams::TestBoolean(bool a, bool* b, bool* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestOctet(uint8_t a, uint8_t* b, + uint8_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestShort(int16_t a, int16_t* b, + int16_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestLong(int32_t a, int32_t* b, + int32_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestLongLong(int64_t a, int64_t* b, + int64_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(uint16_t a, uint16_t* b, + uint16_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(uint32_t a, uint32_t* b, + uint32_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(uint64_t a, uint64_t* b, + uint64_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float* b, float* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float* b, double* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char* b, char* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestString(const char* a, char** b, + char** _retval) { + nsDependentCString aprime(a); + nsDependentCString bprime(*b); + *_retval = ToNewCString(bprime); + *b = ToNewCString(aprime); + + // XPCOM ownership rules dictate that overwritten inout params must be + // callee-freed. See https://developer.mozilla.org/en/XPIDL + free(const_cast<char*>(bprime.get())); + + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestWchar(char16_t a, char16_t* b, + char16_t* _retval) { + GENERIC_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestWstring(const char16_t* a, char16_t** b, + char16_t** _retval) { + nsDependentString aprime(a); + nsDependentString bprime(*b); + *_retval = ToNewUnicode(bprime); + *b = ToNewUnicode(aprime); + + // XPCOM ownership rules dictate that overwritten inout params must be + // callee-freed. See https://developer.mozilla.org/en/XPIDL + free((void*)bprime.get()); + + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString& a, nsAString& b, + nsAString& _retval) { + STRING_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString& a, + nsACString& b, + nsACString& _retval) { + STRING_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString& a, nsACString& b, + nsACString& _retval) { + STRING_METHOD_IMPL; +} + +NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a, + JS::MutableHandle<JS::Value> b, + JS::MutableHandle<JS::Value> _retval) { + _retval.set(b); + b.set(a); + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t* a, + uint32_t* bLength, int16_t** b, + uint32_t* rvLength, + int16_t** rv) { + BUFFER_METHOD_IMPL(int16_t, 0, TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP nsXPCTestParams::TestDoubleArray(uint32_t aLength, double* a, + uint32_t* bLength, double** b, + uint32_t* rvLength, + double** rv) { + BUFFER_METHOD_IMPL(double, 0, TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP nsXPCTestParams::TestByteArrayOptionalLength(uint8_t* a, + uint32_t aLength, + uint32_t* rv) { + *rv = aLength; + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestStringArray(uint32_t aLength, const char** a, + uint32_t* bLength, char*** b, + uint32_t* rvLength, char*** rv) { + BUFFER_METHOD_IMPL(char*, 0, TAKE_OWNERSHIP_STRING); +} + +NS_IMETHODIMP nsXPCTestParams::TestWstringArray( + uint32_t aLength, const char16_t** a, uint32_t* bLength, char16_t*** b, + uint32_t* rvLength, char16_t*** rv) { + BUFFER_METHOD_IMPL(char16_t*, 0, TAKE_OWNERSHIP_WSTRING); +} + +NS_IMETHODIMP nsXPCTestParams::TestInterfaceArray( + uint32_t aLength, nsIXPCTestInterfaceA** a, uint32_t* bLength, + nsIXPCTestInterfaceA*** b, uint32_t* rvLength, nsIXPCTestInterfaceA*** rv) { + BUFFER_METHOD_IMPL(nsIXPCTestInterfaceA*, 0, TAKE_OWNERSHIP_INTERFACE); +} + +NS_IMETHODIMP nsXPCTestParams::TestJsvalArray(uint32_t aLength, JS::Value* a, + uint32_t* bLength, JS::Value** b, + uint32_t* rvLength, + JS::Value** rv) { + BUFFER_METHOD_IMPL(JS::Value, 0, TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP nsXPCTestParams::TestSizedString(uint32_t aLength, const char* a, + uint32_t* bLength, char** b, + uint32_t* rvLength, char** rv) { + BUFFER_METHOD_IMPL(char, 1, TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP nsXPCTestParams::TestSizedWstring(uint32_t aLength, + const char16_t* a, + uint32_t* bLength, char16_t** b, + uint32_t* rvLength, + char16_t** rv) { + BUFFER_METHOD_IMPL(char16_t, 1, TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP nsXPCTestParams::TestInterfaceIs(const nsIID* aIID, void* a, + nsIID** bIID, void** b, + nsIID** rvIID, void** rv) { + // + // Getting the buffers and ownership right here can be a little tricky. + // + + // The interface pointers are heap-allocated, and b has been AddRef'd + // by XPConnect for the duration of the call. If we snatch it away from b + // and leave no trace, XPConnect won't Release it. Since we also need to + // return an already-AddRef'd pointer in rv, we don't need to do anything + // special here. + *rv = *b; + + // rvIID is out-only, so nobody allocated an IID buffer for us. Do that now, + // and store b's IID in the new buffer. + *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID))); + **rvIID = **bIID; + + // Copy the interface pointer from a to b. Since a is in-only, XPConnect will + // release it upon completion of the call. AddRef it for b. + *b = a; + static_cast<nsISupports*>(*b)->AddRef(); + + // We already had a buffer allocated for b's IID, so we can re-use it. + **bIID = *aIID; + + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestInterfaceIsArray( + uint32_t aLength, const nsIID* aIID, void** a, uint32_t* bLength, + nsIID** bIID, void*** b, uint32_t* rvLength, nsIID** rvIID, void*** rv) { + // Transfer the IIDs. See the comments in TestInterfaceIs (above) for an + // explanation of what we're doing. + *rvIID = static_cast<nsIID*>(moz_xmalloc(sizeof(nsID))); + **rvIID = **bIID; + **bIID = *aIID; + + // The macro is agnostic to the actual interface types, so we can re-use code + // here. + // + // Do this second, since the macro returns. + BUFFER_METHOD_IMPL(void*, 0, TAKE_OWNERSHIP_INTERFACE); +} + +NS_IMETHODIMP nsXPCTestParams::TestOutAString(nsAString& o) { + o.AssignLiteral("out"); + return NS_OK; +} + +NS_IMETHODIMP nsXPCTestParams::TestStringArrayOptionalSize(const char** a, + uint32_t length, + nsACString& out) { + out.Truncate(); + for (uint32_t i = 0; i < length; ++i) { + out.Append(a[i]); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXPCTestParams::TestShortSequence(const nsTArray<short>& a, nsTArray<short>& b, + nsTArray<short>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestDoubleSequence(const nsTArray<double>& a, + nsTArray<double>& b, + nsTArray<double>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestInterfaceSequence( + const nsTArray<RefPtr<nsIXPCTestInterfaceA>>& a, + nsTArray<RefPtr<nsIXPCTestInterfaceA>>& b, + nsTArray<RefPtr<nsIXPCTestInterfaceA>>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestAStringSequence(const nsTArray<nsString>& a, + nsTArray<nsString>& b, + nsTArray<nsString>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestACStringSequence(const nsTArray<nsCString>& a, + nsTArray<nsCString>& b, + nsTArray<nsCString>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestJsvalSequence(const nsTArray<JS::Value>& a, + nsTArray<JS::Value>& b, + nsTArray<JS::Value>& _retval) { + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP); +} + +NS_IMETHODIMP +nsXPCTestParams::TestSequenceSequence(const nsTArray<nsTArray<short>>& a, + nsTArray<nsTArray<short>>& b, + nsTArray<nsTArray<short>>& _retval) { + _retval = std::move(b); + for (const auto& element : a) { + b.AppendElement(element.Clone()); + } + return NS_OK; +} + +NS_IMETHODIMP +nsXPCTestParams::TestInterfaceIsSequence(const nsIID* aIID, + const nsTArray<void*>& a, nsIID** bIID, + nsTArray<void*>& b, nsIID** rvIID, + nsTArray<void*>& _retval) { + // Shuffle around our nsIIDs + *rvIID = (*bIID)->Clone(); + *bIID = aIID->Clone(); + + // Perform the generic sequence shuffle. + SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_INTERFACE); +} + +NS_IMETHODIMP +nsXPCTestParams::TestOptionalSequence(const nsTArray<uint8_t>& aInArr, + nsTArray<uint8_t>& aReturnArr) { + aReturnArr = aInArr.Clone(); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCTestParams::TestOmittedOptionalOut(nsIXPCTestParams* aJSObj, + nsIURI** aOut) { + MOZ_ASSERT(!(*aOut), "Unexpected value received"); + // Call the js component, to check XPConnect won't crash when passing nullptr + // as the optional out parameter, and that the out object is built regardless. + nsresult rv; + // Invoke it directly passing nullptr. + rv = aJSObj->TestOmittedOptionalOut(nullptr, nullptr); + NS_ENSURE_SUCCESS(rv, rv); + // Also invoke it with a ref pointer. + nsCOMPtr<nsIURI> someURI; + rv = aJSObj->TestOmittedOptionalOut(nullptr, getter_AddRefs(someURI)); + NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString spec; + rv = someURI->GetSpec(spec); + if (!spec.EqualsLiteral("http://example.com/")) { + return NS_ERROR_UNEXPECTED; + } + someURI.forget(aOut); + return NS_OK; +} + +NS_IMETHODIMP +nsXPCTestParams::GetTestNaN(double* aResult) { + *aResult = + BitwiseCast<double>((uint64_t(JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) + 1); + return NS_OK; +} diff --git a/js/xpconnect/tests/components/native/xpctest_private.h b/js/xpconnect/tests/components/native/xpctest_private.h new file mode 100644 index 0000000000..c5d7bc86cf --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_private.h @@ -0,0 +1,102 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* local header for xpconnect tests components */ + +#ifndef xpctest_private_h___ +#define xpctest_private_h___ + +#include "nsISupports.h" +#include "nsString.h" +#include "xpctest_attributes.h" +#include "xpctest_params.h" +#include "xpctest_returncode.h" +#include "xpctest_cenums.h" +#include "mozilla/Attributes.h" +#include "mozilla/ModuleUtils.h" + +nsresult xpcTestRegisterComponents(); + +class xpcTestObjectReadOnly final : public nsIXPCTestObjectReadOnly { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTOBJECTREADONLY + xpcTestObjectReadOnly(); + + private: + ~xpcTestObjectReadOnly() = default; + + bool boolProperty; + int16_t shortProperty; + int32_t longProperty; + float floatProperty; + char charProperty; + PRTime timeProperty; +}; + +class xpcTestObjectReadWrite final : public nsIXPCTestObjectReadWrite { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTOBJECTREADWRITE + + xpcTestObjectReadWrite(); + + private: + ~xpcTestObjectReadWrite(); + + bool boolProperty; + int16_t shortProperty; + int32_t longProperty; + float floatProperty; + char charProperty; + char* stringProperty; + PRTime timeProperty; +}; + +class nsXPCTestParams final : public nsIXPCTestParams { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTPARAMS + + nsXPCTestParams() = default; + + private: + ~nsXPCTestParams() = default; +}; + +class nsXPCTestReturnCodeParent final : public nsIXPCTestReturnCodeParent { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTRETURNCODEPARENT + + nsXPCTestReturnCodeParent() = default; + + private: + ~nsXPCTestReturnCodeParent() = default; +}; + +class nsXPCTestESMReturnCodeParent final : public nsIXPCTestReturnCodeParent { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTRETURNCODEPARENT + + nsXPCTestESMReturnCodeParent() = default; + + private: + ~nsXPCTestESMReturnCodeParent() = default; +}; + +class xpcTestCEnums final : public nsIXPCTestCEnums { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIXPCTESTCENUMS + + xpcTestCEnums(); + + private: + ~xpcTestCEnums() = default; +}; +#endif /* xpctest_private_h___ */ diff --git a/js/xpconnect/tests/components/native/xpctest_returncode.cpp b/js/xpconnect/tests/components/native/xpctest_returncode.cpp new file mode 100644 index 0000000000..3a52f616d9 --- /dev/null +++ b/js/xpconnect/tests/components/native/xpctest_returncode.cpp @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpctest_private.h" +#include "nsComponentManagerUtils.h" +#include "nsImportModule.h" + +NS_IMPL_ISUPPORTS(nsXPCTestReturnCodeParent, nsIXPCTestReturnCodeParent) + +NS_IMETHODIMP nsXPCTestReturnCodeParent::CallChild(int32_t childBehavior, + nsresult* _retval) { + nsresult rv; + nsCOMPtr<nsIXPCTestReturnCodeChild> child(do_ImportModule( + "resource://test/ReturnCodeChild.jsm", "ReturnCodeChild", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = child->DoIt(childBehavior); + *_retval = rv; + return NS_OK; +} diff --git a/js/xpconnect/tests/idl/moz.build b/js/xpconnect/tests/idl/moz.build new file mode 100644 index 0000000000..8b56f40c21 --- /dev/null +++ b/js/xpconnect/tests/idl/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +XPIDL_SOURCES += [ + "xpctest_attributes.idl", + "xpctest_bug809674.idl", + "xpctest_cenums.idl", + "xpctest_interfaces.idl", + "xpctest_params.idl", + "xpctest_returncode.idl", + "xpctest_utils.idl", +] + +XPIDL_MODULE = "xpctest" diff --git a/js/xpconnect/tests/idl/xpctest_attributes.idl b/js/xpconnect/tests/idl/xpctest_attributes.idl new file mode 100644 index 0000000000..9822b24dfb --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_attributes.idl @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +/* + * This defines the interface for a test object. + * + */ + +[scriptable, uuid(42fbd9f6-b12d-47ef-b7a1-02d73c11fe53)] +interface nsIXPCTestObjectReadOnly : nsISupports { + readonly attribute string strReadOnly; + readonly attribute boolean boolReadOnly; + readonly attribute short shortReadOnly; + readonly attribute long longReadOnly; + readonly attribute float floatReadOnly; + readonly attribute char charReadOnly; + readonly attribute PRTime timeReadOnly; +}; + +[scriptable, uuid(f07529b0-a479-4954-aba5-ab3142c6b1cb)] +interface nsIXPCTestObjectReadWrite : nsISupports { + attribute string stringProperty; + attribute boolean booleanProperty; + attribute short shortProperty; + attribute long longProperty; + attribute float floatProperty; + attribute char charProperty; + attribute PRTime timeProperty; +}; diff --git a/js/xpconnect/tests/idl/xpctest_bug809674.idl b/js/xpconnect/tests/idl/xpctest_bug809674.idl new file mode 100644 index 0000000000..1e83e244ec --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_bug809674.idl @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +/* + * Test interface for https://bugzilla.mozilla.org/show_bug.cgi?id=809674 . + * + * This test makes sure that accessing JS-implemented attributes or methods + * marked with [implicit_jscontext] works as expected. + * + * It also makes sure [optional_argc] is not supported on JS-implemented + * methods. + */ + +[scriptable, uuid(2df46559-da21-49bf-b863-0d7b7bbcbc73)] +interface nsIXPCTestBug809674 : nsISupports { + // Various interesting [implicit_jscontext] cases. + [implicit_jscontext] unsigned long addArgs(in unsigned long x, in unsigned long y); + [implicit_jscontext] unsigned long addSubMulArgs(in unsigned long x, in unsigned long y, + out unsigned long subOut, + out unsigned long mulOut); + [implicit_jscontext] jsval addVals(in jsval x, in jsval y); + + [implicit_jscontext] unsigned long methodNoArgs(); + [implicit_jscontext] void methodNoArgsNoRetVal(); + + // When there are many arguments, the context is passed on the stack on + // most platforms. + [implicit_jscontext] unsigned long addMany(in unsigned long x1, + in unsigned long x2, + in unsigned long x3, + in unsigned long x4, + in unsigned long x5, + in unsigned long x6, + in unsigned long x7, + in unsigned long x8); + + // Attributes can use [implicit_jscontext], too. + [implicit_jscontext] attribute jsval valProperty; + [implicit_jscontext] attribute unsigned long uintProperty; + + // [optional_argc] is not supported. + [optional_argc] void methodWithOptionalArgc(); +}; diff --git a/js/xpconnect/tests/idl/xpctest_cenums.idl b/js/xpconnect/tests/idl/xpctest_cenums.idl new file mode 100644 index 0000000000..70b7f8fae7 --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_cenums.idl @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +/* + * This defines the interface for a test object. + * + */ + +[scriptable, uuid(6a2f918e-cda2-11e8-bc9a-a34c716d1f2a)] +interface nsIXPCTestCEnums : nsISupports { + const long testConst = 1; + + cenum testFlagsExplicit: 8 { + shouldBe1Explicit = 1, + shouldBe2Explicit = 2, + shouldBe4Explicit = 4, + shouldBe8Explicit = 8, + shouldBe12Explicit = shouldBe4Explicit | shouldBe8Explicit, + }; + + cenum testFlagsImplicit: 8 { + shouldBe0Implicit, + shouldBe1Implicit, + shouldBe2Implicit, + shouldBe3Implicit, + shouldBe5Implicit = 5, + shouldBe6Implicit, + shouldBe2AgainImplicit = 2, + shouldBe3AgainImplicit, + }; + + void testCEnumInput(in nsIXPCTestCEnums_testFlagsExplicit abc); + + nsIXPCTestCEnums_testFlagsExplicit testCEnumOutput(); +}; diff --git a/js/xpconnect/tests/idl/xpctest_esmreturncode.idl b/js/xpconnect/tests/idl/xpctest_esmreturncode.idl new file mode 100644 index 0000000000..ac17feda3f --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_esmreturncode.idl @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Test the use of Components.returnCode with system ESM + * + * This ("parent") interface defines a method that in-turn calls another + * ("child") interface implemented in JS, and returns the nsresult from that + * child interface. The child interface manages the return code by way of + * Components.returnCode. + */ + +#include "nsISupports.idl" + + +[scriptable, uuid(494f9336-ad06-46ad-bbb4-b0010e27e12d)] +interface nsIXPCTestESMReturnCodeParent : nsISupports { + // Calls the "child" interface with the specified behavior flag. Returns + // the NSRESULT from the child interface. + nsresult callChild(in long childBehavior); +}; + +[scriptable, uuid(dee07408-75d8-4968-a37c-fe0d48ccd1ac)] +interface nsIXPCTestESMReturnCodeChild : nsISupports { + void doIt(in long behavior); + + // Flags to control that the child does. + // child will throw a JS exception + const long CHILD_SHOULD_THROW = 0; + + // child will just return normally + const long CHILD_SHOULD_RETURN_SUCCESS = 1; + + // child will return after setting Components.returnCode to NS_ERROR_FAILURE + const long CHILD_SHOULD_RETURN_RESULTCODE = 2; + + // child will set Components.returnCode to NS_ERROR_UNEXPECTED, then create + // a new component that sets Components.returnCode to NS_ERROR_FAILURE. + // Our caller should see the NS_ERROR_UNEXPECTED we set rather than the + // value set later by the "inner" child. + const long CHILD_SHOULD_NEST_RESULTCODES = 3; +}; diff --git a/js/xpconnect/tests/idl/xpctest_interfaces.idl b/js/xpconnect/tests/idl/xpctest_interfaces.idl new file mode 100644 index 0000000000..2abc149623 --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_interfaces.idl @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Very simple test interfaces. + * + * This is used by the other test functionality when it needs to play around with + * interface pointers. + */ + +#include "nsISupports.idl" + +[scriptable, uuid(3c8fd2f5-970c-42c6-b5dd-cda1c16dcfd8)] +interface nsIXPCTestInterfaceA : nsISupports { + attribute string name; +}; + +[scriptable, uuid(ff528c3a-2410-46de-acaa-449aa6403a33)] +interface nsIXPCTestInterfaceB : nsISupports { + attribute string name; +}; + +[scriptable, uuid(401cf1b4-355b-4cee-b7b3-c7973aee49bd)] +interface nsIXPCTestInterfaceC : nsISupports { + attribute long someInteger; +}; diff --git a/js/xpconnect/tests/idl/xpctest_params.idl b/js/xpconnect/tests/idl/xpctest_params.idl new file mode 100644 index 0000000000..8bf224507c --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_params.idl @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Test pararameter passing and argument conversion. + * + * Each test method returns the value in 'b', and copies 'a' into 'b'. This lets + * us test return values, in params, and inout params (out params should be + * covered by the intersection of return values and inout). + */ + +#include "nsISupports.idl" + +interface nsIURI; +interface nsIXPCTestInterfaceA; +interface nsIXPCTestInterfaceB; + +[scriptable, uuid(812145c7-9fcc-425e-a878-36ad1b7730b7)] +interface nsIXPCTestParams : nsISupports { + + // These types correspond to the ones in typelib.py + boolean testBoolean(in boolean a, inout boolean b); + octet testOctet(in octet a, inout octet b); + short testShort(in short a, inout short b); + long testLong(in long a, inout long b); + long long testLongLong(in long long a, inout long long b); + unsigned short testUnsignedShort(in unsigned short a, inout unsigned short b); + unsigned long testUnsignedLong(in unsigned long a, inout unsigned long b); + unsigned long long testUnsignedLongLong(in unsigned long long a, inout unsigned long long b); + float testFloat(in float a, inout float b); + double testDouble(in double a, inout float b); + char testChar(in char a, inout char b); + string testString(in string a, inout string b); + wchar testWchar(in wchar a, inout wchar b); + wstring testWstring(in wstring a, inout wstring b); + AString testAString(in AString a, inout AString b); + AUTF8String testAUTF8String(in AUTF8String a, inout AUTF8String b); + ACString testACString(in ACString a, inout ACString b); + jsval testJsval(in jsval a, inout jsval b); + + // Test various forms of the Array<T> type. + Array<short> testShortSequence(in Array<short> a, inout Array<short> b); + Array<double> testDoubleSequence(in Array<double> a, inout Array<double> b); + Array<nsIXPCTestInterfaceA> testInterfaceSequence(in Array<nsIXPCTestInterfaceA> a, inout Array<nsIXPCTestInterfaceA> b); + Array<AString> testAStringSequence(in Array<AString> a, inout Array<AString> b); + Array<ACString> testACStringSequence(in Array<ACString> a, inout Array<ACString> b); + Array<jsval> testJsvalSequence(in Array<jsval> a, inout Array<jsval> b); + Array<Array<short> > testSequenceSequence(in Array<Array<short> > a, inout Array<Array<short> > b); + + void testInterfaceIsSequence(in nsIIDPtr aIID, [iid_is(aIID)] in Array<nsQIResult> a, + inout nsIIDPtr bIID, [iid_is(bIID)] inout Array<nsQIResult> b, + out nsIIDPtr rvIID, [retval, iid_is(rvIID)] out Array<nsQIResult> rv); + + // Returns whatever was passed in. + Array<uint8_t> testOptionalSequence([optional] in Array<uint8_t> arr); + + // + // Dependent parameters use the same types as above, but are handled much differently. + // + + // Test arrays. + void testShortArray(in unsigned long aLength, [array, size_is(aLength)] in short a, + inout unsigned long bLength, [array, size_is(bLength)] inout short b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out short rv); + void testDoubleArray(in unsigned long aLength, [array, size_is(aLength)] in double a, + inout unsigned long bLength, [array, size_is(bLength)] inout double b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out double rv); + void testStringArray(in unsigned long aLength, [array, size_is(aLength)] in string a, + inout unsigned long bLength, [array, size_is(bLength)] inout string b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out string rv); + void testWstringArray(in unsigned long aLength, [array, size_is(aLength)] in wstring a, + inout unsigned long bLength, [array, size_is(bLength)] inout wstring b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out wstring rv); + void testInterfaceArray(in unsigned long aLength, [array, size_is(aLength)] in nsIXPCTestInterfaceA a, + inout unsigned long bLength, [array, size_is(bLength)] inout nsIXPCTestInterfaceA b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out nsIXPCTestInterfaceA rv); + + // uint8 array with optional length. Returns array length. + unsigned long testByteArrayOptionalLength([array, size_is(aLength)] in uint8_t a, [optional] in unsigned long aLength); + + // Test sized strings. + void testSizedString(in unsigned long aLength, [size_is(aLength)] in string a, + inout unsigned long bLength, [size_is(bLength)] inout string b, + out unsigned long rvLength, [retval, size_is(rvLength)] out string rv); + void testSizedWstring(in unsigned long aLength, [size_is(aLength)] in wstring a, + inout unsigned long bLength, [size_is(bLength)] inout wstring b, + out unsigned long rvLength, [retval, size_is(rvLength)] out wstring rv); + + // Test iid_is. + void testInterfaceIs(in nsIIDPtr aIID, [iid_is(aIID)] in nsQIResult a, + inout nsIIDPtr bIID, [iid_is(bIID)] inout nsQIResult b, + out nsIIDPtr rvIID, [retval, iid_is(rvIID)] out nsQIResult rv); + + // Test arrays of iid_is. According to khuey we don't use it for anything + // in mozilla-central, but calendar stuff depends on it. + void testInterfaceIsArray(in unsigned long aLength, in nsIIDPtr aIID, + [array, size_is(aLength), iid_is(aIID)] in nsQIResult a, + inout unsigned long bLength, inout nsIIDPtr bIID, + [array, size_is(bLength), iid_is(bIID)] inout nsQIResult b, + out unsigned long rvLength, out nsIIDPtr rvIID, + [retval, array, size_is(rvLength), iid_is(rvIID)] out nsQIResult rv); + + // Test arrays of jsvals + void testJsvalArray(in unsigned long aLength, [array, size_is(aLength)] in jsval a, + inout unsigned long bLength, [array, size_is(bLength)] inout jsval b, + out unsigned long rvLength, [retval, array, size_is(rvLength)] out jsval rv); + + + // Test for out dipper parameters + void testOutAString(out AString o); + + // Test for optional array size_is. + ACString testStringArrayOptionalSize([array, size_is(aLength)] in string a, [optional] in unsigned long aLength); + + // Test for omitted optional out parameter. + void testOmittedOptionalOut(in nsIXPCTestParams aJSObj, [optional] out nsIURI aOut); + + readonly attribute double testNaN; +}; diff --git a/js/xpconnect/tests/idl/xpctest_returncode.idl b/js/xpconnect/tests/idl/xpctest_returncode.idl new file mode 100644 index 0000000000..5ee6c55479 --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_returncode.idl @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Test the use of Components.returnCode + * + * This ("parent") interface defines a method that in-turn calls another + * ("child") interface implemented in JS, and returns the nsresult from that + * child interface. The child interface manages the return code by way of + * Components.returnCode. + */ + +#include "nsISupports.idl" + + +[scriptable, uuid(479e4532-95cf-48b8-a99b-8a5881e47138)] +interface nsIXPCTestReturnCodeParent : nsISupports { + // Calls the "child" interface with the specified behavior flag. Returns + // the NSRESULT from the child interface. + nsresult callChild(in long childBehavior); +}; + +[scriptable, uuid(672cfd34-1fd1-455d-9901-d879fa6fdb95)] +interface nsIXPCTestReturnCodeChild : nsISupports { + void doIt(in long behavior); + + // Flags to control that the child does. + // child will throw a JS exception + const long CHILD_SHOULD_THROW = 0; + + // child will just return normally + const long CHILD_SHOULD_RETURN_SUCCESS = 1; + + // child will return after setting Components.returnCode to NS_ERROR_FAILURE + const long CHILD_SHOULD_RETURN_RESULTCODE = 2; + + // child will set Components.returnCode to NS_ERROR_UNEXPECTED, then create + // a new component that sets Components.returnCode to NS_ERROR_FAILURE. + // Our caller should see the NS_ERROR_UNEXPECTED we set rather than the + // value set later by the "inner" child. + const long CHILD_SHOULD_NEST_RESULTCODES = 3; +}; diff --git a/js/xpconnect/tests/idl/xpctest_utils.idl b/js/xpconnect/tests/idl/xpctest_utils.idl new file mode 100644 index 0000000000..e59814272b --- /dev/null +++ b/js/xpconnect/tests/idl/xpctest_utils.idl @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Utility interfaces for testing. + */ + +#include "nsISupports.idl" + +[scriptable, function, uuid(d58a82ab-d8f7-4ca9-9273-b3290d42a0cf)] +interface nsIXPCTestFunctionInterface : nsISupports { + string echo(in string arg); +}; + +[scriptable, uuid(1e9cddeb-510d-449a-b152-3c1b5b31d41d)] +interface nsIXPCTestUtils : nsISupports { + nsIXPCTestFunctionInterface doubleWrapFunction(in nsIXPCTestFunctionInterface f); +}; diff --git a/js/xpconnect/tests/mochitest/bug1681664_helper.js b/js/xpconnect/tests/mochitest/bug1681664_helper.js new file mode 100644 index 0000000000..14f2289a19 --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug1681664_helper.js @@ -0,0 +1 @@ +while (true) {}; diff --git a/js/xpconnect/tests/mochitest/bug500931_helper.html b/js/xpconnect/tests/mochitest/bug500931_helper.html new file mode 100644 index 0000000000..da268d99d8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug500931_helper.html @@ -0,0 +1,8 @@ +<html> + <head> + <title>Inner frame for bug 500931 mochitest</title> + <script>x = 42;</script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug571849_helper.html b/js/xpconnect/tests/mochitest/bug571849_helper.html new file mode 100644 index 0000000000..234cd57ccf --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug571849_helper.html @@ -0,0 +1,7 @@ +<html> + <head> + </head> + <body> + TEXT NODE TEXT NODE + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug589028_helper.html b/js/xpconnect/tests/mochitest/bug589028_helper.html new file mode 100644 index 0000000000..dc56ecbc3c --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug589028_helper.html @@ -0,0 +1,27 @@ +<html> + <head> + <script> + function getMyOption() { + return new Option(); + } + function getCallersOption(caller) { + return new caller.Option(); + } + function getMyAudio() { + return new Audio(); + } + function getCallersAudio(caller) { + return new caller.Audio(); + } + function getMyImage() { + return new Image(); + } + function getCallersImage(caller) { + return new caller.Image(); + } + </script> + </head> + <body> + the iframe + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/bug92773_helper.html b/js/xpconnect/tests/mochitest/bug92773_helper.html new file mode 100644 index 0000000000..be10dd54ae --- /dev/null +++ b/js/xpconnect/tests/mochitest/bug92773_helper.html @@ -0,0 +1,7 @@ +<html> + <head> + <script> + Object.defineProperty(window, "foo", { get() { alert("FAIL"); } }); + </script> + </head> +</html> diff --git a/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html new file mode 100644 index 0000000000..a0c1ec87e3 --- /dev/null +++ b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html @@ -0,0 +1,29 @@ +<html> + <head> + <script> + function check_wrapper(ok, wrapper, expected, note) { + let { getClassName } = SpecialPowers.unwrap( + SpecialPowers.wrap(window).ChromeUtils + ); + ok(getClassName(wrapper, false) === expected, note); + } + function run_test(ok, xpcnw, sjow) { + // both wrappers should point to our window: XOW + check_wrapper(ok, ok, "Proxy", "functions are wrapped properly"); + check_wrapper(ok, xpcnw, "Proxy", "XPCNWs are transformed correctly"); + check_wrapper(ok, sjow, "Proxy", "SJOWs are transformed correctly"); + + check_wrapper(ok, window.location, "Location", + "same-compartment security wrappers are gone"); + + ok(defprop1 === 1, "defprop1 exists"); + window.defprop1 = 2; + ok(defprop1 === 2, "defprop1 is properly writable"); + + // defprop2 = {}; disabled because the test doesn't work + } + </script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/class_static_worker.js b/js/xpconnect/tests/mochitest/class_static_worker.js new file mode 100644 index 0000000000..eb949226ba --- /dev/null +++ b/js/xpconnect/tests/mochitest/class_static_worker.js @@ -0,0 +1,13 @@ +class A { + static { this.x = 12; } +} + + +self.onmessage = function (e) { + console.log(e) + if (e.data == 'get') { + postMessage(A.x); + return; + } + postMessage('Unknown message type.'); +}
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/file1_bug629227.html b/js/xpconnect/tests/mochitest/file1_bug629227.html new file mode 100644 index 0000000000..dd12484068 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file1_bug629227.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <script> + function doIt() { + var doc = window.frames[0].document; + var ok = (doc.form1 == doc.getElementById("test1")); + window.parent.postMessage( + JSON.stringify({ ok: ok, + reason: "Should be able to get named items by name" }), + "*"); + window.parent.postMessage("finish", "*"); + } + + window.onmessage = function(ev) { + if (ev.data == "start") { + doIt(); + } + } + + document.domain = "example.org"; + </script> + </head> + <body> + <iframe id="subframe"></iframe> + <script> + document.getElementById("subframe").src = + "http://test2.example.org" + + location.pathname.replace(/file1_bug629227.html/, "file2_bug629227.html"); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file2_bug629227.html b/js/xpconnect/tests/mochitest/file2_bug629227.html new file mode 100644 index 0000000000..02a0540865 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file2_bug629227.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> + <head> + <script> + document.domain = "example.org"; + </script> + </head> + <body> + <form name="form1" id="test1"></form> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug505915.html b/js/xpconnect/tests/mochitest/file_bug505915.html new file mode 100644 index 0000000000..5129126914 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug505915.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<!-- +Inner frame for testing bug 505915. +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> +<body onload="parent.postMessage('', '*');"> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug605167.html b/js/xpconnect/tests/mochitest/file_bug605167.html new file mode 100644 index 0000000000..d5253315b8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug605167.html @@ -0,0 +1,7 @@ +<html> +<body> +<script> + parent.f = function() { return this; }; +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug650273.html b/js/xpconnect/tests/mochitest/file_bug650273.html new file mode 100644 index 0000000000..5fe33e9695 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug650273.html @@ -0,0 +1,31 @@ +<!-- test by moz_bug_r_a4@yahoo.com --> +<body onload="a()"> +<script> +var targetUrl = "http://example.com/"; +var l; + +function a() { + var o = {}; + o.toString = function() { + l(); + return "a"; + }; + var f = Object.getOwnPropertyDescriptor(Document.prototype, "title").set; + setTimeout(f.bind(document), 0, o); +} + +function l() { + var l = false; + onunload = function() { + l = true; + }; + location = targetUrl; + do { + var r = new XMLHttpRequest(); + r.open("GET", location.href, false); + r.overrideMimeType("text/plain"); + try { r.send(null); } + catch (e) {} + } while (!l); +} +</script> diff --git a/js/xpconnect/tests/mochitest/file_bug658560.html b/js/xpconnect/tests/mochitest/file_bug658560.html new file mode 100644 index 0000000000..411d31ac73 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug658560.html @@ -0,0 +1,4 @@ +<html> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug706301.html b/js/xpconnect/tests/mochitest/file_bug706301.html new file mode 100644 index 0000000000..805449b4aa --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug706301.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <script type="application/javascript"> + window.addEventListener('message', doContentTest); + + function doContentTest() { + + // This has always worked. + var nodelist1 = document.getElementsByTagName('details'); + Object.getOwnPropertyDescriptor(nodelist1, 'length'); + ok(nodelist1['length'] == 0, "Content should be able to get the length of " + + "its own nodelist after calling getOwnPropertyDescriptor."); + + // This is bug 706301. + var nodelist2 = document.getElementsByTagName('section'); + ok(getLengthInChrome(nodelist2), "Chrome should be able to get the length of " + + "content nodelist after calling getOwnPropertyDescriptor."); + + // All done. + finishTestInChrome(); + } + </script> + </head> + <body> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug720619.html b/js/xpconnect/tests/mochitest/file_bug720619.html new file mode 100644 index 0000000000..d198ba1fa3 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug720619.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> + <head> + <script> + valueOf = function() { return "v"; } + toString = function() { return "s"; } + </script> + </head> + <body></body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug731471.html b/js/xpconnect/tests/mochitest/file_bug731471.html new file mode 100644 index 0000000000..fcfb194cb6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug731471.html @@ -0,0 +1,5 @@ +<html> +<body> +1 +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug738244.html b/js/xpconnect/tests/mochitest/file_bug738244.html new file mode 100644 index 0000000000..a399d9f0e0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug738244.html @@ -0,0 +1,10 @@ +<html> +<body> +<form name="form1"> + <input name="input1" /> + <input name="appendChild" /> +</form> +<iframe name="frame1"> +</iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug760131.html b/js/xpconnect/tests/mochitest/file_bug760131.html new file mode 100644 index 0000000000..736732a0a4 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug760131.html @@ -0,0 +1,23 @@ +<html> +<div id="target" ontouchstart="alert();"></div> +<script type="application/javascript"> + +/** Test for Bug 760131 **/ + +function accessTouches(evt) +{ + var thrown = false; + try { + var a = evt.touches; + } catch (e) { + thrown = true; + } + ok(!thrown, "Unwrapping a TouchList shouldn't throw"); +} + +document.getElementById("target").ontouchstart = accessTouches; + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug781476.html b/js/xpconnect/tests/mochitest/file_bug781476.html new file mode 100644 index 0000000000..745f8818e5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug781476.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> +function makeEvent() { + var evt = new Event("MouseEvents"); + evt.expando = 42; + is(evt.expando, 42, "Expando properly visible in iframe"); + return evt; +} +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug789713.html b/js/xpconnect/tests/mochitest/file_bug789713.html new file mode 100644 index 0000000000..4c30fe8275 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug789713.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789713 +--> +<head> + <meta charset="utf-8"> +</head> +<body> + +<script type="application/javascript"> + +/** Test for Bug 789713 **/ + +function go() { + var ifr = document.getElementById('ifr'); + var pass = true; + var doc = ifr.contentDocument; + var win = ifr.contentWindow; + + var walker = doc.createTreeWalker(doc.body); + pass = pass && (walker.root === doc.body); + walker.foo = "expando"; + + win.bar = "another-expando"; + + // First, do the document.domain operation. This shouldn't crash. + document.domain = "example.org"; + + // Now make sure we can still access properties on "walker". + try { + walker.root; + pass = pass && walker.foo == "expando"; + } catch (e) { + pass = false; + } + + // And make sure we can't access properties on "win", because the + // document.domain change revoked the access. + try { + win.bar; + pass = false; + } catch (e) { pass = pass && /Permission denied/.exec(e.message); } + window.parent.postMessage(pass, '*'); +} + +</script> +<iframe id="ifr" src="file_empty.html" onload="go()"></iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug795275.html b/js/xpconnect/tests/mochitest/file_bug795275.html new file mode 100644 index 0000000000..c3886b8ba8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug795275.html @@ -0,0 +1,14 @@ +<html> +<head> +<script type="application/javascript"> + function touchComponents() { + Components; + } + function touchInterfaces() { + Components.interfaces; + } +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug799348.html b/js/xpconnect/tests/mochitest/file_bug799348.html new file mode 100644 index 0000000000..5800868db0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug799348.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> +<script> + var foo = window.open('file_empty.html', '', 'width=550, height=420, status=no, resizable=yes, scrollbars=yes, toolbar=no, left=945, top=225'); +</script> +</head> +<body> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/file_bug802557.html b/js/xpconnect/tests/mochitest/file_bug802557.html new file mode 100644 index 0000000000..39f952bc5b --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug802557.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> +<script> +var gTS = window.location.toString; +var gGHR = Object.getOwnPropertyDescriptor(window.location, 'href').get; +function getTests(fromOuter) { + + function loc() { + return fromOuter ? window.location : location; + } + return { + getLocationImplicit: function() { + return loc() + ""; + }, + getLocationExplicit: function() { + return loc().toString(); + }, + getLocationApply1: function() { + return gTS.call(loc()); + }, + getLocationApply2: function() { + return gTS.apply(loc(), []); + }, + getLocationApply3: function() { + return Function.call.apply(gTS, [loc()]); + }, + getHref: function() { + return loc().href; + }, + getHrefViaApply: function() { + return Function.call.apply(gGHR, [loc()]); + }, + } +}; + +function mungeNames(obj, suffix) { + var rv = {}; + Object.getOwnPropertyNames(obj) + .forEach(name => rv[name + suffix] = obj[name]); + return rv; +} + +function mergeObjects(a, b) { + var rv = {}; + Object.getOwnPropertyNames(a).forEach(name => rv[name] = a[name]); + Object.getOwnPropertyNames(b).forEach(name => rv[name] = b[name]); + return rv; +} + +function getAllTests() { + var innerTests = getTests(false); + var outerTests = getTests(true); + return mergeObjects(mungeNames(innerTests, '_inner'), + mungeNames(outerTests, '_outer')); +} + +</script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_bug860494.html b/js/xpconnect/tests/mochitest/file_bug860494.html new file mode 100644 index 0000000000..63a7003796 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_bug860494.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title></title> +</head> +<body> +<iframe name="top"></iframe> +<iframe name="parent"></iframe> +<iframe name="location"></iframe> +<iframe name="length"></iframe> +<iframe name="window"></iframe> +<iframe name="navigator"></iframe> +<iframe name="alert"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html new file mode 100644 index 0000000000..127c479ebe --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html @@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Cross-Compartment DOM WeakMaps</title> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_documentdomain.html b/js/xpconnect/tests/mochitest/file_documentdomain.html new file mode 100644 index 0000000000..784ed269d0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_documentdomain.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + + function setDomain(domain) { + document.domain = domain; + } + + function tryToAccess(otherWin) { + try { + var text = otherWin.document.getElementById('foo').innerHTML; + return /Better Late/.exec(text); + } catch (e) { return false; } + } + + var gRef = null; + function storeReference(otherWin) { + gRef = otherWin.document.getElementById('foo'); + } + + function tryToAccessStored() { + try { + return /Better Late/.exec(gRef.innerHTML); + } catch (e) { return false; } + } + + function invokingFunctionThrowsSecurityException(name) { + try { + window[name](); + return false; + } catch (e) { return /insecure|denied/.test(e); } + } + + +</script> +</head> +<body> +<span id="foo">Better Late than Never</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html new file mode 100644 index 0000000000..f789a33d76 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html @@ -0,0 +1,10 @@ +<html> + <head> + <script> + // We want to put an expando on the object, but we want this object + // to be wrapped in other compartments. This means that the expando + // must implement precreate, which happens (in general) for nodes. + // So we just do a cyclic reference to the document body. + window.expando = document.documentElement; + </script> + </head> diff --git a/js/xpconnect/tests/mochitest/file_empty.html b/js/xpconnect/tests/mochitest/file_empty.html new file mode 100644 index 0000000000..ebe8e56a68 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_empty.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<!-- Note: other tests throughout the tree depend on the layout of this, including the title. Don't make big changes without a try run. --> +<html><head><title>empty test page</title></head><body><span id="text">Nothing to see here</span><iframe name="subframe"></iframe></body></html> diff --git a/js/xpconnect/tests/mochitest/file_evalInSandbox.html b/js/xpconnect/tests/mochitest/file_evalInSandbox.html new file mode 100644 index 0000000000..f53aa1166c --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_evalInSandbox.html @@ -0,0 +1,8 @@ +<html> + <body> + <script> + document.foo = "bar"; + windowfoo = "windowbar"; + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_exnstack.html b/js/xpconnect/tests/mochitest/file_exnstack.html new file mode 100644 index 0000000000..448e3c0a70 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_exnstack.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> + <script type="application/javascript"> + window.doThrow = function(other) { + if (other) + throwAsOuter(other); + else + throwAsInner(); + } + + function throwAsInner() { + throw Error('look at me go!'); + } + + function throwAsOuter(other) { + other.doThrow(null); + } + </script> +</head> +<body> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_expandosharing.html b/js/xpconnect/tests/mochitest/file_expandosharing.html new file mode 100644 index 0000000000..ceb4131bb8 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_expandosharing.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + function setup() { + // Set up different target objects for expandos, one for each binding type. + window.targetWN = window; + window.targetDOM = new XMLHttpRequest(); + window.targetJS = new Date(); + } + + function placeExpando(name, val, target) { + target[name] = val; + } + + // If val === null, then we shouldn't have access. + function checkExpando(name, val, target, msg) { + if (val !== null) { + ok(name in target, msg); + try { + is(target[name], val, "Got the right expando value"); + } catch(e) { ok(false, "Threw when accessing same-origin expando"); } + } + else { + ok(!(name in target), msg); + } + } + +</script> +</head> +<body onload="setup();"> + <span>Salut, Ma Cherise. ;-)</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_matches.html b/js/xpconnect/tests/mochitest/file_matches.html new file mode 100644 index 0000000000..0dc101b533 --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_matches.html @@ -0,0 +1 @@ +<html><body></body></html> diff --git a/js/xpconnect/tests/mochitest/file_nodelists.html b/js/xpconnect/tests/mochitest/file_nodelists.html new file mode 100644 index 0000000000..2195c62ccf --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_nodelists.html @@ -0,0 +1,7 @@ +<html> + <body> + <p> + <p> + <p> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_wrappers-2.html b/js/xpconnect/tests/mochitest/file_wrappers-2.html new file mode 100644 index 0000000000..e27b07ed6a --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_wrappers-2.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <body> + <script> + var obj = {a: 3, next: 1}; + var to_iterate = Object.create(obj); + var enumerate = { 0: 0, "hi": "there" }; + function func () {}; + var o = {}; + var a = [1]; + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/file_xrayic.html b/js/xpconnect/tests/mochitest/file_xrayic.html new file mode 100644 index 0000000000..ad06a3118b --- /dev/null +++ b/js/xpconnect/tests/mochitest/file_xrayic.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<script type="application/javascript"> + function setup() { + // Set up targets for sandbox expandos. + window.targetDOM = [document.getElementById("hello"), document.getElementById("there")]; + } +</script> +</head> +<body onload="setup();"> +<span id="hello" class="iamaspan">Hello</span> +<span id="there" class="iamaspan">There</span> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js new file mode 100644 index 0000000000..d603cdab38 --- /dev/null +++ b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js @@ -0,0 +1,96 @@ +let holdings1 = []; +let holdings2 = []; +let holdings3 = []; +let holdings4 = []; +let holdings5 = []; + +onmessage = (event) => { + switch (event.data) { + case 'startTest': + startTest(); + break; + case 'checkResults': + checkResults(); + break; + default: + throw "Unknown message"; + } +}; + +function startTest() { + // Registry with no registered objects. + let registry1 = new FinalizationRegistry(v => { holdings1.push(v); }); + + // Registry with three registered objects. + let registry2 = new FinalizationRegistry(v => { holdings2.push(v); }); + registry2.register({}, 1); + registry2.register({}, 2); + registry2.register({}, 3); + + // Registry with registered object that is then unregistered. + let registry3 = new FinalizationRegistry(v => { holdings3.push(v); }); + let token3 = {} + registry3.register({}, 1, token3); + registry3.unregister(token3); + + // Registry with registered object that doesn't die. + let registry4 = new FinalizationRegistry(v => { holdings4.push(v); }); + let object4 = {}; + registry4.register(object4, 1); + + // Registry observing cyclic JS data structure. + let registry5 = new FinalizationRegistry(v => { holdings5.push(v); }); + registry5.register(makeJSCycle(4), 5); + + const { gc } = getJSTestingFunctions(); + gc(); + + Promise.resolve().then(() => { + checkNoCallbacks(); + }); + + postMessage('started'); +} + +function checkNoCallbacks() { + is(holdings1.length, 0); + is(holdings2.length, 0); + is(holdings3.length, 0); + is(holdings4.length, 0); + is(holdings5.length, 0); +} + +function checkResults() { + is(holdings1.length, 0); + + let result = holdings2.sort((a, b) => a - b); + is(result.length, 3); + is(result[0], 1); + is(result[1], 2); + is(result[2], 3); + + is(holdings3.length, 0); + is(holdings4.length, 0); + + is(holdings5.length, 1); + is(holdings5[0], 5); + + postMessage('passed'); +} + +function is(a, b) { + if (a !== b) { + throw `Expected ${b} but got ${a}`; + } +} + +function makeJSCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + current.next = {}; + current = current.next; + } + current.next = first; + return first; +} diff --git a/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini b/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini new file mode 100644 index 0000000000..7266b615bb --- /dev/null +++ b/js/xpconnect/tests/mochitest/hasinstance/mochitest.ini @@ -0,0 +1,7 @@ +[DEFAULT] +prefs = + dom.webidl.crosscontext_hasinstance.enabled=false +support-files = + ../file_empty.html + +[test_bug870423.html] diff --git a/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html b/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html new file mode 100644 index 0000000000..9d928cdd63 --- /dev/null +++ b/js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=870423 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 870423</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for cross-scope instanceof. **/ + SimpleTest.waitForExplicitFinish(); + + function go() { + var sowin = $('soifr').contentWindow; + var xowin = $('xoifr').contentWindow; + var xosswin = $('xossifr').contentWindow; + + check(window, sowin, 'HTMLBodyElement', function(win) { return win.document.body; }); + check(window, sowin, 'HTMLDocument', function(win) { return win.document; }); + check(window, sowin, 'Window', function(win) { return win; }); + check(window, sowin, 'Location', function(win) { return win.location; }); + + ok(!(xowin instanceof Window), "Cross-origin instanceof should fail"); + ok(!(xowin.location instanceof Location), "Cross-origin instanceof should fail"); + + // cross-origin same-site. + ok(!(xosswin instanceof Window), "Cross-origin instanceof should fail"); + ok(!(xosswin.location instanceof Location), "Cross-origin instanceof should fail"); + + SimpleTest.finish(); + } + + function check(win1, win2, constructorName, getInstance) { + ok(!(getInstance(win1) instanceof win2[constructorName]), + "Cross-Scope instanceof fails: " + constructorName + ", " + win1.location + ", " + win2.location); + ok(!(getInstance(win2) instanceof win1[constructorName]), + "Cross-Scope instanceof fails: " + constructorName + ", " + win2.location + ", " + win1.location); + } + + </script> +</head> +<body onload="go();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=870423">Mozilla Bug 870423</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="soifr" src="file_empty.html"></iframe> +<iframe id="xoifr" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<!-- cross origin, same site --> +<iframe id="xossifr" src="//test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/inner.html b/js/xpconnect/tests/mochitest/inner.html new file mode 100644 index 0000000000..8021a55539 --- /dev/null +++ b/js/xpconnect/tests/mochitest/inner.html @@ -0,0 +1,7 @@ +<html> + <head> + <title>Inner frame for bug 39685 mochitest</title> + </head> + <body onload="x = 4"> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/mochitest.ini b/js/xpconnect/tests/mochitest/mochitest.ini new file mode 100644 index 0000000000..30536b42e0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/mochitest.ini @@ -0,0 +1,178 @@ +[DEFAULT] +support-files = + bug500931_helper.html + bug571849_helper.html + bug589028_helper.html + bug92773_helper.html + chrome_wrappers_helper.html + file1_bug629227.html + file2_bug629227.html + file_bug505915.html + file_bug605167.html + file_bug650273.html + file_bug658560.html + file_bug706301.html + file_bug720619.html + file_bug731471.html + file_bug738244.html + file_bug760131.html + file_bug781476.html + file_bug789713.html + file_bug795275.html + file_bug799348.html + file_bug802557.html + file_bug860494.html + file_crosscompartment_weakmap.html + file_documentdomain.html + file_doublewrappedcompartments.html + file_empty.html + file_evalInSandbox.html + file_exnstack.html + file_expandosharing.html + file_matches.html + file_nodelists.html + file_wrappers-2.html + file_xrayic.html + inner.html + test1_bug629331.html + test2_bug629331.html + finalizationRegistry_worker.js + private_field_worker.js + class_static_worker.js + bug1681664_helper.js + shadow_realm_worker.js + shadow_realm_module.js +prefs = + javascript.options.weakrefs=true + javascript.options.spectre.disable_for_isolated_content=true + javascript.options.experimental.enable_new_set_methods=false + javascript.options.experimental.shadow_realms=true +[test_bug384632.html] +[test_bug390488.html] +[test_bug393269.html] +[test_bug396851.html] +skip-if = + http3 +[test_bug428021.html] +[test_bug446584.html] +[test_bug462428.html] +[test_bug478438.html] +skip-if = + http3 +[test_bug500691.html] +[test_bug505915.html] +skip-if = + http3 +[test_bug560351.html] +[test_bug585745.html] +[test_bug589028.html] +[test_bug601299.html] +[test_bug605167.html] +skip-if = + http3 +[test_bug618017.html] +[test_bug623437.html] +[test_bug628410.html] +[test_bug628794.html] +[test_bug629227.html] +skip-if = + http3 +[test_bug629331.html] +skip-if = + http3 +[test_bug636097.html] +skip-if = + http3 +[test_bug650273.html] +skip-if = + http3 +[test_bug655297-1.html] +[test_bug655297-2.html] +[test_bug661980.html] +[test_bug691059.html] +[test_bug720619.html] +skip-if = + http3 +[test_bug731471.html] +skip-if = toolkit == "android" && debug +[test_bug764389.html] +[test_bug772288.html] +[test_bug781476.html] +[test_bug789713.html] +skip-if = + http3 +[test_bug790732.html] +[test_bug793969.html] +[test_bug800864.html] +skip-if = + http3 +[test_bug802557.html] +skip-if = + http3 +[test_bug803730.html] +[test_bug809547.html] +[test_bug829872.html] +skip-if = + http3 +[test_bug862380.html] +skip-if = + http3 +[test_bug865260.html] +skip-if = + http3 +[test_bug871887.html] +[test_bug912322.html] +[test_bug916945.html] +skip-if = + http3 +[test_bug92773.html] +skip-if = + http3 +[test_bug940783.html] +skip-if = + http3 +[test_bug965082.html] +skip-if = + http3 +[test_bug960820.html] +[test_bug993423.html] +[test_bug1005806.html] +[test_bug1094930.html] +[test_bug1158558.html] +[test_bug1448048.html] +[test_bug1681664.html] +[test_crosscompartment_weakmap.html] +[test_enable_privilege.html] +[test_frameWrapping.html] +# The JS test component we use below is only available in debug builds. +[test_getWebIDLCaller.html] +skip-if = (debug == false) +[test_getweakmapkeys.html] +[test_isRemoteProxy.html] +[test_paris_weakmap_keys.html] +skip-if = (debug == false) +[test_nukeContentWindow.html] +[test_sameOriginPolicy.html] +skip-if = + http3 +[test_sandbox_fetch.html] + support-files = + ../../../../dom/tests/mochitest/fetch/test_fetch_basic.js +[test_weakmaps.html] +[test_finalizationRegistry.html] +[test_finalizationRegistryInWorker.html] +[test_finalizationRegistry_cleanupSome.html] +[test_finalizationRegistry_incumbent.html] +[test_weakRefs.html] +[test_weakRefs_cross_compartment.html] +[test_weakRefs_collected_wrapper.html] +[test_private_field_dom.html] +[test_private_field_worker.html] +[test_class_static_block_worker.html] +skip-if = !nightly_build +[test_shadowRealm.html] +# This test has been updated to work with worker modules +[test_shadowRealm_worker.html] +skip-if = !nightly_build +[test_spectre_mitigations.html] +skip-if = os == "android" # Fission situation on Android is more complicated. diff --git a/js/xpconnect/tests/mochitest/moz.build b/js/xpconnect/tests/mochitest/moz.build new file mode 100644 index 0000000000..772ed94cce --- /dev/null +++ b/js/xpconnect/tests/mochitest/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += ["hasinstance/mochitest.ini", "mochitest.ini"] diff --git a/js/xpconnect/tests/mochitest/private_field_worker.js b/js/xpconnect/tests/mochitest/private_field_worker.js new file mode 100644 index 0000000000..b822c16248 --- /dev/null +++ b/js/xpconnect/tests/mochitest/private_field_worker.js @@ -0,0 +1,21 @@ +class A { + #x; + + g(o) { + return #x in o; + } +} + +let objects = []; + +self.onmessage = function (e) { + if (e.data === 'allocate') { + objects.push(new A); + return; + } + if (e.data == 'count') { + postMessage(objects.length); + return; + } + postMessage('Unknown message type.'); +}
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/shadow_realm_module.js b/js/xpconnect/tests/mochitest/shadow_realm_module.js new file mode 100644 index 0000000000..35ba80666b --- /dev/null +++ b/js/xpconnect/tests/mochitest/shadow_realm_module.js @@ -0,0 +1 @@ +export var x = 1; diff --git a/js/xpconnect/tests/mochitest/shadow_realm_worker.js b/js/xpconnect/tests/mochitest/shadow_realm_worker.js new file mode 100644 index 0000000000..c91c9bc30c --- /dev/null +++ b/js/xpconnect/tests/mochitest/shadow_realm_worker.js @@ -0,0 +1,81 @@ + +var sr = new ShadowRealm(); +var resolve; + +var allSettled = new Promise((resolved) => { resolve = resolved }); + +self.onmessage = async function (e) { + try { + // Test evaluate + if (e.data === 'evaluate') { + sr.evaluate("var s = 'PASS set string in realm';") + var res = sr.evaluate('s'); + postMessage(res); + return; + } + + // If Import works in a worker, then it ought to work in a shadow realm + // + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1247687 and + // https://bugzilla.mozilla.org/show_bug.cgi?id=1772162 + if (e.data == 'import') { + var import_worked = false; + var importValue_worked = false; + var importNested_worked = false; + try { + var module = await import("./shadow_realm_module.js"); + if (module.x != 1) { + throw "mismatch"; + } + import_worked = true; + } catch (e) { } + + try { + await sr.importValue("./shadow_realm_module.js", 'x').then((x) => { + if (x == 1) { importValue_worked = true; } + }); + } catch (e) { } + + try { + sr.evaluate(` + var imported = false; + import("./shadow_realm_module.js").then((module) => { + if (module.x == 1) { + imported = true; + } + }); + true; + `); + + importNested_worked = sr.evaluate("imported"); + } catch (e) { + + } + + if (importValue_worked == importNested_worked) { + postMessage(`PASS: import in workers ${ + import_worked ? "worked" : "failed" + }. importValue, and nested import all ${ + importValue_worked ? "worked" : "failed" + } `); + resolve(); + return; + } + + postMessage(`FAIL: importValue ${importValue_worked}, import ${import_worked}, importNested ${importNested_worked}`); + resolve(); + return; + } + + + // Reply back with finish + if (e.data == 'finish') { + await allSettled; + postMessage("finish"); + return; + } + } catch (e) { + postMessage("FAIL: " + e.message); + } + postMessage('Unknown message type.'); +} diff --git a/js/xpconnect/tests/mochitest/test1_bug629331.html b/js/xpconnect/tests/mochitest/test1_bug629331.html new file mode 100644 index 0000000000..18843e08da --- /dev/null +++ b/js/xpconnect/tests/mochitest/test1_bug629331.html @@ -0,0 +1,19 @@ +<body> +<iframe src="about:blank" id="ifr"></iframe> +<script> +/** Test for Bug 629331 **/ +function finish() { + parent.postMessage(JSON.stringify({fun: "finish"}), "*"); +} + +function is(a, b, description) { + parent.postMessage(JSON.stringify({ fun: "is", a: a, b: b, description: description }), "*"); +} + +document.domain = "example.org"; +var i = 0; +is(i, 0, 'i meets starting conditions'); +document.getElementById('ifr').src = 'http://test2.example.org/tests/js/xpconnect/tests/mochitest/test2_bug629331.html'; +</script> + + diff --git a/js/xpconnect/tests/mochitest/test2_bug629331.html b/js/xpconnect/tests/mochitest/test2_bug629331.html new file mode 100644 index 0000000000..1bcf037398 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test2_bug629331.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + </head> + <body> + <script> + document.domain = "example.org"; + + for (var j = 1; j <= 9; j++) { + parent.i = j; + var locali = parent.i; + parent.is(locali, j, 'step ' + j + ' worked'); + } + + parent.finish(); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1005806.html b/js/xpconnect/tests/mochitest/test_bug1005806.html new file mode 100644 index 0000000000..41fe6ee1e6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1005806.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1005806 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1005806</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1005806">Mozilla Bug 1005806</a> +<p id="display"></p> +<div id="content" style="display: none"> + <input id="ipt"></input> +</div> +<pre id="test"> +</pre> +<script type="application/javascript"> + +/** Test for Bug 1005806 **/ +is(typeof document.getElementById('ipt').controllers, 'undefined', "Controllers property should not appear for content"); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1094930.html b/js/xpconnect/tests/mochitest/test_bug1094930.html new file mode 100644 index 0000000000..d303bf2495 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1094930.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1094930 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1094930</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <iframe id="ifr"></iframe> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a> +<p id="display"></p> +<script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + class XFoo extends frames[0].HTMLElement { + connectedCallback() { + ok(true, "connectedCallback was called"); + SimpleTest.finish(); + } + }; + + customElements.define.call(frames[0].customElements, "x-foo", XFoo); + frames[0].document.firstChild.appendChild(new XFoo()); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1158558.html b/js/xpconnect/tests/mochitest/test_bug1158558.html new file mode 100644 index 0000000000..f5c50d640e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1158558.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1158558 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1158558</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1158558">Mozilla Bug 1158558</a> +<p id="display"></p> +<div id="content" style="display: none"> + <input id="ipt"></input> +</div> +<pre id="test"> +</pre> +<script type="application/javascript"> + +/** Test for Bug 1158558 **/ + +// Observers of cycle-collector-begin can be implemented in JS, and +// thus can end up starting an incremental GC while we're in the middle +// of a CC slice. + +SimpleTest.waitForExplicitFinish(); + +var observer = { + observe: function(subject, topic, data) { + SpecialPowers.removeObserver(observer, "cycle-collector-begin"); + SpecialPowers.Cu.getJSTestingFunctions().startgc(1); + + ok(true, "Do something so the test harness doesn't get angry"); + + SimpleTest.finish(); + } +}; + +SpecialPowers.addObserver(observer, "cycle-collector-begin"); + +SpecialPowers.Cu.forceCC(); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1448048.html b/js/xpconnect/tests/mochitest/test_bug1448048.html new file mode 100644 index 0000000000..2d58593a6b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1448048.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1448048 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1448048</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1448048 **/ + var { AppConstants } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" + ); + if (AppConstants.NIGHTLY_BUILD) { + is(typeof Components, "undefined", "Should be no Components shim on Nightly"); + } else { + is(typeof Components, "object", "Should have a components shim on non-Nightly"); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1448048">Mozilla Bug 1448048</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug1681664.html b/js/xpconnect/tests/mochitest/test_bug1681664.html new file mode 100644 index 0000000000..685d4aa669 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug1681664.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en" dir="ltr"> + <head> + <title>Test page for bug 1681664</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script> + SimpleTest.waitForExplicitFinish() + async function init() { + var Services = SpecialPowers.Services; + var observer = { + observe(subject, topic, data) { + if (topic === "process-hang-report") { + var report = subject.QueryInterface(Ci.nsIHangReport); + report.terminateScript(); + Services.obs.removeObserver(observer, "process-hang-report"); + } + } + } + + Services.obs.addObserver(observer, "process-hang-report"); + try { + await import("test_bug1681664_helper.js"); + result.textContent = "FAIL"; + } catch (ex) { + result.textContent = "PASS"; + } + } + </script> + </head> + <body> + <p id="result"></p> + <script> + (async function() { + await init(); + is(result.textContent, "PASS", "Infinite loop script should not cause browser crash"); + SimpleTest.finish() + })(); + </script> + </body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug384632.html b/js/xpconnect/tests/mochitest/test_bug384632.html new file mode 100644 index 0000000000..251ec9b153 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug384632.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=384632 +--> +<head> + <title>Test for Bug 384632</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384632">Mozilla Bug 384632</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 384632 **/ +var Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci; +var propBag = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag); +var obj = {}; +propBag.setProperty("foopy", obj); +ok(SpecialPowers.unwrap(propBag.getProperty("foopy")) === obj, + "nsIVariant works with regular objects"); +propBag.setProperty("foopy1", external); +ok(SpecialPowers.unwrap(propBag.getProperty("foopy1")) === external, + "nsIVariant works with bizarre objects"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug390488.html b/js/xpconnect/tests/mochitest/test_bug390488.html new file mode 100644 index 0000000000..ca4bc4024b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug390488.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=390488 +--> +<head> + <title>Test for Bug 390488</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=390488">Mozilla Bug 390488</a> +<p id="display"> + <div id="testdiv" onclick="checkForStacks();" style="visibility:hidden"> + </div> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 390488 **/ + function getStack1() { + var func = arguments.callee.caller; + var stack = ""; + for (var i = 1; func && i < 8; i++) { + stack += " " + i + ". " + func.name; + func = func.caller; + } + return stack; + } + + function getStack2() { + var stack = new Error().stack; + // Remove the two lines due to calling this + return stack.substring(stack.indexOf("\n", stack.indexOf("\n")+1)+1); + } + + function simulateClick() { + var evt = document.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, window, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + $("testdiv").dispatchEvent(evt); + } + + function matches(s, p, name) { + ok(s.match(p) != null, + name + " - got " + s + ", expected a string matching " + p); + } + + function checkForStacks() { + matches(getStack1(), /checkForStacks .* onclick .* simulateClick/, + "Stack from walking caller chain should be correct"); + isnot(getStack2().indexOf("simulateClick@"), -1, + "Stack from |new Error().stack| should include simulateClick"); + } + + simulateClick(); +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug393269.html b/js/xpconnect/tests/mochitest/test_bug393269.html new file mode 100644 index 0000000000..d69e9ef2d1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug393269.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=393269 +--> +<head> + <title>Test for Bug 393269</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=393269">Mozilla Bug 393269</a> +<iframe id="ifr"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +(function () { + /** Test for Bug 393269 **/ + var doc = $("ifr").contentDocument; + is("UTF-8", doc.characterSet, "control, getting a property"); + doc.open(); + try { + is("UTF-8", doc.characterSet, + "can get a property after 1 document.open") + } catch (e) { + fail("Shouldn't have thrown: " + e); + return; + } finally { + doc.close(); + } + + doc.open(); + try { + is("UTF-8", doc.characterSet, + "can get a property after 2 document.opens") + } catch (e) { + fail("Shouldn't have thrown: " + e); + } finally { + doc.close(); + } +})(); +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug396851.html b/js/xpconnect/tests/mochitest/test_bug396851.html new file mode 100644 index 0000000000..dc6bd25d52 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug396851.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=396851 +--> +<head> + <title>Test for Bug 396851</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <script type="text/javascript"> + function throws(func, pattern, msg) { + try { + func(); + ok(false, msg); + } catch (e) { + ok(pattern.test(e), `${msg}: Expect exception mathing ${pattern}`); + } + } + + function go() { + var iframe = $("ifr"); + var win = iframe.contentWindow; + throws(() => win.document, + /Permission denied/, + "Unprivileged code should not be able to access cross-origin document"); + + if (SpecialPowers.useRemoteSubframes) { + throws(() => win.document, + /Permission denied/, + "Privileged code should not be able to access cross-process document"); + } else { + ok(SpecialPowers.wrap(win).document != null, + "Able to access the cross-origin document"); + } + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396851">Mozilla Bug 396851</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<script type="text/javascript"> + SimpleTest.waitForExplicitFinish(); +</script> +<iframe id="ifr" + src="http://example.org/tests/js/xpconnect/tests/mochitest/inner.html" + onload="go()"> +</iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug428021.html b/js/xpconnect/tests/mochitest/test_bug428021.html new file mode 100644 index 0000000000..932dcf7428 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug428021.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=428021 +--> +<head> + <title>Test for Bug 428021</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428021">Mozilla Bug 428021</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + /** Test for Bug 428021 **/ + var rangetter, ransetter; + this.__defineGetter__('x', function() { rangetter = true; }); + this.__defineSetter__('x', function(val) { ransetter = true; }); + + var exn; + try { + e = x; + x = false; + } catch (e) { + exn = e; + } + ok(!exn, "Exception caught: " + exn); + ok(rangetter, "Failed to run getter"); + ok(ransetter, "Failed to run setter"); + +</script> +</pre> +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug446584.html b/js/xpconnect/tests/mochitest/test_bug446584.html new file mode 100644 index 0000000000..09fef92867 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug446584.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=446584 +--> +<head> + <title>Test for Bug 446584</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=446584">Mozilla Bug 446584</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 446584 **/ + +function test(val) { + try { + document.createNodeIterator(document.body, + NodeFilter.SHOW_ALL, + function() { throw val }).nextNode(); + ok(false, "NodeIterator::nextNode() should have thrown an exception."); + } catch (ex) { + ok(val === ex, "NodeIterator did not properly forward exception " + + val + " of type " + typeof val + ". Thrown value was " + ex + "."); + } +} + +test(0); +test(1); +test(3.14); +test('roses'); +test({}); +test(false); +test(true); +test([1,2,3]); +test(function(){}); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug462428.html b/js/xpconnect/tests/mochitest/test_bug462428.html new file mode 100644 index 0000000000..a3f7b7c39a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug462428.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=462428 +--> +<head> + <title>Test for Bug 462428</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=462428">Mozilla Bug 462428</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 462428 **/ +var getter = document.__lookupGetter__('documentElement'); +ok(getter !== undefined, "But able to look it up the normal way"); +ok(!document.hasOwnProperty('documentElement'), "property should still be on the prototype"); + +var sawProp = false; +for (var i in document) { + if (i === "documentElement") { + sawProp = true; + } +} + +ok(sawProp, "property should be enumerable"); + +is(getter.call(document), document.documentElement, "the getter actually works"); + +Document.prototype.__defineSetter__('documentElement', function() {}); +is(getter.call(document), document.documentElement, "the getter works after defineSetter"); + +var oldTitle = document.title; +try { + var setter = document.__lookupSetter__('title'); + setter.call(document, "title 1"); + is(document.title, "title 1", "the setter is bound correctly"); +} finally { + document.title = oldTitle +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug478438.html b/js/xpconnect/tests/mochitest/test_bug478438.html new file mode 100644 index 0000000000..e64a1e89fb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug478438.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=478438 +--> +<head> + <title>Test for Bug 478438</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function fail(s, e) { ok(false, s + e) } + function pass(s, e) { ok(true, s) } + (pass.opposite = fail).opposite = pass; + + function test() { + if (test.calledAlready) + return; + test.calledAlready = true; + + var iwin = document.getElementById("f").contentWindow; + + function testOne(fn, onAllow, infinitive) { + try { fn(); onAllow("able " + infinitive, "") } + catch (e) { onAllow.opposite("unable " + infinitive, ": " + e) } + } + + testOne(() => iwin.focus, pass, + "to resolve/get allAccess property iwin.focus"); + + testOne(() => iwin.focus(), pass, + "to call allAccess method iwin.focus"); + + testOne(() => iwin.alert, fail, + "to resolve/get restricted property iwin.alert"); + + testOne(() => iwin.alert(), fail, + "to call restricted method iwin.alert"); + + testOne(() => iwin.location.toString(), fail, + "to call restricted method iwin.location.toString"); + + testOne(function() { iwin.location = "http://example.org" }, pass, + "to set writable property iwin.location"); + + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478438">Mozilla Bug 478438</a> +<p id="display"></p> +<div id="content"> + <iframe id="f" src="http://example.com" onload="test()"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 478438 **/ + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug484107.html b/js/xpconnect/tests/mochitest/test_bug484107.html new file mode 100644 index 0000000000..38ca7b207b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug484107.html @@ -0,0 +1,99 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=484107 +--> +<head> + <title>Test for Bug 484107</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=484107">Mozilla Bug 484107</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 484107 **/ + + var text = "first group", + xpcWin = new XPCSafeJSObjectWrapper(window); + function get$1() { return RegExp.$1 }; + + function reset() { + var match = /(.*)/.exec(text); + if (!reset.skipStupidTests) { + reset.skipStupidTests = true; + ok(match, "No match?"); + is(match[1], text, "Bad match?"); + is(text, RegExp.$1, "RegExp.$1 missing?"); + is(text, get$1(), "RegExp.$1 inaccessible?"); + } + } + + function test_XPC_SJOW_Call() { + isnot(text, xpcWin.get$1(), "Able to see RegExp.$1 from wrapped method."); + is("", xpcWin.get$1(), "Saw something other than an empty string for " + + "RegExp.$1 from wrapped method."); + is(text, window.get$1(), "Unable to see RegExp.$1 from non-wrapped method."); + } + + function test_XPC_SJOW_Call_foreign_obj() { + var obj = { + xpcGet: xpcWin.get$1, + rawGet: window.get$1 + }; + isnot(text, obj.xpcGet(), "obj.xpcGet() returned matched text."); + is("", obj.xpcGet(), "obj.xpcGet() returned something other than the empty string."); + is(text, obj.rawGet(), "obj.rawGet() did not return matched text."); + } + + function test_XPC_SJOW_toString() { + var str = new XPCSafeJSObjectWrapper({ + toString: function() { return RegExp.$1 } + }) + ""; + isnot(text, str, "toString() returned the matched text."); + is("", str, "toString() returned something other than the empty string."); + } + + function test_XPC_SJOW_GetOrSetProperty() { + window.__defineGetter__("firstMatch", function() { return RegExp.$1 }); + isnot(text, xpcWin.firstMatch, "Getter xpcWin.firstMatch returned matched text."); + is("", xpcWin.firstMatch, + "Getter xpcWin.firstMatch returned something other than the empty string."); + is(text, window.firstMatch, "Getter window.firstMatch did not return matched text."); + } + + function test_XPC_SJOW_Create() { + function ctor() { + this.match = RegExp.$1; + return this; // XXX Why is this necessary? + } + ctor.prototype.getMatch = function() { return this.match }; + var xpcCtor = new XPCSafeJSObjectWrapper(ctor), + match = (new xpcCtor).getMatch(); + isnot(text, match, "(new xpcCtor).getMatch() was the matched text."); + is("", match, "(new xpcCtor).getMatch() was not the empty string."); + } + + var tests = [ + test_XPC_SJOW_Call, + test_XPC_SJOW_Call_foreign_obj, + test_XPC_SJOW_toString, + test_XPC_SJOW_GetOrSetProperty, + test_XPC_SJOW_Create + ]; + + for (var i = 0; i < tests.length; i++) { + reset(); + tests[i](); + is(text, RegExp.$1, "RegExp.$1 was clobbered."); + } + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug500691.html b/js/xpconnect/tests/mochitest/test_bug500691.html new file mode 100644 index 0000000000..2ed127c099 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug500691.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500691 +--> +<head> + <title>Test for Bug 500691</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500691">Mozilla Bug 500691</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 500691 **/ +ok(Function === alert.constructor, "alert's constructor is our Function"); +ok(window.Function === alert.constructor, "window.Function is also correct"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug505915.html b/js/xpconnect/tests/mochitest/test_bug505915.html new file mode 100644 index 0000000000..d5898bc1ed --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug505915.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> + <title>Test for Bug 505915</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505915">Mozilla Bug 505915</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 505915 **/ +window.addEventListener("message", function () { + ok(false, "should not receive message"); +}); + +function go() { + var ifr = $('ifr'); + try { + // NB: the contentDocument getter now returns null for cross-origin + // frames, so use SpecialPowers to get a security wrapper to the document. + var xdoc = SpecialPowers.unwrap(SpecialPowers.wrap(ifr).contentDocument) + document.createTreeWalker(xdoc, 0, null); + ok(false, "should have thrown a security exception"); + } catch (e) { + ok(/TypeError: Document.createTreeWalker: Argument 1 does not implement interface Node/.test(e), + "threw a binding exception instead of an invalid child exception"); + } + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id="ifr" onload="go();" src="http://test1.mochi.test:8888/"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug560351.html b/js/xpconnect/tests/mochitest/test_bug560351.html new file mode 100644 index 0000000000..263e6850d7 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug560351.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=560351 +--> +<head> + <title>Test for Bug 560351</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=560351">Mozilla Bug 560351</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 560351 **/ +var pass = false; +try { + document.body.__lookupGetter__("lastChild")(); +} catch (e) { + pass = true; +} + +</script> +<script> + +ok(pass, "pass was set to true"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug585745.html b/js/xpconnect/tests/mochitest/test_bug585745.html new file mode 100644 index 0000000000..758aeed30d --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug585745.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=585745 +--> +<head> + <title>Test for Bug 585745</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585745">Mozilla Bug 585745</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 585745 **/ + + var a = document.createElementNS("http://www.w3.org/1998/Math/MathML", 'mrow'); + var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); + var htmlProto = Object.getPrototypeOf(b); + var mathMLProto = Object.getPrototypeOf(a); + // XXXbz once bug 560072 is fixed, we should be able to use + // getOwnPropertyDescriptor here. + Object.defineProperty(mathMLProto, "style", { + get: htmlProto.__lookupGetter__("style"), + }); + + var threw = false; + try { + a.style; + } catch(e) { + threw = true; + } + is(threw, true, + "Getting .style off a mathml element should throw in this case"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug589028.html b/js/xpconnect/tests/mochitest/test_bug589028.html new file mode 100644 index 0000000000..2cd0d15ebb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug589028.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=589028 +--> +<head> + <title>Test for Bug 589028</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=589028">Mozilla Bug 589028</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script> + +/** Test for Bug 589028 **/ +SimpleTest.waitForExplicitFinish(); +var p = 0; +function go() { + var ifr = $('ifr'); + var ifrwin = ifr.contentWindow; + var ifrdoc = ifr.contentDocument; + + o1 = new ifrwin.Option(); + is(o1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + o2 = ifrwin.getMyOption(); + is(o2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + o3 = ifrwin.getCallersOption(this); + is(o3.ownerDocument, document); + + a1 = new ifrwin.Audio(); + is(a1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + a2 = ifrwin.getMyAudio(); + is(a2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + a3 = ifrwin.getCallersAudio(this); + is(a3.ownerDocument, document); + + i1 = new ifrwin.Image(); + is(i1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + i2 = ifrwin.getMyImage(); + is(i2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe"); + + i3 = ifrwin.getCallersImage(this); + is(i3.ownerDocument, document); + + SimpleTest.finish(); +} + + +</script> +</pre> +<iframe src="bug589028_helper.html" id="ifr" onload="go()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug601299.html b/js/xpconnect/tests/mochitest/test_bug601299.html new file mode 100644 index 0000000000..cd726d7974 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug601299.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=601299 + +Trigger a fastnative from a frameless context. +--> +<head> + <title>Test for Bug 601299</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="window.setTimeout(RegExp, 0); window.setTimeout(function() { ok(true); SimpleTest.finish(); }, 0);"> +<script> +SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug605167.html b/js/xpconnect/tests/mochitest/test_bug605167.html new file mode 100644 index 0000000000..ba625aa805 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug605167.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=505915 +--> +<head> + <title>Test for Bug 505915</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505915">Mozilla Bug 505915</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 505915 **/ +var url = "file_bug605167.html"; +var targetUrl = "http://example.com"; +var f; + +var p = 0; +function go() { + switch (++p) { + case 1: + frames[0].location = url; + break; + case 2: + frames[0].location = targetUrl; + break; + case 3: + try { + f().cross_origin_property; + ok(false, "should have thrown an exception"); + } catch (e) { + ok(/Permission denied/.test(e) || /attempt to run compile-and-go script/.test(e), + "threw the correct exception"); + } + SimpleTest.finish(); + break; + } +} + + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id="ifr" onload="go();"></iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug618017.html b/js/xpconnect/tests/mochitest/test_bug618017.html new file mode 100644 index 0000000000..8bfb428870 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug618017.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=618017 + +Parsing XML must not override the version. +--> +<head> + <title>Test for Bug 618017</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + +<script type='application/javascript'> +let x = 12; +function doLetEval() { + ok(eval('let x = 13; x') === 13, 'let statement is valid syntax in version 1.7'); +} +</script> + +<script type='application/javascript'> +doLetEval(); // Call to a function with a different version. +</script> + +</body> +</html> + diff --git a/js/xpconnect/tests/mochitest/test_bug623437.html b/js/xpconnect/tests/mochitest/test_bug623437.html new file mode 100644 index 0000000000..0cea6f330b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug623437.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=623437 +--> +<head> + <title>Test for Bug 623437</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=623437">Mozilla Bug 623437</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 623437 **/ + var c = document.createElement("canvas").getContext("2d"); + var seenArcToFirst; + var seenArc = false; + var seenArcTo = false; + for (var i in c) { + if (i == "arc") { + seenArc = true; + if (!seenArcTo) + seenArcToFirst = false; + } + if (i == "arcTo") { + seenArcTo = true; + if (!seenArc) + seenArcToFirst = true; + } + } + is(seenArc, true, "Should see arc"); + is(seenArcTo, true, "Should see arcTo"); + is(seenArcToFirst, true, "Should see arcTo before arc"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug628410.html b/js/xpconnect/tests/mochitest/test_bug628410.html new file mode 100644 index 0000000000..2aec713793 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug628410.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=628410 +--> +<head> + <title>Test for Bug 628410</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=628410">Mozilla Bug 628410</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script type="application/javascript"> + +window.toString(); + +if (SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTrigger.enabled") && + SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTriggerImpl.enabled")) { + InstallTrigger + ""; +} + +console + ""; +ok(true, "Things didn't throw"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug628794.html b/js/xpconnect/tests/mochitest/test_bug628794.html new file mode 100644 index 0000000000..9cbfe0f436 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug628794.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=585745 +--> +<head> + <title>Test for Bug 585745</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585745">Mozilla Bug 585745</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 585745 **/ + + var a = document.createElementNS("http://www.w3.org/2000/svg", 'svg'); + var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span'); + var htmlProto = Object.getPrototypeOf(b); + var svgProto = Object.getPrototypeOf(a); + // XXXbz once bug 560072 is fixed, we should be able to use + // getOwnPropertyDescriptor here. + Object.defineProperty(svgProto, "style", { + get: htmlProto.__lookupGetter__("style"), + }); + + var threw = false; + try { + a.style; + } catch(e) { + threw = true; + } + is(threw, true, + "Getting .style off an svg element should throw in this case"); +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug629227.html b/js/xpconnect/tests/mochitest/test_bug629227.html new file mode 100644 index 0000000000..6d01c37ec0 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug629227.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=629227 +--> +<head> + <title>Test for Bug 629227</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629227">Mozilla Bug 629227</a> +<p id="display"> + <iframe id="testTarget"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 629227 **/ +SimpleTest.waitForExplicitFinish(); + +$("testTarget").src = + "http://test1.example.org" + + location.pathname.replace(/test_bug629227.html/, "file1_bug629227.html"); + +window.onmessage = function(ev) { + if (ev.data == "finish") { + SimpleTest.finish(); + } else { + var data = JSON.parse(ev.data); + if ("ok" in data) { + ok(data.ok, data.reason); + } + } +} + +addLoadEvent(function() { + $("testTarget").contentWindow.postMessage("start", "*"); +}); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug629331.html b/js/xpconnect/tests/mochitest/test_bug629331.html new file mode 100644 index 0000000000..17520b187f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug629331.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=629331 +--> +<head> + <title>Test for Bug 629331</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629331">Mozilla Bug 629331</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function handler(event) { + var obj = JSON.parse(event.data); + if (obj.fun == "finish") { + SimpleTest.finish(); + } else { + is(obj.a, obj.b, obj.description); + } +} + +window.addEventListener('message', handler); + +</script> +<iframe src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/test1_bug629331.html"> +</iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug636097.html b/js/xpconnect/tests/mochitest/test_bug636097.html new file mode 100644 index 0000000000..8ae8e4822e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug636097.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=504877 +test by moz_bug_r_a4@yahoo.com +--> +<head> + <title>Test for Bug 504877</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504877">Mozilla Bug 504877</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 504877 **/ +SimpleTest.waitForExplicitFinish(); + +var targetUrl = "http://example.com/"; +var l; + +function a() { + var r = "FAIL", s; + try { + s = l.toString(); + } + catch (e) { + if (/denied|insecure/.test(e)) + r = "PASS"; + s = e; + } + + is(r, "PASS", "should have thrown an exception"); + SimpleTest.finish(); +} + +var p = 0; +function b() { + switch (++p) { + case 1: + frames[0].location = "about:blank"; + break; + case 2: + l = frames[0].location; + frames[0].location = targetUrl; + break; + case 3: + a(); + break; + } +} +</script> + +</pre> +<iframe onload="b()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug650273.html b/js/xpconnect/tests/mochitest/test_bug650273.html new file mode 100644 index 0000000000..18e029982a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug650273.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650273 +test by moz_bug_r_a4@yahoo.com +--> +<head> + <title>Test for Bug 650273</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" +href="https://bugzilla.mozilla.org/show_bug.cgi?id=650273">Mozilla Bug 650273</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 504877 **/ +SimpleTest.waitForExplicitFinish(); +var count = 0; +function done() { + if (++count == 2) { + try { + ok($('ifr').location.host === 'example.com', "shouldn't see this"); + } catch (e) { + ok(true, "navigation successfully happened"); + } + SimpleTest.finish(); + } +} + +</script> + +<iframe id="ifr" src="file_bug650273.html" onload="done()"></iframe> + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug655297-1.html b/js/xpconnect/tests/mochitest/test_bug655297-1.html new file mode 100644 index 0000000000..38ff528c5b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug655297-1.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=655297 +--> +<head> + <title>Test for Bug 655297</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655297">Mozilla Bug 655297</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + <form>0</form> <form>1</form> <form>2</form> <form>3</form> <form>4</form> + <form>5</form> <form>6</form> <form>7</form> <form>8</form> <form>9</form> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 655297 **/ + +var map = new WeakMap(); +function f() { + var paras = document.getElementsByTagName("form"); + for (var i = 0; i < paras.length; i++) + map.set(paras[i], "ok"); +} +function g() { + var paras = document.getElementsByTagName("form"); + for (var i = 0; i < paras.length; i++) { + if (map.get(paras[i]) != "ok") { + return false; + } + } + return true; +} + +f(); +SpecialPowers.forceGC(); +ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive."); + +</script> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug655297-2.html b/js/xpconnect/tests/mochitest/test_bug655297-2.html new file mode 100644 index 0000000000..67da7964bd --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug655297-2.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=655297 +--> +<head> + <title>Test for Bug 655297</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=655297">Mozilla Bug 655297</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p> + <p>5</p> <p>6</p> <p>7</p> <p>8</p> <p>9</p> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 655297 **/ + +var map = new WeakMap(); +function f() { + var paras = document.getElementsByTagName("p"); + for (var i = 0; i < paras.length; i++) + map.set(paras[i], "ok"); +} +function g() { + var paras = document.getElementsByTagName("p"); + for (var i = 0; i < paras.length; i++) { + if (map.get(paras[i]) != "ok") { + return false; + } + } + return true; +} + +f(); +SpecialPowers.forceGC(); +ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive."); + +</script> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug661980.html b/js/xpconnect/tests/mochitest/test_bug661980.html new file mode 100644 index 0000000000..afe62559a5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug661980.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=661980 +--> +<head> + <title>Test for Bug 661980</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=661980">Mozilla Bug 661980</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 661980 **/ + +// While not currently needed, make this as similar as possible to a real +// EventTarget just to make sure that we're tripping on the wrapping and +// nothing else. +var fakeTarget = { + addEventListener: function() {}, + removeEventListener: function() {}, + dispatchEvent: function() {} +} + +var mouseevent = document.createEvent("MouseEvent"); +var didThrow = false; +dump("hello nurse\n"); +try { + mouseevent.initMouseEvent("mouseover", + false, false, + window, + 1, 2, 3, 4, 5, + false, false, false, false, + 0, + fakeTarget); +} +catch (ex) { + didThrow = true; +} +ok(didThrow, "should not be able to implement EventTarget using script"); + +mouseevent.initMouseEvent("mouseout", + false, false, + window, + 1, 2, 3, 4, 5, + false, false, false, false, + 0, + document.body); +is(mouseevent.type, "mouseout", + "should able to implement EventTarget using Element"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug691059.html b/js/xpconnect/tests/mochitest/test_bug691059.html new file mode 100644 index 0000000000..b00da02b0d --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug691059.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=691059 +--> +<head> + <title>Test for Bug 691059</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=691059">Mozilla Bug 691059</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + + +/** Test for Bug 691059 **/ + +function f() {} + +function testEventTarget(obj) { + obj.onmouseenter = f; + is(obj.onmouseenter, f, + "onmouseenter should be settable"); + obj.onmouseleave = f; + is(obj.onmouseleave, f, + "onmouseenter should be settable"); +} + +function testInterface(obj) { + try { + obj.prototype.onmouseenter = f; + is("onmouseenter" in obj, false, + "setting <Interface>.prototype.onmouseenter has no effect on the " + + "non-existent <Interface>.onmouseenter"); + obj.prototype.onmouseleave = f; + is("onmouseleave" in obj, false, + "setting <Interface>.prototype.onmouseleave has no effect on the " + + "non-existent <Interface>.onmouseleave"); + } catch(ex) { + ok(false, ex); + } +} + +testEventTarget(window); +testEventTarget(document); +testEventTarget(document.documentElement); + +testInterface(Document); +testInterface(HTMLElement); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug720619.html b/js/xpconnect/tests/mochitest/test_bug720619.html new file mode 100644 index 0000000000..804ec96d75 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug720619.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=720619 +--> +<head> + <title>Test for Bug 629227</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=720619">Mozilla Bug 720619</a> +<p id="display"> + <iframe id="testTarget"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 720619 **/ +SimpleTest.waitForExplicitFinish(); + +function checkThrows(f, exception) { + try { + f(); + ok(false, "should have thrown: " + f); + } catch (e) { + ok(exception.test(e.toString()), "correctly threw"); + } +} + +function go() { + var loc = $('ifr').contentWindow.location; + checkThrows(function() {loc + '';}, /Permission denied/); + checkThrows(function() {'' + loc;}, /Permission denied/); + checkThrows(function() {String(loc);}, /Permission denied/); + + var win = $('ifr').contentWindow; + checkThrows(function() {win + '';}, /Permission denied/); + checkThrows(function() {'' + win;}, /Permission denied/); + checkThrows(function() {String(win);}, /Permission denied/); + + SimpleTest.finish(); +} + +</script> + +<iframe id="ifr" onload="go()" + src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug720619.html"> +</iframe> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug731471.html b/js/xpconnect/tests/mochitest/test_bug731471.html new file mode 100644 index 0000000000..e74b07734a --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug731471.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=731471 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 731471</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="setTimeout(boom, 0);"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=731471">Mozilla Bug 731471</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 731471. This is effectively a crashtest, but it uses window.open, which + doesn't work in the crashtest harness. **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); +function boom() +{ + w = window.open("file_bug731471.html"); + setTimeout(function() { + w.document.write("2"); + w.document.close(); + w.document.write("3 - Done"); + w.document.close(); + w.close(); + ok(true, "Didn't assert!"); + SimpleTest.finish(); + }, 400); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug764389.html b/js/xpconnect/tests/mochitest/test_bug764389.html new file mode 100644 index 0000000000..6e90dd448b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug764389.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=764389 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 764389</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=764389">Mozilla Bug 764389</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 764389 **/ + +// This is basically a crash test, but we need to write a mochitest so that it +// runs with http:// urls instead of file:// urls. +SimpleTest.waitForExplicitFinish(); + +function go() { + var ifr = document.getElementById('ifr'); + ifr.contentDocument.open(); + ok(true, "Didn't crash"); + ifr.contentDocument.close(); + SimpleTest.finish(); +} + + + +</script> +<iframe id="ifr" onload="go();" src="file_empty.html"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug772288.html b/js/xpconnect/tests/mochitest/test_bug772288.html new file mode 100644 index 0000000000..5af0f7d2d6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug772288.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=772288 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 772288</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="doTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=772288">Mozilla Bug 772288</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 772288 **/ +SimpleTest.waitForExplicitFinish(); + +const Cu = SpecialPowers.Cu; + +function doTest() { + msg = "AppConstants should be imported on window"; + try { + Cu.import("resource://gre/modules/AppConstants.jsm", window); + ok(AppConstants, msg); + } catch (ex) { + ok(false, msg + " : " + ex); + } + + msg = "AppConstants should be imported on myObj"; + try { + var myObj = {}; + Cu.import("resource://gre/modules/AppConstants.jsm", myObj); + ok(myObj.AppConstants, msg); + } catch (ex) { + ok(false, msg + " : " + ex); + } + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug781476.html b/js/xpconnect/tests/mochitest/test_bug781476.html new file mode 100644 index 0000000000..f9ab40d4d9 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug781476.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=781476 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 781476</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781476">Mozilla Bug 781476</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 781476 **/ +SimpleTest.waitForExplicitFinish(); + +function go() { + var iwin = document.getElementById('ifr').contentWindow; + iwin.is = is; + var evt = iwin.makeEvent(); + is(evt.expando, 42, "Expando properly visible in caller frame"); + SimpleTest.finish(); +} + + +</script> +</pre> +<iframe onload="go();" id="ifr" src="file_bug781476.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug789713.html b/js/xpconnect/tests/mochitest/test_bug789713.html new file mode 100644 index 0000000000..251ecf22c2 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug789713.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789713 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 789713</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789713">Mozilla Bug 789713</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="ifr"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 789713 **/ + +// We can't set document.domain on mochi.test, because it's forbidden to set +// document.domain to a TLD. +var ifr = document.getElementById('ifr'); + +SimpleTest.waitForExplicitFinish(); +ifr.src = window.location.toString().replace("mochi.test:8888", "test1.example.org") + .replace("test_bug789713", "file_bug789713") + .split('?')[0]; +window.onmessage = function(message) { + ok(message.data, "Test succeeded and didn't crash"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug790732.html b/js/xpconnect/tests/mochitest/test_bug790732.html new file mode 100644 index 0000000000..c702273900 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug790732.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=790732 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 790732</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +async function doTest() { + await SpecialPowers.pushPrefEnv({set: [["dom.use_components_shim", true]]}) + + // Basic stuff + ok(Components, "Components shim exists!"); + var Ci = Components.interfaces; + ok(Ci, "interfaces shim exists!"); + is(typeof Components.classes, 'undefined', "Shouldn't have a Cc"); + + // Check each interface that we shim. We start by checking specific + // constants for a couple of interfaces, and then once it's pretty clear that + // it's working as intended we just check that the objects themselves are the + // same. + is(Ci.nsIXMLHttpRequest.HEADERS_RECEIVED, XMLHttpRequest.HEADERS_RECEIVED); + is(Ci.nsIDOMNode.DOCUMENT_NODE, Node.DOCUMENT_NODE); + is(Ci.nsIDOMKeyEvent, KeyEvent); + is(Ci.nsIDOMMouseEvent, MouseEvent); + is(Ci.nsIDOMMouseScrollEvent, MouseScrollEvent); + is(Ci.nsIDOMMutationEvent, MutationEvent); + is(Ci.nsIDOMUIEvent, UIEvent); + is(Ci.nsIDOMHTMLMediaElement, HTMLMediaElement); + is(Ci.nsIDOMRange, Range); + is(Ci.nsIDOMNodeFilter, NodeFilter); + is(Ci.nsIDOMXPathResult, XPathResult); + + SimpleTest.finish(); +} + +doTest(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=790732">Mozilla Bug 790732</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<iframe id="ifr"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug793969.html b/js/xpconnect/tests/mochitest/test_bug793969.html new file mode 100644 index 0000000000..1d06d65904 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug793969.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=793969 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 793969</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=793969">Mozilla Bug 793969</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 793969 **/ +function checkThrows(f, desc, skipMessageCheck) { + try { + f(); + ok(false, "Should have thrown for " + desc); + } catch (e) { + ok(true, "threw correctly"); + if (!skipMessageCheck) + ok(/denied/.exec(e) || + /can't redefine non-configurable property/.exec(e), + "Correctly threw a security exception: " + e); + } +} + +// NB: These sets will be no-ops (throw in strict mode) because setting an inherited readonly value prop has those semantics. +checkThrows(function() { "use strict"; location.valueOf = 'hah'; }, 'Shadow with string', /* skipMessageCheck = */ true); +checkThrows(function() { "use strict"; location.valueOf = function() { return {a: 'hah'};} }, 'Shadow with function', /* skipMessageCheck = */ true); +checkThrows(function() { Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'defineProperty with value'); +checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'delete + defineProperty with value'); +checkThrows(function() { Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'defineProperty with getter'); +checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'delete + defineProperty with getter'); + +Object.prototype.valueOf = function() { return 'hah'; }; +is(({}).valueOf(), 'hah', "Shadowing on Object.prototype works for vanilla objects"); +is(location.valueOf(), location, "Shadowing on Object.prototype and Location.prototype doesn't for location objects"); + +location[Symbol.toPrimitive] = function() { return 'hah'; } +is(location + "", location.toString(), "Should't be able to shadow with toPrimitive"); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug800864.html b/js/xpconnect/tests/mochitest/test_bug800864.html new file mode 100644 index 0000000000..4acee755f5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug800864.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=800864 +--> +<head> + <title>Test for Bug 800864</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=800864">Mozilla Bug 800864</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function checkThrows(f) { + try { + f(); + ok(false, "Didn't throw a security exception like we should"); + } catch(e) { + ok(/denied|insecure/.exec(e), "Should throw security exception. Got: " + e); + } +} + +function go() { + ifr = document.getElementById('ifr'); + win = ifr.contentWindow; + loc = win.location; + ifr.onload = check; + win.location = 'http://test1.example.com'; +} + +function check() { + checkThrows(function() { loc.toString(); }); + checkThrows(function() { loc.valueOf().toString(); }); + checkThrows(function() { loc.href; }); + checkThrows(function() { loc + ''; }); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +<iframe id="ifr" onload="go()" src="file_empty.html"></iframe> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug802557.html b/js/xpconnect/tests/mochitest/test_bug802557.html new file mode 100644 index 0000000000..4479986b8e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug802557.html @@ -0,0 +1,116 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=802557 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 802557</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 802557 **/ + SimpleTest.waitForExplicitFinish(); + + function checkThrows(fun, desc) { + try { + fun(); + ok(false, "Didn't throw when " + desc); + } catch(e) { + ok(true, "Threw when " + desc + " " + e); + ok(/denied|insecure/.exec(e), "Should be security exception"); + } + } + + var loadCount = 0; + function go() { + ++loadCount; + window.ifr = document.getElementById('ifr'); + window.iWin = ifr.contentWindow; + + if (loadCount == 1) { + gLoc = iWin.location; + // Note that accessors pulled off Xrays are currently bound. This is bug 658909. + // [getter, description, locationObj, bound] + gGetters = [[ location.toString, 'toString from LW' ], + [ gLoc.toString, 'toString from XLW' ], + [ Object.__lookupGetter__.call(location, 'href'), 'href getter from LW' ], + [ Object.__lookupGetter__.call(gLoc, 'href'), 'href getter from XLW' ], + [ Object.getOwnPropertyDescriptor(location, 'href').get, 'href getter from location' ], + [ Object.getOwnPropertyDescriptor(gLoc, 'href').get, 'href getter from iWin.location' ], + [ function() { return this + ''; }, 'implicit conversion via [[DefaultValue]]', /* doMessageCheck = */ true ]]; + gGetters.forEach(function(item) { + try { + is(item[0].call(location), location.toString(), 'Same-origin LW: ' + item[1]); + is(item[0].call(gLoc), gLoc.toString(), 'Same-origin XLW: ' + item[1]); + } catch (e) { + ok(false, "Threw while applying " + item[1] + " to same-origin location object: " + e); + } + }); + ifr.src = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + } + else if (loadCount == 2) { + gGetters.forEach(function(item) { + checkThrows(function() { item[0].call(gLoc); }, + 'call()ing ' + item[1] + ' after navigation cross-origin'); + }); + ifr.src = 'http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug802557.html'; + } + else if (loadCount == 3) { + gTestFunctions = ifr.contentWindow.getAllTests(); + var win = ifr.contentWindow; + for (fun in gTestFunctions) + is(gTestFunctions[fun](), win.location.toString(), "allowed via " + fun); + win.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_bug802557.html'; + } + else if (loadCount == 4) { + for (fun in gTestFunctions) { + var f = gTestFunctions[fun]; + checkThrows(f, "calling " + fun); + } + + // Verify that URL.prototype.toString can't be applied to Location + var threw = false; + try { + URL.prototype.toString.call(location); + } catch (e) { + threw = true; + } + ok(threw, + "Should not be able to use URL.prototype.toString on a Location instance"); + + // Verify that URL.prototype.href getter can't be applied to Location + threw = false; + var reachedTest = false; + try { + var get = Object.getOwnPropertyDescriptor(URL.prototype, "href").get; + is(typeof(get), "function", "Should have an href getter on URL.prototype"); + var reachedTest = true; + get.call(location); + } catch (e) { + threw = true; + } + ok(reachedTest, + "Should not be able to find URL.prototype.href getter"); + ok(threw, + "Should not be able to use URL.prototype.href getter on a Location instance"); + SimpleTest.finish(); + } + } + + + +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=802557">Mozilla Bug 802557</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifr" onload="go();" src="file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug803730.html b/js/xpconnect/tests/mochitest/test_bug803730.html new file mode 100644 index 0000000000..88df8d5477 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug803730.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=803730 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 803730</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803730">Mozilla Bug 803730</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 803730 **/ +var foo = { + isNode: function(obj) { + return !!(obj instanceof Node); + } +}; + +var elem = document.createElement("span"); +var trueCount = 0, + falseCount = 0; +for (var x = 0; x < 100000; x++) { + if (foo.isNode(elem)) + trueCount++; + else + falseCount++; +} +is(falseCount, 0, "elem instanceof Node working correctly."); + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug809547.html b/js/xpconnect/tests/mochitest/test_bug809547.html new file mode 100644 index 0000000000..17808867d6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug809547.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=809547 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 809547</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="go()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809547">Mozilla Bug 809547</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 809547 **/ +SimpleTest.waitForExplicitFinish(); +var gObj = {}; +function go() { + window.location.expando = gObj; + is(window.location.expando, gObj, "Expando appears"); + SimpleTest.executeSoon(finish); +} + +function finish() { + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + is(window.location.expando, gObj, "Expando preserved"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug829872.html b/js/xpconnect/tests/mochitest/test_bug829872.html new file mode 100644 index 0000000000..07e2a4ca77 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug829872.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=829872 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 829872</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 829872 and Bug 968003 **/ + SimpleTest.waitForExplicitFinish(); + + var gLoadCount = 0; + function loaded() { + if (++gLoadCount == 3) + go(); + } + + async function check(elem, desc) { + is(elem.contentDocument, null, "null cross-origin contentDocument for " + desc); + ok(await SpecialPowers.spawn(elem, [], () => this.content.eval('frameElement === null;')), + "null cross-origin frameElement for " + desc); + if (!(elem instanceof elem.ownerDocument.defaultView.HTMLFrameElement)) + is(elem.getSVGDocument(), null, "null cross-origin getSVGDocument() for " + desc); + } + + async function go() { + ok(true, "Starting test"); + await check($('ifr'), "iframe element"); + await check($('obj'), "object element"); + await check($('framesetholder').contentDocument.getElementById('fr'), "frameset frame"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=829872">Mozilla Bug 829872</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<iframe id="ifr" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<object id="obj" onload="loaded();" data="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></object> +<iframe id="framesetholder" srcdoc="<html><head></head><frameset cols='100%'><frame id='fr' onload='parent.loaded();' src='http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html' /></frameset></html>"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug862380.html b/js/xpconnect/tests/mochitest/test_bug862380.html new file mode 100644 index 0000000000..d604e3d05f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug862380.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=862380 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 862380</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 862380 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + checkNotEnumerable($('ifr').contentWindow, true); + checkNotEnumerable($('ifr').contentWindow.location, false); + SimpleTest.finish(); + } + +function checkNotEnumerable(obj, isWindow) { + try { + const expectedWindow = ["0"]; + const expectedLocation = []; + const expected = isWindow ? expectedWindow : expectedLocation; + is(Object.keys(obj).length, expected.length, + "Object.keys gives right array length"); + var actual = []; + for (var i in obj) + actual.push(i); + is(actual.length, expected.length, + "Enumeration sees the right number of props"); + actual.sort(); + expected.sort(); + for (var i = 0; i < actual.length; ++i) + is(actual[i], expected[i], "Arrays should be the same " + i); + } catch (e) { + ok(false, "threw: " + e); + } + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=862380">Mozilla Bug 862380</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug865260.html b/js/xpconnect/tests/mochitest/test_bug865260.html new file mode 100644 index 0000000000..b09b488dcd --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug865260.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=865260 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 865260</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 865260 **/ + SimpleTest.waitForExplicitFinish(); + function go() { + var exn = "nothrow"; + try { $('ifr').contentWindow['Date']; } catch (e) { exn = e; }; + ok(!!/denied/.exec(exn), "Threw instead of crashing"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=865260">Mozilla Bug 865260</a> +<p id="display"></p> +<div id="content"> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug871887.html b/js/xpconnect/tests/mochitest/test_bug871887.html new file mode 100644 index 0000000000..082b2ae746 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug871887.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=871887 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 871887</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 871887 **/ + SimpleTest.waitForExplicitFinish(); + + // NB: onstart ends up getting invoked twice, for mysterious and potentially- + // IE6-related reasons. + function checkpoint(invocant) { + ok(true, "onstart called"); + is(invocant, $('llama'), "this-binding is correct"); + $('llama').loop = 1; + $('llama').scrollDelay = 1; + $('llama').scrollAmount = 500; + } + + function done(invocant) { + is(invocant, $('llama'), "this-binding is correct"); + ok(true, "onfinish called"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=871887">Mozilla Bug 871887</a> +<p id="display"></p> +<div id="content"> +<marquee id="llama" onstart="checkpoint(this);" onfinish="done(this);">Watch the Llama</marquee> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug912322.html b/js/xpconnect/tests/mochitest/test_bug912322.html new file mode 100644 index 0000000000..011c4a8f4e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug912322.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=912322 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 912322</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + var { AppConstants } = SpecialPowers.ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" + ); + // Test window.controllers. + if (AppConstants.RELEASE_OR_BETA) { + is(typeof window.controllers, 'object', "shimmed controllers should be available to content in beta and release"); + } else { + is(typeof window.controllers, 'undefined', "controllers should not be available to content in Nightly"); + } + is(typeof SpecialPowers.wrap(window).controllers, 'object', "controllers should be available over Xray"); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=912322">Mozilla Bug 912322</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug916945.html b/js/xpconnect/tests/mochitest/test_bug916945.html new file mode 100644 index 0000000000..01c342eea1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug916945.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=916945 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 916945</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 916945 **/ + SimpleTest.waitForExplicitFinish(); + + var gLoadCount = 0; + function loaded() { + if (++gLoadCount == 2) + go(); + } + async function go() { + // Both same-origin and cross-origin names should be visible if they're set + // on the iframe element. + ok('winA' in window, "same-origin named access works"); + ok(winA instanceof winA.Window, "same-origin named access works"); + ok('winB' in window, "cross-origin named access works when iframe name matches"); + is(winB.parent, window, "cross-origin named access works when iframe name matches"); + + // Setting the 'name' attribute should propagate to the docshell. + var ifrB = document.getElementById('ifrB'); + await SpecialPowers.spawn(ifrB, [], () => { + Assert.equal(this.content.name, 'winB', + 'initial attribute value propagates to the docshell'); + }); + + ifrB.setAttribute('name', 'foo'); + await SpecialPowers.spawn(ifrB, [], () => { + Assert.equal(this.content.name, 'foo', + 'attribute sets propagate to the docshell'); + }); + ok('foo' in window, "names are dynamic if updated via setAttribute"); + is(foo.parent, window, "names are dynamic if updated via setAttribute"); + + // Setting window.name on the subframe should not propagate to the attribute. + await SpecialPowers.spawn(ifrB, [], () => { + this.content.name = "bar"; + }); + is(ifrB.getAttribute('name'), 'foo', 'docshell updates dont propagate to the attribute'); + + // When the frame element attribute and docshell name don't match, nothing is returned. + ok(!('foo' in window), "frame element name not resolved if it doesn't match the docshell"); + ok(!('bar' in window), "docshell name not resolved if it doesn't match the frame element"); + + // This shouldn't assert. + function listener() { + document.body.appendChild(ifrA); + ifrA.name = ""; + } + ifrA.addEventListener("DOMNodeInserted", listener, {once: true}); + document.body.appendChild(ifrA); + + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=916945">Mozilla Bug 916945</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="ifrA" name="winA" onload="loaded();" src="file_empty.html"></iframe> +<iframe id="ifrB" name="winB" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug92773.html b/js/xpconnect/tests/mochitest/test_bug92773.html new file mode 100644 index 0000000000..b1172f377e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug92773.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=92773 +--> +<head> + <title>Test for Bug 92773</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=92773">Mozilla Bug 92773</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 92773 **/ +function go() { + try { + $('ifr').contentWindow.foo; + ok(false, "able to access cross-origin getter"); + } catch (e) { + ok(/Permission denied/.exec(e), "unable to access cross-origin getter"); + } + + SimpleTest.finish(); +} +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> + +<iframe id='ifr' + src='http://example.com/tests/js/xpconnect/tests/mochitest/bug92773_helper.html' + onload="go()"> +</iframe> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug940783.html b/js/xpconnect/tests/mochitest/test_bug940783.html new file mode 100644 index 0000000000..0c87e710c1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug940783.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=940783 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 940783</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 940783 **/ + SimpleTest.waitForExplicitFinish(); + + function checkHistoryThrows(hist) { + checkThrows(function() { hist.length; }); + checkThrows(function() { hist.state; }); + checkThrows(function() { hist.go(); }); + checkThrows(function() { hist.back(); }); + checkThrows(function() { hist.forward(); }); + checkThrows(function() { hist.pushState({}, "foo"); }); + checkThrows(function() { hist.replaceState({}, "foo"); }); + + } + + window.gLoads = 0; + function load() { + var iwin = $('ifr').contentWindow; + ++gLoads; + if (gLoads == 1) { + window.gHist = iwin.history; + iwin.location = "file_empty.html"; + } else if (gLoads == 2) { + checkHistoryThrows(gHist); + window.gHist = iwin.history; + iwin.location = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"; + } else { + checkHistoryThrows(gHist); + $('ifr').setAttribute('onload', null); + SimpleTest.finish(); + } + } + + function checkThrows(fn) { + try { fn(); ok(false, "Should have thrown: " + fn.toSource()); } + catch (e) { ok(!!/denied|insecure/.exec(e), "Threw correctly: " + e); } + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940783">Mozilla Bug 940783</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="ifr" onload="load();" src="file_empty.html"></iframe> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug960820.html b/js/xpconnect/tests/mochitest/test_bug960820.html new file mode 100644 index 0000000000..7667fde624 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug960820.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=960820 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 960820</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for exception stacks crossing **/ + + // Synchronous event dispatch creates a new script entry point. At the time + // of this writing, an event listener defined in a Sandbox will cause the + // SafeJSContext to be pushed to the cx stack, which differs from the JSContext + // associated with this DOM window. So we test both kinds of boundaries. + var sb = new SpecialPowers.Cu.Sandbox(SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal()); + sb.win = window; + SpecialPowers.Cu.evalInSandbox("win.document.addEventListener('click', " + + "function clickHandler() { win.wrappedJSObject.clickCallback(); });", sb); + function clickCallback() { + var stack = (new Error()).stack; + ok(true, "Invoked clickCallback. Stack: " + stack); + ok(/clickCallback/.test(stack), "clickCallback should be in the stack"); + ok(!/clickHandler/.test(stack), "clickHandler should not be in the stack"); + ok(/dispatchClick/.test(stack), "dispatchClick should be in the stack"); + + // Check Components.stack, but first filter through the SpecialPowers junk. + var stack = SpecialPowers.wrap(SpecialPowers.Components).stack; + while (/testing-common/.test(stack)) { + stack = stack.caller; + } + ok(/clickCallback/.test(stack), "clickCallback should be reachable via Components.stack"); + ok(/clickHandler/.test(stack.caller), "clickHandler should be reachable via Components.stack"); + ok(/dispatchClick/.test(stack.caller.caller), "dispatchClick hould be reachable via Components.stack"); + } + function dispatchClick() { + document.dispatchEvent(new MouseEvent('click')); + } + dispatchClick(); + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=960820">Mozilla Bug 960820</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug965082.html b/js/xpconnect/tests/mochitest/test_bug965082.html new file mode 100644 index 0000000000..b2320b52c7 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug965082.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=965082 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 965082</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 965082 **/ + SimpleTest.waitForExplicitFinish(); + + function checkThrows(f, msg) { + try { f(); ok(false, "Should have thrown: " + msg); } + catch (e) { ok(/denied|insecure|can't set prototype/.test(e), "Should throw security exception: " + e + " (" + msg + ")"); } + } + + function go() { + var protoSetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set; + checkThrows(function() { protoSetter.call(window[0], new Object()); }, "Setting cross-origin Window prototype"); + checkThrows(function() { protoSetter.call(window[0].location, new Object()); }, "Setting cross-origin Location prototype"); + SimpleTest.finish(); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965082">Mozilla Bug 965082</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_bug993423.html b/js/xpconnect/tests/mochitest/test_bug993423.html new file mode 100644 index 0000000000..dbe4cef3cc --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_bug993423.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=993423 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 993423</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 993423 **/ + SimpleTest.waitForExplicitFinish(); + + var sCallbackInvocations = 0; + function callback(handlerIsInXBLScope) { + ok(!handlerIsInXBLScope, "Event handler should not be in XBL scope"); + if (++sCallbackInvocations == 2) + SimpleTest.finish(); + } + + function go() { + document.querySelector('use').setAttributeNS('http://www.w3.org/1999/xlink', + 'href', location.href + '#a'); + } + + </script> +</head> +<body onload="go()";> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=993423">Mozilla Bug 993423</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<svg> + <symbol id="a"> + <foreignObject> + <img src="about:logo" onload="var isInXBL = (function() { return this; })() != window; if (isInXBL) callback = window.wrappedJSObject.callback; callback(isInXBL);"> + </foreignObject> + </symbol> + <use /> +</svg> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_class_static_block_worker.html b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html new file mode 100644 index 0000000000..e3ce063fe9 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test class static fields</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + // Make sure static classes parse in regular context too: + class B { + static { this.x = 12; } + } + is(B.x, 12, "static block set class value"); + console.log("script"); + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('class_static_worker.js'); + + console.log("message") + worker.onmessage = function(e) { + + is(e.data, 12, "correctly allocated class-static containing-class in worker"); + SimpleTest.finish(); + } + worker.postMessage("get"); + info("Messages posted"); + } + go(); + </script> + </head> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html new file mode 100644 index 0000000000..d7d364fdeb --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Cross-Compartment DOM WeakMaps</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<script type="application/javascript"> + +var my_map = new WeakMap(); + +function setup() { + var item = window.frames[0].document.querySelector("body"); + + my_map.set(item, "success_string"); +} + +function runTest() { + setup(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + var item = window.frames[0].document.querySelector("body"); + is(my_map.get(item), "success_string", "Preserve reflectors used cross-compartment as weak map keys."); +} + +</script> +<iframe src="file_crosscompartment_weakmap.html" onload="runTest()"></iframe> + + +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_enable_privilege.html b/js/xpconnect/tests/mochitest/test_enable_privilege.html new file mode 100644 index 0000000000..03043e9ce6 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_enable_privilege.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html lang="en" dir="ltr"> + <head> + <title>Test page for enablePrivilege</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script> + function init() { + var result = document.getElementById("result"); + try { + /* globals netscape */ + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + result.textContent = "FAIL"; + } catch (ex) { + result.textContent = "PASS"; + } + } + </script> + </head> + <body> + <p id="result"></p> + <script> + init(); + is(result.textContent, "PASS", "enablePrivilege should be unavaillable"); + </script> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html new file mode 100644 index 0000000000..9d9a798cdf --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html @@ -0,0 +1,168 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry works in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let registry1, holdings1; + let registry2, holdings2; + let registry3, holdings3; + let registry4, holdings4; + let registry5, holdings5; + let registry6, holdings6; + let registry7, holdings7; + let registry8, holdings8; + let registry9, holdings9; + + let object4 = {}; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // Registry with no registered objects. + holdings1 = []; + registry1 = new FinalizationRegistry(v => { holdings1.push(v); }); + + // Registry with three registered objects. + holdings2 = []; + registry2 = new FinalizationRegistry(v => { holdings2.push(v); }); + registry2.register({}, 1); + registry2.register({}, 2); + registry2.register({}, 3); + + // Registry with registered object that is then unregistered. + holdings3 = []; + registry3 = new FinalizationRegistry(v => { holdings3.push(v); }); + let token3 = {} + registry3.register({}, 1, token3); + registry3.unregister(token3); + + // Registry with registered object that doesn't die. + holdings4 = []; + registry4 = new FinalizationRegistry(v => { holdings4.push(v); }); + registry4.register(object4, 1); + + // Registry observing cyclic JS data structure. + holdings5 = []; + registry5 = new FinalizationRegistry(v => { holdings5.push(v); }); + registry5.register(makeJSCycle(4), 5); + + // Registry observing DOM object without preserved wrappers. + holdings6 = []; + registry6 = new FinalizationRegistry(v => { holdings6.push(v); }); + registry6.register(document.createElement("div"), 6); + + // Registry observing DOM object with preserved wrappers. + holdings7 = []; + registry7 = new FinalizationRegistry(v => { holdings7.push(v); }); + let object = document.createElement("div"); + object.someProperty = true; + registry7.register(object, 7); + object = null; + + // Registry observing reachable DOM object without preserved wrappers. + holdings8 = []; + registry8 = new FinalizationRegistry(v => { holdings8.push(v); }); + document.body.appendChild(document.createElement("div")); + registry8.register(document.body.lastChild, 8); + + // Registry observing cyclic DOM/JS data structure. + holdings9 = []; + registry9 = new FinalizationRegistry(v => { holdings9.push(v); }); + registry9.register(makeDOMCycle(4), 9); + + // Need to run full GC/CC/GC cycle to collect cyclic garbage through DOM + // and JS heaps. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + // Microtasks are run before cleanup callbacks. + Promise.resolve().then(() => { + is(holdings1.length, 0); + is(holdings2.length, 0); + is(holdings3.length, 0); + is(holdings4.length, 0); + is(holdings5.length, 0); + is(holdings6.length, 0); + is(holdings7.length, 0); + is(holdings8.length, 0); + is(holdings9.length, 0); + }); + + // setTimeout queues a task which will run after cleanup callbacks. + setTimeout(task2, 0); + } + + function task2() { + is(holdings1.length, 0); + + let result = holdings2.sort((a, b) => a - b); + is(result.length, 3); + is(result[0], 1); + is(result[1], 2); + is(result[2], 3); + + is(holdings3.length, 0); + is(holdings4.length, 0); + + is(holdings5.length, 1); + is(holdings5[0], 5); + + is(holdings6.length, 1); + is(holdings6[0], 6); + + is(holdings7.length, 1); + is(holdings7[0], 7); + + is(holdings8.length, 0); + + is(holdings9.length, 1); + is(holdings9[0], 9); + + document.body.removeChild(document.body.lastChild); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + setTimeout(task3, 0); + } + + function task3() { + is(holdings8.length, 1); + is(holdings8[0], 8); + + SimpleTest.finish(); + } + + function makeJSCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + current.next = {}; + current = current.next; + } + current.next = first; + return first; + } + + function makeDOMCycle(size) { + let first = {}; + let current = first; + for (let i = 0; i < size; i++) { + if (i % 2 === 0) { + current.next = document.createElement("div"); + } else { + current.next = {}; + } + current = current.next; + } + current.next = first; + return first; + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html new file mode 100644 index 0000000000..8393781ce1 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry works in workers</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('finalizationRegistry_worker.js'); + + worker.onevent = (event) => { + console.log(event.message); + throw event.error; + }; + + worker.onmessage = (event) => { + switch (event.data) { + case 'started': + worker.postMessage('checkResults'); + break; + + case 'passed': + ok(true, "Tests passed"); + SimpleTest.finish(); + break; + + default: + console.log(event.data); + break; + } + }; + + worker.postMessage('startTest'); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html new file mode 100644 index 0000000000..d70cfa7172 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry cleanupSome method is not exposed by default</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let registry = new FinalizationRegistry(x => 1); + is(registry.cleanupSome, undefined, + "The cleanupSome method should not be exposed by default"); + </script> + </head> +</html> diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html new file mode 100644 index 0000000000..8b6c71c9cf --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test FinalizationRegistry tracks its incumbent global</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let resolvePromise, rejectPromise; + + async function runTest(global, callback) { + let fr = new global.FinalizationRegistry(callback); + fr.register({}, undefined); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + + let promise = new Promise((resolve, reject) => { + resolvePromise = resolve; + rejectPromise = reject; + }); + + return promise; + } + + function receiveMessage(event) { + resolvePromise(event.source.sourceName); + } + + async function go() { + // This test uses FinalizationRegistry to trigger a callback and reports + // the incumbent global in the callback using postMessage. In all cases + // the author function that scheduled the callback is runTest(), so the + // incumbent global should be the main window. + + SimpleTest.waitForExplicitFinish(); + + window.sourceName = "main"; + window.addEventListener("message", receiveMessage, false); + + let other = window.frames[0]; + other.sourceName = "other"; + other.addEventListener("message", receiveMessage, false); + + is(await runTest(window, v => window.postMessage(v)), "main"); + is(await runTest(window, window.postMessage.bind(window)), "main"); + is(await runTest(other, v => other.postMessage(v)), "main"); + is(await runTest(other, other.postMessage.bind(other)), "main"); + is(await runTest(window, v => other.postMessage(v)), "main"); + is(await runTest(window, other.postMessage.bind(other)), "main"); + is(await runTest(other, v => window.postMessage(v)), "main"); + is(await runTest(other, window.postMessage.bind(window)), "main"); + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"> + <div style="display: none"> + <!-- A subframe so we have another global to work with --> + <iframe></iframe> + </div> + </body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_frameWrapping.html b/js/xpconnect/tests/mochitest/test_frameWrapping.html new file mode 100644 index 0000000000..4c8a6c428c --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_frameWrapping.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +No bug. +--> +<head> + <title>Test for Bug </title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** No bug for this test **/ + +function go() { + var win = frames[0]; + (function() { + var utils = SpecialPowers.getDOMWindowUtils(window); + is(utils.getClassName(win), "Proxy", "correctly wrap frame elements"); + })() + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<iframe id="ifr" src="inner.html" onload="go()"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html new file mode 100644 index 0000000000..22a4ae1c3b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=968335 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 968335</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Cu.getCallerPrincipal (within JS-implemented WebIDL). **/ + + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go); + + + function go() { + var t = new TestInterfaceJS(); + is(t.getCallerPrincipal(), location.origin, + "Cu.getCallerPrincipal works right within JS-implemented WebIDL"); + + try { + SpecialPowers.Cu.getWebIDLCallerPrincipal(); + ok(false, "Should have thrown"); + } catch (e) { + ok(/NOT_AVAILABLE/.test(SpecialPowers.wrap(e)), + "API should throw when invoked outside of JS-implemented WebIDL"); + } + + SimpleTest.finish(); + } + + + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968335">Mozilla Bug 968335</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_getweakmapkeys.html b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html new file mode 100644 index 0000000000..7942d9b945 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=688277 +--> +<head> + <meta charset="utf-8"> + <title>Tests for nondeterministicGetWeakMapKeys</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + /** Test for Bug 688277 **/ + + /* Fail gracefully if junk is passed in. */ + is(SpecialPowers.nondeterministicGetWeakMapKeys(11), undefined, + "nondeterministicGetWeakMapKeys should return undefined for non-objects"); + is(SpecialPowers.nondeterministicGetWeakMapKeys({}), undefined, + "nondeterministicGetWeakMapKeys should return undefined for non-weakmap objects"); + is(SpecialPowers.nondeterministicGetWeakMapKeys(null), undefined, + "nondeterministicGetWeakMapKeys should return undefined for null"); + + /* return an empty array for an empty WeakMap */ + let mempty = new WeakMap(); + is(SpecialPowers.nondeterministicGetWeakMapKeys(mempty).length, 0, + "nondeterministicGetWeakMapKeys should return empty array for empty weakmap"); + + /* Test freeing/nonfreeing. */ + let m = new WeakMap(); + let liveKeys = new Array(); + + let add_elements = function () { + let k1 = {}; + m.set(k1, "live1"); + liveKeys.push(k1); + + let k2 = {}; + m.set(k2, "dead1"); + + let k = {}; + m.set(k, k); /* simple cycle */ + }; + + add_elements(); + + SpecialPowers.exactGC(function () { + let keys = SpecialPowers.nondeterministicGetWeakMapKeys(m); + is(liveKeys.length, 1, "Wrong number of live keys."); + is(keys.length, 1, "Should have one weak map key."); + is(m.get(keys[0]), "live1", "live1 should be live"); + SimpleTest.finish(); + }); + + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<p id="display"></p> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_isRemoteProxy.html b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html new file mode 100644 index 0000000000..9761fce05b --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Tests for Cu.isRemoteProxy</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script> + +async function addFrame(url) { + let frame = document.createElement("iframe"); + frame.src = url; + document.body.appendChild(frame); + + await new Promise(resolve => { + frame.addEventListener("load", resolve, { once: true }); + }); + + return frame; +} + +add_task(async function() { + const { Cu } = SpecialPowers; + + let localFrame = await addFrame("file_empty.html"); + let remoteFrame = await addFrame( + SimpleTest.getTestFileURL("file_empty.html") + .replace("mochi.test:8888", "example.com")); + + ok(frames[0] === localFrame.contentWindow, "frames[0] is localFrame"); + ok(frames[1] === remoteFrame.contentWindow, "frames[1] is remoteFrame"); + + ok(!Cu.isRemoteProxy(window), "window is not a remote proxy"); + ok(!Cu.isRemoteProxy(location), "location is not a remote proxy"); + + ok(!Cu.isRemoteProxy(frames[0]), "frames[0] is not a remote proxy"); + ok( + !Cu.isRemoteProxy(frames[0].location), + "frames[0].location is not a remote proxy" + ); + + const { useRemoteSubframes } = SpecialPowers; + is(Cu.isRemoteProxy(frames[1]), useRemoteSubframes, + "frames[1] is a remote proxy if Fission is enabled"); + is(Cu.isRemoteProxy(frames[1].location), useRemoteSubframes, + "frames[1].location is a remote proxy if Fission is enabled"); +}); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_nukeContentWindow.html b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html new file mode 100644 index 0000000000..0db8749b59 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1322273 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1322273</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322273">Mozilla Bug 1322273</a> + +<iframe id="subframe"></iframe> + +<script type="application/javascript"> +"use strict"; + +function waitForWindowDestroyed(winID, callback) { + let observer = { + observe: function(subject, topic, data) { + let id = subject.QueryInterface(SpecialPowers.Ci.nsISupportsPRUint64).data; + if (id != winID) { + return; + } + SpecialPowers.removeObserver(observer, "outer-window-nuked"); + SpecialPowers.executeSoon(callback); + } + }; + SpecialPowers.addObserver(observer, "outer-window-nuked"); +} + +add_task(async function() { + let frame = $('subframe'); + frame.srcdoc = "foo"; + await new Promise(resolve => frame.addEventListener("load", resolve, {once: true})); + + let win = frame.contentWindow; + let winID = SpecialPowers.wrap(win).docShell.outerWindowID; + + win.eval("obj = {}"); + win.obj.foo = {bar: "baz"}; + + let obj = win.obj; + + let system = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal() + let sandbox = SpecialPowers.Cu.Sandbox(system); + + sandbox.obj = obj; + + let isWrapperDead = SpecialPowers.Cu.evalInSandbox(`(${ + function isWrapperDead() { + return Cu.isDeadWrapper(obj); + } + })`, + sandbox); + + is(isWrapperDead(), false, "Sandbox wrapper for content window should not be dead"); + is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive"); + + // Remove the frame, which should nuke the content window. + info("Remove the content frame"); + frame.remove(); + + // Give the nuke wrappers task a chance to run. + await new Promise(resolve => waitForWindowDestroyed(winID, resolve)); + + is(isWrapperDead(), true, "Sandbox wrapper for content window should be dead"); + is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive"); +}); +</script> + +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html new file mode 100644 index 0000000000..1b786138d4 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=777385 +--> +<head> + <meta charset="utf-8"> + <title>Tests for WebIDL objects as weak map keys</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 777385 **/ + + SimpleTest.waitForExplicitFinish(); + + // We wait to run this until the load event because it needs to access an element. + function go() { + + let live_map = new WeakMap; + + let get_div_style = function () { + return document.getElementById("mydivname").style; + } + + let make_live_map = function () { + let my_div_style = get_div_style(); + let div_fail = false; + try { + live_map.set(my_div_style, 12345); + } catch (e) { + div_fail = true; + } + ok(!div_fail, "Using elem.style as a weak map key should not produce an exception."); + + is(live_map.get(get_div_style()), 12345, "Live map should have live style with right value before GC."); + + } + + make_live_map(); + + let tf = new TestFunctions; + + let add_non_isupports2 = function () { + let testKey = tf.wrapperCachedNonISupportsObject; + + let testFail = false; + try { + live_map.set(testKey, 23456); + } catch (e) { + testFail = true; + } + + ok(!testFail, "Using a wrapper cached non-nsISupports class as a weak map key should not produce an exception."); + + is(live_map.get(testKey), 23456, "Live map should have wrapper cached non-nsISupports class right value before GC."); + } + + add_non_isupports2(); + + + /* Set up for running precise GC/CC then check the results. */ + + SpecialPowers.exactGC(function () { + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceGC(); + + is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2, + "Live WebIDL bindings keys should not be removed from a weak map."); + + is(live_map.get(get_div_style()), 12345, "Live weak map should have live style with right value after GC."); + is(live_map.get(tf.wrapperCachedNonISupportsObject), 23456, + "Live weak map should have live wrapper cached non-nsISupports class with right value after GC."); + + SimpleTest.finish(); + }); + + } + + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, + go); + }); + </script> +</head> +<div></div> +<div id="mydivname"></div> +<body> +<p id="display"></p> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_private_field_dom.html b/js/xpconnect/tests/mochitest/test_private_field_dom.html new file mode 100644 index 0000000000..4a50c7ca95 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_dom.html @@ -0,0 +1,221 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=???? +--> + +<head> + <meta charset="utf-8"> + <title>Test for Bug ????</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a> + <p id="display"></p> + <div id="test_contents"> + <!-- Extracted from nsHTMLTagList.h --> + <applet></applet> + <area></area> + <audio></audio> + <base> + </base> + <bgsound></bgsound> + <blockquote></blockquote> + + <body></body> + <br></br> + <button></button> + <canvas></canvas> + <caption></caption> + <col> + </col> + <colgroup></colgroup> + <data></data> + <datalist></datalist> + <del></del> + <details></details> + <dialog></dialog> + <dir></dir> + <div></div> + <dl></dl> + <embed></embed> + <fieldset></fieldset> + <font></font> + <form></form> + <frame></frame> + <frameset></frameset> + <h1></h1> + <h2></h2> + <h3></h3> + <h4></h4> + <h5></h5> + <h6></h6> + + <head></head> + <hr> + </hr> + <html> + + </html> + <iframe></iframe> + <img></img> + <input></input> + <ins></ins> + <keygen></keygen> + <label></label> + <legend></legend> + <li></li> + <link> + </link> + <listing></listing> + <map></map> + <marquee></marquee> + <menu></menu> + <menuitem> + </menuitem> + <meta> + </meta> + <meter></meter> + <multicol></multicol> + <object></object> + <ol></ol> + <optgroup></optgroup> + <option></option> + <output></output> + <p></p> + <param> + </param> + <picture></picture> + <pre></pre> + <progress></progress> + <q></q> + <script></script> + <select></select> + <slot></slot> + <source> + </source> + <span></span> + <style></style> + <summary></summary> + <table></table> + <tbody></tbody> + <td></td> + <textarea></textarea> + <tfoot></tfoot> + <th></th> + <thead></thead> + <template></template> + <time></time> + <title></title> + <tr></tr> + <track> + </track> + <ul></ul> + <video></video> + <xmp></xmp> + </div> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + info("running") + + + // Because private fields may not be enabled, we construct A via the below eval of an IFFE, + // and return early if it syntax errors. + var A = undefined; + try { + A = eval(`(function(){ + class Base { + constructor(o) { + return o; + } + } + + class A extends Base { + #x = 1; + static g(o) { + return o.#x; + } + static s(o, v) { + o.#x = v; + } + } + + return A; + })();`); + } catch (e) { + is(e instanceof SyntaxError, true, "Threw Syntax Error, Private Fields Not Enabled"); + is(/private fields are not currently supported/.test(e.message), true, "correct message"); + } + + if (A instanceof Function) { + function assertThrewInstance(f, error) { + var threw = true; + try { + f(); + threw = false; + } catch (e) { + // info("Caught " + e.name); + is(e instanceof error, true, "Correct Error thrown"); + } + is(threw, true, "Error was thrown"); + } + + function testNode(node) { + info("Testing node " + node.nodeName); + + assertThrewInstance(() => A.g(node), TypeError); + assertThrewInstance(() => A.s(node, 'node'), TypeError); + // info("Stamping Node"); + new A(node); + // info("Asserting read"); + is(A.g(node), 1, "correct value read"); + // info("Setting"); + A.s(node, 'node'); + // info("Verifing setter set the value"); + is(A.g(node), 'node', "updated value read"); + // info("Verifying we cannot double-init"); + assertThrewInstance(() => new A(node), TypeError); + } + + function testNodeRecursive(node) { + testNode(node); + for (c of node.children) { + testNodeRecursive(c) + } + } + + const test_contents = document.getElementById('test_contents'); + testNodeRecursive(test_contents); + + info("Checking Window"); + // Window itself isn't allowed to host private fields, because it's + // a cross-origin object + assertThrewInstance(() => A.g(window), TypeError) + + info("Checking Window Prototype Chain") + // However, it's prototype chain can. + w = Object.getPrototypeOf(window); + while (w) { + testNode(w); + w = Object.getPrototypeOf(w); + } + + info("Test Document") + testNode(document); + + + info("Test CSSRuleList") + testNode(document.styleSheets[0].cssRules) + + info("Test DOMTokenList") + const div = document.createElement('div'); + testNode(div.classList); + } + SimpleTest.finish(); + </script> +</body> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_private_field_worker.html b/js/xpconnect/tests/mochitest/test_private_field_worker.html new file mode 100644 index 0000000000..68351000c5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_worker.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test Private Fields</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let worker = new Worker('private_field_worker.js'); + + var allocated = 0; + worker.onmessage = function(e) { + is(e.data, allocated, "correctly allocated private field-containing-class"); + SimpleTest.finish(); + } + + worker.postMessage("allocate"); allocated++; + worker.postMessage("count"); + info("Messages posted"); + } + go(); + </script> + </head> + +</html>
\ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html new file mode 100644 index 0000000000..2393e3c24f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html @@ -0,0 +1,109 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=801576 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 801576</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=801576">Mozilla Bug 801576</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for the same-origin policy. **/ +SimpleTest.waitForExplicitFinish(); + +function check(obj, prop, allowed, write) { + var accessed = false; + try { + if (write) { + try { + obj[prop] = 2; + accessed = true; + } catch (e) {} + Object.defineProperty(obj, 'prop', {getter: function() {}, setter: null}); + } + else + obj[prop]; + accessed = true; + } catch (e) {} + is(accessed, allowed, prop + " is correctly (in)accessible for " + (write ? 'write' : 'read')); +} + +var crossOriginReadableWindowProps = ['blur', 'close', 'closed', 'focus', + 'frames', 'location', 'length', + 'opener', 'parent', 'postMessage', + 'self', 'top', 'window', + /* indexed and named accessors */ + '0', 'subframe']; + +function isCrossOriginReadable(obj, prop) { + if (obj == "Window") + return crossOriginReadableWindowProps.includes(prop); + if (obj == "Location") + return prop == 'replace'; + return false; +} + +function isCrossOriginWritable(obj, prop) { + if (obj == "Window") + return prop == 'location'; + if (obj == "Location") + return prop == 'href'; +} + +// NB: we don't want to succeed with writes, so we only check them when it should be denied. +function testAll(sameOrigin) { + var win = document.getElementById('ifr').contentWindow; + + // Build a list of properties to check from the properties available on our + // window. + var props = []; + for (var prop in window) { props.push(prop); } + + // On android, this appears to be on the window but not on the iframe. It's + // not really relevant to this test, so just skip it. + if (props.includes('crypto')) + props.splice(props.indexOf('crypto'), 1); + + // Add the named grand-child, since that won't appear on our window. + props.push('subframe'); + + for (var prop of props) { + check(win, prop, sameOrigin || isCrossOriginReadable('Window', prop), /* write = */ false); + if (!sameOrigin && !isCrossOriginWritable('Window', prop)) + check(win, prop, false, /* write = */ true); + } + for (var prop in window.location) { + check(win.location, prop, sameOrigin || isCrossOriginReadable('Location', prop)); + if (!sameOrigin && !isCrossOriginWritable('Location', prop)) + check(win.location, prop, false, /* write = */ true); + } +} + +var loadCount = 0; +function go() { + ++loadCount; + if (loadCount == 1) { + testAll(true); + document.getElementById('ifr').contentWindow.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html'; + } + else { + is(loadCount, 2); + testAll(false); + SimpleTest.finish(); + } +} + +</script> +</pre> +<iframe id="ifr" onload="go();" src="file_empty.html"></iframe> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_sandbox_fetch.html b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html new file mode 100644 index 0000000000..3b6cffed4e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html @@ -0,0 +1,54 @@ +<!doctype html> +<html> +<head> + <title>Fetch in JS Sandbox</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"></link> + <script src="test_fetch_basic.js"></script> +</head> +<body> +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +function testHttpFetch(url) { + info('fetch: ' + url); + return fetch(new Request(url, { method: 'GET' })) + .then(response => { + is(response.status, 200, 'Response is 200'); + is(response.url, url, 'Response URL matches'); + }); +} + +function runSandboxTest(testFunc, argString) { + is(typeof testFunc, 'function'); + var resolvePromise; + var testPromise = new Promise(r => resolvePromise = r); + var finishFuncName = 'finish_' + testFunc.name; + SpecialPowers.Cu.exportFunction(_ => resolvePromise(), sb, + { defineAs: finishFuncName }); + SpecialPowers.Cu.evalInSandbox('(' + testFunc.toString() + ')' + + '(' + argString + ')' + + '.then(' + finishFuncName + ');', sb); + return testPromise; +} + +var origin = document.location.origin; +var properties = ['fetch', 'Blob', 'URL']; +var sb = new SpecialPowers.Cu.Sandbox(origin, + { wantGlobalProperties: properties }); + +sb.ok = SpecialPowers.Cu.exportFunction(ok, sb); +sb.is = SpecialPowers.Cu.exportFunction(is, sb); +sb.info = SpecialPowers.Cu.exportFunction(info, sb); + +Promise.resolve() + .then(_ => runSandboxTest(testHttpFetch, '"' + origin + window.location.pathname + '"')) + .then(_ => runSandboxTest(testAboutURL)) + .then(_ => runSandboxTest(testDataURL)) + .then(_ => runSandboxTest(testSameOriginBlobURL)) + .then(_ => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm.html b/js/xpconnect/tests/mochitest/test_shadowRealm.html new file mode 100644 index 0000000000..311ce68107 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_shadowRealm.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for ShadowRealms</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <p id="display"></p> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + info("running") + + let realm = new ShadowRealm(); + + let install = (fun, internal_name) => { + let installer = realm.evaluate(`var ${internal_name}; (x) => { ${internal_name} = x}`); + installer(fun); + } + + install(info, "log"); + install(is, "is"); + realm.evaluate(`is(true, true, 'inside realm')`); + + is(realm.evaluate("10"), 10, "ten is ten"); + + SimpleTest.finish(); + </script> +</body> + +</html> diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html new file mode 100644 index 0000000000..d26e665f8f --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for ShadowRealms</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <iframe id="ifr"></iframe> +</head> + +<body> + <p id="display"></p> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var promise = (async ()=> { + var module = await import("./shadow_realm_module.js"); + is(module.x, 1, "import works outside worker"); + + var sr = new ShadowRealm(); + await sr.importValue("./shadow_realm_module.js", 'x').then((x) => is(x,1, "imported x and got 1")); + })(); + + promise.then(() => { + var worker = new Worker("shadow_realm_worker.js"); + + var expected = 0; + var recieved = 0; + + function test(str) { + worker.postMessage(str); + expected++; + } + + worker.onmessage = function(e) { + console.log("Received Message: "+e.data); + recieved++; + + if (e.data == "finish") { + is(expected, recieved, "Got the appropriate Number of messages"); + SimpleTest.finish(); + return; + } + + if (e.data.startsWith("PASS")) { + ok(true, e.data); + return; + } + + ok(false, e.data); + }; + + + test("evaluate"); + test("import"); + + + test("finish"); + }); + </script> +</body> + +</html> diff --git a/js/xpconnect/tests/mochitest/test_spectre_mitigations.html b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html new file mode 100644 index 0000000000..3797b9af0e --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Tests for Spectre mitigations</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script> +add_task(async function() { + const { Cu } = SpecialPowers; + const options = Cu.getJSTestingFunctions().getJitCompilerOptions(); + + const testMitigation = function(name) { + let val = options[name]; + ok(val === 0 || val === 1, "must be valid JitOption"); + is(Boolean(val), !SpecialPowers.useRemoteSubframes, "must be enabled if Fission is disabled"); + }; + + testMitigation("spectre.index-masking"); + testMitigation("spectre.object-mitigations"); + testMitigation("spectre.string-mitigations"); + testMitigation("spectre.value-masking"); + testMitigation("spectre.jit-to-cxx-calls"); +}); +</script> +</body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs.html b/js/xpconnect/tests/mochitest/test_weakRefs.html new file mode 100644 index 0000000000..331bb9bb69 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs.html @@ -0,0 +1,80 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRef works in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let wr1, wr2, wr3, wr4; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // 1. WeakRef with JS target. + wr1 = new WeakRef({}); + + // 2. WeakRef with DOM object target (without preserved wrapper). + wr2 = new WeakRef(document.createElement("div")); + + // 3. WeakRef with DOM object target (with preserved wrapper). + let object = document.createElement("div"); + object.someProperty = true; + wr3 = new WeakRef(object); + object = null + + // 4. WeakRef with reachable DOM object target without preserved wrapper. + document.body.appendChild(document.createElement("div")); + wr4 = new WeakRef(document.body.lastChild); + + // WeakRef should keep the target in the current task. + isnot(wr1.deref(), undefined, "deref() should return its target."); + isnot(wr2.deref(), undefined, "deref() should return its target."); + isnot(wr3.deref(), undefined, "deref() should return its target."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + + // WeakRef should keep the target until the end of current task, which + // includes promise microtasks. + Promise.resolve().then(() => { + isnot(wr1.deref(), undefined, "deref() should return its target."); + isnot(wr2.deref(), undefined, "deref() should return its target."); + isnot(wr3.deref(), undefined, "deref() should return its target."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + }); + + // setTimeout will call its callback in a new task. + setTimeout(task2, 0); + } + + function task2() { + // Trigger a full GC/CC/GC cycle to collect WeakRef targets. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "deref() should return undefined."); + is(wr2.deref(), undefined, "deref() should return undefined."); + is(wr3.deref(), undefined, "deref() should return undefined."); + isnot(wr4.deref(), undefined, "deref() should return its target."); + + // setTimeout will call its callback in a new task. + setTimeout(task3, 0); + } + + function task3() { + document.body.removeChild(document.body.lastChild); + + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "deref() should return undefined."); + is(wr2.deref(), undefined, "deref() should return undefined."); + is(wr3.deref(), undefined, "deref() should return undefined."); + is(wr4.deref(), undefined, "deref() should return undefined."); + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html new file mode 100644 index 0000000000..c7af313d96 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRefs with DOM wrappers that get cycle collected</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + let weakrefs = []; + + function go() { + SimpleTest.waitForExplicitFinish(); + + // 1. nsISupports-derived object. + let doc = document.implementation.createHTMLDocument(); + weakrefs.push(new WeakRef(doc)); + + // 2. non-nsISupports-derived object. + let buffer = new AudioBuffer({length: 1, sampleRate: 8000}); + weakrefs.push(new WeakRef(buffer)); + + // 3. nsISupports non-wrapper-cached object. + let image = new ImageData(1, 1); + weakrefs.push(new WeakRef(image)); + + // 4. non-nsISupports non-wrapper-cached object. + let iterator = document.fonts.values(); + weakrefs.push(new WeakRef(iterator)); + + for (let wr of weakrefs) { + isnot(wr.deref(), undefined, "Check that live wrapper is returned"); + } + + // setTimeout will call its callback in a new task. + setTimeout(task2, 0); + } + + function task2() { + // Trigger a GC and CC to collect the DOM objects, but no GC to + // collect the wrappers. + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.cycleCollect(); + + for (let wr of weakrefs) { + is(wr.deref(), undefined, "Check that stale wrapper is not exposed"); + } + + SimpleTest.finish(); + } + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html new file mode 100644 index 0000000000..87e509b535 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test WeakRef works when target is in different compartment in the browser</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript"> + function go() { + SimpleTest.waitForExplicitFinish(); + + let Cu = SpecialPowers.Cu; + let isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment; + + // Open a new window, which will be from different compartment. + let win = window.open(); + is(isSameCompartment(win, window), false, + "Test for opeing a window from a different compartment."); + + let wr1, wr2, wr3; + { + let obj = {}; + + // WeakRef and target are both from different compartment. + wr1 = new win.WeakRef(new win.Object()); + + // WeakRef is same compartment, but target isn't. + wr2 = new WeakRef(new win.Object()); + + // WeakRef is in different compartment, but target is. + wr3 = new win.WeakRef(obj); + + obj = null; + } + + // WeakRef should keep the target in the current task. + isnot(wr1.deref(), undefined, "wr1.deref() should return its target."); + isnot(wr2.deref(), undefined, "wr2.deref() should return its target."); + isnot(wr3.deref(), undefined, "we3.deref() should return its target."); + + // Weakref should keep the target until the end of current Job, that + // includes microtask(Promise). + Promise.resolve().then(() => { + isnot(wr1.deref(), undefined, + "wr1.deref() should return its target in promise"); + isnot(wr2.deref(), undefined, + "wr2.deref() should return its target in promise"); + isnot(wr3.deref(), undefined, + "wr3.deref() should return its target in promise"); + }); + + // setTimeout will launch a new job and call ClearKeptObjects(). + setTimeout(() => { + // Call gc() forcibly to clear the target of wr. + SpecialPowers.DOMWindowUtils.garbageCollect(); + + is(wr1.deref(), undefined, "wr1.deref() should return undefined in the new job."); + is(wr2.deref(), undefined, "wr2.deref() should return undefined in the new job."); + is(wr3.deref(), undefined, "wr3.deref() should return undefined in the new job."); + + win.close(); + SimpleTest.finish(); + }, 0); + } + + </script> + </head> + <body onload="go()"></body> +</html> diff --git a/js/xpconnect/tests/mochitest/test_weakmaps.html b/js/xpconnect/tests/mochitest/test_weakmaps.html new file mode 100644 index 0000000000..5e00106fed --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakmaps.html @@ -0,0 +1,264 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=668855 +--> +<head> + <meta charset="utf-8"> + <title>Test Cross-Compartment DOM WeakMaps</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<script type="application/javascript"> + /** Test for Bug 668855 **/ + + SimpleTest.waitForExplicitFinish(); + +// We wait to run this until the load event because it needs to access an element. +function go() { + + /* Create a weak reference, with a single-element weak map. */ + let make_weak_ref = function (obj) { + let m = new WeakMap; + m.set(obj, {}); + return m; + }; + + /* Check to see if a weak reference is dead. */ + let weak_ref_dead = function (r) { + return SpecialPowers.nondeterministicGetWeakMapKeys(r).length == 0; + } + + /* Deterministically grab an arbitrary DOM element. */ + let get_live_dom = function () { + let elems = document.getElementsByTagName("a"); + return elems[0]; + }; + + + /* Test case from bug 653248, adapted into a standard test. + + This is a dead cycle involving a DOM edge, so the cycle collector can free it. Keys and + values reachable only from XPConnect must be marked gray for this to work, and the cycle collector + must know the proper structure of the heap. + + */ + let make_gray_loop = function () { + let map = new WeakMap; + let div = document.createElement("div"); + let key = {}; + let obj = {m:map, k:key}; + div.addEventListener("foo", function() { + // The code below doesn't matter (it won't run). Just pull a + // reference to obj. + obj.k = 1; + obj.m = "bar"; + }); + //div.entrain = {m:map, k:key}; This is not sufficient to cause a leak in Fx9 + map.set(key, div); + return make_weak_ref(map); + }; + + let weakref = make_gray_loop(); + + + /* Combinations of live and dead gray maps/keys. */ + let basic_weak_ref = null; + let basic_map_weak_ref = null; + let black_map = new WeakMap; + let black_key = {}; + + let basic_unit_tests = function () { + let live_dom = get_live_dom(); + let dead_dom = document.createElement("div"); + let live_map = new WeakMap; + let dead_map = new WeakMap; + let live_key = {}; + let dead_key = {}; + + // put the live/dead maps/keys into the appropriate DOM elements + live_dom.basic_unit_tests = {m:live_map, k:live_key}; + + let obj = {m:dead_map, k:dead_key}; + // dead_dom.hook = {m:dead_map, k:dead_key}; + dead_dom.addEventListener("foo", function() { + // The code below doesn't matter (it won't run). Just pull a + // reference to obj. + obj.m = 1; + obj.k = "2"; + }); + + // Create a dead value, and a weak ref to it. + // The loop keeps dead_dom alive unless the CC is smart enough to kill it. + let dead_val = {loop:dead_dom}; + basic_weak_ref = make_weak_ref(dead_val); + basic_map_weak_ref = make_weak_ref(dead_map); + + // set up the actual entries. most will die. + live_map.set(live_key, {my_key:'live_live'}); + live_map.set(dead_key, dead_val); + live_map.set(black_key, {my_key:'live_black'}); + + dead_map.set(live_key, dead_val); + dead_map.set(dead_key, dead_val); + dead_map.set(black_key, dead_val); + + black_map.set(live_key, {my_key:'black_live'}); + black_map.set(dead_key, dead_val); + black_map.set(black_key, {my_key:'black_black'}); + + }; + + basic_unit_tests(); + + + let check_basic_unit = function () { + let live_dom = get_live_dom(); + let live_map = live_dom.basic_unit_tests.m; + let live_key = live_dom.basic_unit_tests.k; + + // check the dead elements + ok(weak_ref_dead(basic_weak_ref), "Dead value was kept alive."); + ok(weak_ref_dead(basic_map_weak_ref), "Dead map was kept alive."); + + // check the live gray map + is(live_map.get(live_key).my_key, 'live_live', + "Live key should have the same value in live map."); + is(live_map.get(black_key).my_key, 'live_black', + "Black key should have the same value in live map."); + is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2, + "Live map should have two entries."); + + // check the live black map + is(black_map.get(live_key).my_key, 'black_live', + "Live key should have the same value in black map."); + is(black_map.get(black_key).my_key, 'black_black', + "Black key should have the same value in black map."); + is(SpecialPowers.nondeterministicGetWeakMapKeys(black_map).length, 2, + "Black map should have two entries."); + + }; + + + /* live gray chained weak map entries, involving the cycle collector. */ + let chainm = new WeakMap; + let num_chains = 5; + + let nested_cc_maps = function () { + let dom = get_live_dom(); + for(let i = 0; i < num_chains; i++) { + let k = {count:i}; + dom.key = k; + dom0 = document.createElement("div"); + chainm.set(k, {d:dom0}); + dom = document.createElement("div"); + dom0.appendChild(dom); + }; + }; + + let check_nested_cc_maps = function () { + let dom = get_live_dom(); + let all_ok = true; + for(let i = 0; i < num_chains; i++) { + let k = dom.key; + all_ok = all_ok && k.count == i; + dom = chainm.get(k).d.firstChild; + }; + ok(all_ok, "Count was invalid on a key in chained weak map entries."); + }; + + nested_cc_maps(); + + + /* black weak map, chained garbage cycle involving DOM */ + let garbage_map = new WeakMap; + + let chained_garbage_maps = function () { + let dom0 = document.createElement("div"); + let dom = dom0; + for(let i = 0; i < num_chains; i++) { + let k = {}; + dom.key = k; + let new_dom = document.createElement("div"); + garbage_map.set(k, {val_child:new_dom}); + dom = document.createElement("div"); + new_dom.appendChild(dom); + }; + // tie the knot + dom.appendChild(dom0); + }; + + chained_garbage_maps(); + + + /* black weak map, chained garbage cycle involving DOM, XPCWN keys */ + let wn_garbage_map = new WeakMap; + + let wn_chained_garbage_maps = function () { + let dom0 = document.createElement("div"); + let dom = dom0; + for(let i = 0; i < num_chains; i++) { + let new_dom = document.createElement("div"); + wn_garbage_map.set(dom, {wn_val_child:new_dom}); + dom = document.createElement("div"); + new_dom.appendChild(dom); + }; + // tie the knot + dom.appendChild(dom0); + }; + + wn_chained_garbage_maps(); + + + /* The cycle collector shouldn't remove a live wrapped native key. */ + + let wn_live_map = new WeakMap; + + let make_live_map = function () { + let live = get_live_dom(); + wn_live_map.set(live, {}); + ok(wn_live_map.has(get_live_dom()), "Live map should have live DOM node before GC."); + } + + make_live_map(); + + // We're out of ideas for unpreservable natives, now that just about + // everything is on webidl, so just don't test those. + + /* set up for running precise GC/CC then checking the results */ + + SpecialPowers.exactGC(function () { + SpecialPowers.forceCC(); + SpecialPowers.forceGC(); + SpecialPowers.forceGC(); + + ok(weak_ref_dead(weakref), "Garbage gray cycle should be collected."); + + check_nested_cc_maps(); + + is(SpecialPowers.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak."); + + check_basic_unit(); + + // fixed by Bug 680937 + is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0, + "Chained garbage WN weak map entries should not leak."); + + // fixed by Bug 680937 + is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_live_map).length, 1, + "Live weak map wrapped native key should not be removed."); + + ok(wn_live_map.has(get_live_dom()), "Live map should have live dom."); + + SimpleTest.finish(); + }); + +} + </script> +</head> +<div></div> +<div id="mydivname"></div> +<body onload="go()";> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=668855" target="_blank">Mozilla Bug 668855</a> +<p id="display"></p> +</body> +</html> diff --git a/js/xpconnect/tests/moz.build b/js/xpconnect/tests/moz.build new file mode 100644 index 0000000000..c61dc8da02 --- /dev/null +++ b/js/xpconnect/tests/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +TEST_DIRS += [ + "mochitest", + "chrome", + "browser", + "components/native", +] + +if CONFIG["COMPILE_ENVIRONMENT"]: + TEST_DIRS += [ + "idl", + ] + +XPCSHELL_TESTS_MANIFESTS += [ + "unit/xpcshell.ini", +] diff --git a/js/xpconnect/tests/unit/CatBackgroundTaskRegistrationComponents.manifest b/js/xpconnect/tests/unit/CatBackgroundTaskRegistrationComponents.manifest new file mode 100644 index 0000000000..7bc3763da9 --- /dev/null +++ b/js/xpconnect/tests/unit/CatBackgroundTaskRegistrationComponents.manifest @@ -0,0 +1,4 @@ +category test-cat1 Cat1RegisteredComponent @unit.test.com/cat1-registered-component;1 +category test-cat1 Cat1BackgroundTaskRegisteredComponent @unit.test.com/cat1-backgroundtask-registered-component;1 backgroundtask +category test-cat1 Cat1BackgroundTaskAlwaysRegisteredComponent @unit.test.com/cat1-backgroundtask-alwaysregistered-component;1 backgroundtask=1 +category test-cat1 Cat1BackgroundTaskNotRegisteredComponent @unit.test.com/cat1-backgroundtask-notregistered-component;1 backgroundtask=0 diff --git a/js/xpconnect/tests/unit/CatRegistrationComponents.manifest b/js/xpconnect/tests/unit/CatRegistrationComponents.manifest new file mode 100644 index 0000000000..11646b0282 --- /dev/null +++ b/js/xpconnect/tests/unit/CatRegistrationComponents.manifest @@ -0,0 +1,2 @@ +category test-cat CatRegisteredComponent @unit.test.com/cat-registered-component;1
+category test-cat CatAppRegisteredComponent @unit.test.com/cat-app-registered-component;1 application={adb42a9a-0d19-4849-bf4d-627614ca19be}
diff --git a/js/xpconnect/tests/unit/ReturnCodeChild.jsm b/js/xpconnect/tests/unit/ReturnCodeChild.jsm new file mode 100644 index 0000000000..bf74453969 --- /dev/null +++ b/js/xpconnect/tests/unit/ReturnCodeChild.jsm @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var EXPORTED_SYMBOLS = ["ReturnCodeChild"]; + +function xpcWrap(obj, iface) { + let ifacePointer = Cc[ + "@mozilla.org/supports-interface-pointer;1" + ].createInstance(Ci.nsISupportsInterfacePointer); + + ifacePointer.data = obj; + return ifacePointer.data.QueryInterface(iface); +} + +var ReturnCodeChild = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestReturnCodeChild"]), + + doIt(behaviour) { + switch (behaviour) { + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_THROW: + throw(new Error("a requested error")); + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_SUCCESS: + return; + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_RESULTCODE: + Components.returnCode = Cr.NS_ERROR_FAILURE; + return; + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_NEST_RESULTCODES: + // Use xpconnect to create another instance of *this* component and + // call that. This way we have crossed the xpconnect bridge twice. + + // We set *our* return code early - this should be what is returned + // to our caller, even though our "inner" component will set it to + // a different value that we will see (but our caller should not) + Components.returnCode = Cr.NS_ERROR_UNEXPECTED; + // call the child asking it to do the .returnCode set. + let sub = xpcWrap(ReturnCodeChild, Ci.nsIXPCTestReturnCodeChild); + let childResult = Cr.NS_OK; + try { + sub.doIt(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_RESULTCODE); + } catch (ex) { + childResult = ex.result; + } + // write it to the console so the test can check it. + let consoleService = Cc["@mozilla.org/consoleservice;1"] + .getService(Ci.nsIConsoleService); + consoleService.logStringMessage("nested child returned " + childResult); + return; + } + } +}; diff --git a/js/xpconnect/tests/unit/ReturnCodeChild.sys.mjs b/js/xpconnect/tests/unit/ReturnCodeChild.sys.mjs new file mode 100644 index 0000000000..4d3120da33 --- /dev/null +++ b/js/xpconnect/tests/unit/ReturnCodeChild.sys.mjs @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function xpcWrap(obj, iface) { + let ifacePointer = Cc[ + "@mozilla.org/supports-interface-pointer;1" + ].createInstance(Ci.nsISupportsInterfacePointer); + + ifacePointer.data = obj; + return ifacePointer.data.QueryInterface(iface); +} + +export var ReturnCodeChild = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestReturnCodeChild"]), + + doIt(behaviour) { + switch (behaviour) { + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_THROW: + throw(new Error("a requested error")); + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_SUCCESS: + return; + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_RESULTCODE: + Components.returnCode = Cr.NS_ERROR_FAILURE; + return; + case Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_NEST_RESULTCODES: + // Use xpconnect to create another instance of *this* component and + // call that. This way we have crossed the xpconnect bridge twice. + + // We set *our* return code early - this should be what is returned + // to our caller, even though our "inner" component will set it to + // a different value that we will see (but our caller should not) + Components.returnCode = Cr.NS_ERROR_UNEXPECTED; + // call the child asking it to do the .returnCode set. + let sub = xpcWrap(ReturnCodeChild, Ci.nsIXPCTestReturnCodeChild); + let childResult = Cr.NS_OK; + try { + sub.doIt(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_RESULTCODE); + } catch (ex) { + childResult = ex.result; + } + // write it to the console so the test can check it. + let consoleService = Cc["@mozilla.org/consoleservice;1"] + .getService(Ci.nsIConsoleService); + consoleService.logStringMessage("nested child returned " + childResult); + return; + } + } +}; diff --git a/js/xpconnect/tests/unit/TestBlob.jsm b/js/xpconnect/tests/unit/TestBlob.jsm new file mode 100644 index 0000000000..7d67963dd6 --- /dev/null +++ b/js/xpconnect/tests/unit/TestBlob.jsm @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var EXPORTED_SYMBOLS = ["TestBlob"]; + +const Assert = { + ok(cond, text) { + // we don't have the test harness' utilities in this scope, so we need this + // little helper. In the failure case, the exception is propagated to the + // caller in the main run_test() function, and the test fails. + if (!cond) + throw "Failed check: " + text; + } +}; + +var TestBlob = { + doTest: function() { + // throw if anything goes wrong + let testContent = "<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>"; + // should be able to construct a file + var f1 = new Blob([testContent], {"type" : "text/xml"}); + + // do some tests + Assert.ok(f1 instanceof Blob, "Should be a DOM Blob"); + + Assert.ok(!(f1 instanceof File), "Should not be a DOM File"); + + Assert.ok(f1.type == "text/xml", "Wrong type"); + + Assert.ok(f1.size == testContent.length, "Wrong content size"); + + var f2 = new Blob(); + Assert.ok(f2.size == 0, "Wrong size"); + Assert.ok(f2.type == "", "Wrong type"); + + var threw = false; + try { + // Needs a valid ctor argument + var f2 = new Blob(Date(132131532)); + } catch (e) { + threw = true; + } + Assert.ok(threw, "Passing a random object should fail"); + + return true; + }, +}; diff --git a/js/xpconnect/tests/unit/TestFile.jsm b/js/xpconnect/tests/unit/TestFile.jsm new file mode 100644 index 0000000000..01f07edb7c --- /dev/null +++ b/js/xpconnect/tests/unit/TestFile.jsm @@ -0,0 +1,78 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var EXPORTED_SYMBOLS = ["TestFile"]; + +const Assert = { + ok(cond, text) { + // we don't have the test harness' utilities in this scope, so we need this + // little helper. In the failure case, the exception is propagated to the + // caller in the main run_test() function, and the test fails. + if (!cond) + throw "Failed check: " + text; + } +}; + +var TestFile = { + doTest: function(cb) { + // throw if anything goes wrong + + // find the current directory path + var file = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + file.append("xpcshell.ini"); + + // should be able to construct a file + var f1, f2; + Promise.all([ + File.createFromFileName(file.path).then(f => { f1 = f; }), + File.createFromNsIFile(file).then(f => { f2 = f; }), + ]) + .then(() => { + // do some tests + Assert.ok(f1 instanceof File, "Should be a DOM File"); + Assert.ok(f2 instanceof File, "Should be a DOM File"); + + Assert.ok(f1.name == "xpcshell.ini", "Should be the right file"); + Assert.ok(f2.name == "xpcshell.ini", "Should be the right file"); + + Assert.ok(f1.type == "", "Should be the right type"); + Assert.ok(f2.type == "", "Should be the right type"); + }) + .then(() => { + var threw = false; + try { + // Needs a ctor argument + var f7 = new File(); + } catch (e) { + threw = true; + } + Assert.ok(threw, "No ctor arguments should throw"); + + var threw = false; + try { + // Needs a valid ctor argument + var f7 = new File(Date(132131532)); + } catch (e) { + threw = true; + } + Assert.ok(threw, "Passing a random object should fail"); + + // Directories fail + var dir = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + return File.createFromNsIFile(dir) + }) + .then(() => { + Assert.ok(false, "Can't create a File object for a directory"); + }, () => { + Assert.ok(true, "Can't create a File object for a directory"); + }) + .then(() => { + cb(true); + }); + }, +}; diff --git a/js/xpconnect/tests/unit/api_script.js b/js/xpconnect/tests/unit/api_script.js new file mode 100644 index 0000000000..de4a0a6b59 --- /dev/null +++ b/js/xpconnect/tests/unit/api_script.js @@ -0,0 +1,26 @@ +"use strict"; + +// This is a test script similar to those used by ExtensionAPIs. +// https://searchfox.org/mozilla-central/source/toolkit/components/extensions/parent + +let module3, module4; + +// This should work across ESR 102 and Firefox 103+. +if (ChromeUtils.importESModule) { + module3 = ChromeUtils.importESModule("resource://test/esmified-3.sys.mjs"); + module4 = ChromeUtils.importESModule("resource://test/esmified-4.sys.mjs"); +} else { + module3 = ChromeUtils.import("resource://test/esmified-3.jsm"); + module4 = ChromeUtils.import("resource://test/esmified-4.jsm"); +} + +injected3.obj.value += 3; +module3.obj.value += 3; +module4.obj.value += 4; + +this.testResults = { + injected3: injected3.obj.value, + module3: module3.obj.value, + sameInstance3: injected3 === module3, + module4: module4.obj.value, +}; diff --git a/js/xpconnect/tests/unit/bogus_element_type.jsm b/js/xpconnect/tests/unit/bogus_element_type.jsm new file mode 100644 index 0000000000..882ca56809 --- /dev/null +++ b/js/xpconnect/tests/unit/bogus_element_type.jsm @@ -0,0 +1 @@ +var EXPORTED_SYMBOLS = [{}]; diff --git a/js/xpconnect/tests/unit/bogus_exports_type.jsm b/js/xpconnect/tests/unit/bogus_exports_type.jsm new file mode 100644 index 0000000000..4b306e4e89 --- /dev/null +++ b/js/xpconnect/tests/unit/bogus_exports_type.jsm @@ -0,0 +1 @@ +var EXPORTED_SYMBOLS = "not an array"; diff --git a/js/xpconnect/tests/unit/bug451678_subscript.js b/js/xpconnect/tests/unit/bug451678_subscript.js new file mode 100644 index 0000000000..72ff49a2d6 --- /dev/null +++ b/js/xpconnect/tests/unit/bug451678_subscript.js @@ -0,0 +1,5 @@ +var tags = [];
+function makeTags() {}
+
+// This will be the return value of the script.
+42
diff --git a/js/xpconnect/tests/unit/envChain.jsm b/js/xpconnect/tests/unit/envChain.jsm new file mode 100644 index 0000000000..c60b032fcc --- /dev/null +++ b/js/xpconnect/tests/unit/envChain.jsm @@ -0,0 +1,20 @@ +var qualified = 10; +// NOTE: JSM cannot have unqualified name. +let lexical = 30; +this.prop = 40; + +const funcs = Cu.getJSTestingFunctions(); +const envs = []; +let env = funcs.getInnerMostEnvironmentObject(); +while (env) { + envs.push({ + type: funcs.getEnvironmentObjectType(env) || "*BackstagePass*", + qualified: !!Object.getOwnPropertyDescriptor(env, "qualified"), + prop: !!Object.getOwnPropertyDescriptor(env, "prop"), + lexical: !!Object.getOwnPropertyDescriptor(env, "lexical"), + }); + + env = funcs.getEnclosingEnvironmentObject(env); +} + +const EXPORTED_SYMBOLS = ["envs"]; diff --git a/js/xpconnect/tests/unit/envChain_subscript.jsm b/js/xpconnect/tests/unit/envChain_subscript.jsm new file mode 100644 index 0000000000..473f6eb2d9 --- /dev/null +++ b/js/xpconnect/tests/unit/envChain_subscript.jsm @@ -0,0 +1,27 @@ +const target = {}; +Services.scriptloader.loadSubScript(`data:, +var qualified = 10; +unqualified = 20; +let lexical = 30; +this.prop = 40; + +const funcs = Cu.getJSTestingFunctions(); +const envs = []; +let env = funcs.getInnerMostEnvironmentObject(); +while (env) { + envs.push({ + type: funcs.getEnvironmentObjectType(env) || "*BackstagePass*", + qualified: !!Object.getOwnPropertyDescriptor(env, "qualified"), + unqualified: !!Object.getOwnPropertyDescriptor(env, "unqualified"), + lexical: !!Object.getOwnPropertyDescriptor(env, "lexical"), + prop: !!Object.getOwnPropertyDescriptor(env, "prop"), + }); + + env = funcs.getEnclosingEnvironmentObject(env); +} + +this.ENVS = envs; +`, target); + +const envs = target.ENVS; +const EXPORTED_SYMBOLS = ["envs"]; diff --git a/js/xpconnect/tests/unit/environment_checkscript.jsm b/js/xpconnect/tests/unit/environment_checkscript.jsm new file mode 100644 index 0000000000..b4dc452b8e --- /dev/null +++ b/js/xpconnect/tests/unit/environment_checkscript.jsm @@ -0,0 +1,13 @@ +var EXPORTED_SYMBOLS = ["bound"]; + +var bound = ""; + +try { void vu; bound += "vu,"; } catch (e) {} +try { void vq; bound += "vq,"; } catch (e) {} +try { void vl; bound += "vl,"; } catch (e) {} +try { void gt; bound += "gt,"; } catch (e) {} +try { void ed; bound += "ed,"; } catch (e) {} +try { void ei; bound += "ei,"; } catch (e) {} +try { void fo; bound += "fo,"; } catch (e) {} +try { void fi; bound += "fi,"; } catch (e) {} +try { void fd; bound += "fd,"; } catch (e) {} diff --git a/js/xpconnect/tests/unit/environment_loadscript.jsm b/js/xpconnect/tests/unit/environment_loadscript.jsm new file mode 100644 index 0000000000..0e5a0208ae --- /dev/null +++ b/js/xpconnect/tests/unit/environment_loadscript.jsm @@ -0,0 +1,16 @@ +var EXPORTED_SYMBOLS = ["target", "bound"]; + +var bound = ""; +var target = {}; +Services.scriptloader.loadSubScript("resource://test/environment_script.js", target); + +// Check global bindings +try { void vu; bound += "vu,"; } catch (e) {} +try { void vq; bound += "vq,"; } catch (e) {} +try { void vl; bound += "vl,"; } catch (e) {} +try { void gt; bound += "gt,"; } catch (e) {} +try { void ed; bound += "ed,"; } catch (e) {} +try { void ei; bound += "ei,"; } catch (e) {} +try { void fo; bound += "fo,"; } catch (e) {} +try { void fi; bound += "fi,"; } catch (e) {} +try { void fd; bound += "fd,"; } catch (e) {} diff --git a/js/xpconnect/tests/unit/environment_script.js b/js/xpconnect/tests/unit/environment_script.js new file mode 100644 index 0000000000..18490541ad --- /dev/null +++ b/js/xpconnect/tests/unit/environment_script.js @@ -0,0 +1,14 @@ +let strict = (function() { return this; })() === undefined; + +// Allow this to be used as a JSM +var EXPORTED_SYMBOLS = []; + +if (!strict) vu = 1; // Unqualified Variable +var vq = 2; // Qualified Variable +let vl = 3; // Lexical +this.gt = 4; // Global This +eval("this.ed = 5"); // Direct Eval +(1,eval)("this.ei = 6"); // Indirect Eval +(new Function("this.fo = 7"))(); // Dynamic Function Object +if (!strict) (function() { this.fi = 8; })(); // Indirect Function This +function fd_() { this.fd = 9; }; if (!strict) fd_(); // Direct Function Implicit diff --git a/js/xpconnect/tests/unit/error_export.sys.mjs b/js/xpconnect/tests/unit/error_export.sys.mjs new file mode 100644 index 0000000000..7f0f1ec979 --- /dev/null +++ b/js/xpconnect/tests/unit/error_export.sys.mjs @@ -0,0 +1,2 @@ +export function something() { +} diff --git a/js/xpconnect/tests/unit/error_import.sys.mjs b/js/xpconnect/tests/unit/error_import.sys.mjs new file mode 100644 index 0000000000..2bbeef5da2 --- /dev/null +++ b/js/xpconnect/tests/unit/error_import.sys.mjs @@ -0,0 +1 @@ +import { something } from "./something.sys.mjs"; diff --git a/js/xpconnect/tests/unit/error_other.sys.mjs b/js/xpconnect/tests/unit/error_other.sys.mjs new file mode 100644 index 0000000000..f6d220f17e --- /dev/null +++ b/js/xpconnect/tests/unit/error_other.sys.mjs @@ -0,0 +1 @@ +a = diff --git a/js/xpconnect/tests/unit/es6import.js b/js/xpconnect/tests/unit/es6import.js new file mode 100644 index 0000000000..79d76849fd --- /dev/null +++ b/js/xpconnect/tests/unit/es6import.js @@ -0,0 +1 @@ +export let value = 1; diff --git a/js/xpconnect/tests/unit/es6module.js b/js/xpconnect/tests/unit/es6module.js new file mode 100644 index 0000000000..a160895a01 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module.js @@ -0,0 +1,6 @@ +export let loadCount = 0; +loadCount++; + +export let value = 0; +import {value as importedValue} from "./es6import.js"; +value = importedValue + 1; diff --git a/js/xpconnect/tests/unit/es6module_absolute.js b/js/xpconnect/tests/unit/es6module_absolute.js new file mode 100644 index 0000000000..d74732d296 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_absolute.js @@ -0,0 +1,4 @@ +import { x as x1 } from "resource://test/es6module_absolute2.js"; +import { x as x2 } from "./es6module_absolute2.js"; +export const absoluteX = x1; +export const relativeX = x2; diff --git a/js/xpconnect/tests/unit/es6module_absolute2.js b/js/xpconnect/tests/unit/es6module_absolute2.js new file mode 100644 index 0000000000..d9d1342a3f --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_absolute2.js @@ -0,0 +1 @@ +export const x = { value: 10 }; diff --git a/js/xpconnect/tests/unit/es6module_cycle_a.js b/js/xpconnect/tests/unit/es6module_cycle_a.js new file mode 100644 index 0000000000..62e88d17e2 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_cycle_a.js @@ -0,0 +1,9 @@ +export const name = "a"; + +import { name as bName } from "./es6module_cycle_b.js"; + +export let loaded = true; + +export function getValueFromB() { + return bName; +} diff --git a/js/xpconnect/tests/unit/es6module_cycle_b.js b/js/xpconnect/tests/unit/es6module_cycle_b.js new file mode 100644 index 0000000000..32725f0f0a --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_cycle_b.js @@ -0,0 +1,9 @@ +export const name = "b"; + +import { name as cName } from "./es6module_cycle_c.js"; + +export let loaded = true; + +export function getValueFromC() { + return cName; +} diff --git a/js/xpconnect/tests/unit/es6module_cycle_c.js b/js/xpconnect/tests/unit/es6module_cycle_c.js new file mode 100644 index 0000000000..2fd2f6e3eb --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_cycle_c.js @@ -0,0 +1,9 @@ +export const name = "c"; + +import { name as aName } from "./es6module_cycle_a.js"; + +export let loaded = true; + +export function getValueFromA() { + return aName; +} diff --git a/js/xpconnect/tests/unit/es6module_devtoolsLoader.js b/js/xpconnect/tests/unit/es6module_devtoolsLoader.js new file mode 100644 index 0000000000..30e4f13863 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_devtoolsLoader.js @@ -0,0 +1 @@ +export const object = { uniqueObjectPerLoader: true }; diff --git a/js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs b/js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs new file mode 100644 index 0000000000..c7de54c82f --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs @@ -0,0 +1,29 @@ +export let x = 0; + +export function increment() { + x++; +}; + +import { object } from "resource://test/es6module_devtoolsLoader.js"; +export const importedObject = object; + +const importTrue = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", { loadInDevToolsLoader : true }); +export const importESModuleTrue = importTrue.object; + +const importFalse = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", { loadInDevToolsLoader : false }); +export const importESModuleFalse = importFalse.object; + +const importNull = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", {}); +export const importESModuleNull = importNull.object; + +const importNull2 = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js"); +export const importESModuleNull2 = importNull2.object; + +const lazy = {}; +ChromeUtils.defineESModuleGetters(lazy, { + object: "resource://test/es6module_devtoolsLoader.js", +}); + +export function importLazy() { + return lazy.object; +} diff --git a/js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js b/js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js new file mode 100644 index 0000000000..4d995c5cfb --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js @@ -0,0 +1 @@ +export const object = { onlyLoadedFromDevToolsModule: true }; diff --git a/js/xpconnect/tests/unit/es6module_dynamic_import.js b/js/xpconnect/tests/unit/es6module_dynamic_import.js new file mode 100644 index 0000000000..17a2f41802 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_dynamic_import.js @@ -0,0 +1,7 @@ +let resolve; + +export const result = new Promise(r => { resolve = r; }); + +import("./es6module_dynamic_import2.js").then(ns => {}, e => { + resolve(e); +}); diff --git a/js/xpconnect/tests/unit/es6module_dynamic_import2.js b/js/xpconnect/tests/unit/es6module_dynamic_import2.js new file mode 100644 index 0000000000..abc62eff40 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_dynamic_import2.js @@ -0,0 +1 @@ +export const x = 10; diff --git a/js/xpconnect/tests/unit/es6module_import_error.js b/js/xpconnect/tests/unit/es6module_import_error.js new file mode 100644 index 0000000000..e590d0a450 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_import_error.js @@ -0,0 +1 @@ +import { y } from "./es6module_import_error2.js"; diff --git a/js/xpconnect/tests/unit/es6module_import_error2.js b/js/xpconnect/tests/unit/es6module_import_error2.js new file mode 100644 index 0000000000..abc62eff40 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_import_error2.js @@ -0,0 +1 @@ +export const x = 10; diff --git a/js/xpconnect/tests/unit/es6module_loaded-1.sys.mjs b/js/xpconnect/tests/unit/es6module_loaded-1.sys.mjs new file mode 100644 index 0000000000..e405565d6f --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_loaded-1.sys.mjs @@ -0,0 +1 @@ +export function test() {} diff --git a/js/xpconnect/tests/unit/es6module_loaded-2.sys.mjs b/js/xpconnect/tests/unit/es6module_loaded-2.sys.mjs new file mode 100644 index 0000000000..e405565d6f --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_loaded-2.sys.mjs @@ -0,0 +1 @@ +export function test() {} diff --git a/js/xpconnect/tests/unit/es6module_loaded-3.sys.mjs b/js/xpconnect/tests/unit/es6module_loaded-3.sys.mjs new file mode 100644 index 0000000000..e405565d6f --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_loaded-3.sys.mjs @@ -0,0 +1 @@ +export function test() {} diff --git a/js/xpconnect/tests/unit/es6module_missing_import.js b/js/xpconnect/tests/unit/es6module_missing_import.js new file mode 100644 index 0000000000..df79b6a0b7 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_missing_import.js @@ -0,0 +1 @@ +import { name } from "./es6module_not_found2.js"; diff --git a/js/xpconnect/tests/unit/es6module_parse_error.js b/js/xpconnect/tests/unit/es6module_parse_error.js new file mode 100644 index 0000000000..3128787ba4 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_parse_error.js @@ -0,0 +1 @@ +this is not valid JS diff --git a/js/xpconnect/tests/unit/es6module_parse_error_in_import.js b/js/xpconnect/tests/unit/es6module_parse_error_in_import.js new file mode 100644 index 0000000000..14f057ebe1 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_parse_error_in_import.js @@ -0,0 +1 @@ +import { name } from "./es6module_parse_error.js"; diff --git a/js/xpconnect/tests/unit/es6module_throws.js b/js/xpconnect/tests/unit/es6module_throws.js new file mode 100644 index 0000000000..c3ca94b6eb --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_throws.js @@ -0,0 +1,4 @@ +function throwFunction() { + throw new Error("Failing with error foobar"); +} +throwFunction(); diff --git a/js/xpconnect/tests/unit/es6module_top_level_await.js b/js/xpconnect/tests/unit/es6module_top_level_await.js new file mode 100644 index 0000000000..7377aacb35 --- /dev/null +++ b/js/xpconnect/tests/unit/es6module_top_level_await.js @@ -0,0 +1 @@ +await 1; diff --git a/js/xpconnect/tests/unit/esm_lazy-1.sys.mjs b/js/xpconnect/tests/unit/esm_lazy-1.sys.mjs new file mode 100644 index 0000000000..a995420a56 --- /dev/null +++ b/js/xpconnect/tests/unit/esm_lazy-1.sys.mjs @@ -0,0 +1,4 @@ +export let X = 10; +function GetX() { + return X; +} diff --git a/js/xpconnect/tests/unit/esm_lazy-2.sys.mjs b/js/xpconnect/tests/unit/esm_lazy-2.sys.mjs new file mode 100644 index 0000000000..49410b6187 --- /dev/null +++ b/js/xpconnect/tests/unit/esm_lazy-2.sys.mjs @@ -0,0 +1,4 @@ +export let Y = 20; +export function AddY(n) { + Y += n; +}; diff --git a/js/xpconnect/tests/unit/esmified-1.sys.mjs b/js/xpconnect/tests/unit/esmified-1.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-1.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-2.sys.mjs b/js/xpconnect/tests/unit/esmified-2.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-2.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-3.sys.mjs b/js/xpconnect/tests/unit/esmified-3.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-3.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-4.sys.mjs b/js/xpconnect/tests/unit/esmified-4.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-4.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-5.sys.mjs b/js/xpconnect/tests/unit/esmified-5.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-5.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-6.sys.mjs b/js/xpconnect/tests/unit/esmified-6.sys.mjs new file mode 100644 index 0000000000..0f7a1da661 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-6.sys.mjs @@ -0,0 +1,4 @@ +export let loadCount = 0; +loadCount++; + +export const obj = { value: 10 }; diff --git a/js/xpconnect/tests/unit/esmified-not-exported.sys.mjs b/js/xpconnect/tests/unit/esmified-not-exported.sys.mjs new file mode 100644 index 0000000000..e4ae8c0815 --- /dev/null +++ b/js/xpconnect/tests/unit/esmified-not-exported.sys.mjs @@ -0,0 +1,13 @@ +export var exportedVar = "exported var"; +export function exportedFunction() { + return "exported function"; +} +export let exportedLet = "exported let"; +export const exportedConst = "exported const"; + +var notExportedVar = "not exported var"; +function notExportedFunction() { + return "not exported function"; +} +let notExportedLet = "not exported let"; +const notExportedConst = "not exported const"; diff --git a/js/xpconnect/tests/unit/file_simple_script.js b/js/xpconnect/tests/unit/file_simple_script.js new file mode 100644 index 0000000000..af20291400 --- /dev/null +++ b/js/xpconnect/tests/unit/file_simple_script.js @@ -0,0 +1 @@ +this.bar = ({foo: "®"}); diff --git a/js/xpconnect/tests/unit/frame.js b/js/xpconnect/tests/unit/frame.js new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/js/xpconnect/tests/unit/frame.js @@ -0,0 +1 @@ + diff --git a/js/xpconnect/tests/unit/head.js b/js/xpconnect/tests/unit/head.js new file mode 100644 index 0000000000..ca9a22bee8 --- /dev/null +++ b/js/xpconnect/tests/unit/head.js @@ -0,0 +1,15 @@ +"use strict"; + +// Wraps the given object in an XPConnect wrapper and, if an interface +// is passed, queries the result to that interface. +function xpcWrap(obj, iface) { + let ifacePointer = Cc[ + "@mozilla.org/supports-interface-pointer;1" + ].createInstance(Ci.nsISupportsInterfacePointer); + + ifacePointer.data = obj; + if (iface) { + return ifacePointer.data.QueryInterface(iface); + } + return ifacePointer.data; +} diff --git a/js/xpconnect/tests/unit/head_ongc.js b/js/xpconnect/tests/unit/head_ongc.js new file mode 100644 index 0000000000..146a15eb4f --- /dev/null +++ b/js/xpconnect/tests/unit/head_ongc.js @@ -0,0 +1,35 @@ +var {addDebuggerToGlobal, addSandboxedDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); + +const testingFunctions = Cu.getJSTestingFunctions(); +const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); + +function addTestingFunctionsToGlobal(global) { + for (let k in testingFunctions) { + global[k] = testingFunctions[k]; + } + global.print = info; + global.newGlobal = newGlobal; + addDebuggerToGlobal(global); +} + +function newGlobal() { + const global = new Cu.Sandbox(systemPrincipal, { freshZone: true }); + addTestingFunctionsToGlobal(global); + return global; +} + +addTestingFunctionsToGlobal(this); + +function executeSoon(f) { + Services.tm.dispatchToMainThread({ run: f }); +} + +// The onGarbageCollection tests don't play well gczeal settings and lead to +// intermittents. +if (typeof gczeal == "function") { + gczeal(0); +} + +// Make sure to GC before we start the test, so that no zones are scheduled for +// GC before we start testing onGarbageCollection hooks. +gc(); diff --git a/js/xpconnect/tests/unit/head_watchdog.js b/js/xpconnect/tests/unit/head_watchdog.js new file mode 100644 index 0000000000..f977c1f129 --- /dev/null +++ b/js/xpconnect/tests/unit/head_watchdog.js @@ -0,0 +1,116 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// +// Pref management. +// + +var {PromiseTestUtils} = ChromeUtils.importESModule("resource://testing-common/PromiseTestUtils.sys.mjs"); + +/////////////////// +// +// Whitelisting these tests. +// As part of bug 1077403, the shutdown crash should be fixed. +// +// These tests may crash intermittently on shutdown if the DOM Promise uncaught +// rejection observers are still registered when the watchdog operates. +PromiseTestUtils.thisTestLeaksUncaughtRejectionsAndShouldBeFixed(); + +var gPrefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + +function setWatchdogEnabled(enabled) { + gPrefs.setBoolPref("dom.use_watchdog", enabled); +} + +function isWatchdogEnabled() { + return gPrefs.getBoolPref("dom.use_watchdog"); +} + +function setScriptTimeout(seconds) { + var oldTimeout = gPrefs.getIntPref("dom.max_script_run_time"); + gPrefs.setIntPref("dom.max_script_run_time", seconds); + return oldTimeout; +} + +// +// Utilities. +// + +function busyWait(ms) { + var start = new Date(); + while ((new Date()) - start < ms) {} +} + +function do_log_info(aMessage) +{ + print("TEST-INFO | " + _TEST_FILE + " | " + aMessage); +} + +// We don't use do_execute_soon, because that inserts a +// do_test_{pending,finished} pair that gets screwed up when we terminate scripts +// from the operation callback. +function executeSoon(fn) { + var tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); + tm.dispatchToMainThread({run: fn}); +} + +// +// Asynchronous watchdog diagnostics. +// +// When running, the watchdog wakes up every second, and fires the operation +// callback if the script has been running for >= the minimum script timeout. +// As such, if the script timeout is 1 second, a script should never be able to +// run for two seconds or longer without servicing the operation callback. +// We wait 3 seconds, just to be safe. +// + +function checkWatchdog(expectInterrupt) { + var oldTimeout = setScriptTimeout(1); + var lastWatchdogWakeup = Cu.getWatchdogTimestamp("WatchdogWakeup"); + + return new Promise(resolve => { + let inBusyWait = false; + setInterruptCallback(function() { + // If the watchdog didn't actually trigger the operation callback, ignore + // this call. This allows us to test the actual watchdog behavior without + // interference from other sites where we trigger the operation callback. + if (lastWatchdogWakeup == Cu.getWatchdogTimestamp("WatchdogWakeup")) { + return true; + } + if (!inBusyWait) { + Assert.ok(true, "Not in busy wait, ignoring interrupt callback"); + return true; + } + + Assert.ok(expectInterrupt, "Interrupt callback fired"); + setInterruptCallback(undefined); + setScriptTimeout(oldTimeout); + // Schedule the promise for resolution before we kill this script. + executeSoon(resolve); + return false; + }); + + executeSoon(function() { + inBusyWait = true; + busyWait(3000); + inBusyWait = false; + Assert.ok(!expectInterrupt, "Interrupt callback didn't fire"); + setInterruptCallback(undefined); + setScriptTimeout(oldTimeout); + resolve(); + }); + }); +} + +function run_test() { + + // Run async. + do_test_pending(); + + // Run the async function. + testBody().then(() => { + do_test_finished(); + }); +} + diff --git a/js/xpconnect/tests/unit/import_stack.jsm b/js/xpconnect/tests/unit/import_stack.jsm new file mode 100644 index 0000000000..9f12c25566 --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack.jsm @@ -0,0 +1,2 @@ +function test() {} +var EXPORTED_SYMBOLS = ["test"]; diff --git a/js/xpconnect/tests/unit/import_stack.sys.mjs b/js/xpconnect/tests/unit/import_stack.sys.mjs new file mode 100644 index 0000000000..e405565d6f --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack.sys.mjs @@ -0,0 +1 @@ +export function test() {} diff --git a/js/xpconnect/tests/unit/import_stack_static_1.sys.mjs b/js/xpconnect/tests/unit/import_stack_static_1.sys.mjs new file mode 100644 index 0000000000..1d2e0452c5 --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack_static_1.sys.mjs @@ -0,0 +1 @@ +import { f2 } from './import_stack_static_2.sys.mjs'; diff --git a/js/xpconnect/tests/unit/import_stack_static_2.sys.mjs b/js/xpconnect/tests/unit/import_stack_static_2.sys.mjs new file mode 100644 index 0000000000..d6e332e68c --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack_static_2.sys.mjs @@ -0,0 +1,2 @@ +import { f3 } from './import_stack_static_3.sys.mjs'; +export function f2() {} diff --git a/js/xpconnect/tests/unit/import_stack_static_3.sys.mjs b/js/xpconnect/tests/unit/import_stack_static_3.sys.mjs new file mode 100644 index 0000000000..d40df510bf --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack_static_3.sys.mjs @@ -0,0 +1,2 @@ +import { f4 } from './import_stack_static_4.sys.mjs'; +export function f3() {} diff --git a/js/xpconnect/tests/unit/import_stack_static_4.sys.mjs b/js/xpconnect/tests/unit/import_stack_static_4.sys.mjs new file mode 100644 index 0000000000..1bf71d53e9 --- /dev/null +++ b/js/xpconnect/tests/unit/import_stack_static_4.sys.mjs @@ -0,0 +1 @@ +export function f4() {} diff --git a/js/xpconnect/tests/unit/importer.jsm b/js/xpconnect/tests/unit/importer.jsm new file mode 100644 index 0000000000..e6d2f184e6 --- /dev/null +++ b/js/xpconnect/tests/unit/importer.jsm @@ -0,0 +1 @@ +ChromeUtils.import("resource://test/syntax_error.jsm");
\ No newline at end of file diff --git a/js/xpconnect/tests/unit/jsm_loaded-1.jsm b/js/xpconnect/tests/unit/jsm_loaded-1.jsm new file mode 100644 index 0000000000..9f12c25566 --- /dev/null +++ b/js/xpconnect/tests/unit/jsm_loaded-1.jsm @@ -0,0 +1,2 @@ +function test() {} +var EXPORTED_SYMBOLS = ["test"]; diff --git a/js/xpconnect/tests/unit/jsm_loaded-2.jsm b/js/xpconnect/tests/unit/jsm_loaded-2.jsm new file mode 100644 index 0000000000..9f12c25566 --- /dev/null +++ b/js/xpconnect/tests/unit/jsm_loaded-2.jsm @@ -0,0 +1,2 @@ +function test() {} +var EXPORTED_SYMBOLS = ["test"]; diff --git a/js/xpconnect/tests/unit/jsm_loaded-3.jsm b/js/xpconnect/tests/unit/jsm_loaded-3.jsm new file mode 100644 index 0000000000..9f12c25566 --- /dev/null +++ b/js/xpconnect/tests/unit/jsm_loaded-3.jsm @@ -0,0 +1,2 @@ +function test() {} +var EXPORTED_SYMBOLS = ["test"]; diff --git a/js/xpconnect/tests/unit/not-esmified-not-exported.jsm b/js/xpconnect/tests/unit/not-esmified-not-exported.jsm new file mode 100644 index 0000000000..094eab7f92 --- /dev/null +++ b/js/xpconnect/tests/unit/not-esmified-not-exported.jsm @@ -0,0 +1,20 @@ +var exportedVar = "exported var"; +function exportedFunction() { + return "exported function"; +} +let exportedLet = "exported let"; +const exportedConst = "exported const"; + +var notExportedVar = "not exported var"; +function notExportedFunction() { + return "not exported function"; +} +let notExportedLet = "not exported let"; +const notExportedConst = "not exported const"; + +const EXPORTED_SYMBOLS = [ + "exportedVar", + "exportedFunction", + "exportedLet", + "exportedConst", +]; diff --git a/js/xpconnect/tests/unit/recursive_importA.jsm b/js/xpconnect/tests/unit/recursive_importA.jsm new file mode 100644 index 0000000000..ac763354c4 --- /dev/null +++ b/js/xpconnect/tests/unit/recursive_importA.jsm @@ -0,0 +1,12 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var EXPORTED_SYMBOLS = ["foo", "bar"]; + +function foo() { + return "foo"; +} + +var bar = {} +ChromeUtils.import("resource://test/recursive_importB.jsm", bar); diff --git a/js/xpconnect/tests/unit/recursive_importB.jsm b/js/xpconnect/tests/unit/recursive_importB.jsm new file mode 100644 index 0000000000..1bf84971b6 --- /dev/null +++ b/js/xpconnect/tests/unit/recursive_importB.jsm @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var EXPORTED_SYMBOLS = ["baz", "qux"]; + +function baz() { + return "baz"; +} + +var qux = {} +ChromeUtils.import("resource://test/recursive_importA.jsm", qux); + diff --git a/js/xpconnect/tests/unit/syntax_error.jsm b/js/xpconnect/tests/unit/syntax_error.jsm new file mode 100644 index 0000000000..fca785bcdd --- /dev/null +++ b/js/xpconnect/tests/unit/syntax_error.jsm @@ -0,0 +1 @@ +bogusjs)( diff --git a/js/xpconnect/tests/unit/test_ComponentEnvironment.js b/js/xpconnect/tests/unit/test_ComponentEnvironment.js new file mode 100644 index 0000000000..1d2c474ffd --- /dev/null +++ b/js/xpconnect/tests/unit/test_ComponentEnvironment.js @@ -0,0 +1,20 @@ +let tgt = {}; + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +const a = ChromeUtils.import("resource://test/environment_script.js", tgt); +const b = ChromeUtils.import("resource://test/environment_checkscript.jsm", tgt); + +const isShared = Cu.getGlobalForObject(a) === Cu.getGlobalForObject(b); + + +// Components should not share namespace +if (isShared) { + todo_check_eq(tgt.bound, ""); + Assert.equal(tgt.bound, "ei,fo,", "Modules should have no shared non-eval bindings"); +} else { + Assert.equal(tgt.bound, "", "Modules should have no shared bindings"); +} diff --git a/js/xpconnect/tests/unit/test_FrameScriptEnvironment.js b/js/xpconnect/tests/unit/test_FrameScriptEnvironment.js new file mode 100644 index 0000000000..d02c9900e1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_FrameScriptEnvironment.js @@ -0,0 +1,46 @@ +let ppmm = Services.ppmm.getChildAt(0); + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +add_task(async function test_bindings() { + let {strict, bound} = await new Promise(function(resolve) { + // Use a listener to get results from child + ppmm.addMessageListener("results", function listener(msg) { + ppmm.removeMessageListener("results", listener); + resolve(msg.data); + }); + + // Bind vars in first process script + ppmm.loadProcessScript("resource://test/environment_script.js", false); + + // Check visibility in second process script + ppmm.loadProcessScript(`data:, + let strict = (function() { return this; })() === undefined; + var bound = ""; + + try { void vu; bound += "vu,"; } catch (e) {} + try { void vq; bound += "vq,"; } catch (e) {} + try { void vl; bound += "vl,"; } catch (e) {} + try { void gt; bound += "gt,"; } catch (e) {} + try { void ed; bound += "ed,"; } catch (e) {} + try { void ei; bound += "ei,"; } catch (e) {} + try { void fo; bound += "fo,"; } catch (e) {} + try { void fi; bound += "fi,"; } catch (e) {} + try { void fd; bound += "fd,"; } catch (e) {} + + sendAsyncMessage("results", { strict, bound }); + `, false); + }); + + // FrameScript loader should share |this| access + if (strict) { + if (bound != "gt,ed,ei,fo,") + throw new Error("Unexpected global binding set - " + bound); + } else { + if (bound != "gt,ed,ei,fo,fi,fd,") + throw new Error("Unexpected global binding set - " + bound); + } +}); diff --git a/js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js b/js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js new file mode 100644 index 0000000000..c0a5cf202c --- /dev/null +++ b/js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js @@ -0,0 +1,38 @@ +let tgt = {}; + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +Services.scriptloader.loadSubScript("resource://test/environment_script.js", tgt); + +var bound = ""; +var tgt_bound = ""; + +// Check global bindings +try { void vu; bound += "vu,"; } catch (e) {} +try { void vq; bound += "vq,"; } catch (e) {} +try { void vl; bound += "vl,"; } catch (e) {} +try { void gt; bound += "gt,"; } catch (e) {} +try { void ed; bound += "ed,"; } catch (e) {} +try { void ei; bound += "ei,"; } catch (e) {} +try { void fo; bound += "fo,"; } catch (e) {} +try { void fi; bound += "fi,"; } catch (e) {} +try { void fd; bound += "fd,"; } catch (e) {} + +// Check target bindings +for (var name of ["vu", "vq", "vl", "gt", "ed", "ei", "fo", "fi", "fd"]) + if (tgt.hasOwnProperty(name)) + tgt_bound += name + ","; + + +// Expected subscript loader behavior is as follows: +// - Qualified vars and |this| access occur on target object +// - Lexical vars occur on ExtensibleLexicalEnvironment of target object +// - Bareword assignments and global |this| access occur on caller's global +if (bound != "vu,ei,fo,fi,") + throw new Error("Unexpected global binding set - " + bound); +if (tgt_bound != "vq,gt,ed,fd,") + throw new Error("Unexpected target binding set - " + tgt_bound); diff --git a/js/xpconnect/tests/unit/test_SubscriptLoaderJSMEnvironment.js b/js/xpconnect/tests/unit/test_SubscriptLoaderJSMEnvironment.js new file mode 100644 index 0000000000..1ae9bc3b74 --- /dev/null +++ b/js/xpconnect/tests/unit/test_SubscriptLoaderJSMEnvironment.js @@ -0,0 +1,32 @@ +let tgt_load = {}; +let tgt_check = {}; + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); +const a = ChromeUtils.import("resource://test/environment_loadscript.jsm", tgt_load); +const b = ChromeUtils.import("resource://test/environment_checkscript.jsm", tgt_check); + +const isShared = Cu.getGlobalForObject(a) === Cu.getGlobalForObject(b); + +// Check target bindings +var tgt_subscript_bound = ""; +for (var name of ["vu", "vq", "vl", "gt", "ed", "ei", "fo", "fi", "fd"]) + if (tgt_load.target.hasOwnProperty(name)) + tgt_subscript_bound += name + ","; + +// Expected subscript loader behavior is as follows: +// - Qualified vars and |this| access occur on target object +// - Lexical vars occur on ExtensibleLexicalEnvironment of target object +// - Bareword assignments and global |this| access occur on caller's global +Assert.equal(tgt_load.bound, "vu,ei,fo,fi,", "Should have expected module binding set"); +Assert.equal(tgt_subscript_bound, "vq,gt,ed,fd,", "Should have expected subscript binding set"); + +// Components should not share namespace +if (isShared) { + todo_check_eq(tgt_check.bound, ""); + Assert.equal(tgt_check.bound, "ei,fo,", "Modules should have no shared non-eval bindings"); +} else { + Assert.equal(tgt_check.bound, "", "Modules should have no shared bindings"); +} diff --git a/js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js b/js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js new file mode 100644 index 0000000000..3f4a10a14f --- /dev/null +++ b/js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js @@ -0,0 +1,35 @@ +let tgt = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal()); + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); +Services.scriptloader.loadSubScript("resource://test/environment_script.js", tgt); + +var bound = ""; +var tgt_bound = ""; + +// Check global bindings +try { void vu; bound += "vu,"; } catch (e) {} +try { void vq; bound += "vq,"; } catch (e) {} +try { void vl; bound += "vl,"; } catch (e) {} +try { void gt; bound += "gt,"; } catch (e) {} +try { void ed; bound += "ed,"; } catch (e) {} +try { void ei; bound += "ei,"; } catch (e) {} +try { void fo; bound += "fo,"; } catch (e) {} +try { void fi; bound += "fi,"; } catch (e) {} +try { void fd; bound += "fd,"; } catch (e) {} + +// Check target bindings +for (var name of ["vu", "vq", "vl", "gt", "ed", "ei", "fo", "fi", "fd"]) + if (tgt.hasOwnProperty(name)) + tgt_bound += name + ","; + + +// Expected subscript loader behavior with a Sandbox is as follows: +// - Lexicals occur on ExtensibleLexicalEnvironment of target +// - Everything else occurs on Sandbox global +if (bound != "") + throw new Error("Unexpected global binding set - " + bound); +if (tgt_bound != "vu,vq,gt,ed,ei,fo,fi,fd,") + throw new Error("Unexpected target binding set - " + tgt_bound); diff --git a/js/xpconnect/tests/unit/test_URLSearchParams.js b/js/xpconnect/tests/unit/test_URLSearchParams.js new file mode 100644 index 0000000000..fb2d203187 --- /dev/null +++ b/js/xpconnect/tests/unit/test_URLSearchParams.js @@ -0,0 +1,12 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["URLSearchParams"] }); + sb.equal = equal; + Cu.evalInSandbox('equal(new URLSearchParams("one=1&two=2").get("one"), "1");', + sb); + Cu.importGlobalProperties(["URLSearchParams"]); + Assert.equal(new URLSearchParams("one=1&two=2").get("one"), "1"); +} diff --git a/js/xpconnect/tests/unit/test_allowWaivers.js b/js/xpconnect/tests/unit/test_allowWaivers.js new file mode 100644 index 0000000000..b5a764e352 --- /dev/null +++ b/js/xpconnect/tests/unit/test_allowWaivers.js @@ -0,0 +1,29 @@ +function checkWaivers(from, allowed) { + var sb = new Cu.Sandbox('http://example.com'); + from.test = sb.eval('var o = {prop: 2, f: function() {return 42;}}; o'); + + // Make sure that |from| has Xrays to sb. + Assert.equal(from.eval('test.prop'), 2); + Assert.equal(from.eval('test.f'), undefined); + + // Make sure that waivability works as expected. + Assert.equal(from.eval('!!test.wrappedJSObject'), allowed); + Assert.equal(from.eval('XPCNativeWrapper.unwrap(test) !== test'), allowed); + + // Make a sandbox with the same principal as |from|, but without any waiver + // restrictions, and make sure that the waiver does not transfer. + var friend = new Cu.Sandbox(Cu.getObjectPrincipal(from)); + friend.test = from.test; + friend.eval('var waived = test.wrappedJSObject;'); + Assert.equal(friend.eval('waived.f()'), 42); + friend.from = from; + friend.eval('from.waived = waived'); + Assert.equal(from.eval('!!waived.f'), allowed); +} + +function run_test() { + checkWaivers(new Cu.Sandbox('http://example.com'), true); + checkWaivers(new Cu.Sandbox('http://example.com', {allowWaivers: false}), false); + checkWaivers(new Cu.Sandbox(['http://example.com']), true); + checkWaivers(new Cu.Sandbox(['http://example.com'], {allowWaivers: false}), false); +} diff --git a/js/xpconnect/tests/unit/test_allowedDomains.js b/js/xpconnect/tests/unit/test_allowedDomains.js new file mode 100644 index 0000000000..bc703a9f6d --- /dev/null +++ b/js/xpconnect/tests/unit/test_allowedDomains.js @@ -0,0 +1,41 @@ +function run_test() { + var sbMaster = Cu.Sandbox(["http://www.a.com", + "http://www.b.com", + "http://www.d.com"]); + var sbSubset = Cu.Sandbox(["http://www.d.com", + "http://www.a.com"]); + + var sbA = Cu.Sandbox("http://www.a.com"); + var sbB = Cu.Sandbox("http://www.b.com"); + var sbC = Cu.Sandbox("http://www.c.com"); + + sbMaster.objA = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbA); + sbMaster.objB = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbB); + sbMaster.objC = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbC); + sbMaster.objOwn = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbMaster); + + sbMaster.objSubset = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbSubset); + sbA.objMaster = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbMaster); + sbSubset.objMaster = Cu.evalInSandbox("var obj = {prop1:200}; obj", sbMaster); + + var ret; + ret = Cu.evalInSandbox("objA.prop1", sbMaster); + Assert.equal(ret, 200); + ret = Cu.evalInSandbox("objB.prop1", sbMaster); + Assert.equal(ret, 200); + ret = Cu.evalInSandbox("objSubset.prop1", sbMaster); + Assert.equal(ret, 200); + + function evalAndCatch(str, sb) { + try { + ret = Cu.evalInSandbox(str, sb); + Assert.ok(false, "unexpected pass") + } catch (e) { + Assert.ok(e.message && e.message.includes("Permission denied to access property")); + } + } + + evalAndCatch("objC.prop1", sbMaster); + evalAndCatch("objMaster.prop1", sbA); + evalAndCatch("objMaster.prop1", sbSubset); +} diff --git a/js/xpconnect/tests/unit/test_allowedDomainsXHR.js b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js new file mode 100644 index 0000000000..2ed388fb36 --- /dev/null +++ b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js @@ -0,0 +1,135 @@ +const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); + +var httpserver = new HttpServer(); +var httpserver2 = new HttpServer(); +var httpserver3 = new HttpServer(); +var testpath = "/simple"; +var redirectpath = "/redirect"; +var negativetestpath = "/negative"; +var httpbody = "<?xml version='1.0' ?><root>0123456789</root>"; + +var sb = Cu.Sandbox(["http://www.example.com", + "http://localhost:4444/redirect", + "http://localhost:4444/simple", + "http://localhost:4446/redirect"], + { wantGlobalProperties: ["XMLHttpRequest"] }); + +function createXHR(loc, async) +{ + var xhr = new XMLHttpRequest(); + xhr.open("GET", "http://localhost:" + loc, async); + return xhr; +} + +function checkResults(xhr) +{ + if (xhr.readyState != 4) + return false; + + equal(xhr.status, 200); + equal(xhr.responseText, httpbody); + + var root_node = xhr.responseXML.getElementsByTagName('root').item(0); + equal(root_node.firstChild.data, "0123456789"); + return true; +} + +var httpServersClosed = 0; +function finishIfDone() +{ + if (++httpServersClosed == 3) + do_test_finished(); +} + +function run_test() +{ + do_get_profile(); + do_test_pending(); + + httpserver.registerPathHandler(testpath, serverHandler); + httpserver.registerPathHandler(redirectpath, redirectHandler1); + httpserver.start(4444); + + httpserver2.registerPathHandler(negativetestpath, serverHandler); + httpserver2.start(4445); + + httpserver3.registerPathHandler(redirectpath, redirectHandler2); + httpserver3.start(4446); + + // Test sync XHR sending + Cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb); + var res = Cu.evalInSandbox('var sync = createXHR("4444/simple"); sync.send(null); sync', sb); + Assert.ok(checkResults(res)); + + var principal = res.responseXML.nodePrincipal; + Assert.ok(principal.isContentPrincipal); + var requestURL = "http://localhost:4444/redirect"; + Assert.equal(principal.spec, requestURL); + + // negative test sync XHR sending (to ensure that the xhr do not have chrome caps, see bug 779821) + try { + Cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb); + var res = Cu.evalInSandbox('var sync = createXHR("4445/negative"); sync.send(null); sync', sb); + Assert.equal(false, true, "XHR created from sandbox should not have chrome caps"); + } catch (e) { + Assert.ok(true); + } + + // Test redirect handling. + // This request bounces to server 2 and then back to server 1. Neither of + // these servers support CORS, but if the expanded principal is used as the + // triggering principal, this should work. + Cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb); + var res = Cu.evalInSandbox('var sync = createXHR("4444/redirect"); sync.send(null); sync', sb); + Assert.ok(checkResults(res)); + + var principal = res.responseXML.nodePrincipal; + Assert.ok(principal.isContentPrincipal); + var requestURL = "http://localhost:4444/redirect"; + Assert.equal(principal.spec, requestURL); + + httpserver2.stop(finishIfDone); + httpserver3.stop(finishIfDone); + + // Test async XHR sending + sb.finish = function(){ + httpserver.stop(finishIfDone); + } + + // We want to execute checkResults from the scope of the sandbox as well to + // make sure that there are no permission errors related to nsEP. For that + // we need to clone the function into the sandbox and make a few things + // available for it. + Cu.evalInSandbox('var checkResults = ' + checkResults.toSource(), sb); + sb.equal = equal; + sb.httpbody = httpbody; + + function changeListener(event) { + if (checkResults(async)) + finish(); + } + + var async = Cu.evalInSandbox('var async = createXHR("4444/simple", true);' + + 'async.addEventListener("readystatechange", ' + + changeListener.toString() + ', false);' + + 'async', sb); + async.send(null); +} + +function serverHandler(request, response) +{ + response.setHeader("Content-Type", "text/xml", false); + response.bodyOutputStream.write(httpbody, httpbody.length); +} + +function redirectHandler1(request, response) +{ + response.setStatusLine(request.httpVersion, 302, "Found"); + response.setHeader("Location", "http://localhost:4446/redirect", false); +} + +function redirectHandler2(request, response) +{ + response.setStatusLine(request.httpVersion, 302, "Found"); + response.setHeader("Location", "http://localhost:4444/simple", false); +} diff --git a/js/xpconnect/tests/unit/test_attributes.js b/js/xpconnect/tests/unit/test_attributes.js new file mode 100644 index 0000000000..4fc0acaa91 --- /dev/null +++ b/js/xpconnect/tests/unit/test_attributes.js @@ -0,0 +1,103 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var ObjectReadWrite = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestObjectReadWrite"]), + + /* nsIXPCTestObjectReadWrite */ + stringProperty: "XPConnect Read-Writable String", + booleanProperty: true, + shortProperty: 32767, + longProperty: 2147483647, + floatProperty: 5.5, + charProperty: "X", + // timeProperty is PRTime and signed type. + // So it has to allow negative value. + timeProperty: -1, +}; + +var ObjectReadOnly = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestObjectReadOnly"]), + + /* nsIXPCTestObjectReadOnly */ + strReadOnly: "XPConnect Read-Only String", + boolReadOnly: true, + shortReadOnly: 32767, + longReadOnly: 2147483647, + floatReadOnly: 5.5, + charReadOnly: "X", + // timeProperty is PRTime and signed type. + // So it has to allow negative value. + timeReadOnly: -1, +}; + +function run_test() { + // Load the component manifests. + registerXPCTestComponents(); + + // Test for each component. + test_component_readwrite(Cc["@mozilla.org/js/xpc/test/native/ObjectReadWrite;1"].createInstance()); + test_component_readwrite(xpcWrap(ObjectReadWrite)); + test_component_readonly(Cc["@mozilla.org/js/xpc/test/native/ObjectReadOnly;1"].createInstance()); + test_component_readonly(xpcWrap(ObjectReadOnly)); +} + +function test_component_readwrite(obj) { + // Instantiate the object. + var o = obj.QueryInterface(Ci.nsIXPCTestObjectReadWrite); + + // Test the initial values. + Assert.equal("XPConnect Read-Writable String", o.stringProperty); + Assert.equal(true, o.booleanProperty); + Assert.equal(32767, o.shortProperty); + Assert.equal(2147483647, o.longProperty); + Assert.ok(5.25 < o.floatProperty && 5.75 > o.floatProperty); + Assert.equal("X", o.charProperty); + Assert.equal(-1, o.timeProperty); + + // Write new values. + o.stringProperty = "another string"; + o.booleanProperty = false; + o.shortProperty = -12345; + o.longProperty = 1234567890; + o.floatProperty = 10.2; + o.charProperty = "Z"; + o.timeProperty = 1; + + // Test the new values. + Assert.equal("another string", o.stringProperty); + Assert.equal(false, o.booleanProperty); + Assert.equal(-12345, o.shortProperty); + Assert.equal(1234567890, o.longProperty); + Assert.ok(10.15 < o.floatProperty && 10.25 > o.floatProperty); + Assert.equal("Z", o.charProperty); + Assert.equal(1, o.timeProperty); + + // Assign values that differ from the expected type to verify conversion. + + function SetAndTestBooleanProperty(newValue, expectedValue) { + o.booleanProperty = newValue; + Assert.equal(expectedValue, o.booleanProperty); + }; + SetAndTestBooleanProperty(false, false); + SetAndTestBooleanProperty(1, true); + SetAndTestBooleanProperty(null, false); + SetAndTestBooleanProperty("A", true); + SetAndTestBooleanProperty(undefined, false); + SetAndTestBooleanProperty([], true); + SetAndTestBooleanProperty({}, true); +} + +function test_component_readonly(obj) { + var o = obj.QueryInterface(Ci.nsIXPCTestObjectReadOnly); + + // Test the initial values. + Assert.equal("XPConnect Read-Only String", o.strReadOnly); + Assert.equal(true, o.boolReadOnly); + Assert.equal(32767, o.shortReadOnly); + Assert.equal(2147483647, o.longReadOnly); + Assert.ok(5.25 < o.floatReadOnly && 5.75 > o.floatReadOnly); + Assert.equal("X", o.charReadOnly); + Assert.equal(-1, o.timeReadOnly); +} diff --git a/js/xpconnect/tests/unit/test_blob.js b/js/xpconnect/tests/unit/test_blob.js new file mode 100644 index 0000000000..42f6cf9be8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_blob.js @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + let { TestBlob } = ChromeUtils.import("resource://test/TestBlob.jsm"); + Assert.ok(TestBlob.doTest()); +} diff --git a/js/xpconnect/tests/unit/test_blob2.js b/js/xpconnect/tests/unit/test_blob2.js new file mode 100644 index 0000000000..90d4bdc1c6 --- /dev/null +++ b/js/xpconnect/tests/unit/test_blob2.js @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Cu.importGlobalProperties(['Blob', 'File']); + +function run_test() { + // throw if anything goes wrong + let testContent = "<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>"; + // should be able to construct a file + var f1 = new Blob([testContent], {"type" : "text/xml"}); + + // do some tests + Assert.ok(f1 instanceof Blob, "Should be a DOM Blob"); + + Assert.ok(!(f1 instanceof File), "Should not be a DOM File"); + + Assert.ok(f1.type == "text/xml", "Wrong type"); + + Assert.ok(f1.size == testContent.length, "Wrong content size"); + + var f2 = new Blob(); + Assert.ok(f2.size == 0, "Wrong size"); + Assert.ok(f2.type == "", "Wrong type"); + + var threw = false; + try { + // Needs a valid ctor argument + var f2 = new Blob(Date(132131532)); + } catch (e) { + threw = true; + } + Assert.ok(threw, "Passing a random object should fail"); +} diff --git a/js/xpconnect/tests/unit/test_bogus_files.js b/js/xpconnect/tests/unit/test_bogus_files.js new file mode 100644 index 0000000000..1e8b9f0f2a --- /dev/null +++ b/js/xpconnect/tests/unit/test_bogus_files.js @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function test_BrokenFile(path, shouldThrow, expectedName) { + var didThrow = false; + try { + ChromeUtils.import(path); + } catch (ex) { + var exceptionName = ex.name; + print("ex: " + ex + "; name = " + ex.name); + didThrow = true; + } + + Assert.equal(didThrow, shouldThrow); + if (didThrow) + Assert.equal(exceptionName, expectedName); +} + +function run_test() { + test_BrokenFile("resource://test/bogus_exports_type.jsm", true, "Error"); + + test_BrokenFile("resource://test/bogus_element_type.jsm", true, "Error"); + + test_BrokenFile("resource://test/non_existing.jsm", + true, + "NS_ERROR_FILE_NOT_FOUND"); + + test_BrokenFile("chrome://test/content/test.jsm", + true, + "NS_ERROR_FILE_NOT_FOUND"); +} diff --git a/js/xpconnect/tests/unit/test_bug1001094.js b/js/xpconnect/tests/unit/test_bug1001094.js new file mode 100644 index 0000000000..ac06e4c0f3 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1001094.js @@ -0,0 +1,4 @@ +function run_test() { + // Make sure nsJSID implements classinfo. + Assert.equal(Components.ID("{a6e2a27f-5521-4b35-8b52-99799a744aee}").equals, Components.ID("{daa47351-7d2e-44a7-b8e3-281802a1eab7}").equals); +} diff --git a/js/xpconnect/tests/unit/test_bug1021312.js b/js/xpconnect/tests/unit/test_bug1021312.js new file mode 100644 index 0000000000..ccb9981b43 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1021312.js @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + let sb = new Cu.Sandbox(this); + var called = false; + + Cu.exportFunction(function(str) { Assert.ok(/someString/.test(str)); called = true; }, + sb, { defineAs: "func" }); + // Do something weird with the string to make sure that it doesn't get interned. + Cu.evalInSandbox("var str = 'someString'; for (var i = 0; i < 10; ++i) str += i;", sb); + Cu.evalInSandbox("func(str);", sb); + Assert.ok(called); +} diff --git a/js/xpconnect/tests/unit/test_bug1033253.js b/js/xpconnect/tests/unit/test_bug1033253.js new file mode 100644 index 0000000000..e5860833b2 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1033253.js @@ -0,0 +1,5 @@ +function run_test() { + var sb = Cu.Sandbox('http://www.example.com'); + var f = Cu.evalInSandbox('var f = function() {}; f;', sb); + Assert.equal(f.name, ""); +} diff --git a/js/xpconnect/tests/unit/test_bug1033920.js b/js/xpconnect/tests/unit/test_bug1033920.js new file mode 100644 index 0000000000..6e85ec4f1d --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1033920.js @@ -0,0 +1,6 @@ +function run_test() { + var sb = Cu.Sandbox('http://www.example.com'); + var o = new sb.Object(); + o.__proto__ = null; + Assert.equal(Object.getPrototypeOf(o), null); +} diff --git a/js/xpconnect/tests/unit/test_bug1033927.js b/js/xpconnect/tests/unit/test_bug1033927.js new file mode 100644 index 0000000000..cd2bb210e7 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1033927.js @@ -0,0 +1,8 @@ +function run_test() { + var sb = Cu.Sandbox('http://www.example.com', { wantGlobalProperties: ['XMLHttpRequest']}); + var xhr = Cu.evalInSandbox('new XMLHttpRequest()', sb); + Assert.equal(xhr[Symbol.toStringTag], "XMLHttpRequest"); + Assert.equal(xhr.toString(), '[object XMLHttpRequest]'); + Assert.equal((new sb.Object()).toString(), '[object Object]'); + Assert.equal(sb.Object.prototype.toString.call(new sb.Uint16Array()), '[object Uint16Array]'); +} diff --git a/js/xpconnect/tests/unit/test_bug1034262.js b/js/xpconnect/tests/unit/test_bug1034262.js new file mode 100644 index 0000000000..6bd598bd53 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1034262.js @@ -0,0 +1,8 @@ +function run_test() { + var sb1 = Cu.Sandbox('http://www.example.com', { wantXrays: true }); + var sb2 = Cu.Sandbox('http://www.example.com', { wantXrays: false }); + sb2.f = Cu.evalInSandbox('x => typeof x', sb1); + Assert.equal(Cu.evalInSandbox('f(dump)', sb2), 'function'); + Assert.equal(Cu.evalInSandbox('f.call(null, dump)', sb2), 'function'); + Assert.equal(Cu.evalInSandbox('f.apply(null, [dump])', sb2), 'function'); +} diff --git a/js/xpconnect/tests/unit/test_bug1081990.js b/js/xpconnect/tests/unit/test_bug1081990.js new file mode 100644 index 0000000000..80e37ac282 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1081990.js @@ -0,0 +1,9 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com'); + sb.obj = {}; + sb.arr = []; + sb.fun = function() {}; + Assert.ok(sb.eval('Object.getPrototypeOf(obj) == null')); + Assert.ok(sb.eval('Object.getPrototypeOf(arr) == null')); + Assert.ok(sb.eval('Object.getPrototypeOf(fun) == null')); +} diff --git a/js/xpconnect/tests/unit/test_bug1110546.js b/js/xpconnect/tests/unit/test_bug1110546.js new file mode 100644 index 0000000000..04e1add915 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1110546.js @@ -0,0 +1,4 @@ +function run_test() { + var sb = new Cu.Sandbox(null); + Assert.ok(Cu.getObjectPrincipal(sb).isNullPrincipal); +} diff --git a/js/xpconnect/tests/unit/test_bug1131707.js b/js/xpconnect/tests/unit/test_bug1131707.js new file mode 100644 index 0000000000..57ade9f8c8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1131707.js @@ -0,0 +1,20 @@ +function testStrict(sb) { + "use strict"; + Assert.equal(sb.eval("typeof wrappedCtor()"), "string"); + Assert.equal(sb.eval("typeof new wrappedCtor()"), "object"); +} + +function run_test() { + var sb = new Cu.Sandbox(null); + var dateCtor = sb.Date; + sb.wrappedCtor = Cu.exportFunction(function wrapper(val) { + "use strict"; + var constructing = this.constructor == wrapper; + return constructing ? new dateCtor(val) : dateCtor(val); + }, sb); + Assert.equal(typeof Date(), "string"); + Assert.equal(typeof new Date(), "object"); + Assert.equal(sb.eval("typeof wrappedCtor()"), "string"); + Assert.equal(sb.eval("typeof new wrappedCtor()"), "object"); + testStrict(sb); +} diff --git a/js/xpconnect/tests/unit/test_bug1150771.js b/js/xpconnect/tests/unit/test_bug1150771.js new file mode 100644 index 0000000000..433156d6f5 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1150771.js @@ -0,0 +1,12 @@ +function run_test() { +let sandbox1 = new Cu.Sandbox(null); +let sandbox2 = new Cu.Sandbox(null); +let arg = Cu.evalInSandbox('({ buf: new ArrayBuffer(2) })', sandbox1); + +let clonedArg = Cu.cloneInto(Cu.waiveXrays(arg), sandbox2); +Assert.equal(typeof Cu.waiveXrays(clonedArg).buf, "object"); + +clonedArg = Cu.cloneInto(arg, sandbox2); +Assert.equal(typeof Cu.waiveXrays(clonedArg).buf, "object"); +Assert.equal(Cu.waiveXrays(clonedArg).buf.constructor.name, "ArrayBuffer"); +} diff --git a/js/xpconnect/tests/unit/test_bug1151385.js b/js/xpconnect/tests/unit/test_bug1151385.js new file mode 100644 index 0000000000..913050248f --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1151385.js @@ -0,0 +1,9 @@ +function run_test() +{ + try { + var sandbox = new Cu.Sandbox(null, {"sandboxPrototype" : {}}); + Assert.ok(false); + } catch (e) { + Assert.ok(/must subsume sandboxPrototype/.test(e)); + } +} diff --git a/js/xpconnect/tests/unit/test_bug1170311.js b/js/xpconnect/tests/unit/test_bug1170311.js new file mode 100644 index 0000000000..cdbe62407a --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1170311.js @@ -0,0 +1,4 @@ +function run_test() { + do_check_throws_nsIException(() => Cu.getObjectPrincipal({}).equals(null), "NS_ERROR_ILLEGAL_VALUE"); + do_check_throws_nsIException(() => Cu.getObjectPrincipal({}).subsumes(null), "NS_ERROR_ILLEGAL_VALUE"); +} diff --git a/js/xpconnect/tests/unit/test_bug1244222.js b/js/xpconnect/tests/unit/test_bug1244222.js new file mode 100644 index 0000000000..b907c72033 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1244222.js @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +var TestUtils = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestUtils"]), + doubleWrapFunction(fun) { return fun } +}; + +function run_test() { + // Generate a CCW to a function. + var sb = new Cu.Sandbox(this); + sb.eval('function fun(x) { return x; }'); + Assert.equal(sb.fun("foo"), "foo"); + + // Double-wrap the CCW. + var utils = xpcWrap(TestUtils, Ci.nsIXPCTestUtils); + var doubleWrapped = utils.doubleWrapFunction(sb.fun); + Assert.equal(doubleWrapped.echo("foo"), "foo"); + + // GC. + Cu.forceGC(); + + // Make sure it still works. + Assert.equal(doubleWrapped.echo("foo"), "foo"); +} diff --git a/js/xpconnect/tests/unit/test_bug1617527.js b/js/xpconnect/tests/unit/test_bug1617527.js new file mode 100644 index 0000000000..3db33e60d9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1617527.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + let sb1 = new Cu.Sandbox("https://example.org"); + let throwingFunc = Cu.evalInSandbox("new Function('throw new Error')", sb1); + // NOTE: Different origin from the other sandbox. + let sb2 = new Cu.Sandbox("https://example.com"); + Cu.exportFunction(function() { + // Call a different-compartment throwing function. + throwingFunc(); + }, sb2, { defineAs: "func" }); + let threw = Cu.evalInSandbox("var threw; try { func(); threw = false; } catch (e) { threw = true } threw", + sb2); + Assert.ok(threw); +} diff --git a/js/xpconnect/tests/unit/test_bug267645.js b/js/xpconnect/tests/unit/test_bug267645.js new file mode 100644 index 0000000000..6196a2165c --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug267645.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + let sb = new Cu.Sandbox("https://example.com", + { wantGlobalProperties: ["DOMException"] }); + Cu.exportFunction(function() { + undefined.foo(); + }, sb, { defineAs: "func" }); + // By default, the stacks of things running in a sandbox will contain the + // actual evalInSandbox() call location. To override that, we have to pass an + // explicit filename. + let threw = Cu.evalInSandbox("var threw; try { func(); threw = false; } catch (e) { globalThis.exn = e; threw = true } threw", + sb, "", "FakeFile"); + Assert.ok(threw); + + // Check what the sandbox could see from this exception. + Assert.ok(!Cu.evalInSandbox("exn.filename", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.fileName", sb), undefined); + Assert.ok(!Cu.evalInSandbox("exn.stack", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.message", sb), "An exception was thrown"); + Assert.equal(Cu.evalInSandbox("exn.name", sb), "InvalidStateError"); + + Cu.exportFunction(function() { + throw new Error("Hello"); + }, sb, { defineAs: "func2" }); + threw = Cu.evalInSandbox("var threw; try { func2(); threw = false; } catch (e) { globalThis.exn = e; threw = true } threw", + sb, "", "FakeFile"); + Assert.ok(threw); + Assert.ok(!Cu.evalInSandbox("exn.filename", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.fileName", sb), undefined); + Assert.ok(!Cu.evalInSandbox("exn.stack", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.message", sb), "An exception was thrown"); + Assert.equal(Cu.evalInSandbox("exn.name", sb), "InvalidStateError"); + + let ctor = Cu.evalInSandbox("TypeError", sb); + Cu.exportFunction(function() { + throw new ctor("Hello"); + }, sb, { defineAs: "func3" }); + threw = Cu.evalInSandbox("var threw; try { func3(); threw = false; } catch (e) { globalThis.exn = e; threw = true } threw", + sb, "", "FakeFile"); + Assert.ok(threw); + Assert.ok(!Cu.evalInSandbox("exn.fileName", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.filename", sb), undefined); + Assert.ok(!Cu.evalInSandbox("exn.stack", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.message", sb), "Hello"); + Assert.equal(Cu.evalInSandbox("exn.name", sb), "TypeError"); + + ctor = Cu.evalInSandbox("DOMException", sb); + Cu.exportFunction(function() { + throw new ctor("Goodbye", "InvalidAccessError"); + }, sb, { defineAs: "func4" }); + threw = Cu.evalInSandbox("var threw; try { func4(); threw = false; } catch (e) { globalThis.exn = e; threw = true } threw", + sb, "", "FakeFile"); + Assert.ok(threw); + Assert.ok(!Cu.evalInSandbox("exn.filename", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.fileName", sb), undefined); + Assert.ok(!Cu.evalInSandbox("exn.stack", sb).includes("/unit/")); + Assert.equal(Cu.evalInSandbox("exn.message", sb), "Goodbye"); + Assert.equal(Cu.evalInSandbox("exn.name", sb), "InvalidAccessError"); +} diff --git a/js/xpconnect/tests/unit/test_bug408412.js b/js/xpconnect/tests/unit/test_bug408412.js new file mode 100644 index 0000000000..06321a6f87 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug408412.js @@ -0,0 +1,12 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + try { + ChromeUtils.import("resource://test/syntax_error.jsm"); + do_throw("Failed to report any error at all"); + } catch (e) { + Assert.notEqual(/^SyntaxError:/.exec(e + ''), null); + } +} diff --git a/js/xpconnect/tests/unit/test_bug451678.js b/js/xpconnect/tests/unit/test_bug451678.js new file mode 100644 index 0000000000..90c18a614c --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug451678.js @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + var file = do_get_file("bug451678_subscript.js"); + var ios = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService); + var uri = ios.newFileURI(file); + var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"] + .getService(Ci.mozIJSSubScriptLoader); + var srvScope = {}; + scriptLoader.loadSubScript(uri.spec, srvScope); + Assert.ok('makeTags' in srvScope && srvScope.makeTags instanceof Function); +} diff --git a/js/xpconnect/tests/unit/test_bug604362.js b/js/xpconnect/tests/unit/test_bug604362.js new file mode 100644 index 0000000000..7adcfab96c --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug604362.js @@ -0,0 +1,10 @@ +function run_test() { + var sp = Cc["@mozilla.org/systemprincipal;1"]. + createInstance(Ci.nsIPrincipal); + var s = Cu.Sandbox(sp); + s.a = []; + s.Cu = Cu; + s.C = Components; + s.notEqual = notEqual; + Cu.evalInSandbox("notEqual(Cu.import, undefined);", s); +} diff --git a/js/xpconnect/tests/unit/test_bug677864.js b/js/xpconnect/tests/unit/test_bug677864.js new file mode 100644 index 0000000000..f92d15fe66 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug677864.js @@ -0,0 +1,9 @@ +function check_cl(iface, desc) { + Assert.equal(iface.QueryInterface(Ci.nsIClassInfo).classDescription, desc); +} + +function run_test() { + check_cl(Ci, 'XPCComponents_Interfaces'); + check_cl(Cc, 'XPCComponents_Classes'); + check_cl(Cr, 'XPCComponents_Results'); +} diff --git a/js/xpconnect/tests/unit/test_bug711404.js b/js/xpconnect/tests/unit/test_bug711404.js new file mode 100644 index 0000000000..f74b43316c --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug711404.js @@ -0,0 +1,7 @@ +function run_test() +{ + var p = Cc["@mozilla.org/hash-property-bag;1"]. + createInstance(Ci.nsIWritablePropertyBag2); + p.setPropertyAsInt64("a", -4000); + Assert.notEqual(p.getPropertyAsUint64("a"), -4000); +} diff --git a/js/xpconnect/tests/unit/test_bug742444.js b/js/xpconnect/tests/unit/test_bug742444.js new file mode 100644 index 0000000000..3b8262834f --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug742444.js @@ -0,0 +1,16 @@ +function run_test() { + let sb1A = Cu.Sandbox('http://www.example.com'); + let sb1B = Cu.Sandbox('http://www.example.com'); + let sb2 = Cu.Sandbox('http://www.example.org'); + let sbChrome = Cu.Sandbox(this); + let obj = new sb1A.Object(); + sb1B.obj = obj; + sb1B.waived = Cu.waiveXrays(obj); + sb2.obj = obj; + sb2.waived = Cu.waiveXrays(obj); + sbChrome.obj = obj; + sbChrome.waived = Cu.waiveXrays(obj); + Assert.ok(Cu.evalInSandbox('obj === waived', sb1B)); + Assert.ok(Cu.evalInSandbox('obj === waived', sb2)); + Assert.ok(Cu.evalInSandbox('obj !== waived', sbChrome)); +} diff --git a/js/xpconnect/tests/unit/test_bug778409.js b/js/xpconnect/tests/unit/test_bug778409.js new file mode 100644 index 0000000000..4ca2ea6767 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug778409.js @@ -0,0 +1,10 @@ +function run_test() { + var sb1 = Cu.Sandbox('http://example.com'); + var sb2 = Cu.Sandbox('http://example.org'); + var chromeObj = {foo: 2}; + var sb1obj = Cu.evalInSandbox('new Object()', sb1); + chromeObj.__proto__ = sb1obj; + sb2.wrapMe = chromeObj; + Assert.ok(true, "Didn't crash"); + Assert.equal(sb2.wrapMe.__proto__, sb1obj, 'proto set correctly'); +} diff --git a/js/xpconnect/tests/unit/test_bug780370.js b/js/xpconnect/tests/unit/test_bug780370.js new file mode 100644 index 0000000000..e0da551201 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug780370.js @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=780370 */ + +// Use a COW to expose a function from a standard prototype, and make we deny +// access to it. + +function run_test() +{ + var sb = Cu.Sandbox("http://www.example.com"); + sb.obj = { foo: 42 }; + Assert.equal(Cu.evalInSandbox('typeof obj.foo', sb), 'undefined', "COW works as expected"); + Assert.equal(Cu.evalInSandbox('obj.hasOwnProperty', sb), undefined); +} diff --git a/js/xpconnect/tests/unit/test_bug809652.js b/js/xpconnect/tests/unit/test_bug809652.js new file mode 100644 index 0000000000..6d63c6531f --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug809652.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=813901 */ + +const TypedArrays = [ Int8Array, Uint8Array, Int16Array, Uint16Array, + Int32Array, Uint32Array, Float32Array, Float64Array, + Uint8ClampedArray ]; + +// Make sure that the correct nativecall-y stuff is denied on security wrappers. + +function run_test() { + + var sb = new Cu.Sandbox('http://www.example.org'); + sb.obj = {foo: 2}; + + /* Set up some typed arrays. */ + sb.ab = new ArrayBuffer(8); + for (var i = 0; i < 8; ++i) + new Uint8Array(sb.ab)[i] = i * 10; + sb.ta = []; + TypedArrays.forEach(f => sb.ta.push(new f(sb.ab))); + sb.dv = new DataView(sb.ab); + + /* Things that should throw. */ + checkThrows("Object.prototype.__lookupSetter__('__proto__').call(obj, {});", sb); + sb.re = /f/; + checkThrows("RegExp.prototype.exec.call(re, 'abcdefg').index", sb); + sb.d = new Date(); + checkThrows("Date.prototype.setYear.call(d, 2011)", sb); + sb.m = new Map(); + checkThrows("(new Map()).clear.call(m)", sb); + checkThrows("ArrayBuffer.prototype.__lookupGetter__('byteLength').call(ab);", sb); + checkThrows("ArrayBuffer.prototype.slice.call(ab, 0);", sb); + checkThrows("DataView.prototype.getInt8.call(dv, 0);", sb); + + /* Now that Date is on Xrays, these should all throw. */ + checkThrows("Date.prototype.getYear.call(d)", sb); + checkThrows("Date.prototype.valueOf.call(d)", sb); + checkThrows("d.valueOf()", sb); + checkThrows("d.toString()", sb); + + /* Typed arrays. */ + function testForTypedArray(t) { + sb.curr = t; + sb.currName = t.constructor.name; + checkThrows("this[currName].prototype.subarray.call(curr, 0)[0]", sb); + checkThrows("(new this[currName]).__lookupGetter__('length').call(curr)", sb); + checkThrows("(new this[currName]).__lookupGetter__('buffer').call(curr)", sb); + checkThrows("(new this[currName]).__lookupGetter__('byteOffset').call(curr)", sb); + checkThrows("(new this[currName]).__lookupGetter__('byteLength').call(curr)", sb); + } + sb.ta.forEach(testForTypedArray); +} + +function checkThrows(expression, sb) { + var result = Cu.evalInSandbox('(function() { try { ' + expression + '; return "allowed"; } catch (e) { return e.toString(); }})();', sb); + dump('result: ' + result + '\n\n\n'); + Assert.ok(!!/denied/.exec(result)); +} + diff --git a/js/xpconnect/tests/unit/test_bug809674.js b/js/xpconnect/tests/unit/test_bug809674.js new file mode 100644 index 0000000000..dee089e759 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug809674.js @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +var Bug809674 = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestBug809674"]), + + /* nsIXPCTestBug809674 */ + methodWithOptionalArgc() {}, + + addArgs(x, y) { + return x + y; + }, + addSubMulArgs(x, y, subOut, mulOut) { + subOut.value = x - y; + mulOut.value = x * y; + return x + y; + }, + addVals(x, y) { + return x + y; + }, + addMany(x1, x2, x3, x4, x5, x6, x7, x8) { + return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8; + }, + + methodNoArgs() { + return 7; + }, + methodNoArgsNoRetVal() {}, + + valProperty: {value: 42}, + uintProperty: 123, +}; + +function run_test() { + // XPConnect wrap the object + var o = xpcWrap(Bug809674, Ci.nsIXPCTestBug809674); + + // Methods marked [implicit_jscontext]. + + Assert.equal(o.addArgs(12, 34), 46); + + var subRes = {}, mulRes = {}; + Assert.equal(o.addSubMulArgs(9, 7, subRes, mulRes), 16); + Assert.equal(subRes.value, 2); + Assert.equal(mulRes.value, 63); + + Assert.equal(o.addVals("foo", "x"), "foox"); + Assert.equal(o.addVals("foo", 1.2), "foo1.2"); + Assert.equal(o.addVals(1234, "foo"), "1234foo"); + + Assert.equal(o.addMany(1, 2, 4, 8, 16, 32, 64, 128), 255); + + Assert.equal(o.methodNoArgs(), 7); + Assert.equal(o.methodNoArgsNoRetVal(), undefined); + + // Attributes marked [implicit_jscontext]. + + Assert.equal(o.valProperty.value, 42); + o.valProperty = o; + Assert.equal(o.valProperty, o); + + Assert.equal(o.uintProperty, 123); + o.uintProperty++; + Assert.equal(o.uintProperty, 124); + + // [optional_argc] is not supported. + try { + o.methodWithOptionalArgc(); + Assert.ok(false); + } catch (e) { + Assert.ok(true); + Assert.ok(/optional_argc/.test(e)) + } +} diff --git a/js/xpconnect/tests/unit/test_bug813901.js b/js/xpconnect/tests/unit/test_bug813901.js new file mode 100644 index 0000000000..433c7872ef --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug813901.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=813901 */ + +// Make sure that we can't inject __exposedProps__ via the proto of a COW-ed object. + +function checkThrows(expression, sb, regexp) { + var result = Cu.evalInSandbox('(function() { try { ' + expression + '; return "allowed"; } catch (e) { return e.toString(); }})();', sb); + dump('result: ' + result + '\n\n\n'); + Assert.ok(!!regexp.exec(result)); +} + +function run_test() { + + var sb = new Cu.Sandbox('http://www.example.org'); + sb.obj = {foo: 2}; + checkThrows('obj.foo = 3;', sb, /denied/); + Cu.evalInSandbox("var p = {};", sb); + sb.obj.__proto__ = sb.p; + checkThrows('obj.foo = 4;', sb, /denied/); +} diff --git a/js/xpconnect/tests/unit/test_bug845201.js b/js/xpconnect/tests/unit/test_bug845201.js new file mode 100644 index 0000000000..74253ccaed --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug845201.js @@ -0,0 +1,18 @@ +function sbTest() { + var threw = false; + try { + for (var x in Components) { } + ok(false, "Shouldn't be able to enumerate Components"); + } catch(e) { + ok(true, "Threw appropriately"); + threw = true; + } + ok(threw, "Shouldn't have thrown uncatchable exception"); +} + +function run_test() { + var sb = Cu.Sandbox('http://www.example.com', { wantComponents: true }); + sb.ok = ok; + Cu.evalInSandbox(sbTest.toSource(), sb); + Cu.evalInSandbox('sbTest();', sb); +} diff --git a/js/xpconnect/tests/unit/test_bug845862.js b/js/xpconnect/tests/unit/test_bug845862.js new file mode 100644 index 0000000000..41d799803f --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug845862.js @@ -0,0 +1,7 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com'); + Cu.evalInSandbox("this.foo = {}; Object.defineProperty(foo, 'bar', {get: function() {return {};}});", sb); + var desc = Object.getOwnPropertyDescriptor(Cu.waiveXrays(sb.foo), 'bar'); + var b = desc.get(); + Assert.ok(b != XPCNativeWrapper(b), "results from accessor descriptors are waived"); +} diff --git a/js/xpconnect/tests/unit/test_bug849730.js b/js/xpconnect/tests/unit/test_bug849730.js new file mode 100644 index 0000000000..9be55457bf --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug849730.js @@ -0,0 +1,5 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com'); + sb.arr = [3, 4]; + Assert.ok(Cu.evalInSandbox('!Array.isArray(arr);', sb)); +} diff --git a/js/xpconnect/tests/unit/test_bug851895.js b/js/xpconnect/tests/unit/test_bug851895.js new file mode 100644 index 0000000000..1c3d0f461f --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug851895.js @@ -0,0 +1,9 @@ +function run_test() { + // Make sure Components.utils gets its |this| fixed up. + var isXrayWrapper = Cu.isXrayWrapper; + Assert.ok(!isXrayWrapper({}), "Didn't throw"); + + // Even for classes without |this| fixup, make sure that we don't crash. + var isSuccessCode = Components.isSuccessCode; + try { isSuccessCode(Cr.NS_OK); } catch (e) {}; +} diff --git a/js/xpconnect/tests/unit/test_bug853709.js b/js/xpconnect/tests/unit/test_bug853709.js new file mode 100644 index 0000000000..a59d4707bf --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug853709.js @@ -0,0 +1,30 @@ +function setupChromeSandbox() { + this.chromeObj = {a: 2 }; + this.chromeArr = [4, 2, 1]; +} + +function checkDefineThrows(sb, obj, prop, desc) { + var result = Cu.evalInSandbox('(function() { try { Object.defineProperty(' + obj + ', "' + prop + '", ' + desc.toSource() + '); return "nothrow"; } catch (e) { return e.toString(); }})();', sb); + Assert.notEqual(result, 'nothrow'); + Assert.ok(!!/denied|prohibited/.exec(result)); + Assert.ok(result.includes(prop)); // Make sure the prop name is in the error message. +} + +function run_test() { + var chromeSB = new Cu.Sandbox(this); + var contentSB = new Cu.Sandbox('http://www.example.org'); + Cu.evalInSandbox('(' + setupChromeSandbox.toSource() + ')()', chromeSB); + contentSB.chromeObj = chromeSB.chromeObj; + contentSB.chromeArr = chromeSB.chromeArr; + + Assert.equal(Cu.evalInSandbox('chromeObj.a', contentSB), undefined); + try { + Cu.evalInSandbox('chromeArr[1]', contentSB); + Assert.ok(false); + } catch (e) { Assert.ok(/denied|insecure/.test(e)); } + + checkDefineThrows(contentSB, 'chromeObj', 'a', {get: function() { return 2; }}); + checkDefineThrows(contentSB, 'chromeObj', 'a', {configurable: true, get: function() { return 2; }}); + checkDefineThrows(contentSB, 'chromeObj', 'b', {configurable: true, get: function() { return 2; }, set: function() {}}); + checkDefineThrows(contentSB, 'chromeArr', '1', {configurable: true, get: function() { return 2; }}); +} diff --git a/js/xpconnect/tests/unit/test_bug856067.js b/js/xpconnect/tests/unit/test_bug856067.js new file mode 100644 index 0000000000..b724ba4b18 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug856067.js @@ -0,0 +1,8 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com'); + let w = Cu.evalInSandbox('var w = new Map()[Symbol.iterator](); w.__proto__ = new Set(); w.foopy = 12; w', sb); + Assert.equal(Object.getPrototypeOf(w), sb.Object.prototype); + Assert.equal(Object.getOwnPropertyNames(w).length, 0); + Assert.equal(w.wrappedJSObject.foopy, 12); + Assert.equal(w.foopy, undefined); +} diff --git a/js/xpconnect/tests/unit/test_bug867486.js b/js/xpconnect/tests/unit/test_bug867486.js new file mode 100644 index 0000000000..c053ec27e1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug867486.js @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', { wantComponents: true } ); + Assert.ok(!Cu.evalInSandbox('"Components" in this', sb)); +} diff --git a/js/xpconnect/tests/unit/test_bug868675.js b/js/xpconnect/tests/unit/test_bug868675.js new file mode 100644 index 0000000000..7f5e94f83b --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug868675.js @@ -0,0 +1,29 @@ +function run_test() { + + // Make sure we don't throw for primitive values. + var result = "threw"; + try { result = XPCNativeWrapper.unwrap(2); } catch (e) {} + Assert.equal(result, 2); + result = "threw"; + try { result = XPCNativeWrapper(2); } catch (e) {} + Assert.equal(result, 2); + + // Make sure we throw when using `new` with primitives. + result = null; + try { result = new XPCNativeWrapper(2); } catch (e) { result = "catch"; } + Assert.equal(result, "catch"); + + // Make sure that we can waive on a non-Xrayable object, and that we preserve + // transitive waiving behavior. + var sb = new Cu.Sandbox('http://www.example.com', { wantGlobalProperties: ["XMLHttpRequest"] }); + Cu.evalInSandbox('this.xhr = new XMLHttpRequest();', sb); + Cu.evalInSandbox('this.jsobj = {mynative: xhr};', sb); + Assert.ok(!Cu.isXrayWrapper(XPCNativeWrapper.unwrap(sb.xhr))); + Assert.ok(Cu.isXrayWrapper(sb.jsobj.mynative)); + Assert.ok(!Cu.isXrayWrapper(XPCNativeWrapper.unwrap(sb.jsobj).mynative)); + + // Test the new Cu API. + var waived = Cu.waiveXrays(sb.xhr); + Assert.ok(!Cu.isXrayWrapper(waived)); + Assert.ok(Cu.isXrayWrapper(Cu.unwaiveXrays(waived))); +} diff --git a/js/xpconnect/tests/unit/test_bug872772.js b/js/xpconnect/tests/unit/test_bug872772.js new file mode 100644 index 0000000000..bfb0d7f4f8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug872772.js @@ -0,0 +1,33 @@ +function run_test() { + + // Make a content sandbox with an Xrayable object. + // NB: We use an nsEP here so that we can have access to Components, but still + // have Xray behavior from this scope. + var contentSB = new Cu.Sandbox(['http://www.google.com'], + { wantGlobalProperties: ["XMLHttpRequest"] }); + + // Make an XHR in the content sandbox. + Cu.evalInSandbox('xhr = new XMLHttpRequest();', contentSB); + + // Make sure that waivers can be set as Xray expandos. + var xhr = contentSB.xhr; + Assert.ok(Cu.isXrayWrapper(xhr)); + xhr.unwaivedExpando = xhr; + Assert.ok(Cu.isXrayWrapper(xhr.unwaivedExpando)); + var waived = xhr.wrappedJSObject; + Assert.ok(!Cu.isXrayWrapper(waived)); + xhr.waivedExpando = waived; + Assert.ok(!Cu.isXrayWrapper(xhr.waivedExpando)); + + // Try the same thing for getters/setters, even though that's kind of + // contrived. + Cu.evalInSandbox('function f() {}', contentSB); + var f = contentSB.f; + var fWaiver = Cu.waiveXrays(f); + Assert.ok(f != fWaiver); + Assert.ok(Cu.unwaiveXrays(fWaiver) === f); + Object.defineProperty(xhr, 'waivedAccessors', {get: fWaiver, set: fWaiver}); + var desc = Object.getOwnPropertyDescriptor(xhr, 'waivedAccessors'); + Assert.ok(desc.get === fWaiver); + Assert.ok(desc.set === fWaiver); +} diff --git a/js/xpconnect/tests/unit/test_bug885800.js b/js/xpconnect/tests/unit/test_bug885800.js new file mode 100644 index 0000000000..8e00b997b1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug885800.js @@ -0,0 +1,11 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com'); + var obj = Cu.evalInSandbox('this.obj = {foo: 2}; obj', sb); + var chromeSb = new Cu.Sandbox(this); + chromeSb.objRef = obj; + Assert.equal(Cu.evalInSandbox('objRef.foo', chromeSb), 2); + Cu.nukeSandbox(sb); + Assert.ok(Cu.isDeadWrapper(obj)); + // CCWs to nuked wrappers should be considered dead. + Assert.ok(Cu.isDeadWrapper(chromeSb.objRef)); +} diff --git a/js/xpconnect/tests/unit/test_bug930091.js b/js/xpconnect/tests/unit/test_bug930091.js new file mode 100644 index 0000000000..ef2b7ae253 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug930091.js @@ -0,0 +1,27 @@ +function checkThrows(fn) { + try { + fn(); + ok(false, "Should have thrown"); + } catch (e) { + ok(/denied|insecure|prohibited/.test(e)); + } +} + +function run_test() { + var xosb = new Cu.Sandbox('http://www.example.org'); + var sb = new Cu.Sandbox('http://www.example.com'); + sb.ok = ok; + sb.fun = function() { ok(false, "Shouldn't ever reach me"); }; + sb.cow = { foopy: 2 }; + sb.payload = Cu.evalInSandbox('new Object()', xosb); + Cu.evalInSandbox(checkThrows.toSource(), sb); + Cu.evalInSandbox('checkThrows(function() { fun(payload); });', sb); + Cu.evalInSandbox('checkThrows(function() { Function.prototype.call.call(fun, payload); });', sb); + Cu.evalInSandbox('checkThrows(function() { Function.prototype.call.call(fun, null, payload); });', sb); + Cu.evalInSandbox('checkThrows(function() { new fun(payload); });', sb); + Cu.evalInSandbox('checkThrows(function() { cow.foopy = payload; });', sb); + Cu.evalInSandbox('checkThrows(function() { Object.defineProperty(cow, "foopy", { value: payload }); });', sb); + // These fail for a different reason, .bind can't access the length/name property on the function. + Cu.evalInSandbox('checkThrows(function() { Function.bind.call(fun, null, payload); });', sb); + Cu.evalInSandbox('checkThrows(function() { Function.bind.call(fun, payload); });', sb); +} diff --git a/js/xpconnect/tests/unit/test_bug976151.js b/js/xpconnect/tests/unit/test_bug976151.js new file mode 100644 index 0000000000..2e02c3c541 --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug976151.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + let unprivilegedSb = new Cu.Sandbox('http://www.example.com'); + function checkOpaqueWrapper(val) { + unprivilegedSb.prop = val; + try { + Cu.evalInSandbox('prop();', sb); + } catch (e) { + Assert.ok(/denied|insecure|/.test(e)); + } + } + let xoSb = new Cu.Sandbox('http://www.example.net'); + let epSb = new Cu.Sandbox(['http://www.example.com']); + checkOpaqueWrapper(eval); + checkOpaqueWrapper(xoSb.eval); + checkOpaqueWrapper(epSb.eval); + checkOpaqueWrapper(Function); + checkOpaqueWrapper(xoSb.Function); + checkOpaqueWrapper(epSb.Function); +} diff --git a/js/xpconnect/tests/unit/test_bug_442086.js b/js/xpconnect/tests/unit/test_bug_442086.js new file mode 100644 index 0000000000..ad1d8aabaa --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug_442086.js @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Bug 442086 - XPConnect creates doubles without checking for +// the INT_FITS_IN_JSVAL case + +var types = [ + 'PRUint8', + 'PRUint16', + 'PRUint32', + 'PRUint64', + 'PRInt16', + 'PRInt32', + 'PRInt64', + 'float', + 'double' +]; + +function run_test() +{ + var i; + for (i = 0; i < types.length; i++) { + var name = types[i]; + var cls = Cc["@mozilla.org/supports-" + name + ";1"]; + var ifname = ("nsISupports" + name.charAt(0).toUpperCase() + + name.substring(1)); + var f = cls.createInstance(Ci[ifname]); + + f.data = 0; + switch (f.data) { + case 0: /*ok*/ break; + default: do_throw("FAILED - bug 442086 (type=" + name + ")"); + } + } +} diff --git a/js/xpconnect/tests/unit/test_callFunctionWithAsyncStack.js b/js/xpconnect/tests/unit/test_callFunctionWithAsyncStack.js new file mode 100644 index 0000000000..75c3fa013e --- /dev/null +++ b/js/xpconnect/tests/unit/test_callFunctionWithAsyncStack.js @@ -0,0 +1,28 @@ +function run_test() { + if (!Services.prefs.getBoolPref("javascript.options.asyncstack")) { + info("Async stacks are disabled."); + return; + } + + function getAsyncStack() { + return Components.stack; + } + + // asyncCause may contain non-ASCII characters. + let testAsyncCause = "Tes" + String.fromCharCode(355) + "String"; + + Cu.callFunctionWithAsyncStack(function asyncCallback() { + let stack = Components.stack; + + Assert.equal(stack.name, "asyncCallback"); + Assert.equal(stack.caller, null); + Assert.equal(stack.asyncCause, null); + + Assert.equal(stack.asyncCaller.name, "getAsyncStack"); + Assert.equal(stack.asyncCaller.asyncCause, testAsyncCause); + Assert.equal(stack.asyncCaller.asyncCaller, null); + + Assert.equal(stack.asyncCaller.caller.name, "run_test"); + Assert.equal(stack.asyncCaller.caller.asyncCause, null); + }, getAsyncStack(), testAsyncCause); +} diff --git a/js/xpconnect/tests/unit/test_cenums.js b/js/xpconnect/tests/unit/test_cenums.js new file mode 100644 index 0000000000..6efa8912b1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_cenums.js @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function TestCEnums() { +} + +TestCEnums.prototype = { + /* Boilerplate */ + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestCEnums"]), + + testCEnumInput: function(input) { + if (input != Ci.nsIXPCTestCEnums.shouldBe12Explicit) + { + throw new Error("Enum values do not match expected value"); + } + }, + + testCEnumOutput: function() { + return Ci.nsIXPCTestCEnums.shouldBe8Explicit; + }, +}; + + +function run_test() { + // Load the component manifests. + registerXPCTestComponents(); + + // Test for each component. + test_interface_consts(); + test_component(Cc["@mozilla.org/js/xpc/test/native/CEnums;1"].createInstance()); + test_component(xpcWrap(new TestCEnums())); +} + +function test_interface_consts() { + Assert.equal(Ci.nsIXPCTestCEnums.testConst, 1); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe1Explicit, 1); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe2Explicit, 2); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe4Explicit, 4); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe8Explicit, 8); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe12Explicit, 12); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe1Implicit, 1); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe2Implicit, 2); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe3Implicit, 3); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe5Implicit, 5); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe6Implicit, 6); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe2AgainImplicit, 2); + Assert.equal(Ci.nsIXPCTestCEnums.shouldBe3AgainImplicit, 3); +} + +function test_component(obj) { + var o = obj.QueryInterface(Ci.nsIXPCTestCEnums); + o.testCEnumInput(Ci.nsIXPCTestCEnums.shouldBe12Explicit); + o.testCEnumInput(Ci.nsIXPCTestCEnums.shouldBe8Explicit | Ci.nsIXPCTestCEnums.shouldBe4Explicit); + var a = o.testCEnumOutput(); + Assert.equal(a, Ci.nsIXPCTestCEnums.shouldBe8Explicit); +} + diff --git a/js/xpconnect/tests/unit/test_compileScript.js b/js/xpconnect/tests/unit/test_compileScript.js new file mode 100644 index 0000000000..1baf7ab56e --- /dev/null +++ b/js/xpconnect/tests/unit/test_compileScript.js @@ -0,0 +1,99 @@ +"use strict"; + +const { AddonTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/AddonTestUtils.sys.mjs" +); + +AddonTestUtils.init(this); + +add_task(async function() { + let scriptUrl = Services.io.newFileURI(do_get_file("file_simple_script.js")).spec; + + + let script1 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: true}); + let script2 = await ChromeUtils.compileScript(scriptUrl, {hasReturnValue: false}); + + equal(script1.url, scriptUrl, "Script URL is correct") + equal(script2.url, scriptUrl, "Script URL is correct") + + equal(script1.hasReturnValue, true, "Script hasReturnValue property is correct") + equal(script2.hasReturnValue, false, "Script hasReturnValue property is correct") + + + // Test return-value version. + + let sandbox1 = Cu.Sandbox("http://example.com"); + let sandbox2 = Cu.Sandbox("http://example.org"); + + let obj = script1.executeInGlobal(sandbox1); + equal(Cu.getObjectPrincipal(obj).origin, "http://example.com", "Return value origin is correct"); + equal(obj.foo, "\u00ae", "Return value has the correct charset"); + + obj = script1.executeInGlobal(sandbox2); + equal(Cu.getObjectPrincipal(obj).origin, "http://example.org", "Return value origin is correct"); + equal(obj.foo, "\u00ae", "Return value has the correct charset"); + + + // Test no-return-value version. + + sandbox1.bar = null; + equal(sandbox1.bar, null); + + obj = script2.executeInGlobal(sandbox1); + equal(obj, undefined, "No-return script has no return value"); + + equal(Cu.getObjectPrincipal(sandbox1.bar).origin, "http://example.com", "Object value origin is correct"); + equal(sandbox1.bar.foo, "\u00ae", "Object value has the correct charset"); + + + sandbox2.bar = null; + equal(sandbox2.bar, null); + + obj = script2.executeInGlobal(sandbox2); + equal(obj, undefined, "No-return script has no return value"); + + equal(Cu.getObjectPrincipal(sandbox2.bar).origin, "http://example.org", "Object value origin is correct"); + equal(sandbox2.bar.foo, "\u00ae", "Object value has the correct charset"); +}); + +add_task(async function test_syntaxError() { + // Generate an artificially large script to force off-main-thread + // compilation. + let scriptUrl = `data:,${";".repeat(1024 * 1024)}(`; + + await Assert.rejects( + ChromeUtils.compileScript(scriptUrl), + SyntaxError); + + // Generate a small script to force main thread compilation. + scriptUrl = `data:,;(`; + + await Assert.rejects( + ChromeUtils.compileScript(scriptUrl), + SyntaxError); +}); + +/** + * Assert that executeInGlobal throws a special exception when the content script throws. + * And the content script exception is notified to the console. + */ +add_task(async function test_exceptions_in_webconsole() { + const scriptUrl = `data:,throw new Error("foo")`; + const script = await ChromeUtils.compileScript(scriptUrl); + const sandbox = Cu.Sandbox("http://example.com"); + + Assert.throws(() => script.executeInGlobal(sandbox), + /Error: foo/, + "Without reportException set to true, executeInGlobal throws an exception"); + + info("With reportException, executeInGlobal doesn't throw, but notifies the console"); + const { messages } = await AddonTestUtils.promiseConsoleOutput(() => { + script.executeInGlobal(sandbox, { reportExceptions: true }); + }); + + info("Wait for the console message related to the content script exception"); + equal(messages.length, 1, "Got one console message"); + messages[0].QueryInterface(Ci.nsIScriptError); + equal(messages[0].errorMessage, "Error: foo", "We are notified about the plain content script exception via the console"); + ok(messages[0].stack, "The message has a stack"); +}); diff --git a/js/xpconnect/tests/unit/test_components.js b/js/xpconnect/tests/unit/test_components.js new file mode 100644 index 0000000000..e019b78f8f --- /dev/null +++ b/js/xpconnect/tests/unit/test_components.js @@ -0,0 +1,24 @@ +function run_test() { + var sb1 = Cu.Sandbox("http://www.blah.com"); + var sb2 = Cu.Sandbox(this); + var rv; + + // non-chrome accessing chrome Components + sb1.C = Components; + checkThrows("C.interfaces", sb1); + checkThrows("C.utils", sb1); + checkThrows("C.classes", sb1); + + // non-chrome accessing own Components: shouldn't exist. + Assert.equal(Cu.evalInSandbox("typeof Components", sb1), 'undefined'); + + // chrome accessing chrome + sb2.C = Components; + rv = Cu.evalInSandbox("C.utils", sb2); + Assert.equal(rv, Cu); +} + +function checkThrows(expression, sb) { + var result = Cu.evalInSandbox('(function() { try { ' + expression + '; return "allowed"; } catch (e) { return e.toString(); }})();', sb); + Assert.ok(!!/denied/.exec(result)); +} diff --git a/js/xpconnect/tests/unit/test_crypto.js b/js/xpconnect/tests/unit/test_crypto.js new file mode 100644 index 0000000000..228701d182 --- /dev/null +++ b/js/xpconnect/tests/unit/test_crypto.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + let sb = new Cu.Sandbox('https://www.example.com', + { wantGlobalProperties: + ["crypto", "TextEncoder", "TextDecoder", "isSecureContext"], + forceSecureContext: true, + }); + sb.ok = ok; + Cu.evalInSandbox('ok(this.crypto);', sb); + Cu.evalInSandbox('ok(this.crypto.subtle);', sb); + sb.equal = equal; + let innerPromise = new Promise(r => (sb.test_done = r)); + Cu.evalInSandbox('crypto.subtle.digest("SHA-256", ' + + ' new TextEncoder().encode("abc"))' + + ' .then(h => equal(new Uint16Array(h)[0], 30906))' + + ' .then(test_done);', sb); + + Cu.importGlobalProperties(["crypto"]); + ok(crypto); + ok(crypto.subtle); + let outerPromise = crypto.subtle.digest("SHA-256", new TextEncoder().encode("abc")) + .then(h => Assert.equal(new Uint16Array(h)[0], 30906)); + + do_test_pending(); + Promise.all([innerPromise, outerPromise]).then(() => do_test_finished()); +} diff --git a/js/xpconnect/tests/unit/test_css.js b/js/xpconnect/tests/unit/test_css.js new file mode 100644 index 0000000000..e6635d5293 --- /dev/null +++ b/js/xpconnect/tests/unit/test_css.js @@ -0,0 +1,9 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["CSS"] }); + sb.equal = equal; + Cu.evalInSandbox('equal(CSS.escape("$"), "\\\\$");', + sb); + Cu.importGlobalProperties(["CSS"]); + Assert.equal(CSS.escape("$"), "\\$"); +} diff --git a/js/xpconnect/tests/unit/test_deepFreezeClone.js b/js/xpconnect/tests/unit/test_deepFreezeClone.js new file mode 100644 index 0000000000..949b85f551 --- /dev/null +++ b/js/xpconnect/tests/unit/test_deepFreezeClone.js @@ -0,0 +1,31 @@ +function checkThrows(f, rgxp) { try { f(); do_check_false(); } catch (e) { Assert.ok(rgxp.test(e)); } } + +var o = { foo: 42, bar : { tick: 'tock' } }; +function checkClone(clone, frozen) { + var waived = Cu.waiveXrays(clone); + function touchFoo() { "use strict"; waived.foo = 12; Assert.equal(waived.foo, 12); } + function touchBar() { "use strict"; waived.bar.tick = 'tack'; Assert.equal(waived.bar.tick, 'tack'); } + function addProp() { "use strict"; waived.newProp = 100; Assert.equal(waived.newProp, 100); } + if (!frozen) { + touchFoo(); + touchBar(); + addProp(); + } else { + checkThrows(touchFoo, /read-only/); + checkThrows(touchBar, /read-only/); + checkThrows(addProp, /extensible/); + } + + var desc = Object.getOwnPropertyDescriptor(waived, 'foo'); + Assert.equal(desc.writable, !frozen); + Assert.equal(desc.configurable, !frozen); + desc = Object.getOwnPropertyDescriptor(waived.bar, 'tick'); + Assert.equal(desc.writable, !frozen); + Assert.equal(desc.configurable, !frozen); +} + +function run_test() { + var sb = new Cu.Sandbox(null); + checkClone(Cu.waiveXrays(Cu.cloneInto(o, sb)), false); + checkClone(Cu.cloneInto(o, sb, { deepFreeze: true }), true); +} diff --git a/js/xpconnect/tests/unit/test_defineESModuleGetters.js b/js/xpconnect/tests/unit/test_defineESModuleGetters.js new file mode 100644 index 0000000000..f7f12de1d9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_defineESModuleGetters.js @@ -0,0 +1,76 @@ +function assertAccessor(lazy, name) { + let desc = Object.getOwnPropertyDescriptor(lazy, name); + Assert.equal(typeof desc.get, "function"); + Assert.equal(desc.get.name, name); + Assert.equal(typeof desc.set, "function"); + Assert.equal(desc.set.name, name); + Assert.equal(desc.enumerable, true); + Assert.equal(desc.configurable, true); +} + +function assertDataProperty(lazy, name, value) { + let desc = Object.getOwnPropertyDescriptor(lazy, name); + Assert.equal(desc.value, value); + Assert.equal(desc.writable, true); + Assert.equal(desc.enumerable, true); + Assert.equal(desc.configurable, true); +} + +add_task(function test_getter() { + // The property should be defined as getter, and getting it should make it + // a data property. + + const lazy = {}; + ChromeUtils.defineESModuleGetters(lazy, { + X: "resource://test/esm_lazy-1.sys.mjs", + }); + + assertAccessor(lazy, "X"); + + Assert.equal(lazy.X, 10); + assertDataProperty(lazy, "X", 10); +}); + +add_task(function test_setter() { + // Setting the value before the first get should result in a data property. + const lazy = {}; + ChromeUtils.defineESModuleGetters(lazy, { + X: "resource://test/esm_lazy-1.sys.mjs", + }); + + assertAccessor(lazy, "X"); + lazy.X = 20; + Assert.equal(lazy.X, 20); + assertDataProperty(lazy, "X", 20); + + // The above set shouldn't affect the module's value. + const lazy2 = {}; + ChromeUtils.defineESModuleGetters(lazy2, { + X: "resource://test/esm_lazy-1.sys.mjs", + }); + + Assert.equal(lazy2.X, 10); +}); + +add_task(function test_order() { + // The change to the exported value should be reflected until it's accessed. + + const lazy = {}; + ChromeUtils.defineESModuleGetters(lazy, { + Y: "resource://test/esm_lazy-2.sys.mjs", + AddY: "resource://test/esm_lazy-2.sys.mjs", + }); + + assertAccessor(lazy, "Y"); + assertAccessor(lazy, "AddY"); + + // The change before getting the value should be reflected. + lazy.AddY(2); + Assert.equal(lazy.Y, 22); + assertDataProperty(lazy, "Y", 22); + + // Change after getting the value shouldn't be reflected. + lazy.AddY(2); + Assert.equal(lazy.Y, 22); + assertDataProperty(lazy, "Y", 22); +}); diff --git a/js/xpconnect/tests/unit/test_defineModuleGetter.js b/js/xpconnect/tests/unit/test_defineModuleGetter.js new file mode 100644 index 0000000000..34acceb853 --- /dev/null +++ b/js/xpconnect/tests/unit/test_defineModuleGetter.js @@ -0,0 +1,115 @@ +"use strict"; + +function assertIsGetter(obj, prop) { + let desc = Object.getOwnPropertyDescriptor(obj, prop); + + ok(desc, `Property ${prop} exists on object`); + equal(typeof desc.get, "function", `Getter function exists for property ${prop}`); + equal(typeof desc.set, "function", `Setter function exists for property ${prop}`); + equal(desc.enumerable, true, `Property ${prop} is enumerable`); + equal(desc.configurable, true, `Property ${prop} is configurable`); +} + +function assertIsValue(obj, prop, value) { + let desc = Object.getOwnPropertyDescriptor(obj, prop); + + ok(desc, `Property ${prop} exists on object`); + + ok("value" in desc, `${prop} is a data property`); + equal(desc.value, value, `${prop} has the expected value`); + + equal(desc.enumerable, true, `Property ${prop} is enumerable`); + equal(desc.configurable, true, `Property ${prop} is configurable`); + equal(desc.writable, true, `Property ${prop} is writable`); +} + +add_task(async function() { + let temp = {}; + ChromeUtils.import("resource://gre/modules/AppConstants.jsm", temp); + + let obj = {}; + let child = Object.create(obj); + let sealed = Object.seal(Object.create(obj)); + + + // Test valid import + + ChromeUtils.defineModuleGetter(obj, "AppConstants", + "resource://gre/modules/AppConstants.jsm"); + + assertIsGetter(obj, "AppConstants"); + equal(child.AppConstants, temp.AppConstants, "Getter works on descendent object"); + assertIsValue(child, "AppConstants", temp.AppConstants); + assertIsGetter(obj, "AppConstants"); + + Assert.throws(() => sealed.AppConstants, /Object is not extensible/, + "Cannot access lazy getter from sealed object"); + Assert.throws(() => sealed.AppConstants = null, /Object is not extensible/, + "Cannot access lazy setter from sealed object"); + assertIsGetter(obj, "AppConstants"); + + equal(obj.AppConstants, temp.AppConstants, "Getter works on object"); + assertIsValue(obj, "AppConstants", temp.AppConstants); + + + // Test overwriting via setter + + child = Object.create(obj); + + ChromeUtils.defineModuleGetter(obj, "AppConstants", + "resource://gre/modules/AppConstants.jsm"); + + assertIsGetter(obj, "AppConstants"); + + child.AppConstants = "foo"; + assertIsValue(child, "AppConstants", "foo"); + assertIsGetter(obj, "AppConstants"); + + obj.AppConstants = "foo"; + assertIsValue(obj, "AppConstants", "foo"); + + + // Test import missing property + + ChromeUtils.defineModuleGetter(obj, "meh", + "resource://gre/modules/AppConstants.jsm"); + assertIsGetter(obj, "meh"); + equal(obj.meh, undefined, "Missing property returns undefined"); + assertIsValue(obj, "meh", undefined); + + + // Test import broken module + + ChromeUtils.defineModuleGetter(obj, "broken", + "resource://test/bogus_exports_type.jsm"); + assertIsGetter(obj, "broken"); + + let errorPattern = /EXPORTED_SYMBOLS is not an array/; + Assert.throws(() => child.broken, errorPattern, + "Broken import throws on child"); + Assert.throws(() => child.broken, errorPattern, + "Broken import throws on child again"); + Assert.throws(() => sealed.broken, errorPattern, + "Broken import throws on sealed child"); + Assert.throws(() => obj.broken, errorPattern, + "Broken import throws on object"); + assertIsGetter(obj, "broken"); + + + // Test import missing module + + ChromeUtils.defineModuleGetter(obj, "missing", + "resource://test/does_not_exist.jsm"); + assertIsGetter(obj, "missing"); + + Assert.throws(() => obj.missing, /NS_ERROR_FILE_NOT_FOUND/, + "missing import throws on object"); + assertIsGetter(obj, "missing"); + + + // Test overwriting broken import via setter + + assertIsGetter(obj, "broken"); + obj.broken = "foo"; + assertIsValue(obj, "broken", "foo"); +}); diff --git a/js/xpconnect/tests/unit/test_envChain_JSM.js b/js/xpconnect/tests/unit/test_envChain_JSM.js new file mode 100644 index 0000000000..0c5b2e1b80 --- /dev/null +++ b/js/xpconnect/tests/unit/test_envChain_JSM.js @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Verify the environment chain for JSM described in +// js/src/vm/EnvironmentObject.h. + +add_task(async function() { + const { envs } = ChromeUtils.import("resource://test/envChain.jsm"); + + Assert.equal(envs.length, 4); + + let i = 0, env; + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.lexical, true, "lexical must live in the NSLEO"); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticVariablesObject"); + Assert.equal(env.qualified, true, "qualified var must live in the NSVO"); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, true, "prop var must live in the NSVO"); + + env = envs[i]; i++; + Assert.equal(env.type, "GlobalLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "*BackstagePass*"); + Assert.equal(env.qualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); +}); diff --git a/js/xpconnect/tests/unit/test_envChain_frameScript.js b/js/xpconnect/tests/unit/test_envChain_frameScript.js new file mode 100644 index 0000000000..2d877d822f --- /dev/null +++ b/js/xpconnect/tests/unit/test_envChain_frameScript.js @@ -0,0 +1,211 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Verify the environment chain for frame scripts described in +// js/src/vm/EnvironmentObject.h. + +const { XPCShellContentUtils } = ChromeUtils.importESModule( + "resource://testing-common/XPCShellContentUtils.sys.mjs" +); + +XPCShellContentUtils.init(this); + +add_task(async function unique_scope() { + const page = await XPCShellContentUtils.loadContentPage("about:blank", { + remote: true, + }); + + const envsPromise = new Promise(resolve => { + Services.mm.addMessageListener("unique-envs-result", msg => { + resolve(msg.data); + }); + }); + const sharePromise = new Promise(resolve => { + Services.mm.addMessageListener("unique-share-result", msg => { + resolve(msg.data); + }); + }); + + const runInUniqueScope = true; + const runInGlobalScope = !runInUniqueScope; + + Services.mm.loadFrameScript(`data:, +var unique_qualified = 10; +unique_unqualified = 20; +let unique_lexical = 30; +this.unique_prop = 40; + +const funcs = Cu.getJSTestingFunctions(); +const envs = []; +let env = funcs.getInnerMostEnvironmentObject(); +while (env) { + envs.push({ + type: funcs.getEnvironmentObjectType(env) || "*BackstagePass*", + qualified: !!Object.getOwnPropertyDescriptor(env, "unique_qualified"), + unqualified: !!Object.getOwnPropertyDescriptor(env, "unique_unqualified"), + lexical: !!Object.getOwnPropertyDescriptor(env, "unique_lexical"), + prop: !!Object.getOwnPropertyDescriptor(env, "unique_prop"), + }); + + env = funcs.getEnclosingEnvironmentObject(env); +} + +sendSyncMessage("unique-envs-result", envs); +`, false, runInGlobalScope); + + Services.mm.loadFrameScript(`data:, +sendSyncMessage("unique-share-result", { + unique_qualified: typeof unique_qualified, + unique_unqualified: typeof unique_unqualified, + unique_lexical: typeof unique_lexical, + unique_prop: this.unique_prop, +}); +`, false, runInGlobalScope); + + const envs = await envsPromise; + const share = await sharePromise; + + Assert.equal(envs.length, 5); + + let i = 0, env; + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, true, "lexical must live in the NSLEO"); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "WithEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, true, "this property must live in the with env"); + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticVariablesObject"); + Assert.equal(env.qualified, true, "qualified var must live in the NSVO"); + Assert.equal(env.unqualified, true, "unqualified var must live in the NSVO"); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "GlobalLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "*BackstagePass*"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + Assert.equal(share.unique_qualified, "undefined", "qualified var must not be shared"); + Assert.equal(share.unique_unqualified, "undefined", "unqualified name must not be shared"); + Assert.equal(share.unique_lexical, "undefined", "lexical must not be shared"); + Assert.equal(share.unique_prop, 40, "this property must be shared"); + + await page.close(); +}); + +add_task(async function non_unique_scope() { + const page = await XPCShellContentUtils.loadContentPage("about:blank", { + remote: true, + }); + + const envsPromise = new Promise(resolve => { + Services.mm.addMessageListener("non-unique-envs-result", msg => { + resolve(msg.data); + }); + }); + const sharePromise = new Promise(resolve => { + Services.mm.addMessageListener("non-unique-share-result", msg => { + resolve(msg.data); + }); + }); + + const runInUniqueScope = false; + const runInGlobalScope = !runInUniqueScope; + + Services.mm.loadFrameScript(`data:, +var non_unique_qualified = 10; +non_unique_unqualified = 20; +let non_unique_lexical = 30; +this.non_unique_prop = 40; + +const funcs = Cu.getJSTestingFunctions(); +const envs = []; +let env = funcs.getInnerMostEnvironmentObject(); +while (env) { + envs.push({ + type: funcs.getEnvironmentObjectType(env) || "*BackstagePass*", + qualified: !!Object.getOwnPropertyDescriptor(env, "non_unique_qualified"), + unqualified: !!Object.getOwnPropertyDescriptor(env, "non_unique_unqualified"), + lexical: !!Object.getOwnPropertyDescriptor(env, "non_unique_lexical"), + prop: !!Object.getOwnPropertyDescriptor(env, "non_unique_prop"), + }); + + env = funcs.getEnclosingEnvironmentObject(env); +} + +sendSyncMessage("non-unique-envs-result", envs); +`, false, runInGlobalScope); + + Services.mm.loadFrameScript(`data:, +sendSyncMessage("non-unique-share-result", { + non_unique_qualified, + non_unique_unqualified, + non_unique_lexical, + non_unique_prop, +}); +`, false, runInGlobalScope); + + const envs = await envsPromise; + const share = await sharePromise; + + Assert.equal(envs.length, 4); + + let i = 0, env; + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, true, "lexical must live in the NSLEO"); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "WithEnvironmentObject"); + Assert.equal(env.qualified, true, "qualified var must live in the with env"); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, true, "this property must live in the with env"); + + env = envs[i]; i++; + Assert.equal(env.type, "GlobalLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "*BackstagePass*"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, true, "unqualified name must live in the backstage pass"); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + Assert.equal(share.non_unique_qualified, 10, "qualified var must be shared"); + Assert.equal(share.non_unique_unqualified, 20, "unqualified name must be shared"); + Assert.equal(share.non_unique_lexical, 30, "lexical must be shared"); + Assert.equal(share.non_unique_prop, 40, "this property must be shared"); + + await page.close(); +}); diff --git a/js/xpconnect/tests/unit/test_envChain_subscript.js b/js/xpconnect/tests/unit/test_envChain_subscript.js new file mode 100644 index 0000000000..e7774d0d0d --- /dev/null +++ b/js/xpconnect/tests/unit/test_envChain_subscript.js @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Verify the environment chain for subscripts described in +// js/src/vm/EnvironmentObject.h. + +add_task(async function() { + const target = {}; + Services.scriptloader.loadSubScript(`data:, +var qualified = 10; +unqualified = 20; +let lexical = 30; +this.prop = 40; + +const funcs = Cu.getJSTestingFunctions(); +const envs = []; +let env = funcs.getInnerMostEnvironmentObject(); +while (env) { + envs.push({ + type: funcs.getEnvironmentObjectType(env) || "*global*", + qualified: !!Object.getOwnPropertyDescriptor(env, "qualified"), + unqualified: !!Object.getOwnPropertyDescriptor(env, "unqualified"), + lexical: !!Object.getOwnPropertyDescriptor(env, "lexical"), + prop: !!Object.getOwnPropertyDescriptor(env, "prop"), + }); + + env = funcs.getEnclosingEnvironmentObject(env); +} + +this.ENVS = envs; +`, target); + + const envs = target.ENVS; + + Assert.equal(envs.length, 4); + + let i = 0, env; + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, true, "lexical must live in the NSLEO"); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "WithEnvironmentObject"); + Assert.equal(env.qualified, true, "qualified var must live in the with env"); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, true, "this property must live in the with env"); + + env = envs[i]; i++; + Assert.equal(env.type, "GlobalLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "*global*"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, true, "unqualified var must live in the global"); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + Assert.equal(target.qualified, 10, "qualified var must be reflected to the target object"); + Assert.equal(target.prop, 40, "this property must be reflected to the target object"); +}); diff --git a/js/xpconnect/tests/unit/test_envChain_subscript_in_JSM.js b/js/xpconnect/tests/unit/test_envChain_subscript_in_JSM.js new file mode 100644 index 0000000000..a95806177e --- /dev/null +++ b/js/xpconnect/tests/unit/test_envChain_subscript_in_JSM.js @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Verify the environment chain for subscripts in JSM described in +// js/src/vm/EnvironmentObject.h. + +add_task(async function() { + const { envs } = ChromeUtils.import("resource://test/envChain_subscript.jsm"); + + Assert.equal(envs.length, 6); + + let i = 0, env; + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, true, "lexical must live in the NSLEO"); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "WithEnvironmentObject"); + Assert.equal(env.qualified, true, "qualified var must live in the with env"); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, true, "this property must live in the with env"); + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "NonSyntacticVariablesObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, true, "unqualified var must live in the global"); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "GlobalLexicalEnvironmentObject"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); + + env = envs[i]; i++; + Assert.equal(env.type, "*BackstagePass*"); + Assert.equal(env.qualified, false); + Assert.equal(env.unqualified, false); + Assert.equal(env.lexical, false); + Assert.equal(env.prop, false); +}); diff --git a/js/xpconnect/tests/unit/test_eventSource.js b/js/xpconnect/tests/unit/test_eventSource.js new file mode 100644 index 0000000000..8983d852bd --- /dev/null +++ b/js/xpconnect/tests/unit/test_eventSource.js @@ -0,0 +1,6 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +Assert.throws(() => new EventSource('a'), + /NS_ERROR_FAILURE/, + "This should fail, but not crash, in xpcshell"); diff --git a/js/xpconnect/tests/unit/test_exportFunction.js b/js/xpconnect/tests/unit/test_exportFunction.js new file mode 100644 index 0000000000..a7b2ca8056 --- /dev/null +++ b/js/xpconnect/tests/unit/test_exportFunction.js @@ -0,0 +1,152 @@ +function run_test() { + var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true }); + var subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] }); + var subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] }); + var xorigsb = new Cu.Sandbox("http://test.com", { wantGlobalProperties: ["XMLHttpRequest"] }); + + epsb.subsb = subsb; + epsb.xorigsb = xorigsb; + epsb.ok = ok; + epsb.equal = equal; + subsb.ok = ok; + subsb.equal = equal; + + // Exporting should work if prinicipal of the source sandbox + // subsumes the principal of the target sandbox. + Cu.evalInSandbox("(" + function() { + var wasCalled = false; + this.funToExport = function(expectedThis, a, obj, native, mixed, callback) { + equal(arguments.callee.length, 6); + equal(a, 42); + equal(obj, subsb.tobecloned); + equal(obj.cloned, "cloned"); + equal(native, subsb.native); + equal(expectedThis, this); + equal(mixed.xrayed, subsb.xrayed); + equal(mixed.xrayed2, subsb.xrayed2); + if (typeof callback == 'function') { + equal(typeof subsb.callback, 'function'); + equal(callback, subsb.callback); + callback(); + } + wasCalled = true; + }; + this.checkIfCalled = function() { + ok(wasCalled); + wasCalled = false; + } + exportFunction(funToExport, subsb, { defineAs: "imported", allowCallbacks: true }); + exportFunction((x) => x, subsb, { defineAs: "echoAllowXO", allowCallbacks: true, allowCrossOriginArguments: true }); + }.toSource() + ")()", epsb); + + subsb.xrayed = Cu.evalInSandbox("(" + function () { + return new XMLHttpRequest(); + }.toSource() + ")()", subsb2); + + // Exported function should be able to be call from the + // target sandbox. Native arguments should be just wrapped + // every other argument should be cloned. + Cu.evalInSandbox("(" + function () { + native = new XMLHttpRequest(); + xrayed2 = XPCNativeWrapper(new XMLHttpRequest()); + mixed = { xrayed: xrayed, xrayed2: xrayed2 }; + tobecloned = { cloned: "cloned" }; + invokedCallback = false; + callback = function() { invokedCallback = true; }; + imported(this, 42, tobecloned, native, mixed, callback); + equal(imported.length, 6); + ok(invokedCallback); + }.toSource() + ")()", subsb); + + // Invoking an exported function with cross-origin arguments should throw. + subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb); + try { + Cu.evalInSandbox('imported(this, xoNative)', subsb); + Assert.ok(false); + } catch (e) { + Assert.ok(/denied|insecure/.test(e)); + } + + // Callers can opt-out of the above. + subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb); + try { + Assert.equal(Cu.evalInSandbox('echoAllowXO(xoNative)', subsb), subsb.xoNative); + Assert.ok(true); + } catch (e) { + Assert.ok(false); + } + + // Apply should work and |this| should carry over appropriately. + Cu.evalInSandbox("(" + function() { + var someThis = {}; + imported.apply(someThis, [someThis, 42, tobecloned, native, mixed]); + }.toSource() + ")()", subsb); + + Cu.evalInSandbox("(" + function() { + checkIfCalled(); + }.toSource() + ")()", epsb); + + // Exporting should throw if principal of the source sandbox does + // not subsume the principal of the target. + Cu.evalInSandbox("(" + function() { + try{ + exportFunction(function() {}, this.xorigsb, { defineAs: "denied" }); + ok(false); + } catch (e) { + ok(e.toString().indexOf('Permission denied') > -1); + } + }.toSource() + ")()", epsb); + + // Exporting should throw if the principal of the source sandbox does + // not subsume the principal of the function. + epsb.xo_function = new xorigsb.Function(); + Cu.evalInSandbox("(" + function() { + try{ + exportFunction(xo_function, this.subsb, { defineAs: "denied" }); + ok(false); + } catch (e) { + dump('Exception: ' + e); + ok(e.toString().indexOf('Permission denied') > -1); + } + }.toSource() + ")()", epsb); + + // Let's create an object in the target scope and add privileged + // function to it as a property. + Cu.evalInSandbox("(" + function() { + var newContentObject = createObjectIn(subsb, { defineAs: "importedObject" }); + exportFunction(funToExport, newContentObject, { defineAs: "privMethod" }); + }.toSource() + ")()", epsb); + + Cu.evalInSandbox("(" + function () { + importedObject.privMethod(importedObject, 42, tobecloned, native, mixed); + }.toSource() + ")()", subsb); + + Cu.evalInSandbox("(" + function() { + checkIfCalled(); + }.toSource() + ")()", epsb); + + // exportFunction and createObjectIn should be available from Cu too. + var newContentObject = Cu.createObjectIn(subsb, { defineAs: "importedObject2" }); + var wasCalled = false; + Cu.exportFunction(function(arg) { wasCalled = arg.wasCalled; }, + newContentObject, { defineAs: "privMethod" }); + + Cu.evalInSandbox("(" + function () { + importedObject2.privMethod({wasCalled: true}); + }.toSource() + ")()", subsb); + + // 3rd argument of exportFunction should be optional. + Cu.evalInSandbox("(" + function() { + subsb.imported2 = exportFunction(funToExport, subsb); + }.toSource() + ")()", epsb); + + Cu.evalInSandbox("(" + function () { + imported2(this, 42, tobecloned, native, mixed); + }.toSource() + ")()", subsb); + + Cu.evalInSandbox("(" + function() { + checkIfCalled(); + }.toSource() + ")()", epsb); + + Assert.ok(wasCalled); +} diff --git a/js/xpconnect/tests/unit/test_file.js b/js/xpconnect/tests/unit/test_file.js new file mode 100644 index 0000000000..ff4589c3f5 --- /dev/null +++ b/js/xpconnect/tests/unit/test_file.js @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +add_task(function() { + let { TestFile } = ChromeUtils.import("resource://test/TestFile.jsm"); + TestFile.doTest(result => { + Assert.ok(result); + run_next_test(); + }); +}); diff --git a/js/xpconnect/tests/unit/test_file2.js b/js/xpconnect/tests/unit/test_file2.js new file mode 100644 index 0000000000..9c72eb4c62 --- /dev/null +++ b/js/xpconnect/tests/unit/test_file2.js @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Cu.importGlobalProperties(['File']); + +add_task(async function() { + // throw if anything goes wrong + + // find the current directory path + var file = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + file.append("xpcshell.ini"); + + // should be able to construct a file + var f1 = await File.createFromFileName(file.path); + // and with nsIFiles + var f2 = await File.createFromNsIFile(file); + + // do some tests + Assert.ok(f1 instanceof File, "Should be a DOM File"); + Assert.ok(f2 instanceof File, "Should be a DOM File"); + + Assert.ok(f1.name == "xpcshell.ini", "Should be the right file"); + Assert.ok(f2.name == "xpcshell.ini", "Should be the right file"); + + Assert.ok(f1.type == "", "Should be the right type"); + Assert.ok(f2.type == "", "Should be the right type"); + + var threw = false; + try { + // Needs a ctor argument + var f7 = File(); + } catch (e) { + threw = true; + } + Assert.ok(threw, "No ctor arguments should throw"); + + var threw = false; + try { + // Needs a valid ctor argument + var f7 = File(Date(132131532)); + } catch (e) { + threw = true; + } + Assert.ok(threw, "Passing a random object should fail"); + + var threw = false + try { + // Directories fail + var dir = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var f7 = await File.createFromNsIFile(dir) + } catch (e) { + threw = true; + } + Assert.ok(threw, "Can't create a File object for a directory"); +}); diff --git a/js/xpconnect/tests/unit/test_fileReader.js b/js/xpconnect/tests/unit/test_fileReader.js new file mode 100644 index 0000000000..ea86096319 --- /dev/null +++ b/js/xpconnect/tests/unit/test_fileReader.js @@ -0,0 +1,12 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["FileReader"] }); + sb.ok = ok; + Cu.evalInSandbox('ok((new FileReader()) instanceof FileReader);', + sb); + Cu.importGlobalProperties(["FileReader"]); + Assert.ok((new FileReader()) instanceof FileReader); +} diff --git a/js/xpconnect/tests/unit/test_function_names.js b/js/xpconnect/tests/unit/test_function_names.js new file mode 100644 index 0000000000..6eadc1fce7 --- /dev/null +++ b/js/xpconnect/tests/unit/test_function_names.js @@ -0,0 +1,37 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function callback() {} + +let sandbox = Cu.Sandbox(this); +let callbackWrapped = Cu.evalInSandbox("(function wrapped() {})", sandbox); + +function run_test() { + let functions = [ + [{ notify: callback }, "callback[test_function_names.js]:JS"], + [{ notify: { notify: callback } }, "callback[test_function_names.js]:JS"], + [callback, "callback[test_function_names.js]:JS"], + [function() {}, "run_test/functions<[test_function_names.js]:JS"], + [function foobar() {}, "foobar[test_function_names.js]:JS"], + [function Δ() {}, "Δ[test_function_names.js]:JS"], + [{ notify1: callback, notify2: callback }, "nonfunction:JS"], + [{ notify: 10 }, "nonfunction:JS"], + [{}, "nonfunction:JS"], + [{ notify: callbackWrapped }, "wrapped[test_function_names.js]:JS"], + ]; + + // Use the observer service so we can get double-wrapped functions. + var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + + function observer(subject, topic, data) + { + let named = subject.QueryInterface(Ci.nsINamed); + Assert.equal(named.name, data); + dump(`name: ${named.name}\n`); + } + obs.addObserver(observer, "test-obs-fun", false); + + for (let [f, requiredName] of functions) { + obs.notifyObservers(f, "test-obs-fun", requiredName); + } +} diff --git a/js/xpconnect/tests/unit/test_generateQI.js b/js/xpconnect/tests/unit/test_generateQI.js new file mode 100644 index 0000000000..d54ed53212 --- /dev/null +++ b/js/xpconnect/tests/unit/test_generateQI.js @@ -0,0 +1,29 @@ +"use strict"; + +add_task(async function test_generateQI() { + function checkQI(interfaces, iface) { + let obj = { + QueryInterface: ChromeUtils.generateQI(interfaces), + }; + equal(obj.QueryInterface(iface), obj, + `Correct return value for query to ${iface}`); + } + + // Test success scenarios. + checkQI([], Ci.nsISupports); + + checkQI([Ci.nsIPropertyBag, "nsIPropertyBag2"], Ci.nsIPropertyBag); + checkQI([Ci.nsIPropertyBag, "nsIPropertyBag2"], Ci.nsIPropertyBag2); + + checkQI([Ci.nsIPropertyBag, "nsIPropertyBag2", "nsINotARealInterface"], Ci.nsIPropertyBag2); + + // Non-IID values get stringified, and don't cause any errors as long + // as there isn't a non-IID property with the same name on Ci. + checkQI([Ci.nsIPropertyBag, "nsIPropertyBag2", null, Object], Ci.nsIPropertyBag2); + + ChromeUtils.generateQI([])(Ci.nsISupports); + + // Test failure scenarios. + Assert.throws(() => checkQI([], Ci.nsIPropertyBag), + e => e.result == Cr.NS_ERROR_NO_INTERFACE); +}); diff --git a/js/xpconnect/tests/unit/test_getCallerLocation.js b/js/xpconnect/tests/unit/test_getCallerLocation.js new file mode 100644 index 0000000000..569d76f8eb --- /dev/null +++ b/js/xpconnect/tests/unit/test_getCallerLocation.js @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +Cu.importGlobalProperties(["ChromeUtils"]); + +const {AddonTestUtils} = ChromeUtils.importESModule("resource://testing-common/AddonTestUtils.sys.mjs"); + +add_task(async function() { + const sandbox = Cu.Sandbox("http://example.com/"); + + function foo() { + return bar(); + } + + function bar() { + return baz(); + } + + function baz() { + return ChromeUtils.getCallerLocation(Cu.getObjectPrincipal(sandbox)); + } + + Cu.evalInSandbox(` + function it() { + // Use map() to throw a self-hosted frame on the stack, which we + // should filter out. + return [0].map(foo)[0]; + } + function thing() { + return it(); + } + `, sandbox, undefined, "thing.js"); + + Cu.exportFunction(foo, sandbox, {defineAs: "foo"}); + + let frame = sandbox.thing(); + + equal(frame.source, "thing.js", "Frame source"); + equal(frame.line, 5, "Frame line"); + equal(frame.column, 18, "Frame column"); + equal(frame.functionDisplayName, "it", "Frame function name"); + equal(frame.parent, null, "Frame parent"); + + equal(String(frame), "it@thing.js:5:18\n", "Stringified frame"); + + + // reportError + + let {messages} = await AddonTestUtils.promiseConsoleOutput(() => { + Cu.reportError("Meh", frame); + }); + + let [msg] = messages.filter(m => m.message.includes("Meh")); + + equal(msg.stack, frame, "reportError stack frame"); + equal(msg.message, '[JavaScript Error: "Meh" {file: "thing.js" line: 5}]\nit@thing.js:5:18\n'); + + Assert.throws(() => { Cu.reportError("Meh", {}); }, + err => err.result == Cr.NS_ERROR_INVALID_ARG, + "reportError should throw when passed a non-SavedFrame object"); + + + // createError + + Assert.throws(() => { ChromeUtils.createError("Meh", {}); }, + err => err.result == Cr.NS_ERROR_INVALID_ARG, + "createError should throw when passed a non-SavedFrame object"); + + let cloned = Cu.cloneInto(frame, sandbox); + let error = ChromeUtils.createError("Meh", cloned); + + equal(String(cloned), String(frame), + "Cloning a SavedStack preserves its stringification"); + + equal(Cu.getGlobalForObject(error), sandbox, + "createError creates errors in the global of the SavedFrame"); + equal(error.stack, String(cloned), + "createError creates errors with the correct stack"); + + equal(error.message, "Meh", "Error message"); + equal(error.fileName, "thing.js", "Error filename"); + equal(error.lineNumber, 5, "Error line"); + equal(error.columnNumber, 18, "Error column"); +}); diff --git a/js/xpconnect/tests/unit/test_getObjectPrincipal.js b/js/xpconnect/tests/unit/test_getObjectPrincipal.js new file mode 100644 index 0000000000..03c6ffce3d --- /dev/null +++ b/js/xpconnect/tests/unit/test_getObjectPrincipal.js @@ -0,0 +1,6 @@ +function run_test() { + Assert.ok(Cu.getObjectPrincipal({}).isSystemPrincipal); + var sb = new Cu.Sandbox('http://www.example.com'); + Cu.evalInSandbox('var obj = { foo: 42 };', sb); + Assert.equal(Cu.getObjectPrincipal(sb.obj).origin, 'http://www.example.com'); +} diff --git a/js/xpconnect/tests/unit/test_import.js b/js/xpconnect/tests/unit/test_import.js new file mode 100644 index 0000000000..05c6a52647 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import.js @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var AppConstants; +function run_test() { + var scope = {}; + var exports = ChromeUtils.import("resource://gre/modules/AppConstants.jsm", scope); + Assert.equal(typeof(scope.AppConstants), "object"); + Assert.equal(typeof(scope.AppConstants.isPlatformAndVersionAtLeast), "function"); + + equal(scope.AppConstants, exports.AppConstants); + deepEqual(Object.keys(scope), ["AppConstants"]); + deepEqual(Object.keys(exports), ["AppConstants"]); + + exports = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); + equal(scope.AppConstants, exports.AppConstants); + deepEqual(Object.keys(exports), ["AppConstants"]); + + // access module's global object directly without importing any + // symbols + Assert.throws( + () => ChromeUtils.import("resource://gre/modules/AppConstants.jsm", null), + TypeError + ); + + // import symbols to our global object + Assert.equal(typeof(Cu.import), "function"); + ({AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm")); + Assert.equal(typeof(AppConstants), "object"); + Assert.equal(typeof(AppConstants.isPlatformAndVersionAtLeast), "function"); + + // try on a new object + var scope2 = {}; + ChromeUtils.import("resource://gre/modules/AppConstants.jsm", scope2); + Assert.equal(typeof(scope2.AppConstants), "object"); + Assert.equal(typeof(scope2.AppConstants.isPlatformAndVersionAtLeast), "function"); + + Assert.ok(scope2.AppConstants == scope.AppConstants); + + // try on a new object using the resolved URL + var res = Cc["@mozilla.org/network/protocol;1?name=resource"] + .getService(Ci.nsIResProtocolHandler); + var resURI = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService) + .newURI("resource://gre/modules/AppConstants.jsm"); + dump("resURI: " + resURI + "\n"); + var filePath = res.resolveURI(resURI); + var scope3 = {}; + Assert.throws( + () => ChromeUtils.import(filePath, scope3), + /SecurityError/, "Expecting file URI not to be imported" + ); + + // make sure we throw when the second arg is bogus + var didThrow = false; + try { + ChromeUtils.import("resource://gre/modules/AppConstants.jsm", "wrong"); + } catch (ex) { + print("exception (expected): " + ex); + didThrow = true; + } + Assert.ok(didThrow); + + // make sure we throw when the URL scheme is not known + var scope4 = {}; + const wrongScheme = "data:text/javascript,var a = {a:1}"; + Assert.throws( + () => ChromeUtils.import(wrongScheme, scope4), + /SecurityError/, "Expecting data URI not to be imported" + ); +} diff --git a/js/xpconnect/tests/unit/test_import_devtools_loader.js b/js/xpconnect/tests/unit/test_import_devtools_loader.js new file mode 100644 index 0000000000..d7e6fe42f6 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_devtools_loader.js @@ -0,0 +1,85 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const { AppConstants } = ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); +const { addDebuggerToGlobal } = ChromeUtils.importESModule( + "resource://gre/modules/jsdebugger.sys.mjs" +); +addDebuggerToGlobal(this); + +const ESM_URL = "resource://test/es6module_devtoolsLoader.sys.mjs"; + +// Toggle the following pref to enable Cu.getModuleImportStack() +if (AppConstants.NIGHTLY_BUILD) { + Services.prefs.setBoolPref("browser.startup.record", true); + registerCleanupFunction(() => { + Services.prefs.clearUserPref("browser.startup.record"); + }); +} + +add_task(async function testDevToolsModuleLoader() { + const dbg = new Debugger(); + + const sharedGlobal = Cu.getGlobalForObject(Services); + const sharedPrincipal = Cu.getObjectPrincipal(sharedGlobal); + + info("Test importing in the regular shared loader"); + const ns = ChromeUtils.importESModule(ESM_URL); + Assert.equal(ns.x, 0); + ns.increment(); + Assert.equal(ns.x, 1); + const nsGlobal = Cu.getGlobalForObject(ns); + const nsPrincipal = Cu.getObjectPrincipal(nsGlobal); + Assert.equal(nsGlobal, sharedGlobal, "Without any parameter, importESModule load in the shared JSM global"); + Assert.equal(nsPrincipal, sharedPrincipal); + Assert.ok(nsPrincipal.isSystemPrincipal); + info("Global of ESM loaded in the shared loader can be inspected by the Debugger"); + dbg.addDebuggee(nsGlobal); + Assert.ok(true, "The global is accepted by the Debugger API"); + + const ns1 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader : false }); + Assert.equal(ns1, ns, "Passing loadInDevToolsLoader=false from the shared JSM global is equivalent to regular importESModule"); + + info("Test importing in the devtools loader"); + const ns2 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader: true }); + Assert.equal(ns2.x, 0, "We get a new module instance with a new incremented number"); + Assert.notEqual(ns2, ns, "We imported a new instance of the module"); + Assert.notEqual(ns2.importedObject, ns.importedObject, "The two module instances expose distinct objects"); + Assert.equal(ns2.importESModuleTrue, ns2.importedObject, "When using loadInDevToolsLoader:true from a devtools global, we keep loading in the same loader"); + Assert.equal(ns2.importESModuleNull, ns2.importedObject, "When having an undefined loadInDevToolsLoader from a devtools global, we keep loading in the same loader"); + Assert.equal(ns2.importESModuleNull2, ns2.importedObject, "When having no optional argument at all, we keep loading in the same loader"); + Assert.equal(ns2.importESModuleFalse, ns.importedObject, "When passing an explicit loadInDevToolsLoader:false, we load in the shared global, even from a devtools global"); + Assert.equal(ns2.importLazy(), ns2.importedObject, "ChromeUtils.defineESModuleGetters imports will follow the contextual loader"); + + info("When using the devtools loader, we load in a distinct global, but the same compartment"); + const ns2Global = Cu.getGlobalForObject(ns2); + const ns2Principal = Cu.getObjectPrincipal(ns2Global); + Assert.notEqual(ns2Global, sharedGlobal, "The module is loaded in a distinct global"); + Assert.equal(ns2Principal, sharedPrincipal, "The principal is still the shared system principal"); + Assert.equal(Cu.getGlobalForObject(ns2.importedObject), ns2Global, "Nested dependencies are also loaded in the same devtools global"); + Assert.throws(() => dbg.addDebuggee(ns2Global), /TypeError: passing non-debuggable global to addDebuggee/, + "Global os ESM loaded in the devtools loader can't be inspected by the Debugee"); + + info("Re-import the same module in the devtools loader"); + const ns3 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader: true }); + Assert.equal(ns3, ns2, "We import the exact same module"); + Assert.equal(ns3.importedObject, ns2.importedObject, "The two module expose the same objects"); + + info("Import a module only from the devtools loader"); + const ns4 = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader_only.js", { loadInDevToolsLoader: true }); + const ns4Global = Cu.getGlobalForObject(ns4); + Assert.equal(ns4Global, ns2Global, "The module is loaded in the same devtools global"); + + // getModuleImportStack only works on nightly builds + if (AppConstants.NIGHTLY_BUILD) { + info("Assert the behavior of getModuleImportStack on modules loaded in the devtools loader"); + Assert.ok(Cu.getModuleImportStack(ESM_URL).includes("testDevToolsModuleLoader")); + Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader.js").includes("testDevToolsModuleLoader")); + Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader.js").includes(ESM_URL)); + // Previous import stack were for module loaded via the shared jsm loader. + // Let's also assert that we get stack traces for modules loaded via the devtools loader. + Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader_only.js").includes("testDevToolsModuleLoader")); + } +}); diff --git a/js/xpconnect/tests/unit/test_import_es6_modules.js b/js/xpconnect/tests/unit/test_import_es6_modules.js new file mode 100644 index 0000000000..9b5659871f --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_es6_modules.js @@ -0,0 +1,180 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_task(async function() { + // Test basic import. + let ns = ChromeUtils.importESModule("resource://test/es6module.js"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns.value, 2); + + // Test re-import of the same module. + let ns2 = ChromeUtils.importESModule("resource://test/es6module.js"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns, ns2); + + // Test imports with absolute and relative URIs return the same thing. + let ns3 = ChromeUtils.importESModule("resource://test/es6module_absolute.js"); + let ns4 = ChromeUtils.importESModule("resource://test/es6module_absolute2.js"); + Assert.ok(ns3.absoluteX === ns3.relativeX); + Assert.ok(ns3.absoluteX === ns4.x); + + // Test load failure. + testFailure("resource://test/es6module_not_found.js", { + type: "Error", + message: "Failed to load resource://test/es6module_not_found.js", + fileName: "test_import_es6_modules.js", + stack: "testFailure", + lineNumber: "*", + columnNumber: "*", + result: Cr.NS_ERROR_FILE_NOT_FOUND, + }); + + // Test load failure in import. + testFailure("resource://test/es6module_missing_import.js", { + type: "Error", + message: "Failed to load resource://test/es6module_not_found2.js", + fileName: "test_import_es6_modules.js", + stack: "testFailure", + lineNumber: "*", + columnNumber: "*", + result: Cr.NS_ERROR_FILE_NOT_FOUND, + }); + + // Test parse error. + testFailure("resource://test/es6module_parse_error.js", { + type: "SyntaxError", + fileName: "resource://test/es6module_parse_error.js", + stack: "testFailure", + lineNumber: 1, + columnNumber: 5, + }); + + // Test parse error in import. + testFailure("resource://test/es6module_parse_error_in_import.js", { + type: "SyntaxError", + fileName: "resource://test/es6module_parse_error.js", + stack: "testFailure", + lineNumber: 1, + columnNumber: 5, + }); + + // Test import error. + testFailure("resource://test/es6module_import_error.js", { + type: "SyntaxError", + fileName: "resource://test/es6module_import_error.js", + lineNumber: 1, + columnNumber: 9, + }); + + // Test execution failure. + let exception1 = testFailure("resource://test/es6module_throws.js", { + type: "Error", + message: "foobar", + stack: "throwFunction", + fileName: "resource://test/es6module_throws.js", + lineNumber: 2, + columnNumber: 9, + }); + + // Test re-import throws the same exception. + let exception2 = testFailure("resource://test/es6module_throws.js", { + type: "Error", + message: "foobar", + stack: "throwFunction", + fileName: "resource://test/es6module_throws.js", + lineNumber: 2, + columnNumber: 9, + }); + Assert.ok(exception1 === exception2); + + // Test loading cyclic module graph. + ns = ChromeUtils.importESModule("resource://test/es6module_cycle_a.js"); + Assert.ok(ns.loaded); + Assert.equal(ns.getValueFromB(), "b"); + ns = ChromeUtils.importESModule("resource://test/es6module_cycle_b.js"); + Assert.ok(ns.loaded); + Assert.equal(ns.getValueFromC(), "c"); + ns = ChromeUtils.importESModule("resource://test/es6module_cycle_c.js"); + Assert.ok(ns.loaded); + Assert.equal(ns.getValueFromA(), "a"); + + // Test top-level await is not supported. + testFailure("resource://test/es6module_top_level_await.js", { + type: "SyntaxError", + message: "not supported", + stack: "testFailure", + fileName: "resource://test/es6module_top_level_await.js", + lineNumber: 1, + columnNumber: 0, + }); + + // Test dynamic import is not supported. + ns = ChromeUtils.importESModule("resource://test/es6module_dynamic_import.js"); + const e = await ns.result; + checkException(e, { + type: "TypeError", + message: "not supported", + fileName: "resource://test/es6module_dynamic_import.js", + lineNumber: 5, + columnNumber: 1, + }); +}); + +function testFailure(url, expected) { + let threw = false; + let exception; + let importLine, importColumn; + try { + // Get the line/column for ChromeUtils.importESModule. + // lineNumber/columnNumber value with "*" in `expected` points the + // line/column. + let e = new Error(); + importLine = e.lineNumber + 3; + importColumn = 17; + ChromeUtils.importESModule(url); + } catch (e) { + threw = true; + exception = e; + } + + Assert.ok(threw, "Error should be thrown"); + + checkException(exception, expected, importLine, importColumn); + + return exception; +} + +function checkException(exception, expected, importLine, importColumn) { + if ("type" in expected) { + Assert.equal(exception.constructor.name, expected.type, "error type"); + } + if ("message" in expected) { + Assert.ok(exception.message.includes(expected.message), + `Message "${exception.message}" should contain "${expected.message}"`); + } + if ("stack" in expected) { + Assert.ok(exception.stack.includes(expected.stack), + `Stack "${exception.stack}" should contain "${expected.stack}"`); + } + if ("fileName" in expected) { + Assert.ok(exception.fileName.includes(expected.fileName), + `fileName "${exception.fileName}" should contain "${expected.fileName}"`); + } + if ("lineNumber" in expected) { + let expectedLine = expected.lineNumber; + if (expectedLine === "*") { + expectedLine = importLine; + } + Assert.equal(exception.lineNumber, expectedLine, "lineNumber"); + } + if ("columnNumber" in expected) { + let expectedColumn = expected.columnNumber; + if (expectedColumn === "*") { + expectedColumn = importColumn; + } + Assert.equal(exception.columnNumber, expectedColumn, "columnNumber"); + } + if ("result" in expected) { + Assert.equal(exception.result, expected.result, "result"); + } +} diff --git a/js/xpconnect/tests/unit/test_import_fail.js b/js/xpconnect/tests/unit/test_import_fail.js new file mode 100644 index 0000000000..9ad7fcb072 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_fail.js @@ -0,0 +1,10 @@ +function run_test() +{ + try { + ChromeUtils.import("resource://test/importer.jsm"); + Assert.ok(false, "import should not succeed."); + } catch (x) { + Assert.notEqual(x.fileName.indexOf("syntax_error.jsm"), -1); + Assert.equal(x.lineNumber, 1); + } +}
\ No newline at end of file diff --git a/js/xpconnect/tests/unit/test_import_from_sandbox.js b/js/xpconnect/tests/unit/test_import_from_sandbox.js new file mode 100644 index 0000000000..ddd384a77b --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_from_sandbox.js @@ -0,0 +1,82 @@ +"use strict"; + +function makeSandbox() { + return Cu.Sandbox( + Services.scriptSecurityManager.getSystemPrincipal(), + { + wantXrays: false, + wantGlobalProperties: ["ChromeUtils"], + sandboxName: `Sandbox type used for ext-*.js ExtensionAPI subscripts`, + } + ); +} + +// This test will fail (and should be removed) once the JSM shim is dropped. +add_task(function test_import_from_sandbox_using_shim() { + let sandbox = makeSandbox(); + Object.assign(sandbox, { + injected1: ChromeUtils.import("resource://test/esmified-1.jsm"), + }); + + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-2.jsm"), false); + + Services.scriptloader.loadSubScript( + `data:, + "use strict"; + + const shimmed1 = ChromeUtils.import("resource://test/esmified-1.jsm"); + const shimmed2 = ChromeUtils.import("resource://test/esmified-2.jsm"); + + this.testResults = { + shimmed1: shimmed1.obj.value, + injected1: injected1.obj.value, + sameInstance1: injected1 === shimmed1, + shimmed2: shimmed2.obj.value, + }; + `, + sandbox + ); + let tr = sandbox.testResults; + + Assert.equal(tr.injected1, 10, "Injected esmified-1.mjs has correct value."); + Assert.equal(tr.shimmed1, 10, "Shim-imported esmified-1.jsm correct value."); + Assert.ok(tr.sameInstance1, "Injected and imported are the same instance."); + Assert.equal(tr.shimmed2, 10, "Shim-imported esmified-2.jsm correct value."); + + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-2.jsm"), true); +}); + +// This tests the ESMification transition for extension API scripts. +add_task(function test_import_from_sandbox_transition() { + let sandbox = makeSandbox(); + + Object.assign(sandbox, { + injected3: ChromeUtils.importESModule("resource://test/esmified-3.sys.mjs"), + }); + + Services.scriptloader.loadSubScript("resource://test/api_script.js", sandbox); + let tr = sandbox.testResults; + + Assert.equal(tr.injected3, 16, "Injected esmified-3.mjs has correct value."); + Assert.equal(tr.module3, 16, "Iimported esmified-3.mjs has correct value."); + Assert.ok(tr.sameInstance3, "Injected and imported are the same instance."); + Assert.equal(tr.module4, 14, "Iimported esmified-4.mjs has correct value."); +}); + +// Same as above, just using a PrecompiledScript. +add_task(async function test_import_from_sandbox_transition() { + let sandbox = makeSandbox(); + + Object.assign(sandbox, { + injected3: ChromeUtils.importESModule("resource://test/esmified-3.sys.mjs"), + }); + + let script = await ChromeUtils.compileScript("resource://test/api_script.js"); + script.executeInGlobal(sandbox); + let tr = sandbox.testResults; + + Assert.equal(tr.injected3, 22, "Injected esmified-3.mjs has correct value."); + Assert.equal(tr.module3, 22, "Iimported esmified-3.mjs has correct value."); + Assert.ok(tr.sameInstance3, "Injected and imported are the same instance."); + Assert.equal(tr.module4, 18, "Iimported esmified-4.mjs has correct value."); +}); diff --git a/js/xpconnect/tests/unit/test_import_shim.js b/js/xpconnect/tests/unit/test_import_shim.js new file mode 100644 index 0000000000..3e265414f8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_shim.js @@ -0,0 +1,377 @@ +add_task(function test_Cu_import_shim_first() { + // Load and cache with shim. + + const exports = {}; + const global = Components.utils.import( + "resource://test/esmified-1.jsm", + exports + ); + Assert.equal(global.loadCount, 1); + Assert.equal(global.obj.value, 10); + Assert.equal(exports.loadCount, 1); + Assert.equal(exports.obj.value, 10); + Assert.ok(exports.obj === global.obj); + + const ns = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns.obj.value, 10); + Assert.ok(ns.obj === global.obj); + + const exports2 = {}; + const global2 = Components.utils.import( + "resource://test/esmified-1.jsm", exports2 + ); + Assert.equal(global2.loadCount, 1); + Assert.equal(global2.obj.value, 10); + Assert.equal(exports2.loadCount, 1); + Assert.equal(exports2.obj.value, 10); + Assert.ok(exports2.obj === global2.obj); + Assert.ok(exports2.obj === global.obj); + + // Also test with *.js extension. + const exports3 = {}; + const global3 = Components.utils.import( + "resource://test/esmified-1.js", exports3 + ); + Assert.equal(global3.loadCount, 1); + Assert.equal(global3.obj.value, 10); + Assert.equal(exports3.loadCount, 1); + Assert.equal(exports3.obj.value, 10); + Assert.ok(exports3.obj === global3.obj); + Assert.ok(exports3.obj === global.obj); + + // Also test with *.jsm.js extension. + const exports4 = {}; + const global4 = Components.utils.import( + "resource://test/esmified-1.js", exports4 + ); + Assert.equal(global4.loadCount, 1); + Assert.equal(global4.obj.value, 10); + Assert.equal(exports4.loadCount, 1); + Assert.equal(exports4.obj.value, 10); + Assert.ok(exports4.obj === global4.obj); + Assert.ok(exports4.obj === global.obj); +}); + +add_task(function test_Cu_import_no_shim_first() { + // Load and cache with importESModule. + + const ns = ChromeUtils.importESModule("resource://test/esmified-2.sys.mjs"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns.obj.value, 10); + + const exports = {}; + const global = Components.utils.import( + "resource://test/esmified-2.jsm", exports + ); + Assert.equal(global.loadCount, 1); + Assert.equal(global.obj.value, 10); + Assert.equal(exports.loadCount, 1); + Assert.equal(exports.obj.value, 10); + Assert.ok(exports.obj === global.obj); + Assert.ok(ns.obj === global.obj); + + const ns2 = ChromeUtils.importESModule("resource://test/esmified-2.sys.mjs"); + Assert.equal(ns2.loadCount, 1); + Assert.equal(ns2.obj.value, 10); +}); + +add_task(function test_ChromeUtils_import_shim_first() { + // Load and cache with shim. + + const exports = {}; + const global = ChromeUtils.import( + "resource://test/esmified-3.jsm", exports + ); + Assert.equal(global.loadCount, 1); + Assert.equal(global.obj.value, 10); + Assert.equal(exports.loadCount, 1); + Assert.equal(exports.obj.value, 10); + Assert.ok(exports.obj === global.obj); + + const ns = ChromeUtils.importESModule("resource://test/esmified-3.sys.mjs"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns.obj.value, 10); + Assert.ok(ns.obj === global.obj); + + const exports2 = {}; + const global2 = ChromeUtils.import( + "resource://test/esmified-3.jsm", exports2 + ); + Assert.equal(global2.loadCount, 1); + Assert.equal(global2.obj.value, 10); + Assert.equal(exports2.loadCount, 1); + Assert.equal(exports2.obj.value, 10); + Assert.ok(exports2.obj === global2.obj); + Assert.ok(exports2.obj === global.obj); +}); + +add_task(function test_ChromeUtils_import_no_shim_first() { + // Load and cache with importESModule. + + const ns = ChromeUtils.importESModule("resource://test/esmified-4.sys.mjs"); + Assert.equal(ns.loadCount, 1); + Assert.equal(ns.obj.value, 10); + + const exports = {}; + const global = ChromeUtils.import( + "resource://test/esmified-4.jsm", exports + ); + Assert.equal(global.loadCount, 1); + Assert.equal(global.obj.value, 10); + Assert.equal(exports.loadCount, 1); + Assert.equal(exports.obj.value, 10); + Assert.ok(exports.obj === global.obj); + Assert.ok(ns.obj === global.obj); + + const ns2 = ChromeUtils.importESModule("resource://test/esmified-4.sys.mjs"); + Assert.equal(ns2.loadCount, 1); + Assert.equal(ns2.obj.value, 10); +}); + +add_task(function test_ChromeUtils_import_not_exported_no_shim_JSM() { + // `exports` properties for not-ESM-ified case. + + const exports = ChromeUtils.import( + "resource://test/not-esmified-not-exported.jsm" + ); + + Assert.equal(exports.exportedVar, "exported var"); + Assert.equal(exports.exportedFunction(), "exported function"); + Assert.equal(exports.exportedLet, "exported let"); + Assert.equal(exports.exportedConst, "exported const"); + Assert.equal(exports.notExportedVar, undefined); + Assert.equal(exports.notExportedFunction, undefined); + Assert.equal(exports.notExportedLet, undefined); + Assert.equal(exports.notExportedConst, undefined); +}); + +add_task(function test_ChromeUtils_import_not_exported_shim() { + // `exports` properties for shim case. + + const exports = ChromeUtils.import( + "resource://test/esmified-not-exported.jsm" + ); + + Assert.equal(exports.exportedVar, "exported var"); + Assert.equal(exports.exportedFunction(), "exported function"); + Assert.equal(exports.exportedLet, "exported let"); + Assert.equal(exports.exportedConst, "exported const"); + Assert.equal(exports.notExportedVar, undefined); + Assert.equal(exports.notExportedFunction, undefined); + Assert.equal(exports.notExportedLet, undefined); + Assert.equal(exports.notExportedConst, undefined); +}); + +add_task(function test_ChromeUtils_import_not_exported_no_shim_ESM() { + // `exports` properties for ESM-ified case. + + const exports = ChromeUtils.importESModule( + "resource://test/esmified-not-exported.sys.mjs" + ); + + Assert.equal(exports.exportedVar, "exported var"); + Assert.equal(exports.exportedFunction(), "exported function"); + Assert.equal(exports.exportedLet, "exported let"); + Assert.equal(exports.exportedConst, "exported const"); + Assert.equal(exports.notExportedVar, undefined); + Assert.equal(exports.notExportedFunction, undefined); + Assert.equal(exports.notExportedLet, undefined); + Assert.equal(exports.notExportedConst, undefined); +}); + +function testReadProxyOps(global, expectedNames, expectedDesc) { + expectedNames.sort(); + + // enumerate + const names = Object.keys(global).sort(); + Assert.equal(JSON.stringify(names), JSON.stringify(expectedNames), + `enumerate`); + + // has + for (const name of expectedNames) { + Assert.ok(name in global, `has for ${name}`); + } + + // getOwnPropertyDescriptor + for (const name of expectedNames) { + const desc = Object.getOwnPropertyDescriptor(global, name); + Assert.equal(desc.value, global[name]); + Assert.equal(desc.writable, expectedDesc.writable, + `writable for ${name}`); + Assert.equal(desc.enumerable, expectedDesc.enumerable, + `enumerable for ${name}`); + Assert.equal(desc.configurable, expectedDesc.configurable, + `configurable for ${name}`); + } +} + +function testWriteProxyOps(global, expectedNames) { + // set: no-op + for (const name of expectedNames) { + const before = global[name]; + global[name] = -1; + Assert.equal(global[name], before, `value after set for ${name}`); + } + + // delete: no-op + for (const name of expectedNames) { + const before = global[name]; + Assert.ok(!(delete global[name]), `delete result for ${name}`); + Assert.equal(global[name], before, `value after delete for ${name}`); + } +} + +add_task(function test_Cu_import_not_exported_no_shim_JSM() { + // `exports` and `global` properties for not-ESM-ified case. + // Not-exported variables should be visible in `global`. + + const exports = {}; + const global = Components.utils.import( + "resource://test/not-esmified-not-exported.jsm", + exports + ); + + Assert.equal(global.exportedVar, "exported var"); + Assert.equal(global.exportedFunction(), "exported function"); + Assert.equal(global.exportedLet, "exported let"); + Assert.equal(global.exportedConst, "exported const"); + Assert.equal(global.notExportedVar, "not exported var"); + Assert.equal(global.notExportedFunction(), "not exported function"); + Assert.equal(global.notExportedLet, "not exported let"); + Assert.equal(global.notExportedConst, "not exported const"); + + const expectedNames = [ + "EXPORTED_SYMBOLS", + "exportedVar", + "exportedFunction", + "exportedLet", + "exportedConst", + "notExportedVar", + "notExportedFunction", + "notExportedLet", + "notExportedConst", + ]; + + testReadProxyOps(global, expectedNames, { + writable: false, + enumerable: true, + configurable: false, + }); + testWriteProxyOps(global, expectedNames); + + Assert.equal(exports.exportedVar, "exported var"); + Assert.equal(exports.exportedFunction(), "exported function"); + Assert.equal(exports.exportedLet, "exported let"); + Assert.equal(exports.exportedConst, "exported const"); + Assert.equal(exports.notExportedVar, undefined); + Assert.equal(exports.notExportedFunction, undefined); + Assert.equal(exports.notExportedLet, undefined); + Assert.equal(exports.notExportedConst, undefined); +}); + +add_task(function test_Cu_import_not_exported_shim() { + // `exports` and `global` properties for shim case. + // Not-exported variables should be visible in global. + + const exports = {}; + const global = Components.utils.import( + "resource://test/esmified-not-exported.jsm", + exports + ); + + Assert.equal(global.exportedVar, "exported var"); + Assert.equal(global.exportedFunction(), "exported function"); + Assert.equal(global.exportedLet, "exported let"); + Assert.equal(global.exportedConst, "exported const"); + + Assert.equal(global.notExportedVar, "not exported var"); + Assert.equal(global.notExportedFunction(), "not exported function"); + Assert.equal(global.notExportedLet, "not exported let"); + Assert.equal(global.notExportedConst, "not exported const"); + + const expectedNames = [ + "exportedVar", + "exportedFunction", + "exportedLet", + "exportedConst", + "notExportedVar", + "notExportedFunction", + "notExportedLet", + "notExportedConst", + ]; + + testReadProxyOps(global, expectedNames, { + writable: false, + enumerable: true, + configurable: false, + }); + testWriteProxyOps(global, expectedNames); + + Assert.equal(exports.exportedVar, "exported var"); + Assert.equal(exports.exportedFunction(), "exported function"); + Assert.equal(exports.exportedLet, "exported let"); + Assert.equal(exports.exportedConst, "exported const"); + Assert.equal(exports.notExportedVar, undefined); + Assert.equal(exports.notExportedFunction, undefined); + Assert.equal(exports.notExportedLet, undefined); + Assert.equal(exports.notExportedConst, undefined); + + const desc = Object.getOwnPropertyDescriptor(global, "*namespace*"); + Assert.ok(!desc, `*namespace* special binding should not be exposed`); + Assert.equal("*namespace*" in global, false, + `*namespace* special binding should not be exposed`); + Assert.equal(global["*namespace*"], undefined, + `*namespace* special binding should not be exposed`); +}); + +add_task(function test_Cu_isModuleLoaded_shim() { + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.js"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm.js"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.jsm"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.sys.mjs"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.sys.mjs"), false); + + Cu.import("resource://test/esmified-5.jsm", {}); + + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm"), true); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.js"), true); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.jsm.js"), true); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.jsm"), true); + + // This is false because Cu.isModuleLoaded does not support ESM directly + // (bug 1768819) + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-5.sys.mjs"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-5.sys.mjs"), false); +}); + +add_task(function test_Cu_isModuleLoaded_no_shim() { + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.js"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm.js"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.js"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm.js"), false); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.sys.mjs"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.sys.mjs"), false); + + ChromeUtils.importESModule("resource://test/esmified-6.sys.mjs"); + + // Regardless of whether the ESM is loaded by shim or not, + // query that accesses the ESM-ified module returns the existence of + // ESM. + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm"), true); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.js"), true); + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.jsm.js"), true); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm"), true); + + // This is false because shim always use *.jsm. + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.js"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.jsm.js"), false); + + // This is false because Cu.isModuleLoaded does not support ESM directly + // (bug 1768819) + Assert.equal(Cu.isModuleLoaded("resource://test/esmified-6.sys.mjs"), false); + Assert.equal(Cu.loadedModules.includes("resource://test/esmified-6.sys.mjs"), false); +}); diff --git a/js/xpconnect/tests/unit/test_import_stack.js b/js/xpconnect/tests/unit/test_import_stack.js new file mode 100644 index 0000000000..2fa35a7502 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_stack.js @@ -0,0 +1,39 @@ +Services.prefs.setBoolPref("browser.startup.record", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("browser.startup.record"); +}); + +add_task(function test_JSModule() { + const URL = "resource://test/import_stack.jsm"; + ChromeUtils.import(URL); + Assert.ok(Cu.getModuleImportStack(URL).includes("test_JSModule")); +}); + +add_task(function test_ESModule() { + const URL = "resource://test/import_stack.sys.mjs"; + ChromeUtils.importESModule(URL); + Assert.ok(Cu.getModuleImportStack(URL).includes("test_ESModule")); +}); + +add_task(function test_ESModule_static_import() { + const URL1 = "resource://test/import_stack_static_1.sys.mjs"; + const URL2 = "resource://test/import_stack_static_2.sys.mjs"; + const URL3 = "resource://test/import_stack_static_3.sys.mjs"; + const URL4 = "resource://test/import_stack_static_4.sys.mjs"; + + ChromeUtils.importESModule(URL1); + + Assert.ok(Cu.getModuleImportStack(URL1).includes("test_ESModule_static")); + + Assert.ok(Cu.getModuleImportStack(URL2).includes("test_ESModule_static")); + Assert.ok(Cu.getModuleImportStack(URL2).includes(URL1)); + + Assert.ok(Cu.getModuleImportStack(URL3).includes("test_ESModule_static")); + Assert.ok(Cu.getModuleImportStack(URL3).includes(URL1)); + Assert.ok(Cu.getModuleImportStack(URL3).includes(URL2)); + + Assert.ok(Cu.getModuleImportStack(URL4).includes("test_ESModule_static")); + Assert.ok(Cu.getModuleImportStack(URL4).includes(URL1)); + Assert.ok(Cu.getModuleImportStack(URL4).includes(URL2)); + Assert.ok(Cu.getModuleImportStack(URL4).includes(URL3)); +}); diff --git a/js/xpconnect/tests/unit/test_import_syntax_error.js b/js/xpconnect/tests/unit/test_import_syntax_error.js new file mode 100644 index 0000000000..bfdcaf9e04 --- /dev/null +++ b/js/xpconnect/tests/unit/test_import_syntax_error.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + + +add_task(async function() { + Assert.throws( + () => ChromeUtils.import("resource://test/error_import.sys.mjs"), + /use ChromeUtils.importESModule instead/, + "Error should be caught and suggest ChromeUtils.importESModule" + ); + + Assert.throws( + () => ChromeUtils.import("resource://test/error_export.sys.mjs"), + /use ChromeUtils.importESModule instead/, + "Error should be caught and suggest ChromeUtils.importESModule" + ); + + Assert.throws( + () => ChromeUtils.import("resource://test/error_other.sys.mjs"), + /expected expression, got end of script/, + "Error should be caught but should not suggest ChromeUtils.importESModule" + ); +}); diff --git a/js/xpconnect/tests/unit/test_isModuleLoaded.js b/js/xpconnect/tests/unit/test_isModuleLoaded.js new file mode 100644 index 0000000000..aaf67c13c7 --- /dev/null +++ b/js/xpconnect/tests/unit/test_isModuleLoaded.js @@ -0,0 +1,20 @@ +function run_test() { + // Existing module. + Assert.ok(!Cu.isModuleLoaded("resource://test/jsm_loaded-1.jsm"), + "isModuleLoaded returned correct value for non-loaded module"); + ChromeUtils.import("resource://test/jsm_loaded-1.jsm"); + Assert.ok(Cu.isModuleLoaded("resource://test/jsm_loaded-1.jsm"), + "isModuleLoaded returned true after loading that module"); + Cu.unload("resource://test/jsm_loaded-1.jsm"); + Assert.ok(!Cu.isModuleLoaded("resource://test/jsm_loaded-1.jsm"), + "isModuleLoaded returned false after unloading that module"); + + // Non-existing module + Assert.ok(!Cu.isModuleLoaded("resource://gre/modules/non-existing-module.jsm"), + "isModuleLoaded returned correct value for non-loaded module"); + Assert.throws( + () => ChromeUtils.import("resource://gre/modules/non-existing-module.jsm"), + /NS_ERROR_FILE_NOT_FOUND/, + "Should have thrown while trying to load a non existing file" + ); +} diff --git a/js/xpconnect/tests/unit/test_isProxy.js b/js/xpconnect/tests/unit/test_isProxy.js new file mode 100644 index 0000000000..996aa320b9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_isProxy.js @@ -0,0 +1,26 @@ +function run_test() { + var handler = { + get: function(target, name){ + return name in target? + target[name] : + 37; + } + }; + + var p = new Proxy({}, handler); + Assert.ok(Cu.isProxy(p)); + Assert.ok(!Cu.isProxy({})); + Assert.ok(!Cu.isProxy(42)); + + sb = new Cu.Sandbox(this, + { wantExportHelpers: true }); + + Assert.ok(!Cu.isProxy(sb)); + + sb.ok = ok; + sb.p = p; + Cu.evalInSandbox('ok(isProxy(p));' + + 'ok(!isProxy({}));' + + 'ok(!isProxy(42));', + sb); +} diff --git a/js/xpconnect/tests/unit/test_js_memory_telemetry.js b/js/xpconnect/tests/unit/test_js_memory_telemetry.js new file mode 100644 index 0000000000..4c44f2e48c --- /dev/null +++ b/js/xpconnect/tests/unit/test_js_memory_telemetry.js @@ -0,0 +1,53 @@ +"use strict"; + +add_task(function test_compartment_realm_counts() { + const compsSystem = "MEMORY_JS_COMPARTMENTS_SYSTEM"; + const compsUser = "MEMORY_JS_COMPARTMENTS_USER"; + const realmsSystem = "MEMORY_JS_REALMS_SYSTEM"; + const realmsUser = "MEMORY_JS_REALMS_USER"; + + Cu.forceShrinkingGC(); + + Services.telemetry.gatherMemory(); + let snapshot1 = Services.telemetry.getSnapshotForHistograms("main", true).parent; + + // We can't hard code exact counts, but we can check some basic invariants: + // + // * Compartments must contain at least one realm, so there must be more + // realms than compartments. + // * There must be at least one system realm. + + Assert.ok(snapshot1[realmsSystem].sum <= snapshot1[compsSystem].sum, + "Number of system compartments can't exceed number of system realms"); + Assert.ok(snapshot1[realmsUser].sum <= snapshot1[compsUser].sum, + "Number of user compartments can't exceed number of user realms"); + Assert.ok(snapshot1[realmsSystem].sum > 0, + "There must be at least one system realm"); + + // Now we create a bunch of sandboxes (more than one to be more resilient + // against GCs happening in the meantime), so we can check: + // + // * There are now more realms and user compartments than before. Not system + // compartments, because system realms share a compartment. + // * The system compartment contains multiple realms. + + let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); + let arr = []; + for (let i = 0; i < 5; i++) { + arr.push(Cu.Sandbox(null)); + arr.push(Cu.Sandbox(systemPrincipal)); + } + + Services.telemetry.gatherMemory(); + let snapshot2 = Services.telemetry.getSnapshotForHistograms("main", true).parent; + + for (let k of [realmsSystem, realmsUser, compsUser]) { + Assert.ok(snapshot2[k].sum > snapshot1[k].sum, + "There must be more compartments/realms now: " + k); + } + + Assert.ok(snapshot2[realmsSystem].sum > snapshot2[compsSystem].sum, + "There must be more system realms than system compartments now"); + + arr[0].x = 10; // Ensure the JS engine keeps |arr| alive until this point. +}); diff --git a/js/xpconnect/tests/unit/test_js_weak_references.js b/js/xpconnect/tests/unit/test_js_weak_references.js new file mode 100644 index 0000000000..2603f24ee2 --- /dev/null +++ b/js/xpconnect/tests/unit/test_js_weak_references.js @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=317304 */ + +function run_test() +{ + // Bug 712649: Calling getWeakReference(null) should work. + try { + var nullWeak = Cu.getWeakReference(null); + Assert.ok(nullWeak.get() === null); + } catch (e) { + Assert.ok(false); + } + + var obj = { num: 5, str: 'foo' }; + var weak = Cu.getWeakReference(obj); + + Assert.ok(weak.get() === obj); + Assert.ok(weak.get().num == 5); + Assert.ok(weak.get().str == 'foo'); + + // Force garbage collection + Cu.forceGC(); + + // obj still references the object, so it should still be accessible via weak + Assert.ok(weak.get() === obj); + Assert.ok(weak.get().num == 5); + Assert.ok(weak.get().str == 'foo'); + + // Clear obj's reference to the object and force garbage collection. To make + // sure that there are no instances of obj stored in the registers or on the + // native stack and the conservative GC would not find it we force the same + // code paths that we used for the initial allocation. + obj = { num: 6, str: 'foo2' }; + var weak2 = Cu.getWeakReference(obj); + Assert.ok(weak2.get() === obj); + + Cu.forceGC(); + + // The object should have been garbage collected and so should no longer be + // accessible via weak + Assert.ok(weak.get() === null); +} diff --git a/js/xpconnect/tests/unit/test_lazyproxy.js b/js/xpconnect/tests/unit/test_lazyproxy.js new file mode 100644 index 0000000000..2cf90b339d --- /dev/null +++ b/js/xpconnect/tests/unit/test_lazyproxy.js @@ -0,0 +1,113 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This file tests the method defineLazyProxy from XPCOMUtils.sys.mjs. + */ + +const {XPCOMUtils} = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs"); + +add_task(function test_lazy_proxy() { + let tmp = {}; + let realObject = { + "prop1": "value1", + "prop2": "value2", + }; + + let evaluated = false; + let untrapCalled = false; + + let lazyProxy = XPCOMUtils.defineLazyProxy( + tmp, + "myLazyProxy", + + // Initiliazer function + function init() { + evaluated = true; + return realObject; + }, + + // Stub properties + { + "prop1": "stub" + }, + + // Untrap callback + function untrapCallback(obj) { + Assert.equal(obj, realObject, "The underlying object can be obtained in the untrap callback"); + untrapCalled = true; + } + ); + + // Check that the proxy returned and the one + // defined in tmp are the same. + // + // Note: Assert.strictEqual can't be used here + // because it wants to stringify the two objects + // compared, which defeats the lazy proxy. + Assert.ok(lazyProxy === tmp.myLazyProxy, "Return value and object defined are the same"); + + Assert.ok(Cu.isProxy(lazyProxy), "Returned value is in fact a proxy"); + + // Check that just using the proxy above didn't + // trigger the lazy getter evaluation. + Assert.ok(!evaluated, "The lazy proxy hasn't been evaluated yet"); + Assert.ok(!untrapCalled, "The untrap callback hasn't been called yet"); + + // Accessing a stubbed property returns the stub + // value and doesn't trigger evaluation. + Assert.equal(lazyProxy.prop1, "stub", "Accessing a stubbed property returns the stubbed value"); + + Assert.ok(!evaluated, "The access to the stubbed property above didn't evaluate the lazy proxy"); + Assert.ok(!untrapCalled, "The untrap callback hasn't been called yet"); + + // Now the access to another property will trigger + // the evaluation, as expected. + Assert.equal(lazyProxy.prop2, "value2", "Property access is correctly forwarded to the underlying object"); + + Assert.ok(evaluated, "Accessing a non-stubbed property triggered the proxy evaluation"); + Assert.ok(untrapCalled, "The untrap callback was called"); + + // The value of prop1 is now the real value and not the stub value. + Assert.equal(lazyProxy.prop1, "value1", "The value of prop1 is now the real value and not the stub one"); +}); + +add_task(function test_module_version() { + // Test that passing a string instead of an initialization function + // makes this behave like a lazy module getter. + const TEST_FILE_URI = "resource://test/TestFile.jsm"; + let underlyingObject; + + Cu.unload(TEST_FILE_URI); + + let lazyProxy = XPCOMUtils.defineLazyProxy( + null, + "TestFile", + TEST_FILE_URI, + null, /* no stubs */ + function untrapCallback(object) { + underlyingObject = object; + } + ); + + Assert.ok(!Cu.isModuleLoaded(TEST_FILE_URI), "The NetUtil module was not loaded by the lazy proxy definition"); + + // Access the object, which will evaluate the proxy. + lazyProxy.foo = "bar"; + + // Module was loaded. + Assert.ok(Cu.isModuleLoaded(TEST_FILE_URI), "The NetUtil module was loaded"); + + let { TestFile } = ChromeUtils.import(TEST_FILE_URI, {}); + + // Avoids a gigantic stringification in the logs. + Assert.ok(TestFile === underlyingObject, "The module loaded is the same as the one directly obtained by ChromeUtils.import"); + + // Proxy correctly passed the setter to the underlying object. + Assert.equal(TestFile.foo, "bar", "Proxy correctly passed the setter to the underlying object"); + + delete lazyProxy.foo; + + // Proxy correctly passed the delete operation to the underlying object. + Assert.ok(!TestFile.hasOwnProperty("foo"), "Proxy correctly passed the delete operation to the underlying object"); +}); diff --git a/js/xpconnect/tests/unit/test_loadedESModules.js b/js/xpconnect/tests/unit/test_loadedESModules.js new file mode 100644 index 0000000000..00e1059037 --- /dev/null +++ b/js/xpconnect/tests/unit/test_loadedESModules.js @@ -0,0 +1,127 @@ +add_task(function test_JSModule() { + const URL1 = "resource://test/jsm_loaded-1.jsm"; + const URL2 = "resource://test/jsm_loaded-2.jsm"; + const URL3 = "resource://test/jsm_loaded-3.jsm"; + + Assert.ok(!Cu.loadedJSModules.includes(URL1)); + Assert.ok(!Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(!Cu.loadedESModules.includes(URL1)); + Assert.ok(!Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.import(URL1); + + Assert.ok(Cu.loadedJSModules.includes(URL1)); + Assert.ok(Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(!Cu.loadedESModules.includes(URL1)); + Assert.ok(!Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.import(URL2); + + Assert.ok(Cu.loadedJSModules.includes(URL1)); + Assert.ok(Cu.isJSModuleLoaded(URL1)); + Assert.ok(Cu.loadedJSModules.includes(URL2)); + Assert.ok(Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(!Cu.loadedESModules.includes(URL1)); + Assert.ok(!Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.import(URL3); + + Assert.ok(Cu.loadedJSModules.includes(URL1)); + Assert.ok(Cu.isJSModuleLoaded(URL1)); + Assert.ok(Cu.loadedJSModules.includes(URL2)); + Assert.ok(Cu.isJSModuleLoaded(URL2)); + Assert.ok(Cu.loadedJSModules.includes(URL3)); + Assert.ok(Cu.isJSModuleLoaded(URL3)); + Assert.ok(!Cu.loadedESModules.includes(URL1)); + Assert.ok(!Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); +}); + +add_task(function test_ESModule() { + const URL1 = "resource://test/es6module_loaded-1.sys.mjs"; + const URL2 = "resource://test/es6module_loaded-2.sys.mjs"; + const URL3 = "resource://test/es6module_loaded-3.sys.mjs"; + + Assert.ok(!Cu.loadedJSModules.includes(URL1)); + Assert.ok(!Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(!Cu.loadedESModules.includes(URL1)); + Assert.ok(!Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.importESModule(URL1); + + Assert.ok(!Cu.loadedJSModules.includes(URL1)); + Assert.ok(!Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(Cu.loadedESModules.includes(URL1)); + Assert.ok(Cu.isESModuleLoaded(URL1)); + Assert.ok(!Cu.loadedESModules.includes(URL2)); + Assert.ok(!Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.importESModule(URL2); + + Assert.ok(!Cu.loadedJSModules.includes(URL1)); + Assert.ok(!Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(Cu.loadedESModules.includes(URL1)); + Assert.ok(Cu.isESModuleLoaded(URL1)); + Assert.ok(Cu.loadedESModules.includes(URL2)); + Assert.ok(Cu.isESModuleLoaded(URL2)); + Assert.ok(!Cu.loadedESModules.includes(URL3)); + Assert.ok(!Cu.isESModuleLoaded(URL3)); + + ChromeUtils.importESModule(URL3); + + Assert.ok(!Cu.loadedJSModules.includes(URL1)); + Assert.ok(!Cu.isJSModuleLoaded(URL1)); + Assert.ok(!Cu.loadedJSModules.includes(URL2)); + Assert.ok(!Cu.isJSModuleLoaded(URL2)); + Assert.ok(!Cu.loadedJSModules.includes(URL3)); + Assert.ok(!Cu.isJSModuleLoaded(URL3)); + Assert.ok(Cu.loadedESModules.includes(URL1)); + Assert.ok(Cu.isESModuleLoaded(URL1)); + Assert.ok(Cu.loadedESModules.includes(URL2)); + Assert.ok(Cu.isESModuleLoaded(URL2)); + Assert.ok(Cu.loadedESModules.includes(URL3)); + Assert.ok(Cu.isESModuleLoaded(URL3)); +}); diff --git a/js/xpconnect/tests/unit/test_localeCompare.js b/js/xpconnect/tests/unit/test_localeCompare.js new file mode 100644 index 0000000000..fa98d865e4 --- /dev/null +++ b/js/xpconnect/tests/unit/test_localeCompare.js @@ -0,0 +1,6 @@ +function run_test() { + Assert.ok("C".localeCompare("D") < 0); + Assert.ok("D".localeCompare("C") > 0); + Assert.ok("\u010C".localeCompare("D") < 0); + Assert.ok("D".localeCompare("\u010C") > 0); +} diff --git a/js/xpconnect/tests/unit/test_messageChannel.js b/js/xpconnect/tests/unit/test_messageChannel.js new file mode 100644 index 0000000000..685aa10e43 --- /dev/null +++ b/js/xpconnect/tests/unit/test_messageChannel.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_task(async function() { + let sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["MessageChannel"] }); + sb.ok = ok; + Cu.evalInSandbox('ok((new MessageChannel()) instanceof MessageChannel);', + sb); + Cu.evalInSandbox('ok((new MessageChannel()).port1 instanceof MessagePort);', + sb); + + Cu.importGlobalProperties(["MessageChannel"]); + + let mc = new MessageChannel(); + Assert.ok(mc instanceof MessageChannel); + Assert.ok(mc.port1 instanceof MessagePort); + Assert.ok(mc.port2 instanceof MessagePort); + + mc.port1.postMessage(42); + + let result = await new Promise(resolve => { + mc.port2.onmessage = e => { + resolve(e.data); + } + }); + + Assert.equal(result, 42); +}); diff --git a/js/xpconnect/tests/unit/test_nuke_sandbox.js b/js/xpconnect/tests/unit/test_nuke_sandbox.js new file mode 100644 index 0000000000..c555121306 --- /dev/null +++ b/js/xpconnect/tests/unit/test_nuke_sandbox.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=769273 */ + +const global = this; + +function run_test() +{ + var ifacePointer = Cc["@mozilla.org/supports-interface-pointer;1"] + .createInstance(Ci.nsISupportsInterfacePointer); + + var sb = Cu.Sandbox(global, {wantGlobalProperties: ["ChromeUtils"]}); + sb.prop = "prop" + sb.ifacePointer = ifacePointer + + var refToObjFromSb = Cu.evalInSandbox(` + ifacePointer.data = { + QueryInterface: ChromeUtils.generateQI([]), + wrappedJSObject: {foo: "bar"}, + }; + + var a = {prop2:'prop2'}; + a + `, sb); + + equal(ifacePointer.data.wrappedJSObject.foo, "bar", + "Got expected wrapper into sandbox") + + Cu.nukeSandbox(sb); + ok(Cu.isDeadWrapper(sb), "sb should be dead"); + ok(Cu.isDeadWrapper(ifacePointer.data.wrappedJSObject), + "Wrapper retrieved via XPConnect should be dead"); + + try{ + sb.prop; + Assert.ok(false); + } catch (e) { + Assert.ok(e.toString().indexOf("can't access dead object") > -1); + } + + Cu.isDeadWrapper(refToObjFromSb, "ref to object from sb should be dead"); + try{ + refToObjFromSb.prop2; + Assert.ok(false); + } catch (e) { + Assert.ok(e.toString().indexOf("can't access dead object") > -1); + } +} diff --git a/js/xpconnect/tests/unit/test_nuke_sandbox_event_listeners.js b/js/xpconnect/tests/unit/test_nuke_sandbox_event_listeners.js new file mode 100644 index 0000000000..2e304a8b72 --- /dev/null +++ b/js/xpconnect/tests/unit/test_nuke_sandbox_event_listeners.js @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1273251 + +function promiseEvent(target, event) { + return new Promise(resolve => { + target.addEventListener(event, resolve, {capture: true, once: true}); + }); +} + +add_task(async function() { + let principal = Services.scriptSecurityManager + .createContentPrincipalFromOrigin("http://example.com/"); + + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + + docShell.createAboutBlankContentViewer(principal, principal); + + let window = webnav.document.defaultView; + let sandbox = Cu.Sandbox(window, {sandboxPrototype: window}); + + function sandboxContent() { + window.onload = function SandboxOnLoad() {}; + + window.addEventListener("FromTest", () => { + window.dispatchEvent(new CustomEvent("FromSandbox")); + }, true); + } + + Cu.evalInSandbox(`(${sandboxContent})()`, sandbox); + + + let fromTestPromise = promiseEvent(window, "FromTest"); + let fromSandboxPromise = promiseEvent(window, "FromSandbox"); + + equal(typeof window.onload, "function", + "window.onload should contain sandbox event listener"); + equal(window.onload.name, "SandboxOnLoad", + "window.onload have the correct function name"); + + info("Dispatch FromTest event"); + window.dispatchEvent(new window.CustomEvent("FromTest")); + + await fromTestPromise; + info("Got event from test"); + + await fromSandboxPromise; + info("Got response from sandbox"); + + + window.addEventListener("FromSandbox", () => { + ok(false, "Got unexpected reply from sandbox"); + }, true); + + info("Nuke sandbox"); + Cu.nukeSandbox(sandbox); + + + info("Dispatch FromTest event"); + fromTestPromise = promiseEvent(window, "FromTest"); + window.dispatchEvent(new window.CustomEvent("FromTest")); + await fromTestPromise; + info("Got event from test"); + + + // Force cycle collection, which should cause our callback reference + // to be dropped, and dredge up potential issues there. + Cu.forceGC(); + Cu.forceCC(); + + ok(Cu.isDeadWrapper(window.onload), + "window.onload should contain a dead wrapper after sandbox is nuked"); + + info("Dispatch FromTest event"); + fromTestPromise = promiseEvent(window, "FromTest"); + window.dispatchEvent(new window.CustomEvent("FromTest")); + await fromTestPromise; + info("Got event from test"); + + let listeners = Services.els.getListenerInfoFor(window); + ok(!listeners.some(info => info.type == "FromTest"), + "No 'FromTest' listeners returned for nuked sandbox"); + + webnav.close(); +}); diff --git a/js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js b/js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js new file mode 100644 index 0000000000..34fd0511bc --- /dev/null +++ b/js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js @@ -0,0 +1,71 @@ +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1273251 + +const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +ChromeUtils.importESModule("resource://gre/modules/Timer.sys.mjs"); +const {TestUtils} = ChromeUtils.importESModule("resource://testing-common/TestUtils.sys.mjs"); + +function getWindowlessBrowser(url) { + let ssm = Services.scriptSecurityManager; + + let uri = NetUtil.newURI(url); + + let principal = ssm.createContentPrincipal(uri, {}); + + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + + docShell.createAboutBlankContentViewer(principal, principal); + + return webnav; +} + +function StubPolicy(id) { + return new WebExtensionPolicy({ + id, + mozExtensionHostname: id, + baseURL: `file:///{id}`, + + allowedOrigins: new MatchPatternSet([]), + localizeCallback(string) {}, + }); +} + +add_task(async function() { + let policy = StubPolicy("foo"); + policy.active = true; + + let webnavA = getWindowlessBrowser("moz-extension://foo/a.html"); + let webnavB = getWindowlessBrowser("moz-extension://foo/b.html"); + + let winA = Cu.waiveXrays(webnavA.document.defaultView); + let winB = Cu.waiveXrays(webnavB.document.defaultView); + + winB.winA = winA; + winB.eval(`winA.thing = {foo: "bar"};`); + + let getThing = winA.eval(String(() => { + try { + return thing.foo; + } catch (e) { + return String(e); + } + })); + + // Check that the object can be accessed normally before windowB is closed. + equal(getThing(), "bar"); + + webnavB.close(); + + // Wrappers are nuked asynchronously, so wait for that to happen. + await TestUtils.topicObserved("inner-window-nuked"); + + // Check that it can't be accessed after he window has been closed. + let result = getThing(); + ok(/dead object/.test(result), + `Result should show a dead wrapper error: ${result}`); + + webnavA.close(); + + policy.active = false; +}); diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-01.js b/js/xpconnect/tests/unit/test_onGarbageCollection-01.js new file mode 100644 index 0000000000..81ac713865 --- /dev/null +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-01.js @@ -0,0 +1,69 @@ +// Test basic usage of onGarbageCollection + +const root = newGlobal(); +const dbg = new Debugger(); +const wrappedRoot = dbg.addDebuggee(root) + +const NUM_SLICES = root.NUM_SLICES = 10; + +let fired = false; +let slicesFound = 0; + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +dbg.memory.onGarbageCollection = data => { + fired = true; + + print("Got onGarbageCollection: " + JSON.stringify(data, null, 2)); + + equal(typeof data.reason, "string"); + equal(typeof data.nonincrementalReason == "string" || data.nonincrementalReason === null, + true); + + let lastStartTimestamp = 0; + for (let i = 0; i < data.collections.length; i++) { + let slice = data.collections[i]; + + equal(slice.startTimestamp >= lastStartTimestamp, true); + equal(slice.startTimestamp <= slice.endTimestamp, true); + + lastStartTimestamp = slice.startTimestamp; + } + + equal(data.collections.length >= 1, true); + slicesFound += data.collections.length; +} + +function run_test() { + do_test_pending(); + + root.eval( + ` + this.allocs = []; + + // GC slices + for (var i = 0; i < NUM_SLICES; i++) { + this.allocs.push({}); + gcslice(); + } + + // Full GC + this.allocs.push({}); + gc(); + ` + ); + + executeSoon(() => { + equal(fired, true, "The GC hook should have fired at least once"); + + // NUM_SLICES + 1 full gc + however many were triggered naturally (due to + // whatever zealousness setting). + print("Found " + slicesFound + " slices"); + equal(slicesFound >= NUM_SLICES + 1, true); + + do_test_finished(); + }); +} diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-02.js b/js/xpconnect/tests/unit/test_onGarbageCollection-02.js new file mode 100644 index 0000000000..fc3bf685ef --- /dev/null +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-02.js @@ -0,0 +1,99 @@ +// Test multiple debuggers, GCs, and zones interacting with each other. +// +// Note: when observing both globals, but GC'ing in only one, we don't test that +// we *didn't* GC in the other zone because GCs are finicky and unreliable. That +// used to work when this was a jit-test, but in the process of migrating to +// xpcshell, we lost some amount of reliability and determinism. + +const root1 = newGlobal(); +const dbg1 = new Debugger(); +dbg1.addDebuggee(root1) + +const root2 = newGlobal(); +const dbg2 = new Debugger(); +dbg2.addDebuggee(root2) + +let fired1 = false; +let fired2 = false; +dbg1.memory.onGarbageCollection = _ => fired1 = true; +dbg2.memory.onGarbageCollection = _ => fired2 = true; + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +function reset() { + fired1 = false; + fired2 = false; +} + +function run_test() { + do_test_pending(); + + gc(); + executeSoon(() => { + reset(); + + // GC 1 only + root1.eval(`gc(this)`); + executeSoon(() => { + equal(fired1, true); + + // GC 2 only + reset(); + root2.eval(`gc(this)`); + executeSoon(() => { + equal(fired2, true); + + // Full GC + reset(); + gc(); + executeSoon(() => { + equal(fired1, true); + equal(fired2, true); + + // Full GC with no debuggees + reset(); + dbg1.removeAllDebuggees(); + dbg2.removeAllDebuggees(); + gc(); + executeSoon(() => { + equal(fired1, false); + equal(fired2, false); + + // One debugger with multiple debuggees in different zones. + + dbg1.addDebuggee(root1); + dbg1.addDebuggee(root2); + + // Just debuggee 1 + reset(); + root1.eval(`gc(this)`); + executeSoon(() => { + equal(fired1, true); + equal(fired2, false); + + // Just debuggee 2 + reset(); + root2.eval(`gc(this)`); + executeSoon(() => { + equal(fired1, true); + equal(fired2, false); + + // All debuggees + reset(); + gc(); + executeSoon(() => { + equal(fired1, true); + equal(fired2, false); + do_test_finished(); + }); + }); + }); + }); + }); + }); + }); + }); +} diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-03.js b/js/xpconnect/tests/unit/test_onGarbageCollection-03.js new file mode 100644 index 0000000000..d983e2cd11 --- /dev/null +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-03.js @@ -0,0 +1,39 @@ +// Test that the onGarbageCollection hook is not reentrant. + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +function run_test() { + do_test_pending(); + + const root = newGlobal(); + const dbg = new Debugger(); + const wrappedRoot = dbg.addDebuggee(root) + + let fired = true; + let depth = 0; + + dbg.memory.onGarbageCollection = _ => { + fired = true; + + equal(depth, 0); + depth++; + try { + root.eval(`gc()`); + } finally { + equal(depth, 1); + depth--; + } + } + + root.eval(`gc()`); + + executeSoon(() => { + ok(fired); + equal(depth, 0); + dbg.memory.onGarbageCollection = undefined; + do_test_finished(); + }); +} diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-04.js b/js/xpconnect/tests/unit/test_onGarbageCollection-04.js new file mode 100644 index 0000000000..72e6d32284 --- /dev/null +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-04.js @@ -0,0 +1,72 @@ +// Test that the onGarbageCollection reentrancy guard is on a per Debugger +// basis. That is if our first Debugger is observing our second Debugger's +// compartment, and this second Debugger triggers a GC inside its +// onGarbageCollection hook, the first Debugger's onGarbageCollection hook is +// still called. +// +// This is the scenario we are setting up: top level debugging the `debuggeree` +// global, which is debugging the `debuggee` global. Then, we trigger the +// following events: +// +// debuggee gc +// | +// V +// debuggeree's onGarbageCollection +// | +// V +// debuggeree gc +// | +// V +// top level onGarbageCollection +// +// Note that the top level's onGarbageCollection hook should be fired, at the +// same time that we are preventing reentrancy into debuggeree's +// onGarbageCollection hook. + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +function run_test() { + do_test_pending(); + + const debuggeree = newGlobal(); + const debuggee = debuggeree.debuggee = newGlobal(); + + debuggeree.eval( + ` + var dbg = new Debugger(this.debuggee); + var fired = 0; + dbg.memory.onGarbageCollection = _ => { + fired++; + gc(this); + }; + ` + ); + + const dbg = new Debugger(debuggeree); + let fired = 0; + dbg.memory.onGarbageCollection = _ => { + fired++; + }; + + debuggee.eval(`gc(this)`); + + // Let first onGarbageCollection runnable get run. + executeSoon(() => { + + // Let second onGarbageCollection runnable get run. + executeSoon(() => { + + // Even though we request GC'ing a single zone, we can't rely on that + // behavior and both zones could have been scheduled for gc for both + // gc(this) calls. + ok(debuggeree.fired >= 1); + ok(fired >= 1); + + debuggeree.dbg.removeAllDebuggees(); + do_test_finished(); + }); + }); +} diff --git a/js/xpconnect/tests/unit/test_onGarbageCollection-05.js b/js/xpconnect/tests/unit/test_onGarbageCollection-05.js new file mode 100644 index 0000000000..e3b5e5fd9e --- /dev/null +++ b/js/xpconnect/tests/unit/test_onGarbageCollection-05.js @@ -0,0 +1,42 @@ +// Test that the onGarbageCollection hook reports its gc cycle's number (aka the +// major GC number) and that it is monotonically increasing. + +const root = newGlobal(); +const dbg = new Debugger(); +const wrappedRoot = dbg.addDebuggee(root) + +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +function run_test() { + do_test_pending(); + + let numFired = 0; + let lastGCCycleNumber = undefined; + + (function loop() { + if (numFired == 10) { + dbg.memory.onGarbageCollection = undefined; + dbg.enabled = false; + return void do_test_finished(); + } + + dbg.memory.onGarbageCollection = data => { + print("onGarbageCollection: " + uneval(data)); + + if (numFired != 0) { + equal(typeof lastGCCycleNumber, "number"); + equal(data.gcCycleNumber - lastGCCycleNumber, 1); + } + + numFired++; + lastGCCycleNumber = data.gcCycleNumber; + + executeSoon(loop); + }; + + root.eval("gc(this)"); + }()); +} diff --git a/js/xpconnect/tests/unit/test_params.js b/js/xpconnect/tests/unit/test_params.js new file mode 100644 index 0000000000..fc986424c6 --- /dev/null +++ b/js/xpconnect/tests/unit/test_params.js @@ -0,0 +1,384 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function TestParams() { +} + +/* For once I'm happy that JS is weakly typed. */ +function f(a, b) { + var rv = b.value; + b.value = a; + return rv; +}; + +/* Implementation for size_is and iid_is methods. */ +function f_is(aIs, a, bIs, b, rvIs) { + + // Set up the return value and its 'is' parameter. + var rv = b.value; + rvIs.value = bIs.value; + + // Set up b and its 'is' parameter. + b.value = a; + bIs.value = aIs; + + return rv; +} + +function f_size_and_iid(aSize, aIID, a, bSize, bIID, b, rvSize, rvIID) { + + // Copy the iids. + rvIID.value = bIID.value; + bIID.value = aIID; + + // Now that we've reduced the problem to one dependent variable, use f_is. + return f_is(aSize, a, bSize, b, rvSize); +} + +TestParams.prototype = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestParams"]), + + /* nsIXPCTestParams */ + testBoolean: f, + testOctet: f, + testShort: f, + testLong: f, + testLongLong: f, + testUnsignedShort: f, + testUnsignedLong: f, + testUnsignedLongLong: f, + testFloat: f, + testDouble: f, + testChar: f, + testString: f, + testWchar: f, + testWstring: f, + testAString: f, + testAUTF8String: f, + testACString: f, + testJsval: f, + testShortSequence: f, + testDoubleSequence: f, + testAStringSequence: f, + testACStringSequence: f, + testInterfaceSequence: f, + testJsvalSequence: f, + testInterfaceIsSequence: f_is, + testOptionalSequence: function (arr) { return arr; }, + testShortArray: f_is, + testDoubleArray: f_is, + testStringArray: f_is, + testByteArrayOptionalLength(arr) { return arr.length; }, + testWstringArray: f_is, + testInterfaceArray: f_is, + testJsvalArray: f_is, + testSizedString: f_is, + testSizedWstring: f_is, + testInterfaceIs: f_is, + testInterfaceIsArray: f_size_and_iid, + testOutAString: function(o) { o.value = "out"; }, + testStringArrayOptionalSize: function(arr, size) { + if (arr.length != size) { throw "bad size passed to test method"; } + var rv = ""; + arr.forEach((x) => rv += x); + return rv; + }, + testOmittedOptionalOut(jsObj, o) { + if (typeof o != "object" || o.value !== undefined) { + throw new Components.Exception( + "unexpected value", + Cr.NS_ERROR_ILLEGAL_VALUE + ); + } + o.value = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService) + .newURI("http://example.com/"); + }, + testNaN: NaN, +}; + +function TestInterfaceA() {} +TestInterfaceA.prototype = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceA"]), + + /* nsIXPCTestInterfaceA */ + name: "TestInterfaceADefaultName" +}; + +function TestInterfaceB() {} +TestInterfaceB.prototype = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceB"]), + + /* nsIXPCTestInterfaceA */ + name: "TestInterfaceADefaultName" +}; + +function run_test() { + + // Load the component manifests. + registerXPCTestComponents(); + + // Test for each component. + test_component(Cc["@mozilla.org/js/xpc/test/native/Params;1"].createInstance()); + test_component(xpcWrap(new TestParams())); +} + +function test_component(obj) { + var o = obj.QueryInterface(Ci.nsIXPCTestParams); + + // Possible comparator functions. + var standardComparator = function(a,b) {return a == b;}; + var dotEqualsComparator = function(a,b) {return a.equals(b); } + var fuzzComparator = function(a,b) {return Math.abs(a - b) < 0.1;}; + var interfaceComparator = function(a,b) {return a.name == b.name; } + var arrayComparator = function(innerComparator) { + return function(a,b) { + if (a.length != b.length) + return false; + for (var i = 0; i < a.length; ++i) + if (!innerComparator(a[i], b[i])) + return false; + return true; + }; + }; + + // Helper test function - takes the name of test method and two values of + // the given type. + // + // The optional comparator argument can be used for alternative notions of + // equality. The comparator should return true on equality. + function doTest(name, val1, val2, comparator) { + if (!comparator) + comparator = standardComparator; + var a = val1; + var b = {value: val2}; + var rv = o[name].call(o, a, b); + Assert.ok(comparator(rv, val2)); + Assert.ok(comparator(val1, b.value)); + }; + + function doIsTest(name, val1, val1Is, val2, val2Is, valComparator, isComparator) { + if (!isComparator) + isComparator = standardComparator; + var a = val1; + var aIs = val1Is; + var b = {value: val2}; + var bIs = {value: val2Is}; + var rvIs = {}; + var rv = o[name].call(o, aIs, a, bIs, b, rvIs); + Assert.ok(valComparator(rv, val2)); + Assert.ok(isComparator(rvIs.value, val2Is)); + Assert.ok(valComparator(val1, b.value)); + Assert.ok(isComparator(val1Is, bIs.value)); + } + + // Special-purpose function for testing arrays of iid_is interfaces, where we + // have 2 distinct sets of dependent parameters. + function doIs2Test(name, val1, val1Size, val1IID, val2, val2Size, val2IID) { + var a = val1; + var aSize = val1Size; + var aIID = val1IID; + var b = {value: val2}; + var bSize = {value: val2Size}; + var bIID = {value: val2IID}; + var rvSize = {}; + var rvIID = {}; + var rv = o[name].call(o, aSize, aIID, a, bSize, bIID, b, rvSize, rvIID); + Assert.ok(arrayComparator(interfaceComparator)(rv, val2)); + Assert.ok(standardComparator(rvSize.value, val2Size)); + Assert.ok(dotEqualsComparator(rvIID.value, val2IID)); + Assert.ok(arrayComparator(interfaceComparator)(val1, b.value)); + Assert.ok(standardComparator(val1Size, bSize.value)); + Assert.ok(dotEqualsComparator(val1IID, bIID.value)); + } + + // Check that the given call (type mismatch) results in an exception being thrown. + function doTypedArrayMismatchTest(name, val1, val1Size, val2, val2Size) { + var comparator = arrayComparator(standardComparator); + var error = false; + try { + doIsTest(name, val1, val1Size, val2, val2Size, comparator); + + // An exception was not thrown as would have been expected. + Assert.ok(false); + } + catch (e) { + // An exception was thrown as expected. + Assert.ok(true); + } + } + + // Workaround for bug 687612 (inout parameters broken for dipper types). + // We do a simple test of copying a into b, and ignore the rv. + function doTestWorkaround(name, val1) { + var a = val1; + var b = {value: ""}; + o[name].call(o, a, b); + Assert.equal(val1, b.value); + } + + // Test all the different types + doTest("testBoolean", true, false); + doTest("testOctet", 4, 156); + doTest("testShort", -456, 1299); + doTest("testLong", 50060, -12121212); + doTest("testLongLong", 12345, -10000000000); + doTest("testUnsignedShort", 1532, 65000); + doTest("testUnsignedLong", 0, 4000000000); + doTest("testUnsignedLongLong", 215435, 3453492580348535809); + doTest("testFloat", 4.9, -11.2, fuzzComparator); + doTest("testDouble", -80.5, 15000.2, fuzzComparator); + doTest("testChar", "a", "2"); + doTest("testString", "someString", "another string"); + doTest("testWstring", "Why wasnt this", "turned on before? ಠ_ಠ"); + doTest("testWchar", "z", "ア"); + doTestWorkaround("testAString", "Frosty the ☃ ;-)"); + doTestWorkaround("testAUTF8String", "We deliver 〠!"); + doTestWorkaround("testACString", "Just a regular C string."); + doTest("testJsval", {aprop: 12, bprop: "str"}, 4.22); + + // Test out dipper parameters, since they're special and we can't really test + // inouts. + let outAString = {}; + o.testOutAString(outAString); + Assert.equal(outAString.value, "out"); + try { o.testOutAString(undefined); } catch (e) {} // Don't crash + try { o.testOutAString(null); } catch (e) {} // Don't crash + try { o.testOutAString("string"); } catch (e) {} // Don't crash + + // Helpers to instantiate various test XPCOM objects. + var numAsMade = 0; + function makeA() { + var a = xpcWrap(new TestInterfaceA(), Ci.nsIXPCTestInterfaceA); + a.name = 'testA' + numAsMade++; + return a; + }; + var numBsMade = 0; + function makeB() { + var b = xpcWrap(new TestInterfaceB(), Ci.nsIXPCTestInterfaceB); + b.name = 'testB' + numBsMade++; + return b; + }; + + // Test arrays. + doIsTest("testShortArray", [2, 4, 6], 3, [1, 3, 5, 7], 4, arrayComparator(standardComparator)); + doIsTest("testDoubleArray", [-10, -0.5], 2, [1, 3, 1e11, -8e-5 ], 4, arrayComparator(fuzzComparator)); + + doIsTest("testStringArray", ["mary", "hat", "hey", "lid", "tell", "lam"], 6, + ["ids", "fleas", "woes", "wide", "has", "know", "!"], 7, arrayComparator(standardComparator)); + doIsTest("testWstringArray", ["沒有語言", "的偉大嗎?]"], 2, + ["we", "are", "being", "sooo", "international", "right", "now"], 7, arrayComparator(standardComparator)); + doIsTest("testInterfaceArray", [makeA(), makeA()], 2, + [makeA(), makeA(), makeA(), makeA(), makeA(), makeA()], 6, arrayComparator(interfaceComparator)); + doIsTest("testJsvalArray", [{ cheese: 'whiz', apple: 8 }, [1, 5, '3'], /regex/], 3, + ['apple', 2.2e10, 3.3e30, { only: "wheedle", except: {} }], 4, arrayComparator(standardComparator)); + + // Test typed arrays and ArrayBuffer aliasing. + var arrayBuffer = new ArrayBuffer(16); + var int16Array = new Int16Array(arrayBuffer, 2, 3); + int16Array.set([-32768, 0, 32767]); + doIsTest("testShortArray", int16Array, 3, new Int16Array([1773, -32768, 32767, 7]), 4, arrayComparator(standardComparator)); + doIsTest("testDoubleArray", new Float64Array([-10, -0.5]), 2, new Float64Array([0, 3.2, 1.0e10, -8.33 ]), 4, arrayComparator(fuzzComparator)); + + // Test sized strings. + var ssTests = ["Tis not possible, I muttered", "give me back my free hardcore!", "quoth the server:", "4〠4"]; + doIsTest("testSizedString", ssTests[0], ssTests[0].length, ssTests[1], ssTests[1].length, standardComparator); + doIsTest("testSizedWstring", ssTests[2], ssTests[2].length, ssTests[3], ssTests[3].length, standardComparator); + + // Test iid_is. + doIsTest("testInterfaceIs", makeA(), Ci['nsIXPCTestInterfaceA'], + makeB(), Ci['nsIXPCTestInterfaceB'], + interfaceComparator, dotEqualsComparator); + + // Test arrays of iids. + doIs2Test("testInterfaceIsArray", [makeA(), makeA(), makeA(), makeA(), makeA()], 5, Ci['nsIXPCTestInterfaceA'], + [makeB(), makeB(), makeB()], 3, Ci['nsIXPCTestInterfaceB']); + + // Test optional array size. + Assert.equal(o.testStringArrayOptionalSize(["some", "string", "array"]), "somestringarray"); + + // Test incorrect (too big) array size parameter; this should throw NOT_ENOUGH_ELEMENTS. + doTypedArrayMismatchTest("testShortArray", new Int16Array([-3, 7, 4]), 4, + new Int16Array([1, -32, 6]), 3); + + // Test type mismatch (int16 <-> uint16); this should throw BAD_CONVERT_JS. + doTypedArrayMismatchTest("testShortArray", new Uint16Array([0, 7, 4, 3]), 4, + new Uint16Array([1, 5, 6]), 3); + + // Test Sequence<T> types. + doTest("testShortSequence", [2, 4, 6], [1, 3, 5, 7], arrayComparator(standardComparator)); + doTest("testDoubleSequence", [-10, -0.5], [1, 3, 1e11, -8e-5 ], arrayComparator(fuzzComparator)); + doTest("testACStringSequence", ["mary", "hat", "hey", "lid", "tell", "lam"], + ["ids", "fleas", "woes", "wide", "has", "know", "!"], + arrayComparator(standardComparator)); + doTest("testAStringSequence", ["沒有語言", "的偉大嗎?]"], + ["we", "are", "being", "sooo", "international", "right", "now"], + arrayComparator(standardComparator)); + + doTest("testInterfaceSequence", [makeA(), makeA()], + [makeA(), makeA(), makeA(), makeA(), makeA(), makeA()], arrayComparator(interfaceComparator)); + + doTest("testJsvalSequence", [{ cheese: 'whiz', apple: 8 }, [1, 5, '3'], /regex/], + ['apple', 2.2e10, 3.3e30, { only: "wheedle", except: {} }], arrayComparator(standardComparator)); + + doIsTest("testInterfaceIsSequence", [makeA(), makeA(), makeA(), makeA(), makeA()], Ci['nsIXPCTestInterfaceA'], + [makeB(), makeB(), makeB()], Ci['nsIXPCTestInterfaceB'], + arrayComparator(interfaceComparator), dotEqualsComparator); + + var ret = o.testOptionalSequence(); + Assert.ok(Array.isArray(ret)); + Assert.equal(ret.length, 0); + + ret = o.testOptionalSequence([]); + Assert.ok(Array.isArray(ret)); + Assert.equal(ret.length, 0); + + ret = o.testOptionalSequence([1, 2, 3]); + Assert.ok(Array.isArray(ret)); + Assert.equal(ret.length, 3); + + let jsObj = new TestParams(); + o.testOmittedOptionalOut(jsObj); + ret = {}; + o.testOmittedOptionalOut(jsObj, ret); + Assert.equal(ret.value.spec, "http://example.com/") + + // Tests for large ArrayBuffers. + var ab = null; + try { + ab = new ArrayBuffer(4.5 * 1024 * 1024 * 1024); // 4.5 GB. + } catch (e) { + // Large ArrayBuffers not available (32-bit or disabled). + } + if (ab) { + var uint8 = new Uint8Array(ab); + + // Test length check in JSArray2Native. + var ex = null; + try { + o.testOptionalSequence(uint8); + } catch (e) { + ex = e; + } + Assert.ok(ex.message.includes("Could not convert JavaScript argument arg 0")); + + // Test length check for optional length argument in GetArraySizeFromParam. + ex = null; + try { + o.testByteArrayOptionalLength(uint8); + } catch (e) { + ex = e; + } + Assert.ok(ex.message.includes("Cannot convert JavaScript object into an array")); + + // Smaller array views on the buffer are fine. + uint8 = new Uint8Array(ab, ab.byteLength - 3); + uint8[0] = 123; + Assert.equal(uint8.byteLength, 3); + Assert.equal(o.testOptionalSequence(uint8).toString(), "123,0,0"); + Assert.equal(o.testByteArrayOptionalLength(uint8), 3); + } + + Assert.ok(isNaN(o.testNaN), "Should handle returning NaNs"); +} diff --git a/js/xpconnect/tests/unit/test_print_stderr.js b/js/xpconnect/tests/unit/test_print_stderr.js new file mode 100644 index 0000000000..4c2d87ae7a --- /dev/null +++ b/js/xpconnect/tests/unit/test_print_stderr.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +add_task(async function() { + Assert.throws( + () => Cu.printStderr(), + /Not enough arguments/, + "Without argument printStderr throws" + ); + + const types = ["", "foo", 42, true, null, {foo: "bar"}]; + types.forEach(type => Cu.printStderr(type)); +}); diff --git a/js/xpconnect/tests/unit/test_private_field_xrays.js b/js/xpconnect/tests/unit/test_private_field_xrays.js new file mode 100644 index 0000000000..bd37eb44c7 --- /dev/null +++ b/js/xpconnect/tests/unit/test_private_field_xrays.js @@ -0,0 +1,58 @@ +'use strict' + +ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs"); + +add_task(async function () { + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + + docShell.createAboutBlankContentViewer(null, null); + + let window = webnav.document.defaultView; + + let iframe = window.eval(` + iframe = document.createElement("iframe"); + iframe.id = "iframe" + document.body.appendChild(iframe) + iframe`); + + + let unwrapped = Cu.waiveXrays(iframe); + + + class Base { + constructor(o) { + return o; + } + }; + + + class A extends Base { + #x = 12; + static gx(o) { + return o.#x; + } + + static sx(o, v) { + o.#x = v; + } + }; + + new A(iframe); + Assert.equal(A.gx(iframe), 12); + A.sx(iframe, 'wrapped'); + + // Shouldn't tunnel past xray. + Assert.throws(() => A.gx(unwrapped), TypeError); + Assert.throws(() => A.sx(unwrapped, 'unwrapped'), TypeError); + + new A(unwrapped); + Assert.equal(A.gx(unwrapped), 12); + Assert.equal(A.gx(iframe), 'wrapped'); + + A.sx(iframe, 'modified'); + Assert.equal(A.gx(unwrapped), 12); + A.sx(unwrapped, 16); + Assert.equal(A.gx(iframe), 'modified'); +}); diff --git a/js/xpconnect/tests/unit/test_promise.js b/js/xpconnect/tests/unit/test_promise.js new file mode 100644 index 0000000000..305e016fb5 --- /dev/null +++ b/js/xpconnect/tests/unit/test_promise.js @@ -0,0 +1,7 @@ +function run_test() { + sb = new Cu.Sandbox('http://www.example.com'); + sb.equal = equal; + Cu.evalInSandbox('equal(typeof new Promise(function(resolve){resolve();}), "object");', + sb); + Assert.equal(typeof new Promise(function(resolve){resolve();}), "object"); +} diff --git a/js/xpconnect/tests/unit/test_recursive_import.js b/js/xpconnect/tests/unit/test_recursive_import.js new file mode 100644 index 0000000000..94c6b0b7e9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_recursive_import.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + var scope = {}; + ChromeUtils.import("resource://test/recursive_importA.jsm", scope); + + // A imported correctly + Assert.ok(scope.foo() == "foo"); + + // Symbols from B are visible through A + Assert.ok(scope.bar.baz() == "baz"); + + // Symbols from A are visible through A, B, A. + Assert.ok(scope.bar.qux.foo() == "foo"); +} diff --git a/js/xpconnect/tests/unit/test_reflect_parse.js b/js/xpconnect/tests/unit/test_reflect_parse.js new file mode 100644 index 0000000000..a96ce0bb61 --- /dev/null +++ b/js/xpconnect/tests/unit/test_reflect_parse.js @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* +({ + loc:{start:{line:1, column:0}, end:{line:1, column:12}, source:null}, + type:"Program", + body:[ + { + loc:{start:{line:1, column:0}, end:{line:1, column:12}, source:null}, + type:"ExpressionStatement", + expression:{ + loc:{start:{line:1, column:0}, end:{line:1, column:12}, source:null}, + type:"Literal", + value:"use strict" + } + } + ] +}) +*/ + +function run_test() { + // Reflect.parse is better tested in js shell; this basically tests its presence. + var parseData = Reflect.parse('"use strict"'); + Assert.equal(parseData.body[0].expression.value, "use strict"); +} diff --git a/js/xpconnect/tests/unit/test_resolve_dead_promise.js b/js/xpconnect/tests/unit/test_resolve_dead_promise.js new file mode 100644 index 0000000000..70615b39c0 --- /dev/null +++ b/js/xpconnect/tests/unit/test_resolve_dead_promise.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=1298597 */ + +function run_test() +{ + var sb = Cu.Sandbox("http://www.blah.com"); + var resolveFun; + var p1 = new sb.Promise((res, rej) => {resolveFun = res}); + var rejectFun; + var p2 = new sb.Promise((res, rej) => {rejectFun = rej}); + Cu.nukeSandbox(sb); + Assert.ok(Cu.isDeadWrapper(sb), "sb should be dead"); + Assert.ok(Cu.isDeadWrapper(p1), "p1 should be dead"); + Assert.ok(Cu.isDeadWrapper(p2), "p2 should be dead"); + + var exception; + + try{ + resolveFun(1); + Assert.ok(false); + } catch (e) { + exception = e; + } + Assert.ok(exception.toString().includes("can't access dead object"), + "Resolving dead wrapped promise should throw"); + + exception = undefined; + try{ + rejectFun(1); + Assert.ok(false); + } catch (e) { + exception = e; + } + Assert.ok(exception.toString().includes("can't access dead object"), + "Rejecting dead wrapped promise should throw"); +} diff --git a/js/xpconnect/tests/unit/test_returncode.js b/js/xpconnect/tests/unit/test_returncode.js new file mode 100644 index 0000000000..de4289c013 --- /dev/null +++ b/js/xpconnect/tests/unit/test_returncode.js @@ -0,0 +1,74 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function getConsoleMessages() { + let consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService); + let messages = consoleService.getMessageArray().map((m) => m.toString()); + // reset ready for the next call. + consoleService.reset(); + return messages; +} + +function run_test() { + // Load the component manifests. + registerXPCTestComponents(); + + // and the tests. + test_simple("@mozilla.org/js/xpc/test/native/ReturnCodeParent;1"); + test_nested("@mozilla.org/js/xpc/test/native/ReturnCodeParent;1"); + + test_simple("@mozilla.org/js/xpc/test/native/ESMReturnCodeParent;1"); + test_nested("@mozilla.org/js/xpc/test/native/ESMReturnCodeParent;1"); +} + +function test_simple(contractID) { + let parent = Cc[contractID].createInstance(Ci.nsIXPCTestReturnCodeParent); + let result; + + // flush existing messages before we start testing. + getConsoleMessages(); + + // Ask the C++ to call the JS object which will throw. + result = parent.callChild(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_THROW); + Assert.equal(result, Cr.NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS, + "exception caused NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS"); + + let messages = getConsoleMessages(); + Assert.equal(messages.length, 1, "got a console message from the exception"); + Assert.ok(messages[0].includes("a requested error"), "got the message text"); + + // Ask the C++ to call the JS object which will return success. + result = parent.callChild(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_SUCCESS); + Assert.equal(result, Cr.NS_OK, "success is success"); + + Assert.deepEqual(getConsoleMessages(), [], "no messages reported on success."); + + // And finally the point of this test! + // Ask the C++ to call the JS object which will use .returnCode + result = parent.callChild(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_RETURN_RESULTCODE); + Assert.equal(result, Cr.NS_ERROR_FAILURE, + "NS_ERROR_FAILURE was seen as the error code."); + + Assert.deepEqual(getConsoleMessages(), [], "no messages reported with .returnCode"); +} + +function test_nested(contractID) { + let parent = Cc[contractID].createInstance(Ci.nsIXPCTestReturnCodeParent); + let result; + + // flush existing messages before we start testing. + getConsoleMessages(); + + // Ask the C++ to call the "outer" JS object, which will set .returnCode, but + // then create and call *another* component which itself sets the .returnCode + // to a different value. This checks the returnCode is correctly saved + // across call contexts. + result = parent.callChild(Ci.nsIXPCTestReturnCodeChild.CHILD_SHOULD_NEST_RESULTCODES); + Assert.equal(result, Cr.NS_ERROR_UNEXPECTED, + "NS_ERROR_UNEXPECTED was seen as the error code."); + // We expect one message, which is the child reporting what it got as the + // return code - which should be NS_ERROR_FAILURE + let expected = ["nested child returned " + Cr.NS_ERROR_FAILURE]; + Assert.deepEqual(getConsoleMessages(), expected, "got the correct sub-error"); +} diff --git a/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js b/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js new file mode 100644 index 0000000000..10934f550b --- /dev/null +++ b/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=1354733 */ + +const global = this; + +function run_test() +{ + var sb = Cu.Sandbox(global); + let obj = new sb.Object(); + Cu.nukeSandbox(sb); + + ok(Cu.isDeadWrapper(obj), "object should be a dead wrapper"); + + // Create a new sandbox to wrap objects for. + + var sb = Cu.Sandbox(global); + Cu.evalInSandbox(function echo(val) { return val; }, + sb); + + let echoed = sb.echo(obj); + ok(Cu.isDeadWrapper(echoed), "Rewrapped object should be a dead wrapper"); + ok(echoed !== obj, "Rewrapped object should be a new dead wrapper"); + + ok(obj === obj, "Dead wrapper object should be equal to itself"); + + let liveObj = {}; + ok(liveObj === sb.echo(liveObj), "Rewrapped live object should be equal to itself"); +} diff --git a/js/xpconnect/tests/unit/test_rtcIdentityProvider.js b/js/xpconnect/tests/unit/test_rtcIdentityProvider.js new file mode 100644 index 0000000000..7786691513 --- /dev/null +++ b/js/xpconnect/tests/unit/test_rtcIdentityProvider.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + let sb = new Cu.Sandbox('https://www.example.com', + { wantGlobalProperties: ['rtcIdentityProvider'] }); + + function exerciseInterface() { + equal(typeof rtcIdentityProvider, 'object'); + equal(typeof rtcIdentityProvider.register, 'function'); + rtcIdentityProvider.register({ + generateAssertion: function(a, b, c) { + return Promise.resolve({ + idp: { domain: 'example.com' }, + assertion: JSON.stringify([a, b, c]) + }); + }, + validateAssertion: function(d, e) { + return Promise.resolve({ + identity: 'user@example.com', + contents: JSON.stringify([d, e]) + }); + } + }); + } + + sb.equal = equal; + Cu.evalInSandbox('(' + exerciseInterface.toSource() + ')();', sb); + ok(sb.rtcIdentityProvider.hasIdp); + + Cu.importGlobalProperties(['rtcIdentityProvider']); + exerciseInterface(); + ok(rtcIdentityProvider.hasIdp); +} diff --git a/js/xpconnect/tests/unit/test_sandbox_DOMException.js b/js/xpconnect/tests/unit/test_sandbox_DOMException.js new file mode 100644 index 0000000000..04592c6db2 --- /dev/null +++ b/js/xpconnect/tests/unit/test_sandbox_DOMException.js @@ -0,0 +1,10 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + var Cu = Components.utils; + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["DOMException"] }); + sb.notEqual = Assert.notEqual.bind(Assert); + Cu.evalInSandbox('notEqual(DOMException, undefined);', sb); +} diff --git a/js/xpconnect/tests/unit/test_sandbox_atob.js b/js/xpconnect/tests/unit/test_sandbox_atob.js new file mode 100644 index 0000000000..a4bd75c13d --- /dev/null +++ b/js/xpconnect/tests/unit/test_sandbox_atob.js @@ -0,0 +1,9 @@ +function run_test() { + sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["atob", "btoa"] }); + sb.equal = equal; + Cu.evalInSandbox('var dummy = "Dummy test.";' + + 'equal(dummy, atob(btoa(dummy)));' + + 'equal(btoa("budapest"), "YnVkYXBlc3Q=");', + sb); +} diff --git a/js/xpconnect/tests/unit/test_sandbox_metadata.js b/js/xpconnect/tests/unit/test_sandbox_metadata.js new file mode 100644 index 0000000000..2d0ebe36b0 --- /dev/null +++ b/js/xpconnect/tests/unit/test_sandbox_metadata.js @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=898559 */ + +function run_test() +{ + let sandbox = Cu.Sandbox("http://www.blah.com", { + metadata: "test metadata", + }); + + Cu.importGlobalProperties(["XMLHttpRequest"]); + + Assert.equal(Cu.getSandboxMetadata(sandbox), "test metadata"); + + sandbox = Cu.Sandbox("http://www.blah.com", { + metadata: { foopy: { bar: 2 }, baz: "hi" } + }); + + let metadata = Cu.getSandboxMetadata(sandbox); + Assert.equal(metadata.baz, "hi"); + Assert.equal(metadata.foopy.bar, 2); + metadata.baz = "foo"; + + metadata = Cu.getSandboxMetadata(sandbox); + Assert.equal(metadata.baz, "foo"); + + metadata = { foo: "bar" }; + Cu.setSandboxMetadata(sandbox, metadata); + metadata.foo = "baz"; + metadata = Cu.getSandboxMetadata(sandbox); + Assert.equal(metadata.foo, "bar"); + + let thrown = false; + let reflector = new XMLHttpRequest(); + + try { + Cu.setSandboxMetadata(sandbox, { foo: reflector }); + } catch(e) { + thrown = true; + } + + Assert.equal(thrown, true); + + sandbox = Cu.Sandbox(this, { + metadata: { foopy: { bar: 2 }, baz: "hi" } + }); + + let inner = Cu.evalInSandbox("Components.utils.Sandbox('http://www.blah.com')", sandbox); + + metadata = Cu.getSandboxMetadata(inner); + Assert.equal(metadata.baz, "hi"); + Assert.equal(metadata.foopy.bar, 2); + metadata.baz = "foo"; +} + diff --git a/js/xpconnect/tests/unit/test_sandbox_name.js b/js/xpconnect/tests/unit/test_sandbox_name.js new file mode 100644 index 0000000000..1eaa971a9e --- /dev/null +++ b/js/xpconnect/tests/unit/test_sandbox_name.js @@ -0,0 +1,26 @@ +"use strict"; + +/** + * Test that the name of a sandbox contains the name of all principals. + */ +function test_sandbox_name() { + let names = [ + "http://example.com/?" + Math.random(), + "http://example.org/?" + Math.random() + ]; + let sandbox = Cu.Sandbox(names); + let fileName = Cu.evalInSandbox( + "(new Error()).fileName", + sandbox, + "latest" /*js version*/, + ""/*file name*/ + ); + + for (let name of names) { + Assert.ok(fileName.includes(name), `Name ${name} appears in ${fileName}`); + } +}; + +function run_test() { + test_sandbox_name(); +} diff --git a/js/xpconnect/tests/unit/test_storage.js b/js/xpconnect/tests/unit/test_storage.js new file mode 100644 index 0000000000..1ef6b653b5 --- /dev/null +++ b/js/xpconnect/tests/unit/test_storage.js @@ -0,0 +1,12 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["storage"] }); + sb.ok = ok; + Cu.evalInSandbox('ok(storage instanceof StorageManager);', + sb); + Cu.importGlobalProperties(["storage"]); + Assert.ok(storage instanceof StorageManager); +} diff --git a/js/xpconnect/tests/unit/test_structuredClone.js b/js/xpconnect/tests/unit/test_structuredClone.js new file mode 100644 index 0000000000..9ecb51951d --- /dev/null +++ b/js/xpconnect/tests/unit/test_structuredClone.js @@ -0,0 +1,33 @@ +function run_test() { + var sb = new Cu.Sandbox("http://www.example.com", { + wantGlobalProperties: ["structuredClone"], + }); + + sb.equal = equal; + + sb.testing = Cu.cloneInto({ xyz: 123 }, sb); + Cu.evalInSandbox( + ` + equal(structuredClone("abc"), "abc"); + + var obj = { a: 1 }; + obj.self = obj; + var clone = structuredClone(obj); + equal(clone.a, 1); + equal(clone.self, clone); + + var ab = new ArrayBuffer(1); + clone = structuredClone(ab, { transfer: [ab] }); + equal(clone.byteLength, 1); + equal(ab.byteLength, 0); + + clone = structuredClone(testing); + equal(clone.xyz, 123); + `, + sb + ); + + Cu.importGlobalProperties(["structuredClone"]); + const clone = structuredClone({ b: 2 }); + Assert.equal(clone.b, 2); +} diff --git a/js/xpconnect/tests/unit/test_subScriptLoader.js b/js/xpconnect/tests/unit/test_subScriptLoader.js new file mode 100644 index 0000000000..70301f9da4 --- /dev/null +++ b/js/xpconnect/tests/unit/test_subScriptLoader.js @@ -0,0 +1,16 @@ +"use strict"; + +add_task(async function test_executeScriptAfterNuked() { + let scriptUrl = Services.io.newFileURI(do_get_file("file_simple_script.js")).spec; + + // Load the script for the first time into a sandbox, and then nuke + // that sandbox. + let sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal()); + Services.scriptloader.loadSubScript(scriptUrl, sandbox); + Cu.nukeSandbox(sandbox); + + // Load the script again into a new sandbox, and make sure it + // succeeds. + sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal()); + Services.scriptloader.loadSubScript(scriptUrl, sandbox); +}); diff --git a/js/xpconnect/tests/unit/test_tearoffs.js b/js/xpconnect/tests/unit/test_tearoffs.js new file mode 100644 index 0000000000..18b07d1da1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_tearoffs.js @@ -0,0 +1,115 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function TestInterfaceAll() {} +TestInterfaceAll.prototype = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceA", + "nsIXPCTestInterfaceB", + "nsIXPCTestInterfaceC"]), + + /* nsIXPCTestInterfaceA / nsIXPCTestInterfaceB */ + name: "TestInterfaceAllDefaultName", + + /* nsIXPCTestInterfaceC */ + someInteger: 42 +}; + +function newWrappedJS() { + return xpcWrap(new TestInterfaceAll()); +} + +function run_test() { + // Shortcut the interfaces we're using. + var ifs = { + a: Ci['nsIXPCTestInterfaceA'], + b: Ci['nsIXPCTestInterfaceB'], + c: Ci['nsIXPCTestInterfaceC'] + }; + + // Run through the logic a few times. + for (let i = 0; i < 2; ++i) + play_with_tearoffs(ifs); +} + +function play_with_tearoffs(ifs) { + + // Allocate a bunch of objects, QI-ed to B. + var instances = []; + for (var i = 0; i < 300; ++i) + instances.push(newWrappedJS().QueryInterface(ifs.b)); + + // Nothing to collect. + gc(); + + // QI them to A. + instances.forEach(function(v, i, a) { v.QueryInterface(ifs.a); }); + + // QI them to C. + instances.forEach(function(v, i, a) { v.QueryInterface(ifs.c); }); + + // Check + Assert.ok('name' in instances[10], 'Have the prop from A/B'); + Assert.ok('someInteger' in instances[10], 'Have the prop from C'); + + // Grab tearoff reflections for a and b. + var aTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceA; } ); + var bTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceB; } ); + + // Check + Assert.ok('name' in aTearOffs[1], 'Have the prop from A'); + Assert.ok(!('someInteger' in aTearOffs[1]), 'Dont have the prop from C'); + + // Nothing to collect. + gc(); + + // Null out every even instance pointer. + for (var i = 0; i < instances.length; ++i) + if (i % 2 == 0) + instances[i] = null; + + // Nothing to collect, since we still have the A and B tearoff reflections. + gc(); + + // Null out A tearoff reflections that are a multiple of 3. + for (var i = 0; i < aTearOffs.length; ++i) + if (i % 3 == 0) + aTearOffs[i] = null; + + // Nothing to collect, since we still have the B tearoff reflections. + gc(); + + // Null out B tearoff reflections that are a multiple of 5. + for (var i = 0; i < bTearOffs.length; ++i) + if (i % 5 == 0) + bTearOffs[i] = null; + + // This should collect every 30th object (indices that are multiples of 2, 3, and 5). + gc(); + + // Kill the b tearoffs entirely. + bTearOffs = 0; + + // Collect more. + gc(); + + // Get C tearoffs. + var cTearOffs = instances.map(function(v, i, a) { return v ? v.nsIXPCTestInterfaceC : null; } ); + + // Check. + Assert.ok(!('name' in cTearOffs[1]), 'Dont have the prop from A'); + Assert.ok('someInteger' in cTearOffs[1], 'have the prop from C'); + + // Null out the a tearoffs. + aTearOffs = null; + + // Collect all even indices. + gc(); + + // Collect all indices. + instances = null; + gc(); + + // Give ourselves a pat on the back. :-) + Assert.ok(true, "Got all the way through without crashing!"); +} diff --git a/js/xpconnect/tests/unit/test_textDecoder.js b/js/xpconnect/tests/unit/test_textDecoder.js new file mode 100644 index 0000000000..b97aab9f7c --- /dev/null +++ b/js/xpconnect/tests/unit/test_textDecoder.js @@ -0,0 +1,11 @@ +function run_test() { + sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["TextDecoder", "TextEncoder"] }); + sb.equal = equal; + Cu.evalInSandbox('equal(new TextDecoder().encoding, "utf-8");' + + 'equal(new TextEncoder().encoding, "utf-8");', + sb); + Cu.importGlobalProperties(["TextDecoder", "TextEncoder"]); + Assert.equal(new TextDecoder().encoding, "utf-8"); + Assert.equal(new TextEncoder().encoding, "utf-8"); +} diff --git a/js/xpconnect/tests/unit/test_uawidget_scope.js b/js/xpconnect/tests/unit/test_uawidget_scope.js new file mode 100644 index 0000000000..ede9d656cd --- /dev/null +++ b/js/xpconnect/tests/unit/test_uawidget_scope.js @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +ChromeUtils.importESModule("resource://gre/modules/Timer.sys.mjs"); +const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const {TestUtils} = ChromeUtils.importESModule("resource://testing-common/TestUtils.sys.mjs"); + +function getWindowlessBrowser(url) { + let ssm = Services.scriptSecurityManager; + let uri = NetUtil.newURI(url); + let principal = ssm.createContentPrincipal(uri, {}); + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + docShell.createAboutBlankContentViewer(principal, principal); + + let document = webnav.document; + let video = document.createElement("video"); + document.documentElement.appendChild(video); + + let shadowRoot = video.openOrClosedShadowRoot; + ok(shadowRoot, "should have shadowRoot"); + ok(shadowRoot.isUAWidget(), "ShadowRoot should be a UAWidget"); + equal(Cu.getGlobalForObject(shadowRoot), Cu.getUAWidgetScope(principal), + "shadowRoot should be in UAWidget scope"); + + return webnav; +} + +function StubPolicy(id) { + return new WebExtensionPolicy({ + id, + mozExtensionHostname: id, + baseURL: `file:///{id}`, + allowedOrigins: new MatchPatternSet([]), + localizeCallback(string) {}, + }); +} + +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1588356 +add_task(async function() { + let policy = StubPolicy("foo"); + policy.active = true; + + let webnav = getWindowlessBrowser("moz-extension://foo/a.html"); + webnav.close(); + + // Wrappers are nuked asynchronously, so wait for that to happen. + await TestUtils.topicObserved("inner-window-nuked"); + + webnav = getWindowlessBrowser("moz-extension://foo/a.html"); + webnav.close(); + + policy.active = false; +}); diff --git a/js/xpconnect/tests/unit/test_uninitialized_lexical.js b/js/xpconnect/tests/unit/test_uninitialized_lexical.js new file mode 100644 index 0000000000..f5f2f254ee --- /dev/null +++ b/js/xpconnect/tests/unit/test_uninitialized_lexical.js @@ -0,0 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Assert.throws(() => ChromeUtils.import("resource://test/uninitialized_lexical.jsm"), + /Symbol 'foo' accessed before initialization/, + "Uninitialized lexicals result in an exception"); diff --git a/js/xpconnect/tests/unit/test_unload.js b/js/xpconnect/tests/unit/test_unload.js new file mode 100644 index 0000000000..13e2e0c63e --- /dev/null +++ b/js/xpconnect/tests/unit/test_unload.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() { + var scope1 = {}; + var exports1 = ChromeUtils.import("resource://test/TestBlob.jsm", scope1); + + var scope2 = {}; + var exports2 = ChromeUtils.import("resource://test/TestBlob.jsm", scope2); + + Assert.ok(exports1 === exports2); + Assert.ok(scope1.TestBlob === scope2.TestBlob); + + Cu.unload("resource://test/TestBlob.jsm"); + + var scope3 = {}; + var exports3 = ChromeUtils.import("resource://test/TestBlob.jsm", scope3); + + Assert.equal(false, exports1 === exports3); + Assert.equal(false, scope1.TestBlob === scope3.TestBlob); + + // When the jsm was unloaded, the value of all its global's properties were + // set to undefined. While it must be safe (not crash) to call into the + // module, we expect it to throw an error (e.g., when trying to use Ci). + try { scope1.TestBlob.doTest(() => {}); } catch (e) {} + try { scope3.TestBlob.doTest(() => {}); } catch (e) {} +} diff --git a/js/xpconnect/tests/unit/test_url.js b/js/xpconnect/tests/unit/test_url.js new file mode 100644 index 0000000000..0f912d12e9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_url.js @@ -0,0 +1,9 @@ +function run_test() { + var sb = new Cu.Sandbox('http://www.example.com', + { wantGlobalProperties: ["URL"] }); + sb.equal = equal; + Cu.evalInSandbox('equal(new URL("http://www.example.com").host, "www.example.com");', + sb); + Cu.importGlobalProperties(["URL"]); + Assert.equal(new URL("http://www.example.com").host, "www.example.com"); +} diff --git a/js/xpconnect/tests/unit/test_want_components.js b/js/xpconnect/tests/unit/test_want_components.js new file mode 100644 index 0000000000..1c203c3e9d --- /dev/null +++ b/js/xpconnect/tests/unit/test_want_components.js @@ -0,0 +1,16 @@ +function run_test() { + var sb; + + sb = Cu.Sandbox(this, {wantComponents: false}); + Assert.equal(Cu.evalInSandbox("this.Components", sb), undefined); + Assert.equal(Cu.evalInSandbox("this.Services", sb), undefined); + + sb = Cu.Sandbox(this, {wantComponents: true}); + Assert.equal(Cu.evalInSandbox("typeof this.Components", sb), "object"); + Assert.equal(Cu.evalInSandbox("typeof this.Services", sb), "object"); + + // wantComponents defaults to true. + sb = Cu.Sandbox(this, {}); + Assert.equal(Cu.evalInSandbox("typeof this.Components", sb), "object"); + Assert.equal(Cu.evalInSandbox("typeof this.Services", sb), "object"); +} diff --git a/js/xpconnect/tests/unit/test_watchdog_default.js b/js/xpconnect/tests/unit/test_watchdog_default.js new file mode 100644 index 0000000000..4634184f3c --- /dev/null +++ b/js/xpconnect/tests/unit/test_watchdog_default.js @@ -0,0 +1,9 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function testBody() { + // Check that we properly implement whatever behavior is specified by the + // default profile for this configuration. + return checkWatchdog(isWatchdogEnabled()); +} diff --git a/js/xpconnect/tests/unit/test_watchdog_disable.js b/js/xpconnect/tests/unit/test_watchdog_disable.js new file mode 100644 index 0000000000..926edf2ffa --- /dev/null +++ b/js/xpconnect/tests/unit/test_watchdog_disable.js @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function testBody() { + setWatchdogEnabled(false); + return checkWatchdog(false); +} diff --git a/js/xpconnect/tests/unit/test_watchdog_enable.js b/js/xpconnect/tests/unit/test_watchdog_enable.js new file mode 100644 index 0000000000..f39757dfae --- /dev/null +++ b/js/xpconnect/tests/unit/test_watchdog_enable.js @@ -0,0 +1,8 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function testBody() { + setWatchdogEnabled(true); + return checkWatchdog(true); +} diff --git a/js/xpconnect/tests/unit/test_watchdog_hibernate.js b/js/xpconnect/tests/unit/test_watchdog_hibernate.js new file mode 100644 index 0000000000..119cc095e2 --- /dev/null +++ b/js/xpconnect/tests/unit/test_watchdog_hibernate.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +async function testBody() { + + setWatchdogEnabled(true); + + // It's unlikely that we've ever hibernated at this point, but the timestamps + // default to 0, so this should always be true. + var now = Date.now() * 1000; + var startHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStart"); + var stopHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStop"); + do_log_info("Pre-hibernation statistics:"); + do_log_info("now: " + now / 1000000); + do_log_info("startHibernation: " + startHibernation / 1000000); + do_log_info("stopHibernation: " + stopHibernation / 1000000); + Assert.less(startHibernation, now, "startHibernation ok"); + Assert.less(stopHibernation, now, "stopHibernation ok"); + + // When the watchdog runs, it hibernates if there's been no activity for the + // last 2 seconds, otherwise it sleeps for 1 second. As such, given perfect + // scheduling, we should never have more than 3 seconds of inactivity without + // hibernating. To add some padding for automation, we mandate that hibernation + // must begin between 2 and 5 seconds from now. + + // Sleep for 10 seconds. Note: we don't use nsITimer here because then we may run + // arbitrary (idle) events involving script before it fires. + simulateNoScriptActivity(10); + + busyWait(1000); // Give the watchdog time to wake up on the condvar. + var stateChange = Cu.getWatchdogTimestamp("ContextStateChange"); + startHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStart"); + stopHibernation = Cu.getWatchdogTimestamp("WatchdogHibernateStop"); + do_log_info("Post-hibernation statistics:"); + do_log_info("stateChange: " + stateChange / 1000000); + do_log_info("startHibernation: " + startHibernation / 1000000); + do_log_info("stopHibernation: " + stopHibernation / 1000000); + // XPCOM timers, JS times, and PR_Now() are apparently not directly + // comparable, as evidenced by certain seemingly-impossible timing values + // that occasionally get logged in windows automation. We're really just + // making sure this behavior is roughly as expected on the macro scale, + // so we add a 1 second fuzz factor here. + const FUZZ_FACTOR = 1 * 1000 * 1000; + Assert.greater(stateChange, now + 10*1000*1000 - FUZZ_FACTOR, "stateChange ok"); + Assert.greater(startHibernation, now + 2*1000*1000 - FUZZ_FACTOR, "startHibernation ok"); + Assert.less(startHibernation, now + 5*1000*1000 + FUZZ_FACTOR, "startHibernation ok"); + Assert.greater(stopHibernation, now + 10*1000*1000 - FUZZ_FACTOR, "stopHibernation ok"); +} diff --git a/js/xpconnect/tests/unit/test_watchdog_toggle.js b/js/xpconnect/tests/unit/test_watchdog_toggle.js new file mode 100644 index 0000000000..6f43a8b876 --- /dev/null +++ b/js/xpconnect/tests/unit/test_watchdog_toggle.js @@ -0,0 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function testBody() { + var defaultBehavior = isWatchdogEnabled(); + setWatchdogEnabled(!defaultBehavior); + setWatchdogEnabled(defaultBehavior); + return checkWatchdog(defaultBehavior); +} diff --git a/js/xpconnect/tests/unit/test_weak_keys.js b/js/xpconnect/tests/unit/test_weak_keys.js new file mode 100644 index 0000000000..58e3237bd8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_weak_keys.js @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=1165807 */ + +function run_test() +{ + var bunnies = new String("bunnies"); + var lizards = new String("lizards"); + + var weakset = new WeakSet([bunnies, lizards]); + var weakmap = new WeakMap(); + weakmap.set(bunnies, 23); + weakmap.set(lizards, "oh no"); + + var keys = ChromeUtils.nondeterministicGetWeakMapKeys(bunnies); + equal(keys, undefined, "test nondeterministicGetWeakMapKeys on non-WeakMap"); + + keys = ChromeUtils.nondeterministicGetWeakMapKeys(weakmap); + equal(keys.length, 2, "length of nondeterministicGetWeakMapKeys"); + equal(weakmap.get(bunnies), 23, "check bunnies in weakmap"); + equal(weakmap.get(lizards), "oh no", "check lizards in weakmap"); + + keys = ChromeUtils.nondeterministicGetWeakSetKeys(bunnies); + equal(keys, undefined, "test nondeterministicGetWeakSetKeys on non-WeakMap"); + + keys = ChromeUtils.nondeterministicGetWeakSetKeys(weakset); + equal(keys.length, 2, "length of nondeterministicGetWeakSetKeys"); + ok(weakset.has(bunnies), "check bunnies in weakset"); + ok(weakset.has(lizards), "check lizards in weakset"); + + bunnies = null; + keys = null; + + Cu.forceGC(); + + keys = ChromeUtils.nondeterministicGetWeakMapKeys(weakmap); + equal(keys.length, 1, "length of nondeterministicGetWeakMapKeys after GC"); + equal(weakmap.get(lizards), "oh no", "check lizards still in weakmap"); + + keys = ChromeUtils.nondeterministicGetWeakSetKeys(weakset); + equal(keys.length, 1, "length of nondeterministicGetWeakSetKeys after GC"); + ok(weakset.has(lizards), "check lizards still in weakset"); +} diff --git a/js/xpconnect/tests/unit/test_wrapped_js_enumerator.js b/js/xpconnect/tests/unit/test_wrapped_js_enumerator.js new file mode 100644 index 0000000000..5a366ba25d --- /dev/null +++ b/js/xpconnect/tests/unit/test_wrapped_js_enumerator.js @@ -0,0 +1,71 @@ +"use strict"; + +// Tests that JS iterators are automatically wrapped into +// equivalent nsISimpleEnumerator objects. + +const Variant = Components.Constructor("@mozilla.org/variant;1", + "nsIWritableVariant", + "setFromVariant"); +const SupportsInterfacePointer = Components.Constructor( + "@mozilla.org/supports-interface-pointer;1", "nsISupportsInterfacePointer"); + +function wrapEnumerator1(iter) { + var ip = SupportsInterfacePointer(); + ip.data = iter; + return ip.data.QueryInterface(Ci.nsISimpleEnumerator); +} + +function wrapEnumerator2(iter) { + var ip = SupportsInterfacePointer(); + ip.data = { + QueryInterface: ChromeUtils.generateQI(["nsIFilePicker"]), + get files() { + return iter; + }, + }; + return ip.data.QueryInterface(Ci.nsIFilePicker).files; +} + + +function enumToArray(iter) { + let result = []; + while (iter.hasMoreElements()) { + result.push(iter.getNext().QueryInterface(Ci.nsIVariant)); + } + return result; +} + +add_task(async function test_wrapped_js_enumerator() { + let array = [1, 2, 3, 4]; + + for (let wrapEnumerator of [wrapEnumerator1, wrapEnumerator2]) { + // Test a plain JS iterator. This should automatically be wrapped into + // an equivalent nsISimpleEnumerator. + { + let iter = wrapEnumerator(array.values()); + let result = enumToArray(iter); + + deepEqual(result, array, "Got correct result"); + } + + // Test an object with a QueryInterface method, which implements + // nsISimpleEnumerator. This should be wrapped and used directly. + { + let obj = { + QueryInterface: ChromeUtils.generateQI(["nsISimpleEnumerator"]), + _idx: 0, + hasMoreElements() { + return this._idx < array.length; + }, + getNext() { + return Variant(array[this._idx++]); + }, + }; + + let iter = wrapEnumerator(obj); + let result = enumToArray(iter); + + deepEqual(result, array, "Got correct result"); + } + } +}); diff --git a/js/xpconnect/tests/unit/test_xpcomutils.js b/js/xpconnect/tests/unit/test_xpcomutils.js new file mode 100644 index 0000000000..90605c4ca8 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xpcomutils.js @@ -0,0 +1,275 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- + * vim: sw=4 ts=4 sts=4 et + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * This file tests the methods on XPCOMUtils.sys.mjs. + * Also on ComponentUtils.jsm. Which is deprecated. + */ + +const {AppConstants} = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs"); +const {ComponentUtils} = ChromeUtils.importESModule("resource://gre/modules/ComponentUtils.sys.mjs"); +const {Preferences} = ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs"); +const {XPCOMUtils} = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs"); + +//////////////////////////////////////////////////////////////////////////////// +//// Tests + +add_test(function test_generateQI_string_names() +{ + var x = { + QueryInterface: ChromeUtils.generateQI([ + "nsIClassInfo", + "nsIObserver" + ]) + }; + + try { + x.QueryInterface(Ci.nsIClassInfo); + } catch(e) { + do_throw("Should QI to nsIClassInfo"); + } + try { + x.QueryInterface(Ci.nsIObserver); + } catch(e) { + do_throw("Should QI to nsIObserver"); + } + try { + x.QueryInterface(Ci.nsIObserverService); + do_throw("QI should not have succeeded!"); + } catch(e) {} + run_next_test(); +}); + +add_test(function test_defineLazyGetter() +{ + let accessCount = 0; + let obj = { + inScope: false + }; + const TEST_VALUE = "test value"; + XPCOMUtils.defineLazyGetter(obj, "foo", function() { + accessCount++; + this.inScope = true; + return TEST_VALUE; + }); + Assert.equal(accessCount, 0); + + // Get the property, making sure the access count has increased. + Assert.equal(obj.foo, TEST_VALUE); + Assert.equal(accessCount, 1); + Assert.ok(obj.inScope); + + // Get the property once more, making sure the access count has not + // increased. + Assert.equal(obj.foo, TEST_VALUE); + Assert.equal(accessCount, 1); + run_next_test(); +}); + + +add_test(function test_defineLazyServiceGetter() +{ + let obj = { }; + XPCOMUtils.defineLazyServiceGetter(obj, "service", + "@mozilla.org/consoleservice;1", + "nsIConsoleService"); + let service = Cc["@mozilla.org/consoleservice;1"]. + getService(Ci.nsIConsoleService); + + // Check that the lazy service getter and the actual service have the same + // properties. + for (let prop in obj.service) + Assert.ok(prop in service); + for (let prop in service) + Assert.ok(prop in obj.service); + run_next_test(); +}); + + +add_test(function test_defineLazyPreferenceGetter() +{ + const PREF = "xpcomutils.test.pref"; + + let obj = {}; + XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue"); + + + equal(obj.pref, "defaultValue", "Should return the default value before pref is set"); + + Preferences.set(PREF, "currentValue"); + + + info("Create second getter on new object"); + + obj = {}; + XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue"); + + + equal(obj.pref, "currentValue", "Should return the current value on initial read when pref is already set"); + + Preferences.set(PREF, "newValue"); + + equal(obj.pref, "newValue", "Should return new value after preference change"); + + Preferences.set(PREF, "currentValue"); + + equal(obj.pref, "currentValue", "Should return new value after second preference change"); + + + Preferences.reset(PREF); + + equal(obj.pref, "defaultValue", "Should return default value after pref is reset"); + + obj = {}; + XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "a,b", + null, value => value.split(",")); + + deepEqual(obj.pref, ["a", "b"], "transform is applied to default value"); + + Preferences.set(PREF, "x,y,z"); + deepEqual(obj.pref, ["x", "y", "z"], "transform is applied to updated value"); + + Preferences.reset(PREF); + deepEqual(obj.pref, ["a", "b"], "transform is applied to reset default"); + + if (AppConstants.DEBUG) { + // Need to use a 'real' pref so it will have a valid prefType + obj = {}; + Assert.throws( + () => XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", "javascript.enabled", 1), + /Default value does not match preference type/, + "Providing a default value of a different type than the preference throws an exception" + ); + } + + run_next_test(); +}); + + +add_test(function test_categoryRegistration() +{ + const CATEGORY_NAME = "test-cat"; + const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1"; + const XULAPPINFO_CID = Components.ID("{fc937916-656b-4fb3-a395-8c63569e27a8}"); + + // Create a fake app entry for our category registration apps filter. + let { newAppInfo } = ChromeUtils.importESModule("resource://testing-common/AppInfo.sys.mjs"); + let XULAppInfo = newAppInfo({ + name: "catRegTest", + ID: "{adb42a9a-0d19-4849-bf4d-627614ca19be}", + version: "1", + platformVersion: "", + }); + let XULAppInfoFactory = { + createInstance: function (iid) { + return XULAppInfo.QueryInterface(iid); + } + }; + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + registrar.registerFactory( + XULAPPINFO_CID, + "XULAppInfo", + XULAPPINFO_CONTRACTID, + XULAppInfoFactory + ); + + // Load test components. + do_load_manifest("CatRegistrationComponents.manifest"); + + const expectedEntries = new Map([ + ["CatRegisteredComponent", "@unit.test.com/cat-registered-component;1"], + ["CatAppRegisteredComponent", "@unit.test.com/cat-app-registered-component;1"], + ]); + + // Verify the correct entries are registered in the "test-cat" category. + for (let {entry, value} of Services.catMan.enumerateCategory(CATEGORY_NAME)) { + ok(expectedEntries.has(entry), `${entry} is expected`); + Assert.equal(value, expectedEntries.get(entry), "${entry} has correct value."); + expectedEntries.delete(entry); + } + Assert.deepEqual( + Array.from(expectedEntries.keys()), + [], + "All expected entries have been deleted." + ); + run_next_test(); +}); + +add_test(function test_categoryBackgroundTaskRegistration() +{ + const CATEGORY_NAME = "test-cat1"; + + // Note that this test should succeed whether or not MOZ_BACKGROUNDTASKS is + // defined. If it's defined, there's no active task so the `backgroundtask` + // directive is processed, dropped, and always succeeds. If it's not defined, + // then the `backgroundtask` directive is processed and ignored. + + // Load test components. + do_load_manifest("CatBackgroundTaskRegistrationComponents.manifest"); + + let expectedEntriesList = [ + ["Cat1RegisteredComponent", "@unit.test.com/cat1-registered-component;1"], + ["Cat1BackgroundTaskNotRegisteredComponent", "@unit.test.com/cat1-backgroundtask-notregistered-component;1"], + ]; + if (!AppConstants.MOZ_BACKGROUNDTASKS) { + expectedEntriesList.push(...[ + ["Cat1BackgroundTaskRegisteredComponent", "@unit.test.com/cat1-backgroundtask-registered-component;1"], + ["Cat1BackgroundTaskAlwaysRegisteredComponent", "@unit.test.com/cat1-backgroundtask-alwaysregistered-component;1"], + ]); + } + const expectedEntries = new Map(expectedEntriesList); + + // Verify the correct entries are registered in the "test-cat" category. + for (let {entry, value} of Services.catMan.enumerateCategory(CATEGORY_NAME)) { + ok(expectedEntries.has(entry), `${entry} is expected`); + Assert.equal(value, expectedEntries.get(entry), "Verify that the value is correct in the expected entries."); + expectedEntries.delete(entry); + } + Assert.deepEqual( + Array.from(expectedEntries.keys()), + [], + "All expected entries have been deleted." + ); + run_next_test(); +}); + +add_test(function test_generateSingletonFactory() +{ + const XPCCOMPONENT_CONTRACTID = "@mozilla.org/singletonComponentTest;1"; + const XPCCOMPONENT_CID = Components.ID("{31031c36-5e29-4dd9-9045-333a5d719a3e}"); + + function XPCComponent() {} + XPCComponent.prototype = { + classID: XPCCOMPONENT_CID, + QueryInterface: ChromeUtils.generateQI([]) + }; + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + registrar.registerFactory( + XPCCOMPONENT_CID, + "XPCComponent", + XPCCOMPONENT_CONTRACTID, + ComponentUtils.generateSingletonFactory(XPCComponent) + ); + + // First, try to instance the component. + let instance = Cc[XPCCOMPONENT_CONTRACTID].createInstance(Ci.nsISupports); + // Try again, check that it returns the same instance as before. + Assert.equal(instance, + Cc[XPCCOMPONENT_CONTRACTID].createInstance(Ci.nsISupports)); + // Now, for sanity, check that getService is also returning the same instance. + Assert.equal(instance, + Cc[XPCCOMPONENT_CONTRACTID].getService(Ci.nsISupports)); + + run_next_test(); +}); + +//////////////////////////////////////////////////////////////////////////////// +//// Test Runner + +function run_test() +{ + run_next_test(); +} diff --git a/js/xpconnect/tests/unit/test_xpcwn_instanceof.js b/js/xpconnect/tests/unit/test_xpcwn_instanceof.js new file mode 100644 index 0000000000..96268fd0b4 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xpcwn_instanceof.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Tests for custom `instanceof` behavior via XPC_SCRIPTABLE_WANT_HASINSTANCE. + +add_task(function id_instanceof() { + // ID objects are instances of Components.ID. + let id = Components.ID("{f2f5c784-7f6c-43f5-81b0-45ff32c312b1}"); + Assert.equal(id instanceof Components.ID, true); + Assert.equal({} instanceof Components.ID, false); + Assert.equal(null instanceof Components.ID, false); + + // Components.ID has a Symbol.hasInstance function. + let desc = Object.getOwnPropertyDescriptor(Components.ID, Symbol.hasInstance); + Assert.equal(typeof desc, "object"); + Assert.equal(typeof desc.value, "function"); + + // Test error handling when calling this function with unexpected values. + Assert.throws(() => desc.value.call(null), /At least 1 argument required/); + Assert.throws(() => desc.value.call(null, 1), /unexpected this value/); + Assert.throws(() => desc.value.call({}, {}), /NS_ERROR_XPC_BAD_OP_ON_WN_PROTO/); +}); diff --git a/js/xpconnect/tests/unit/test_xpcwn_tamperproof.js b/js/xpconnect/tests/unit/test_xpcwn_tamperproof.js new file mode 100644 index 0000000000..62d57533fa --- /dev/null +++ b/js/xpconnect/tests/unit/test_xpcwn_tamperproof.js @@ -0,0 +1,180 @@ +// Test that it's not possible to create expando properties on XPCWNs. +// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1143810#c5>. + +function TestInterfaceAll() {} +TestInterfaceAll.prototype = { + QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceA", + "nsIXPCTestInterfaceB", + "nsIXPCTestInterfaceC"]), + + /* nsIXPCTestInterfaceA / nsIXPCTestInterfaceB */ + name: "TestInterfaceAllDefaultName", + + /* nsIXPCTestInterfaceC */ + someInteger: 42 +}; + +function check_throws(f) { + try { + f(); + } catch (exc) { + return; + } + throw new TypeError("Expected exception, no exception thrown"); +} + +/* + * Test that XPCWrappedNative objects do not permit expando properties to be created. + * + * This function is called twice. The first time, realObj is an nsITimer XPCWN + * and accessObj === realObj. + * + * The second time, accessObj is a scripted proxy with realObj as its target. + * So the second time we are testing that scripted proxies don't magically + * bypass whatever mechanism enforces the expando policy on XPCWNs. + */ +function test_tamperproof(realObj, accessObj, {method, constant, attribute}) { + // Assignment can't create an expando property. + check_throws(function () { accessObj.expando = 14; }); + Assert.equal(false, "expando" in realObj); + + // Strict assignment throws. + check_throws(function () { "use strict"; accessObj.expando = 14; }); + Assert.equal(false, "expando" in realObj); + + // Assignment to an inherited method name doesn't work either. + check_throws(function () { accessObj.hasOwnProperty = () => "lies"; }); + check_throws(function () { "use strict"; accessObj.hasOwnProperty = () => "lies"; }); + Assert.ok(!realObj.hasOwnProperty("hasOwnProperty")); + + // Assignment to a method name doesn't work either. + let originalMethod; + if (method) { + originalMethod = accessObj[method]; + accessObj[method] = "nope"; // non-writable data property, no exception in non-strict code + check_throws(function () { "use strict"; accessObj[method] = "nope"; }); + Assert.ok(realObj[method] === originalMethod); + } + + // A constant is the same thing. + let originalConstantValue; + if (constant) { + originalConstantValue = accessObj[constant]; + accessObj[constant] = "nope"; + Assert.equal(realObj[constant], originalConstantValue); + check_throws(function () { "use strict"; accessObj[constant] = "nope"; }); + Assert.equal(realObj[constant], originalConstantValue); + } + + // Assignment to a readonly accessor property with no setter doesn't work either. + let originalAttributeDesc; + if (attribute) { + originalAttributeDesc = Object.getOwnPropertyDescriptor(realObj, attribute); + Assert.ok("set" in originalAttributeDesc); + Assert.ok(originalAttributeDesc.set === undefined); + + accessObj[attribute] = "nope"; // accessor property with no setter: no exception in non-strict code + check_throws(function () { "use strict"; accessObj[attribute] = "nope"; }); + + let desc = Object.getOwnPropertyDescriptor(realObj, attribute); + Assert.ok("set" in desc); + Assert.equal(originalAttributeDesc.get, desc.get); + Assert.equal(undefined, desc.set); + } + + // Reflect.set doesn't work either. + if (method) { + Assert.ok(!Reflect.set({}, method, "bad", accessObj)); + Assert.equal(realObj[method], originalMethod); + } + if (attribute) { + Assert.ok(!Reflect.set({}, attribute, "bad", accessObj)); + Assert.equal(originalAttributeDesc.get, Object.getOwnPropertyDescriptor(realObj, attribute).get); + } + + // Object.defineProperty can't do anything either. + let names = ["expando"]; + if (method) names.push(method); + if (constant) names.push(constant); + if (attribute) names.push(attribute); + for (let name of names) { + let originalDesc = Object.getOwnPropertyDescriptor(realObj, name); + check_throws(function () { + Object.defineProperty(accessObj, name, {configurable: true}); + }); + check_throws(function () { + Object.defineProperty(accessObj, name, {writable: true}); + }); + check_throws(function () { + Object.defineProperty(accessObj, name, {get: function () { return "lies"; }}); + }); + check_throws(function () { + Object.defineProperty(accessObj, name, {value: "bad"}); + }); + let desc = Object.getOwnPropertyDescriptor(realObj, name); + if (originalDesc === undefined) { + Assert.equal(undefined, desc); + } else { + Assert.equal(originalDesc.configurable, desc.configurable); + Assert.equal(originalDesc.enumerable, desc.enumerable); + Assert.equal(originalDesc.writable, desc.writable); + Assert.equal(originalDesc.value, desc.value); + Assert.equal(originalDesc.get, desc.get); + Assert.equal(originalDesc.set, desc.set); + } + } + + // Existing properties can't be deleted. + if (method) { + Assert.equal(false, delete accessObj[method]); + check_throws(function () { "use strict"; delete accessObj[method]; }); + Assert.equal(realObj[method], originalMethod); + } + if (constant) { + Assert.equal(false, delete accessObj[constant]); + check_throws(function () { "use strict"; delete accessObj[constant]; }); + Assert.equal(realObj[constant], originalConstantValue); + } + if (attribute) { + Assert.equal(false, delete accessObj[attribute]); + check_throws(function () { "use strict"; delete accessObj[attribute]; }); + desc = Object.getOwnPropertyDescriptor(realObj, attribute); + Assert.equal(originalAttributeDesc.get, desc.get); + } +} + +function test_twice(obj, options) { + test_tamperproof(obj, obj, options); + + let handler = { + getPrototypeOf(t) { + return new Proxy(Object.getPrototypeOf(t), handler); + } + }; + test_tamperproof(obj, new Proxy(obj, handler), options); +} + +function run_test() { + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + test_twice(timer, { + method: "init", + constant: "TYPE_ONE_SHOT", + attribute: "callback" + }); + + let cmdline = Cu.createCommandLine([], null, Ci.nsICommandLine.STATE_INITIAL_LAUNCH); + test_twice(cmdline, {}); + + test_twice(Object.getPrototypeOf(cmdline), { + method: "getArgument", + constant: "STATE_INITIAL_LAUNCH", + attribute: "length" + }); + + // Test a tearoff object. + let b = xpcWrap(new TestInterfaceAll(), Ci.nsIXPCTestInterfaceB); + let tearoff = b.nsIXPCTestInterfaceA; + test_twice(tearoff, { + method: "QueryInterface" + }); +} diff --git a/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js b/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js new file mode 100644 index 0000000000..e9b5752044 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_SavedFrame-02.js @@ -0,0 +1,71 @@ +// Test calling SavedFrame getters across wrappers from privileged and +// un-privileged globals. + +const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); +addDebuggerToGlobal(globalThis); + +const lowP = Services.scriptSecurityManager.createNullPrincipal({}); +const highP = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); + +const low = new Cu.Sandbox(lowP); +const high = new Cu.Sandbox(highP); + +function run_test() { + // Privileged compartment accessing unprivileged stack. + high.stack = getSavedFrameInstanceFromSandbox(low); + Cu.evalInSandbox("this.parent = stack.parent", high); + Cu.evalInSandbox("this.asyncParent = stack.asyncParent", high); + Cu.evalInSandbox("this.source = stack.source", high); + Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", high); + + // Un-privileged compartment accessing privileged stack. + low.stack = getSavedFrameInstanceFromSandbox(high); + try { + Cu.evalInSandbox("this.parent = stack.parent", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.asyncParent = stack.asyncParent", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.source = stack.source", low); + } catch (e) { } + try { + Cu.evalInSandbox("this.functionDisplayName = stack.functionDisplayName", low); + } catch (e) { } + + // Privileged compartment accessing privileged stack. + let stack = getSavedFrameInstanceFromSandbox(high); + let parent = stack.parent; + let asyncParent = stack.asyncParent; + let source = stack.source; + let functionDisplayName = stack.functionDisplayName; + + ok(true, "Didn't crash"); +} + +// Get a SavedFrame instance from inside the given sandbox. +// +// We can't use Cu.getJSTestingFunctions().saveStack() because Cu isn't +// available to sandboxes that don't have the system principal. The easiest way +// to get the SavedFrame is to use the Debugger API to track allocation sites +// and then do an allocation. +function getSavedFrameInstanceFromSandbox(sandbox) { + const dbg = new Debugger(sandbox); + + dbg.memory.trackingAllocationSites = true; + Cu.evalInSandbox("(function iife() { return new RegExp }())", sandbox); + const allocs = dbg.memory.drainAllocationsLog().filter(e => e.class === "RegExp"); + dbg.memory.trackingAllocationSites = false; + + ok(allocs[0], "We should observe the allocation"); + const { frame } = allocs[0]; + + if (sandbox !== high) { + ok(Cu.isXrayWrapper(frame), "`frame` should be an xray..."); + equal(Object.prototype.toString.call(Cu.waiveXrays(frame)), + "[object SavedFrame]", + "...and that xray should wrap a SavedFrame"); + } + + return frame; +} diff --git a/js/xpconnect/tests/unit/test_xray_SavedFrame.js b/js/xpconnect/tests/unit/test_xray_SavedFrame.js new file mode 100644 index 0000000000..85c91a2aa1 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_SavedFrame.js @@ -0,0 +1,104 @@ +// Bug 1117242: Test calling SavedFrame getters from globals that don't subsume +// that frame's principals. + +const {addDebuggerToGlobal} = ChromeUtils.importESModule("resource://gre/modules/jsdebugger.sys.mjs"); +addDebuggerToGlobal(globalThis); + +const lowP = Services.scriptSecurityManager.createNullPrincipal({}); +const midP = [lowP, "http://other.com"]; +const highP = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); + +const low = new Cu.Sandbox(lowP); +const mid = new Cu.Sandbox(midP); +const high = new Cu.Sandbox(highP); + +function run_test() { + // Test that the priveleged view of a SavedFrame from a subsumed compartment + // is the same view that the subsumed compartment gets. Create the following + // chain of function calls (with some intermediate system-principaled frames + // due to implementation): + // + // low.lowF -> mid.midF -> high.highF -> high.saveStack + // + // Where high.saveStack gets monkey patched to create stacks in each of our + // sandboxes. + + Cu.evalInSandbox("function highF() { return saveStack(); }", high); + + mid.highF = () => high.highF(); + Cu.evalInSandbox("function midF() { return highF(); }", mid); + + low.midF = () => mid.midF(); + Cu.evalInSandbox("function lowF() { return midF(); }", low); + + const expected = [ + { + sandbox: low, + frames: ["lowF"], + }, + { + sandbox: mid, + frames: ["midF", "lowF"], + }, + { + sandbox: high, + frames: ["getSavedFrameInstanceFromSandbox", + "saveStack", + "highF", + "run_test/mid.highF", + "midF", + "run_test/low.midF", + "lowF", + "run_test", + "_execute_test", + null], + } + ]; + + for (let { sandbox, frames } of expected) { + high.saveStack = function saveStack() { + return getSavedFrameInstanceFromSandbox(sandbox); + }; + + const xrayStack = low.lowF(); + equal(xrayStack.functionDisplayName, "getSavedFrameInstanceFromSandbox", + "Xrays should always be able to see everything."); + + let waived = Cu.waiveXrays(xrayStack); + do { + ok(frames.length, + "There should still be more expected frames while we have actual frames."); + equal(waived.functionDisplayName, frames.shift(), + "The waived wrapper should give us the stack's compartment's view."); + waived = waived.parent; + } while (waived); + } +} + +// Get a SavedFrame instance from inside the given sandbox. +// +// We can't use Cu.getJSTestingFunctions().saveStack() because Cu isn't +// available to sandboxes that don't have the system principal. The easiest way +// to get the SavedFrame is to use the Debugger API to track allocation sites +// and then do an allocation. +function getSavedFrameInstanceFromSandbox(sandbox) { + const dbg = new Debugger(sandbox); + + dbg.memory.trackingAllocationSites = true; + Cu.evalInSandbox("new Object", sandbox); + const allocs = dbg.memory.drainAllocationsLog(); + dbg.memory.trackingAllocationSites = false; + + ok(allocs[0], "We should observe the allocation"); + const { frame } = allocs[0]; + + if (sandbox !== high) { + ok(Cu.isXrayWrapper(frame), "`frame` should be an xray..."); + equal(Object.prototype.toString.call(Cu.waiveXrays(frame)), + "[object SavedFrame]", + "...and that xray should wrap a SavedFrame"); + } + + return frame; +} + diff --git a/js/xpconnect/tests/unit/test_xray_instanceof.js b/js/xpconnect/tests/unit/test_xray_instanceof.js new file mode 100644 index 0000000000..950d7c0060 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_instanceof.js @@ -0,0 +1,206 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +add_task(function instanceof_xrays() { + let sandbox = Cu.Sandbox(null); + Cu.evalInSandbox(` + this.proxy = new Proxy([], { + getPrototypeOf() { + return Date.prototype; + }, + }); + + this.inheritedProxy = Object.create(this.proxy); + + this.FunctionProxy = new Proxy(function() {}, {}); + this.functionProxyInstance = new this.FunctionProxy(); + + this.CustomClass = class {}; + this.customClassInstance = new this.CustomClass(); + `, sandbox); + + { + // Sanity check that instanceof still works with standard constructors when xrays are present. + Assert.ok(Cu.evalInSandbox(`new Date()`, sandbox) instanceof sandbox.Date, + "async function result in sandbox instanceof sandbox.Date"); + Assert.ok(new sandbox.Date() instanceof sandbox.Date, + "sandbox.Date() instanceof sandbox.Date"); + + Assert.ok(sandbox.CustomClass instanceof sandbox.Function, + "Class constructor instanceof sandbox.Function"); + Assert.ok(sandbox.CustomClass instanceof sandbox.Object, + "Class constructor instanceof sandbox.Object"); + + // Both operands must have the same kind of Xray vision. + Assert.equal(Cu.waiveXrays(sandbox.CustomClass) instanceof sandbox.Function, false, + "Class constructor with waived xrays instanceof sandbox.Function"); + Assert.equal(Cu.waiveXrays(sandbox.CustomClass) instanceof sandbox.Object, false, + "Class constructor with waived xrays instanceof sandbox.Object"); + } + + { + let {proxy} = sandbox; + Assert.equal(proxy instanceof sandbox.Date, false, + "instanceof should ignore the proxy trap"); + Assert.equal(proxy instanceof sandbox.Array, false, + "instanceof should ignore the proxy target"); + Assert.equal(Cu.waiveXrays(proxy) instanceof sandbox.Date, false, + "instanceof should ignore the proxy trap despite the waived xrays on the proxy"); + Assert.equal(Cu.waiveXrays(proxy) instanceof sandbox.Array, false, + "instanceof should ignore the proxy target despite the waived xrays on the proxy"); + + Assert.ok(proxy instanceof Cu.waiveXrays(sandbox.Date), + "instanceof should trigger the proxy trap after waiving Xrays on the constructor"); + Assert.equal(proxy instanceof Cu.waiveXrays(sandbox.Array), false, + "instanceof should trigger the proxy trap after waiving Xrays on the constructor"); + + Assert.ok(Cu.waiveXrays(proxy) instanceof Cu.waiveXrays(sandbox.Date), + "instanceof should trigger the proxy trap after waiving both Xrays"); + } + + + { + let {inheritedProxy} = sandbox; + Assert.equal(inheritedProxy instanceof sandbox.Date, false, + "instanceof should ignore the inherited proxy trap"); + Assert.equal(Cu.waiveXrays(inheritedProxy) instanceof sandbox.Date, false, + "instanceof should ignore the inherited proxy trap despite the waived xrays on the proxy"); + + Assert.ok(inheritedProxy instanceof Cu.waiveXrays(sandbox.Date), + "instanceof should trigger the inherited proxy trap after waiving Xrays on the constructor"); + + Assert.ok(Cu.waiveXrays(inheritedProxy) instanceof Cu.waiveXrays(sandbox.Date), + "instanceof should trigger the inherited proxy trap after waiving both Xrays"); + } + + { + let {FunctionProxy, functionProxyInstance} = sandbox; + + // Ideally, the next two test cases should both throw "... not a function". + // However, because the opaque XrayWrapper does not override isCallable, an + // opaque XrayWrapper is still considered callable if the proxy target is, + // and "instanceof" will try to look up the prototype of the wrapper (and + // fail because opaque XrayWrappers hide the properties). + Assert.throws( + () => functionProxyInstance instanceof FunctionProxy, + /'prototype' property of FunctionProxy is not an object/, + "Opaque constructor proxy should be hidden by Xrays"); + Assert.throws( + () => functionProxyInstance instanceof sandbox.proxy, + /sandbox.proxy is not a function/, + "Opaque non-constructor proxy should be hidden by Xrays"); + + Assert.ok(functionProxyInstance instanceof Cu.waiveXrays(FunctionProxy), + "instanceof should get through the proxy after waiving Xrays on the constructor proxy"); + Assert.ok(Cu.waiveXrays(functionProxyInstance) instanceof Cu.waiveXrays(FunctionProxy), + "instanceof should get through the proxy after waiving both Xrays"); + } + + { + let {CustomClass, customClassInstance} = sandbox; + // Under Xray vision, every JS object is either a plain object or array. + // Prototypical inheritance is invisible when the constructor is wrapped. + Assert.throws( + () => customClassInstance instanceof CustomClass, + /TypeError: 'prototype' property of CustomClass is not an object/, + "instanceof on a custom JS class with xrays should fail"); + Assert.ok(customClassInstance instanceof Cu.waiveXrays(CustomClass), + "instanceof should see the true prototype of CustomClass after waiving Xrays on the class"); + Assert.ok(Cu.waiveXrays(customClassInstance) instanceof Cu.waiveXrays(CustomClass), + "instanceof should see the true prototype of CustomClass after waiving Xrays"); + } +}); + +add_task(function instanceof_dom_xrays_hasInstance() { + const principal = Services.scriptSecurityManager.createNullPrincipal({}); + const webnav = Services.appShell.createWindowlessBrowser(false); + webnav.docShell.createAboutBlankContentViewer(principal, principal); + let window = webnav.document.defaultView; + + let sandbox = Cu.Sandbox(principal); + sandbox.DOMObjectWithHasInstance = window.document; + Cu.evalInSandbox(` + this.DOMObjectWithHasInstance[Symbol.hasInstance] = function() { + return true; + }; + this.ObjectWithHasInstance = { + [Symbol.hasInstance](v) { + v.throwsIfVCannotBeAccessed; + return true; + }, + }; + `, sandbox); + + // Override the hasInstance handler in the window, so that we can detect when + // we end up triggering hasInstance in the window's compartment. + window.eval(` + document[Symbol.hasInstance] = function() { + throw "hasInstance_in_window"; + }; + `); + + sandbox.domobj = window.document.body; + Assert.ok(sandbox.eval(`domobj.wrappedJSObject`), + "DOM object is a XrayWrapper"); + Assert.ok(sandbox.eval(`DOMObjectWithHasInstance.wrappedJSObject`), + "DOM object with Symbol.hasInstance is a XrayWrapper"); + + for (let Obj of ["ObjectWithHasInstance", "DOMObjectWithHasInstance"]) { + // Tests Xray vision *inside* the sandbox. The Symbol.hasInstance member + // is a property / expando object in the sandbox's compartment, so the + // "instanceof" operator should always trigger the hasInstance function. + Assert.ok(sandbox.eval(`[] instanceof ${Obj}`), + `Should call ${Obj}[Symbol.hasInstance] when left operand has no Xrays`); + Assert.ok(sandbox.eval(`domobj instanceof ${Obj}`), + `Should call ${Obj}[Symbol.hasInstance] when left operand has Xrays`); + Assert.ok(sandbox.eval(`domobj.wrappedJSObject instanceof ${Obj}`), + `Should call ${Obj}[Symbol.hasInstance] when left operand has waived Xrays`); + + // Tests Xray vision *outside* the sandbox. The Symbol.hasInstance member + // should be hidden by Xrays. + let sandboxObjWithHasInstance = sandbox[Obj]; + Assert.ok(Cu.isXrayWrapper(sandboxObjWithHasInstance), + `sandbox.${Obj} is a XrayWrapper`); + Assert.throws( + () => sandbox.Object() instanceof sandboxObjWithHasInstance, + /sandboxObjWithHasInstance is not a function/, + `sandbox.${Obj}[Symbol.hasInstance] should be hidden by Xrays`); + + Assert.throws( + () => Cu.waiveXrays(sandbox.Object()) instanceof sandboxObjWithHasInstance, + /sandboxObjWithHasInstance is not a function/, + `sandbox.${Obj}[Symbol.hasInstance] should be hidden by Xrays, despite the waived Xrays at the left`); + + // (Cases where the left operand has no Xrays are checked below.) + } + + // hasInstance is expected to be called, but still trigger an error because + // properties of the object from the current context should not be readable + // by the hasInstance function in the sandbox with a different principal. + Assert.throws( + () => [] instanceof Cu.waiveXrays(sandbox.ObjectWithHasInstance), + /Permission denied to access property "throwsIfVCannotBeAccessed"/, + `Should call (waived) sandbox.ObjectWithHasInstance[Symbol.hasInstance] when the right operand has waived Xrays`); + + // The Xray waiver on the right operand should be sufficient to call + // hasInstance even if the left operand still has Xrays. + Assert.ok(sandbox.Object() instanceof Cu.waiveXrays(sandbox.ObjectWithHasInstance), + `Should call (waived) sandbox.ObjectWithHasInstance[Symbol.hasInstance] when the right operand has waived Xrays`); + Assert.ok(Cu.waiveXrays(sandbox.Object()) instanceof Cu.waiveXrays(sandbox.ObjectWithHasInstance), + `Should call (waived) sandbox.ObjectWithHasInstance[Symbol.hasInstance] when both operands have waived Xrays`); + + // When Xrays of the DOM object are waived, we end up in the owner document's + // compartment (instead of the sandbox). + Assert.throws( + () => [] instanceof Cu.waiveXrays(sandbox.DOMObjectWithHasInstance), + /hasInstance_in_window/, + "Should call (waived) sandbox.DOMObjectWithHasInstance[Symbol.hasInstance] when the right operand has waived Xrays"); + + Assert.throws( + () => Cu.waiveXrays(sandbox.Object()) instanceof Cu.waiveXrays(sandbox.DOMObjectWithHasInstance), + /hasInstance_in_window/, + "Should call (waived) sandbox.DOMObjectWithHasInstance[Symbol.hasInstance] when both operands have waived Xrays"); + + webnav.close(); +}); diff --git a/js/xpconnect/tests/unit/test_xray_named_element_access.js b/js/xpconnect/tests/unit/test_xray_named_element_access.js new file mode 100644 index 0000000000..c35bf352a9 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_named_element_access.js @@ -0,0 +1,23 @@ +// See https://bugzilla.mozilla.org/show_bug.cgi?id=1273251 +"use strict" + +ChromeUtils.importESModule("resource://gre/modules/Preferences.sys.mjs"); + +add_task(async function() { + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + + docShell.createAboutBlankContentViewer(null, null); + + let window = webnav.document.defaultView; + let unwrapped = Cu.waiveXrays(window); + + window.document.body.innerHTML = '<div id="foo"></div>'; + + equal(window.foo, undefined, "Should not have named X-ray property access"); + equal(typeof unwrapped.foo, "object", "Should always have non-X-ray named property access"); + + webnav.close(); +}); + diff --git a/js/xpconnect/tests/unit/test_xray_regexp.js b/js/xpconnect/tests/unit/test_xray_regexp.js new file mode 100644 index 0000000000..72eb9563d0 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xray_regexp.js @@ -0,0 +1,7 @@ +function run_test() { + var sandbox = Cu.Sandbox('http://www.example.com'); + var regexp = Cu.evalInSandbox("/test/i", sandbox); + equal(RegExp.prototype.toString.call(regexp), "/test/i"); + var prototype = Cu.evalInSandbox("RegExp.prototype", sandbox); + equal(typeof prototype.lastIndex, "undefined"); +} diff --git a/js/xpconnect/tests/unit/test_xrayed_arguments.js b/js/xpconnect/tests/unit/test_xrayed_arguments.js new file mode 100644 index 0000000000..fae0a0c865 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xrayed_arguments.js @@ -0,0 +1,16 @@ +function run_test() { + var sbContent = Cu.Sandbox(null); + let xrayedArgs = sbContent.eval("(function(a, b) { return arguments; })('hi', 42)"); + + function checkArgs(a) { + Assert.equal(a.length, 2); + Assert.equal(a[0], 'hi'); + Assert.equal(a[1], 42); + } + + // Check Xrays to the args. + checkArgs(xrayedArgs); + + // Make sure the spread operator works. + checkArgs([...xrayedArgs]); +} diff --git a/js/xpconnect/tests/unit/test_xrayed_iterator.js b/js/xpconnect/tests/unit/test_xrayed_iterator.js new file mode 100644 index 0000000000..26d40420a3 --- /dev/null +++ b/js/xpconnect/tests/unit/test_xrayed_iterator.js @@ -0,0 +1,40 @@ +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.allow_eval_with_system_principal"); +}); + +function run_test() { + + var toEval = [ + "var customIterator = {", + " _array: [6, 7, 8, 9]", + "};", + "customIterator[Symbol.iterator] = function* () {", + " for (var i = 0; i < this._array.length; ++i)", + " yield this._array[i];", + "};" + ].join('\n'); + + function checkIterator(iterator) { + var control = [6, 7, 8, 9]; + var i = 0; + for (var item of iterator) { + Assert.equal(item, control[i]); + ++i; + } + } + + // First, try in our own scope. + eval(toEval); + checkIterator(customIterator); + + // Next, try a vanilla CCW. + var sbChrome = Cu.Sandbox(this); + Cu.evalInSandbox(toEval, sbChrome, '1.7'); + checkIterator(sbChrome.customIterator); + + // Finally, try an Xray waiver. + var sbContent = Cu.Sandbox('http://www.example.com'); + Cu.evalInSandbox(toEval, sbContent, '1.7'); + checkIterator(Cu.waiveXrays(sbContent.customIterator)); +} diff --git a/js/xpconnect/tests/unit/uninitialized_lexical.jsm b/js/xpconnect/tests/unit/uninitialized_lexical.jsm new file mode 100644 index 0000000000..e0d661bcd4 --- /dev/null +++ b/js/xpconnect/tests/unit/uninitialized_lexical.jsm @@ -0,0 +1,2 @@ +var EXPORTED_SYMBOLS = ["foo"]; +const foo = ChromeUtils.import("resource://test/uninitialized_lexical.jsm"); diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini new file mode 100644 index 0000000000..23c1270028 --- /dev/null +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -0,0 +1,223 @@ +[DEFAULT] +head = head.js +support-files = + CatRegistrationComponents.manifest + CatBackgroundTaskRegistrationComponents.manifest + bogus_element_type.jsm + bogus_exports_type.jsm + bug451678_subscript.js + TestBlob.jsm + TestFile.jsm + environment_script.js + environment_loadscript.jsm + environment_checkscript.jsm + file_simple_script.js + importer.jsm + recursive_importA.jsm + recursive_importB.jsm + ReturnCodeChild.jsm + ReturnCodeChild.sys.mjs + syntax_error.jsm + uninitialized_lexical.jsm + es6module.js + es6import.js + es6module_throws.js + es6module_missing_import.js + es6module_parse_error.js + es6module_parse_error_in_import.js + es6module_cycle_a.js + es6module_cycle_b.js + es6module_cycle_c.js + es6module_top_level_await.js + es6module_devtoolsLoader.js + es6module_devtoolsLoader.sys.mjs + es6module_devtoolsLoader_only.js + esmified-1.sys.mjs + esmified-2.sys.mjs + esmified-3.sys.mjs + esmified-4.sys.mjs + esmified-5.sys.mjs + esmified-6.sys.mjs + esmified-not-exported.sys.mjs + not-esmified-not-exported.jsm + esm_lazy-1.sys.mjs + esm_lazy-2.sys.mjs + jsm_loaded-1.jsm + jsm_loaded-2.jsm + jsm_loaded-3.jsm + es6module_loaded-1.sys.mjs + es6module_loaded-2.sys.mjs + es6module_loaded-3.sys.mjs + api_script.js + import_stack.jsm + import_stack.sys.mjs + import_stack_static_1.sys.mjs + import_stack_static_2.sys.mjs + import_stack_static_3.sys.mjs + import_stack_static_4.sys.mjs + es6module_import_error.js + es6module_import_error2.js + es6module_dynamic_import.js + es6module_dynamic_import2.js + es6module_absolute.js + es6module_absolute2.js + envChain.jsm + envChain_subscript.jsm + error_export.sys.mjs + error_import.sys.mjs + error_other.sys.mjs + +[test_allowWaivers.js] +[test_bogus_files.js] +[test_bug267645.js] +[test_bug408412.js] +[test_bug451678.js] +[test_bug604362.js] +[test_bug677864.js] +[test_bug711404.js] +[test_bug742444.js] +[test_bug778409.js] +[test_bug780370.js] +[test_bug809652.js] +[test_bug809674.js] +[test_bug813901.js] +[test_bug845201.js] +[test_bug845862.js] +[test_bug849730.js] +[test_bug851895.js] +[test_bug853709.js] +[test_bug856067.js] +[test_bug868675.js] +[test_bug867486.js] +[test_bug872772.js] +[test_bug885800.js] +[test_bug930091.js] +[test_bug976151.js] +[test_bug1001094.js] +[test_bug1021312.js] +[test_bug1033253.js] +[test_bug1033920.js] +[test_bug1033927.js] +[test_bug1034262.js] +[test_bug1081990.js] +[test_bug1110546.js] +[test_bug1131707.js] +[test_bug1150771.js] +[test_bug1151385.js] +[test_bug1170311.js] +[test_bug1244222.js] +[test_bug1617527.js] +[test_bug_442086.js] +[test_callFunctionWithAsyncStack.js] +[test_cenums.js] +[test_compileScript.js] +[test_deepFreezeClone.js] +[test_defineModuleGetter.js] +[test_eventSource.js] +[test_file.js] +skip-if = os == 'android' && processor == 'x86_64' +[test_blob.js] +[test_blob2.js] +[test_file2.js] +skip-if = os == 'android' && processor == 'x86_64' +[test_getCallerLocation.js] +[test_generateQI.js] +[test_import.js] +[test_import_fail.js] +[test_isModuleLoaded.js] +[test_js_weak_references.js] +[test_onGarbageCollection-01.js] +head = head_ongc.js +[test_onGarbageCollection-02.js] +head = head_ongc.js +[test_onGarbageCollection-03.js] +head = head_ongc.js +[test_onGarbageCollection-04.js] +head = head_ongc.js +[test_onGarbageCollection-05.js] +head = head_ongc.js +[test_reflect_parse.js] +[test_localeCompare.js] +[test_recursive_import.js] +[test_xpcomutils.js] +[test_unload.js] +[test_lazyproxy.js] +[test_attributes.js] +[test_params.js] +[test_tearoffs.js] +[test_want_components.js] +[test_components.js] +[test_allowedDomains.js] +[test_allowedDomainsXHR.js] +[test_nuke_sandbox.js] +[test_nuke_sandbox_event_listeners.js] +[test_nuke_webextension_wrappers.js] +[test_subScriptLoader.js] +[test_rewrap_dead_wrapper.js] +[test_sandbox_metadata.js] +[test_sandbox_DOMException.js] +[test_exportFunction.js] +[test_promise.js] +[test_returncode.js] +[test_textDecoder.js] +[test_url.js] +[test_URLSearchParams.js] +[test_fileReader.js] +[test_messageChannel.js] +[test_crypto.js] +[test_css.js] +[test_rtcIdentityProvider.js] +[test_sandbox_atob.js] +[test_structuredClone.js] +[test_isProxy.js] +[test_js_memory_telemetry.js] +[test_getObjectPrincipal.js] +[test_sandbox_name.js] +[test_storage.js] +[test_watchdog_enable.js] +head = head_watchdog.js +[test_watchdog_disable.js] +head = head_watchdog.js +[test_watchdog_toggle.js] +head = head_watchdog.js +[test_watchdog_default.js] +head = head_watchdog.js +[test_watchdog_hibernate.js] +head = head_watchdog.js +[test_weak_keys.js] +[test_xpcwn_instanceof.js] +[test_xpcwn_tamperproof.js] +[test_xrayed_arguments.js] +[test_xrayed_iterator.js] +[test_xray_instanceof.js] +[test_xray_named_element_access.js] +[test_private_field_xrays.js] +[test_xray_SavedFrame.js] +[test_xray_SavedFrame-02.js] +[test_xray_regexp.js] +[test_resolve_dead_promise.js] +[test_function_names.js] +[test_FrameScriptEnvironment.js] +[test_SubscriptLoaderEnvironment.js] +[test_SubscriptLoaderSandboxEnvironment.js] +[test_SubscriptLoaderJSMEnvironment.js] +[test_ComponentEnvironment.js] +[test_wrapped_js_enumerator.js] +[test_uawidget_scope.js] +[test_uninitialized_lexical.js] +[test_print_stderr.js] +[test_import_devtools_loader.js] +[test_import_es6_modules.js] +[test_import_shim.js] +[test_defineESModuleGetters.js] +[test_loadedESModules.js] +[test_import_from_sandbox.js] +[test_import_stack.js] +skip-if = + !nightly_build + !debug +[test_envChain_frameScript.js] +[test_envChain_JSM.js] +[test_envChain_subscript.js] +[test_envChain_subscript_in_JSM.js] +[test_import_syntax_error.js] diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp new file mode 100644 index 0000000000..a38ae5bb13 --- /dev/null +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "AccessCheck.h" + +#include "nsJSPrincipals.h" +#include "nsGlobalWindow.h" + +#include "XPCWrapper.h" +#include "XrayWrapper.h" +#include "FilteringWrapper.h" + +#include "jsfriendapi.h" +#include "js/Object.h" // JS::GetClass, JS::GetCompartment +#include "mozilla/BasePrincipal.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/LocationBinding.h" +#include "mozilla/dom/WindowBinding.h" +#include "nsJSUtils.h" +#include "xpcprivate.h" + +using namespace mozilla; +using namespace JS; +using namespace js; + +namespace xpc { + +BasePrincipal* GetRealmPrincipal(JS::Realm* realm) { + return BasePrincipal::Cast( + nsJSPrincipals::get(JS::GetRealmPrincipals(realm))); +} + +nsIPrincipal* GetObjectPrincipal(JSObject* obj) { + return GetRealmPrincipal(js::GetNonCCWObjectRealm(obj)); +} + +bool AccessCheck::subsumes(JSObject* a, JSObject* b) { + return CompartmentOriginInfo::Subsumes(JS::GetCompartment(a), + JS::GetCompartment(b)); +} + +// Same as above, but considering document.domain. +bool AccessCheck::subsumesConsideringDomain(JS::Realm* a, JS::Realm* b) { + MOZ_ASSERT(OriginAttributes::IsRestrictOpenerAccessForFPI()); + BasePrincipal* aprin = GetRealmPrincipal(a); + BasePrincipal* bprin = GetRealmPrincipal(b); + return aprin->FastSubsumesConsideringDomain(bprin); +} + +bool AccessCheck::subsumesConsideringDomainIgnoringFPD(JS::Realm* a, + JS::Realm* b) { + MOZ_ASSERT(!OriginAttributes::IsRestrictOpenerAccessForFPI()); + BasePrincipal* aprin = GetRealmPrincipal(a); + BasePrincipal* bprin = GetRealmPrincipal(b); + return aprin->FastSubsumesConsideringDomainIgnoringFPD(bprin); +} + +// Does the compartment of the wrapper subsumes the compartment of the wrappee? +bool AccessCheck::wrapperSubsumes(JSObject* wrapper) { + MOZ_ASSERT(js::IsWrapper(wrapper)); + JSObject* wrapped = js::UncheckedUnwrap(wrapper); + return CompartmentOriginInfo::Subsumes(JS::GetCompartment(wrapper), + JS::GetCompartment(wrapped)); +} + +bool AccessCheck::isChrome(JS::Compartment* compartment) { + return js::IsSystemCompartment(compartment); +} + +bool AccessCheck::isChrome(JS::Realm* realm) { + return isChrome(JS::GetCompartmentForRealm(realm)); +} + +bool AccessCheck::isChrome(JSObject* obj) { + return isChrome(JS::GetCompartment(obj)); +} + +bool IsCrossOriginAccessibleObject(JSObject* obj) { + obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false); + const JSClass* clasp = JS::GetClass(obj); + + return (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) || + (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window")); +} + +bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, + HandleValue v) { + // Primitives are fine. + if (!v.isObject()) { + return true; + } + RootedObject obj(cx, &v.toObject()); + + // Non-wrappers are fine. + if (!js::IsWrapper(obj)) { + return true; + } + + // Same-origin wrappers are fine. + if (AccessCheck::wrapperSubsumes(obj)) { + return true; + } + + // Badness. + JS_ReportErrorASCII(cx, + "Permission denied to pass object to privileged code"); + return false; +} + +bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, + const CallArgs& args) { + if (!checkPassToPrivilegedCode(cx, wrapper, args.thisv())) { + return false; + } + for (size_t i = 0; i < args.length(); ++i) { + if (!checkPassToPrivilegedCode(cx, wrapper, args[i])) { + return false; + } + } + return true; +} + +void AccessCheck::reportCrossOriginDenial(JSContext* cx, JS::HandleId id, + const nsACString& accessType) { + // This function exists because we want to report DOM SecurityErrors, not JS + // Errors, when denying access on cross-origin DOM objects. It's + // conceptually pretty similar to + // AutoEnterPolicy::reportErrorIfExceptionIsNotPending. + if (JS_IsExceptionPending(cx)) { + return; + } + + nsAutoCString message; + if (id.isVoid()) { + message = "Permission denied to access object"_ns; + } else { + // We want to use JS_ValueToSource here, because that most closely + // matches what AutoEnterPolicy::reportErrorIfExceptionIsNotPending + // does. + JS::RootedValue idVal(cx, js::IdToValue(id)); + nsAutoJSString propName; + JS::RootedString idStr(cx, JS_ValueToSource(cx, idVal)); + if (!idStr || !propName.init(cx, idStr)) { + return; + } + message = "Permission denied to "_ns + accessType + " property "_ns + + NS_ConvertUTF16toUTF8(propName) + " on cross-origin object"_ns; + } + ErrorResult rv; + rv.ThrowSecurityError(message); + MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(cx)); +} + +bool OpaqueWithSilentFailing::deny(JSContext* cx, js::Wrapper::Action act, + HandleId id, bool mayThrow) { + // Fail silently for GET, ENUMERATE, and GET_PROPERTY_DESCRIPTOR. + if (act == js::Wrapper::GET || act == js::Wrapper::ENUMERATE || + act == js::Wrapper::GET_PROPERTY_DESCRIPTOR) { + // Note that ReportWrapperDenial doesn't do any _exception_ reporting, + // so we want to do this regardless of the value of mayThrow. + return ReportWrapperDenial(cx, id, WrapperDenialForCOW, + "Access to privileged JS object not permitted"); + } + + return false; +} + +} // namespace xpc diff --git a/js/xpconnect/wrappers/AccessCheck.h b/js/xpconnect/wrappers/AccessCheck.h new file mode 100644 index 0000000000..c42e56ea02 --- /dev/null +++ b/js/xpconnect/wrappers/AccessCheck.h @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __AccessCheck_h__ +#define __AccessCheck_h__ + +#include "js/Id.h" +#include "js/Wrapper.h" +#include "nsString.h" + +#ifdef XP_MACOSX +// AssertMacros.h defines 'check' which conflicts with the method declarations +// in this file. +# undef check +#endif + +namespace xpc { + +class AccessCheck { + public: + static bool subsumes(JSObject* a, JSObject* b); + static bool wrapperSubsumes(JSObject* wrapper); + static bool subsumesConsideringDomain(JS::Realm* a, JS::Realm* b); + static bool subsumesConsideringDomainIgnoringFPD(JS::Realm* a, JS::Realm* b); + static bool isChrome(JS::Compartment* compartment); + static bool isChrome(JS::Realm* realm); + static bool isChrome(JSObject* obj); + static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper, + JS::HandleValue value); + static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args); + // Called to report the correct sort of exception when our policy denies and + // should throw. The accessType argument should be one of "access", + // "define", "delete", depending on which operation is being denied. + static void reportCrossOriginDenial(JSContext* cx, JS::HandleId id, + const nsACString& accessType); +}; + +/** + * Returns true if the given object (which is expected to be stripped of + * cross-compartment wrappers in practice, but this function doesn't assume + * that) is a WindowProxy or Location object, which need special wrapping + * behavior due to being usable cross-origin in limited ways. + */ +bool IsCrossOriginAccessibleObject(JSObject* obj); + +struct Policy { + static bool checkCall(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args) { + MOZ_CRASH("As a rule, filtering wrappers are non-callable"); + } +}; + +// This policy allows no interaction with the underlying callable. Everything +// throws. +struct Opaque : public Policy { + static bool check(JSContext* cx, JSObject* wrapper, jsid id, + js::Wrapper::Action act) { + return false; + } + static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id, + bool mayThrow) { + return false; + } + static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl) { + return false; + } +}; + +// Like the above, but allows CALL. +struct OpaqueWithCall : public Policy { + static bool check(JSContext* cx, JSObject* wrapper, jsid id, + js::Wrapper::Action act) { + return act == js::Wrapper::CALL; + } + static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id, + bool mayThrow) { + return false; + } + static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl) { + return false; + } + static bool checkCall(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args) { + return AccessCheck::checkPassToPrivilegedCode(cx, wrapper, args); + } +}; + +// This class used to support permitting access to properties if they +// appeared in an access list on the object, but now it acts like an +// Opaque wrapper, with the exception that it fails silently for GET, +// ENUMERATE, and GET_PROPERTY_DESCRIPTOR. This is done for backwards +// compatibility. See bug 1397513. +struct OpaqueWithSilentFailing : public Policy { + static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + js::Wrapper::Action act) { + return false; + } + + static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id, + bool mayThrow); + static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl) { + return false; + } +}; + +} // namespace xpc + +#endif /* __AccessCheck_h__ */ diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp new file mode 100644 index 0000000000..28ea3d2c02 --- /dev/null +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ChromeObjectWrapper.h" +#include "WrapperFactory.h" +#include "AccessCheck.h" +#include "xpcprivate.h" +#include "jsapi.h" +#include "js/Wrapper.h" +#include "nsXULAppAPI.h" + +using namespace JS; + +namespace xpc { + +const ChromeObjectWrapper ChromeObjectWrapper::singleton; + +bool ChromeObjectWrapper::defineProperty(JSContext* cx, HandleObject wrapper, + HandleId id, + Handle<PropertyDescriptor> desc, + ObjectOpResult& result) const { + if (desc.hasValue() && + !AccessCheck::checkPassToPrivilegedCode(cx, wrapper, desc.value())) { + return false; + } + return ChromeObjectWrapperBase::defineProperty(cx, wrapper, id, desc, result); +} + +bool ChromeObjectWrapper::set(JSContext* cx, HandleObject wrapper, HandleId id, + HandleValue v, HandleValue receiver, + ObjectOpResult& result) const { + if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, v)) { + return false; + } + return ChromeObjectWrapperBase::set(cx, wrapper, id, v, receiver, result); +} + +} // namespace xpc diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.h b/js/xpconnect/wrappers/ChromeObjectWrapper.h new file mode 100644 index 0000000000..49ce4fc139 --- /dev/null +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __ChromeObjectWrapper_h__ +#define __ChromeObjectWrapper_h__ + +#include "mozilla/Attributes.h" + +#include "FilteringWrapper.h" + +namespace xpc { + +struct OpaqueWithSilentFailing; + +// When a vanilla chrome JS object is exposed to content, we use a wrapper that +// fails silently on GET, ENUMERATE, and GET_PROPERTY_DESCRIPTOR for legacy +// reasons. For extra security, we override the traps that allow content to pass +// an object to chrome, and perform extra security checks on them. +#define ChromeObjectWrapperBase \ + FilteringWrapper<js::CrossCompartmentSecurityWrapper, OpaqueWithSilentFailing> + +class ChromeObjectWrapper : public ChromeObjectWrapperBase { + public: + constexpr ChromeObjectWrapper() : ChromeObjectWrapperBase(0) {} + + virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, + JS::Handle<JS::PropertyDescriptor> desc, + JS::ObjectOpResult& result) const override; + virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::HandleValue v, JS::HandleValue receiver, + JS::ObjectOpResult& result) const override; + + static const ChromeObjectWrapper singleton; +}; + +} /* namespace xpc */ + +#endif /* __ChromeObjectWrapper_h__ */ diff --git a/js/xpconnect/wrappers/FilteringWrapper.cpp b/js/xpconnect/wrappers/FilteringWrapper.cpp new file mode 100644 index 0000000000..f4812e04ba --- /dev/null +++ b/js/xpconnect/wrappers/FilteringWrapper.cpp @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "FilteringWrapper.h" +#include "AccessCheck.h" +#include "ChromeObjectWrapper.h" +#include "XrayWrapper.h" +#include "nsJSUtils.h" +#include "mozilla/ErrorResult.h" +#include "xpcpublic.h" +#include "xpcprivate.h" + +#include "jsapi.h" +#include "js/Symbol.h" + +using namespace JS; +using namespace js; + +namespace xpc { + +static JS::SymbolCode sCrossOriginWhitelistedSymbolCodes[] = { + JS::SymbolCode::toStringTag, JS::SymbolCode::hasInstance, + JS::SymbolCode::isConcatSpreadable}; + +static bool IsCrossOriginWhitelistedSymbol(JSContext* cx, JS::HandleId id) { + if (!id.isSymbol()) { + return false; + } + + JS::Symbol* symbol = id.toSymbol(); + for (auto code : sCrossOriginWhitelistedSymbolCodes) { + if (symbol == JS::GetWellKnownSymbol(cx, code)) { + return true; + } + } + + return false; +} + +bool IsCrossOriginWhitelistedProp(JSContext* cx, JS::HandleId id) { + return id == GetJSIDByIndex(cx, XPCJSContext::IDX_THEN) || + IsCrossOriginWhitelistedSymbol(cx, id); +} + +bool AppendCrossOriginWhitelistedPropNames(JSContext* cx, + JS::MutableHandleIdVector props) { + // Add "then" if it's not already in the list. + RootedIdVector thenProp(cx); + if (!thenProp.append(GetJSIDByIndex(cx, XPCJSContext::IDX_THEN))) { + return false; + } + + if (!AppendUnique(cx, props, thenProp)) { + return false; + } + + // Now add the three symbol-named props cross-origin objects have. +#ifdef DEBUG + for (size_t n = 0; n < props.length(); ++n) { + MOZ_ASSERT(!props[n].isSymbol(), "Unexpected existing symbol-name prop"); + } +#endif + if (!props.reserve( + props.length() + + mozilla::ArrayLength(sCrossOriginWhitelistedSymbolCodes))) { + return false; + } + + for (auto code : sCrossOriginWhitelistedSymbolCodes) { + props.infallibleAppend(JS::GetWellKnownSymbolKey(cx, code)); + } + + return true; +} + +// Note: Previously, FilteringWrapper supported complex access policies where +// certain properties on an object were accessible and others weren't. Today, +// the only supported policies are Opaque and OpaqueWithCall, none of which need +// that. So we just stub out the unreachable paths. +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::getOwnPropertyDescriptor( + JSContext* cx, HandleObject wrapper, HandleId id, + MutableHandle<mozilla::Maybe<PropertyDescriptor>> desc) const { + MOZ_CRASH("FilteringWrappers are now always opaque"); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::ownPropertyKeys( + JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const { + MOZ_CRASH("FilteringWrappers are now always opaque"); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::getOwnEnumerablePropertyKeys( + JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const { + MOZ_CRASH("FilteringWrappers are now always opaque"); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::enumerate( + JSContext* cx, HandleObject wrapper, + JS::MutableHandleIdVector props) const { + MOZ_CRASH("FilteringWrappers are now always opaque"); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::call(JSContext* cx, + JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const { + if (!Policy::checkCall(cx, wrapper, args)) { + return false; + } + return Base::call(cx, wrapper, args); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::construct(JSContext* cx, + JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const { + if (!Policy::checkCall(cx, wrapper, args)) { + return false; + } + return Base::construct(cx, wrapper, args); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::nativeCall( + JSContext* cx, JS::IsAcceptableThis test, JS::NativeImpl impl, + const JS::CallArgs& args) const { + if (Policy::allowNativeCall(cx, test, impl)) { + return Base::Permissive::nativeCall(cx, test, impl, args); + } + return Base::Restrictive::nativeCall(cx, test, impl, args); +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::getPrototype( + JSContext* cx, JS::HandleObject wrapper, + JS::MutableHandleObject protop) const { + // Filtering wrappers do not allow access to the prototype. + protop.set(nullptr); + return true; +} + +template <typename Base, typename Policy> +bool FilteringWrapper<Base, Policy>::enter(JSContext* cx, HandleObject wrapper, + HandleId id, Wrapper::Action act, + bool mayThrow, bool* bp) const { + if (!Policy::check(cx, wrapper, id, act)) { + *bp = + JS_IsExceptionPending(cx) ? false : Policy::deny(cx, act, id, mayThrow); + return false; + } + *bp = true; + return true; +} + +#define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque> +#define NNXOWC FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall> + +template <> +const NNXOW NNXOW::singleton(0); +template <> +const NNXOWC NNXOWC::singleton(0); + +template class NNXOW; +template class NNXOWC; +template class ChromeObjectWrapperBase; +} // namespace xpc diff --git a/js/xpconnect/wrappers/FilteringWrapper.h b/js/xpconnect/wrappers/FilteringWrapper.h new file mode 100644 index 0000000000..620837cc1b --- /dev/null +++ b/js/xpconnect/wrappers/FilteringWrapper.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __FilteringWrapper_h__ +#define __FilteringWrapper_h__ + +#include "XrayWrapper.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" +#include "js/CallNonGenericMethod.h" +#include "js/Wrapper.h" + +namespace xpc { + +template <typename Base, typename Policy> +class FilteringWrapper : public Base { + public: + constexpr explicit FilteringWrapper(unsigned flags) : Base(flags) {} + + virtual bool enter(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, js::Wrapper::Action act, + bool mayThrow, bool* bp) const override; + + virtual bool getOwnPropertyDescriptor( + JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) + const override; + virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + + virtual bool getOwnEnumerablePropertyKeys( + JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + + virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + + virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl, + const JS::CallArgs& args) const override; + + virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::MutableHandleObject protop) const override; + + static const FilteringWrapper singleton; +}; + +} // namespace xpc + +#endif /* __FilteringWrapper_h__ */ diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp new file mode 100644 index 0000000000..17c273a5e0 --- /dev/null +++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WaiveXrayWrapper.h" +#include "WrapperFactory.h" +#include "jsapi.h" +#include "js/CallAndConstruct.h" // JS::IsCallable + +using namespace JS; + +namespace xpc { + +bool WaiveXrayWrapper::getOwnPropertyDescriptor( + JSContext* cx, HandleObject wrapper, HandleId id, + MutableHandle<mozilla::Maybe<PropertyDescriptor>> desc) const { + if (!CrossCompartmentWrapper::getOwnPropertyDescriptor(cx, wrapper, id, + desc)) { + return false; + } + + if (desc.isNothing()) { + return true; + } + + Rooted<PropertyDescriptor> desc_(cx, *desc); + if (desc_.hasValue()) { + if (!WrapperFactory::WaiveXrayAndWrap(cx, desc_.value())) { + return false; + } + } + if (desc_.hasGetter() && desc_.getter()) { + RootedValue v(cx, JS::ObjectValue(*desc_.getter())); + if (!WrapperFactory::WaiveXrayAndWrap(cx, &v)) { + return false; + } + desc_.setGetter(&v.toObject()); + } + if (desc_.hasSetter() && desc_.setter()) { + RootedValue v(cx, JS::ObjectValue(*desc_.setter())); + if (!WrapperFactory::WaiveXrayAndWrap(cx, &v)) { + return false; + } + desc_.setSetter(&v.toObject()); + } + + desc.set(mozilla::Some(desc_.get())); + return true; +} + +bool WaiveXrayWrapper::get(JSContext* cx, HandleObject wrapper, + HandleValue receiver, HandleId id, + MutableHandleValue vp) const { + return CrossCompartmentWrapper::get(cx, wrapper, receiver, id, vp) && + WrapperFactory::WaiveXrayAndWrap(cx, vp); +} + +bool WaiveXrayWrapper::call(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args) const { + return CrossCompartmentWrapper::call(cx, wrapper, args) && + WrapperFactory::WaiveXrayAndWrap(cx, args.rval()); +} + +bool WaiveXrayWrapper::construct(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args) const { + return CrossCompartmentWrapper::construct(cx, wrapper, args) && + WrapperFactory::WaiveXrayAndWrap(cx, args.rval()); +} + +// NB: This is important as the other side of a handshake with FieldGetter. See +// nsXBLProtoImplField.cpp. +bool WaiveXrayWrapper::nativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl, + const JS::CallArgs& args) const { + return CrossCompartmentWrapper::nativeCall(cx, test, impl, args) && + WrapperFactory::WaiveXrayAndWrap(cx, args.rval()); +} + +bool WaiveXrayWrapper::getPrototype(JSContext* cx, HandleObject wrapper, + MutableHandleObject protop) const { + return CrossCompartmentWrapper::getPrototype(cx, wrapper, protop) && + (!protop || WrapperFactory::WaiveXrayAndWrap(cx, protop)); +} + +bool WaiveXrayWrapper::getPrototypeIfOrdinary( + JSContext* cx, HandleObject wrapper, bool* isOrdinary, + MutableHandleObject protop) const { + return CrossCompartmentWrapper::getPrototypeIfOrdinary(cx, wrapper, + isOrdinary, protop) && + (!protop || WrapperFactory::WaiveXrayAndWrap(cx, protop)); +} + +} // namespace xpc diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.h b/js/xpconnect/wrappers/WaiveXrayWrapper.h new file mode 100644 index 0000000000..02784fdd8f --- /dev/null +++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __CrossOriginWrapper_h__ +#define __CrossOriginWrapper_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" + +#include "js/Wrapper.h" + +namespace xpc { + +class WaiveXrayWrapper : public js::CrossCompartmentWrapper { + public: + explicit constexpr WaiveXrayWrapper(unsigned flags) + : js::CrossCompartmentWrapper(flags) {} + + virtual bool getOwnPropertyDescriptor( + JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) + const override; + virtual bool getPrototype(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandle<JSObject*> protop) const override; + virtual bool getPrototypeIfOrdinary( + JSContext* cx, JS::Handle<JSObject*> wrapper, bool* isOrdinary, + JS::MutableHandle<JSObject*> protop) const override; + virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, + JS::MutableHandle<JS::Value> vp) const override; + virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + + virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test, + JS::NativeImpl impl, + const JS::CallArgs& args) const override; + + static const WaiveXrayWrapper singleton; +}; + +} // namespace xpc + +#endif diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp new file mode 100644 index 0000000000..9faf636388 --- /dev/null +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -0,0 +1,818 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WaiveXrayWrapper.h" +#include "FilteringWrapper.h" +#include "XrayWrapper.h" +#include "AccessCheck.h" +#include "XPCWrapper.h" +#include "ChromeObjectWrapper.h" +#include "WrapperFactory.h" + +#include "xpcprivate.h" +#include "XPCMaps.h" +#include "mozilla/dom/BindingUtils.h" +#include "jsfriendapi.h" +#include "js/friend/WindowProxy.h" // js::IsWindow, js::IsWindowProxy +#include "js/Object.h" // JS::GetPrivate, JS::GetCompartment +#include "mozilla/Likely.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/MaybeCrossOriginObject.h" +#include "nsContentUtils.h" +#include "nsXULAppAPI.h" + +using namespace JS; +using namespace js; +using namespace mozilla; + +namespace xpc { + +#ifndef MOZ_UNIFIED_BUILD +extern template class FilteringWrapper<js::CrossCompartmentSecurityWrapper, + Opaque>; +extern template class FilteringWrapper<js::CrossCompartmentSecurityWrapper, + OpaqueWithCall>; +#endif + +// When chrome pulls a naked property across the membrane using +// .wrappedJSObject, we want it to cross the membrane into the +// chrome compartment without automatically being wrapped into an +// X-ray wrapper. We achieve this by wrapping it into a special +// transparent wrapper in the origin (non-chrome) compartment. When +// an object with that special wrapper applied crosses into chrome, +// we know to not apply an X-ray wrapper. +const Wrapper XrayWaiver(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG); + +// When objects for which we waived the X-ray wrapper cross into +// chrome, we wrap them into a special cross-compartment wrapper +// that transitively extends the waiver to all properties we get +// off it. +const WaiveXrayWrapper WaiveXrayWrapper::singleton(0); + +bool WrapperFactory::IsOpaqueWrapper(JSObject* obj) { + return IsWrapper(obj) && + Wrapper::wrapperHandler(obj) == &PermissiveXrayOpaque::singleton; +} + +bool WrapperFactory::IsCOW(JSObject* obj) { + return IsWrapper(obj) && + Wrapper::wrapperHandler(obj) == &ChromeObjectWrapper::singleton; +} + +JSObject* WrapperFactory::GetXrayWaiver(HandleObject obj) { + // Object should come fully unwrapped but outerized. + MOZ_ASSERT(obj == UncheckedUnwrap(obj)); + MOZ_ASSERT(!js::IsWindow(obj)); + XPCWrappedNativeScope* scope = ObjectScope(obj); + MOZ_ASSERT(scope); + + if (!scope->mWaiverWrapperMap) { + return nullptr; + } + + return scope->mWaiverWrapperMap->Find(obj); +} + +JSObject* WrapperFactory::CreateXrayWaiver(JSContext* cx, HandleObject obj, + bool allowExisting) { + // The caller is required to have already done a lookup, unless it's + // trying to replace an existing waiver. + // NB: This implictly performs the assertions of GetXrayWaiver. + MOZ_ASSERT(bool(GetXrayWaiver(obj)) == allowExisting); + XPCWrappedNativeScope* scope = ObjectScope(obj); + + JSAutoRealm ar(cx, obj); + JSObject* waiver = Wrapper::New(cx, obj, &XrayWaiver); + if (!waiver) { + return nullptr; + } + + // Add the new waiver to the map. It's important that we only ever have + // one waiver for the lifetime of the target object. + if (!scope->mWaiverWrapperMap) { + scope->mWaiverWrapperMap = mozilla::MakeUnique<JSObject2JSObjectMap>(); + } + if (!scope->mWaiverWrapperMap->Add(cx, obj, waiver)) { + return nullptr; + } + return waiver; +} + +JSObject* WrapperFactory::WaiveXray(JSContext* cx, JSObject* objArg) { + RootedObject obj(cx, objArg); + obj = UncheckedUnwrap(obj); + MOZ_ASSERT(!js::IsWindow(obj)); + + JSObject* waiver = GetXrayWaiver(obj); + if (!waiver) { + waiver = CreateXrayWaiver(cx, obj); + } + JS::AssertObjectIsNotGray(waiver); + return waiver; +} + +/* static */ +bool WrapperFactory::AllowWaiver(JS::Compartment* target, + JS::Compartment* origin) { + return CompartmentPrivate::Get(target)->allowWaivers && + CompartmentOriginInfo::Subsumes(target, origin); +} + +/* static */ +bool WrapperFactory::AllowWaiver(JSObject* wrapper) { + MOZ_ASSERT(js::IsCrossCompartmentWrapper(wrapper)); + return AllowWaiver(JS::GetCompartment(wrapper), + JS::GetCompartment(js::UncheckedUnwrap(wrapper))); +} + +inline bool ShouldWaiveXray(JSContext* cx, JSObject* originalObj) { + unsigned flags; + (void)js::UncheckedUnwrap(originalObj, /* stopAtWindowProxy = */ true, + &flags); + + // If the original object did not point through an Xray waiver, we're done. + if (!(flags & WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG)) { + return false; + } + + // If the original object was not a cross-compartment wrapper, that means + // that the caller explicitly created a waiver. Preserve it so that things + // like WaiveXrayAndWrap work. + if (!(flags & Wrapper::CROSS_COMPARTMENT)) { + return true; + } + + // Otherwise, this is a case of explicitly passing a wrapper across a + // compartment boundary. In that case, we only want to preserve waivers + // in transactions between same-origin compartments. + JS::Compartment* oldCompartment = JS::GetCompartment(originalObj); + JS::Compartment* newCompartment = js::GetContextCompartment(cx); + bool sameOrigin = false; + if (OriginAttributes::IsRestrictOpenerAccessForFPI()) { + sameOrigin = + CompartmentOriginInfo::Subsumes(oldCompartment, newCompartment) && + CompartmentOriginInfo::Subsumes(newCompartment, oldCompartment); + } else { + sameOrigin = CompartmentOriginInfo::SubsumesIgnoringFPD(oldCompartment, + newCompartment) && + CompartmentOriginInfo::SubsumesIgnoringFPD(newCompartment, + oldCompartment); + } + return sameOrigin; +} + +// Special handling is needed when wrapping local and remote window proxies. +// This function returns true if it found a window proxy and dealt with it. +static bool MaybeWrapWindowProxy(JSContext* cx, HandleObject origObj, + HandleObject obj, MutableHandleObject retObj) { + bool isWindowProxy = js::IsWindowProxy(obj); + + if (!isWindowProxy && + !dom::IsRemoteObjectProxy(obj, dom::prototypes::id::Window)) { + return false; + } + + dom::BrowsingContext* bc = nullptr; + if (isWindowProxy) { + nsGlobalWindowInner* win = + WindowOrNull(js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false)); + if (win && win->GetOuterWindow()) { + bc = win->GetOuterWindow()->GetBrowsingContext(); + } + if (!bc) { + retObj.set(obj); + return true; + } + } else { + bc = dom::GetBrowsingContext(obj); + MOZ_ASSERT(bc); + } + + // We should only have a remote window proxy if bc is in a state where we + // expect remote window proxies. Otherwise, they should have been cleaned up + // by a call to CleanUpDanglingRemoteOuterWindowProxies(). + MOZ_RELEASE_ASSERT(isWindowProxy || bc->CanHaveRemoteOuterProxies()); + + if (bc->IsInProcess()) { + retObj.set(obj); + } else { + // If bc is not in process, then use a remote window proxy, whether or not + // obj is one already. + if (!dom::GetRemoteOuterWindowProxy(cx, bc, origObj, retObj)) { + MOZ_CRASH("GetRemoteOuterWindowProxy failed"); + } + } + + return true; +} + +void WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, + HandleObject origObj, + HandleObject objArg, + HandleObject objectPassedToWrap, + MutableHandleObject retObj) { + // The JS engine calls ToWindowProxyIfWindow and deals with dead wrappers. + MOZ_ASSERT(!js::IsWindow(objArg)); + MOZ_ASSERT(!JS_IsDeadWrapper(objArg)); + + bool waive = ShouldWaiveXray(cx, objectPassedToWrap); + RootedObject obj(cx, objArg); + retObj.set(nullptr); + + // There are a few cases related to window proxies that are handled first to + // allow us to assert against wrappers below. + if (MaybeWrapWindowProxy(cx, origObj, obj, retObj)) { + if (waive) { + // We don't put remote window proxies in a waiving wrapper. + MOZ_ASSERT(js::IsWindowProxy(obj)); + retObj.set(WaiveXray(cx, retObj)); + } + return; + } + + // Here are the rules for wrapping: + // We should never get a proxy here (the JS engine unwraps those for us). + MOZ_ASSERT(!IsWrapper(obj)); + + // Now, our object is ready to be wrapped, but several objects (notably + // nsJSIIDs) have a wrapper per scope. If we are about to wrap one of + // those objects in a security wrapper, then we need to hand back the + // wrapper for the new scope instead. Also, global objects don't move + // between scopes so for those we also want to return the wrapper. So... + if (!IsWrappedNativeReflector(obj) || JS_IsGlobalObject(obj)) { + retObj.set(waive ? WaiveXray(cx, obj) : obj); + return; + } + + XPCWrappedNative* wn = XPCWrappedNative::Get(obj); + + JSAutoRealm ar(cx, obj); + XPCCallContext ccx(cx, obj); + RootedObject wrapScope(cx, scope); + + if (ccx.GetScriptable() && ccx.GetScriptable()->WantPreCreate()) { + // We have a precreate hook. This object might enforce that we only + // ever create JS object for it. + + // Note: this penalizes objects that only have one wrapper, but are + // being accessed across compartments. We would really prefer to + // replace the above code with a test that says "do you only have one + // wrapper?" + nsresult rv = wn->GetScriptable()->PreCreate(wn->Native(), cx, scope, + wrapScope.address()); + if (NS_FAILED(rv)) { + retObj.set(waive ? WaiveXray(cx, obj) : obj); + return; + } + + // If the handed back scope differs from the passed-in scope and is in + // a separate compartment, then this object is explicitly requesting + // that we don't create a second JS object for it: create a security + // wrapper. + // + // Note: The only two objects that still use PreCreate are BackstagePass + // and Components, both of which unconditionally request their canonical + // scope. Since SpiderMonkey only invokes the prewrap callback in + // situations where the object is nominally cross-compartment, we should + // always get a different scope here. + MOZ_RELEASE_ASSERT(JS::GetCompartment(scope) != + JS::GetCompartment(wrapScope)); + retObj.set(waive ? WaiveXray(cx, obj) : obj); + return; + } + + // This public WrapNativeToJSVal API enters the compartment of 'wrapScope' + // so we don't have to. + RootedValue v(cx); + nsresult rv = nsXPConnect::XPConnect()->WrapNativeToJSVal( + cx, wrapScope, wn->Native(), nullptr, &NS_GET_IID(nsISupports), false, + &v); + if (NS_FAILED(rv)) { + return; + } + + obj.set(&v.toObject()); + MOZ_ASSERT(IsWrappedNativeReflector(obj), "bad object"); + JS::AssertObjectIsNotGray(obj); // We should never return gray reflectors. + + // Because the underlying native didn't have a PreCreate hook, we had + // to a new (or possibly pre-existing) XPCWN in our compartment. + // This could be a problem for chrome code that passes XPCOM objects + // across compartments, because the effects of QI would disappear across + // compartments. + // + // So whenever we pull an XPCWN across compartments in this manner, we + // give the destination object the union of the two native sets. We try + // to do this cleverly in the common case to avoid too much overhead. + XPCWrappedNative* newwn = XPCWrappedNative::Get(obj); + RefPtr<XPCNativeSet> unionSet = + XPCNativeSet::GetNewOrUsed(cx, newwn->GetSet(), wn->GetSet(), false); + if (!unionSet) { + return; + } + newwn->SetSet(unionSet.forget()); + + retObj.set(waive ? WaiveXray(cx, obj) : obj); +} + +// This check is completely symmetric, so we don't need to keep track of origin +// vs target here. Two compartments may have had transparent CCWs between them +// only if they are same-origin (ignoring document.domain) or have both had +// document.domain set at some point and are same-site. In either case they +// will have the same SiteIdentifier, so check that first. +static bool CompartmentsMayHaveHadTransparentCCWs( + CompartmentPrivate* private1, CompartmentPrivate* private2) { + auto& info1 = private1->originInfo; + auto& info2 = private2->originInfo; + + if (!info1.SiteRef().Equals(info2.SiteRef())) { + return false; + } + + return info1.GetPrincipalIgnoringDocumentDomain()->FastEquals( + info2.GetPrincipalIgnoringDocumentDomain()) || + (info1.HasChangedDocumentDomain() && info2.HasChangedDocumentDomain()); +} + +#ifdef DEBUG +static void DEBUG_CheckUnwrapSafety(HandleObject obj, + const js::Wrapper* handler, + JS::Realm* origin, JS::Realm* target) { + JS::Compartment* targetCompartment = JS::GetCompartmentForRealm(target); + if (!js::AllowNewWrapper(targetCompartment, obj)) { + // The JS engine should have returned a dead wrapper in this case and we + // shouldn't even get here. + MOZ_ASSERT_UNREACHABLE("CheckUnwrapSafety called for a dead wrapper"); + } else if (AccessCheck::isChrome(targetCompartment)) { + // If the caller is chrome (or effectively so), unwrap should always be + // allowed, but we might have a CrossOriginObjectWrapper here which allows + // it dynamically. + MOZ_ASSERT(!handler->hasSecurityPolicy() || + handler == &CrossOriginObjectWrapper::singleton); + } else { + // Otherwise, it should depend on whether the target subsumes the origin. + bool subsumes = + (OriginAttributes::IsRestrictOpenerAccessForFPI() + ? AccessCheck::subsumesConsideringDomain(target, origin) + : AccessCheck::subsumesConsideringDomainIgnoringFPD(target, + origin)); + if (!subsumes) { + // If the target (which is where the wrapper lives) does not subsume the + // origin (which is where the wrapped object lives), then we should + // generally have a security check on the wrapper here. There is one + // exception, though: things that used to be same-origin and then stopped + // due to document.domain changes. In that case we will have a + // transparent cross-compartment wrapper here even though "subsumes" is no + // longer true. + CompartmentPrivate* originCompartmentPrivate = + CompartmentPrivate::Get(origin); + CompartmentPrivate* targetCompartmentPrivate = + CompartmentPrivate::Get(target); + if (!originCompartmentPrivate->wantXrays && + !targetCompartmentPrivate->wantXrays && + CompartmentsMayHaveHadTransparentCCWs(originCompartmentPrivate, + targetCompartmentPrivate)) { + // We should have a transparent CCW, unless we have a cross-origin + // object, in which case it will be a CrossOriginObjectWrapper. + MOZ_ASSERT(handler == &CrossCompartmentWrapper::singleton || + handler == &CrossOriginObjectWrapper::singleton); + } else { + MOZ_ASSERT(handler->hasSecurityPolicy()); + } + } else { + // Even if target subsumes origin, we might have a wrapper with a security + // policy here, if it happens to be a CrossOriginObjectWrapper. + MOZ_ASSERT(!handler->hasSecurityPolicy() || + handler == &CrossOriginObjectWrapper::singleton); + } + } +} +#else +# define DEBUG_CheckUnwrapSafety(obj, handler, origin, target) \ + {} +#endif + +const CrossOriginObjectWrapper CrossOriginObjectWrapper::singleton; + +bool CrossOriginObjectWrapper::dynamicCheckedUnwrapAllowed( + HandleObject obj, JSContext* cx) const { + MOZ_ASSERT(js::GetProxyHandler(obj) == this, + "Why are we getting called for some random object?"); + JSObject* target = wrappedObject(obj); + return dom::MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(cx, + target); +} + +static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType, + bool waiveXrays, JSObject* obj) { + // Waived Xray uses a modified CCW that has transparent behavior but + // transitively waives Xrays on arguments. + if (waiveXrays) { + MOZ_ASSERT(!securityWrapper); + return &WaiveXrayWrapper::singleton; + } + + // If we don't want or can't use Xrays, select a wrapper that's either + // entirely transparent or entirely opaque. + if (xrayType == NotXray) { + if (!securityWrapper) { + return &CrossCompartmentWrapper::singleton; + } + return &FilteringWrapper<CrossCompartmentSecurityWrapper, + Opaque>::singleton; + } + + // Ok, we're using Xray. If this isn't a security wrapper, use the permissive + // version and skip the filter. + if (!securityWrapper) { + if (xrayType == XrayForDOMObject) { + return &PermissiveXrayDOM::singleton; + } else if (xrayType == XrayForJSObject) { + return &PermissiveXrayJS::singleton; + } + MOZ_ASSERT(xrayType == XrayForOpaqueObject); + return &PermissiveXrayOpaque::singleton; + } + + // There's never any reason to expose other objects to non-subsuming actors. + // Just use an opaque wrapper in these cases. + return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton; +} + +JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, + HandleObject obj) { + MOZ_ASSERT(!IsWrapper(obj) || GetProxyHandler(obj) == &XrayWaiver || + js::IsWindowProxy(obj), + "wrapped object passed to rewrap"); + MOZ_ASSERT(!js::IsWindow(obj)); + MOZ_ASSERT(dom::IsJSAPIActive()); + + // Compute the information we need to select the right wrapper. + JS::Realm* origin = js::GetNonCCWObjectRealm(obj); + JS::Realm* target = js::GetContextRealm(cx); + MOZ_ASSERT(target, "Why is our JSContext not in a Realm?"); + bool originIsChrome = AccessCheck::isChrome(origin); + bool targetIsChrome = AccessCheck::isChrome(target); + bool originSubsumesTarget = + OriginAttributes::IsRestrictOpenerAccessForFPI() + ? AccessCheck::subsumesConsideringDomain(origin, target) + : AccessCheck::subsumesConsideringDomainIgnoringFPD(origin, target); + bool targetSubsumesOrigin = + OriginAttributes::IsRestrictOpenerAccessForFPI() + ? AccessCheck::subsumesConsideringDomain(target, origin) + : AccessCheck::subsumesConsideringDomainIgnoringFPD(target, origin); + bool sameOrigin = targetSubsumesOrigin && originSubsumesTarget; + + const Wrapper* wrapper; + + CompartmentPrivate* originCompartmentPrivate = + CompartmentPrivate::Get(origin); + CompartmentPrivate* targetCompartmentPrivate = + CompartmentPrivate::Get(target); + + // Track whether we decided to use a transparent wrapper because of + // document.domain usage, so we don't override that decision. + bool isTransparentWrapperDueToDocumentDomain = false; + + // + // First, handle the special cases. + // + + // Special handling for chrome objects being exposed to content. + if (originIsChrome && !targetIsChrome) { + // If this is a chrome function being exposed to content, we need to allow + // call (but nothing else). + JSProtoKey key = IdentifyStandardInstance(obj); + if (key == JSProto_Function || key == JSProto_BoundFunction) { + wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, + OpaqueWithCall>::singleton; + } + + // For vanilla JSObjects exposed from chrome to content, we use a wrapper + // that fails silently in a few cases. We'd like to get rid of this + // eventually, but in their current form they don't cause much trouble. + else if (key == JSProto_Object) { + wrapper = &ChromeObjectWrapper::singleton; + } + + // Otherwise we get an opaque wrapper. + else { + wrapper = + &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton; + } + } + + // Special handling for the web's cross-origin objects (WindowProxy and + // Location). We only need or want to do this in web-like contexts, where all + // security relationships are symmetric and there are no forced Xrays. + else if (originSubsumesTarget == targetSubsumesOrigin && + // Check for the more rare case of cross-origin objects before doing + // the more-likely-to-pass checks for wantXrays. + IsCrossOriginAccessibleObject(obj) && + (!targetSubsumesOrigin || (!originCompartmentPrivate->wantXrays && + !targetCompartmentPrivate->wantXrays))) { + wrapper = &CrossOriginObjectWrapper::singleton; + } + + // Special handling for other web objects. Again, we only want this in + // web-like contexts (symmetric security relationships, no forced Xrays). In + // this situation, if the two compartments may ever have had transparent CCWs + // between them, we want to keep using transparent CCWs. + else if (originSubsumesTarget == targetSubsumesOrigin && + !originCompartmentPrivate->wantXrays && + !targetCompartmentPrivate->wantXrays && + CompartmentsMayHaveHadTransparentCCWs(originCompartmentPrivate, + targetCompartmentPrivate)) { + isTransparentWrapperDueToDocumentDomain = true; + wrapper = &CrossCompartmentWrapper::singleton; + } + + // + // Now, handle the regular cases. + // + // These are wrappers we can compute using a rule-based approach. In order + // to do so, we need to compute some parameters. + // + else { + // The wrapper is a security wrapper (protecting the wrappee) if and + // only if the target does not subsume the origin. + bool securityWrapper = !targetSubsumesOrigin; + + // Xrays are warranted if either the target or the origin don't trust + // each other. This is generally the case, unless the two are same-origin + // and the caller has not requested same-origin Xrays. + // + // Xrays are a bidirectional protection, since it affords clarity to the + // caller and privacy to the callee. + bool sameOriginXrays = originCompartmentPrivate->wantXrays || + targetCompartmentPrivate->wantXrays; + bool wantXrays = !sameOrigin || sameOriginXrays; + + XrayType xrayType = wantXrays ? GetXrayType(obj) : NotXray; + + // If Xrays are warranted, the caller may waive them for non-security + // wrappers (unless explicitly forbidden from doing so). + bool waiveXrays = wantXrays && !securityWrapper && + targetCompartmentPrivate->allowWaivers && + HasWaiveXrayFlag(obj); + + wrapper = SelectWrapper(securityWrapper, xrayType, waiveXrays, obj); + } + + if (!targetSubsumesOrigin && !isTransparentWrapperDueToDocumentDomain) { + // Do a belt-and-suspenders check against exposing eval()/Function() to + // non-subsuming content. + if (JSFunction* fun = JS_GetObjectFunction(obj)) { + if (JS_IsBuiltinEvalFunction(fun) || + JS_IsBuiltinFunctionConstructor(fun)) { + NS_WARNING( + "Trying to expose eval or Function to non-subsuming content!"); + wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, + Opaque>::singleton; + } + } + } + + DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target); + + if (existing) { + return Wrapper::Renew(existing, obj, wrapper); + } + + return Wrapper::New(cx, obj, wrapper); +} + +// Call WaiveXrayAndWrap when you have a JS object that you don't want to be +// wrapped in an Xray wrapper. cx->compartment is the compartment that will be +// using the returned object. If the object to be wrapped is already in the +// correct compartment, then this returns the unwrapped object. +bool WrapperFactory::WaiveXrayAndWrap(JSContext* cx, MutableHandleValue vp) { + if (vp.isPrimitive()) { + return JS_WrapValue(cx, vp); + } + + RootedObject obj(cx, &vp.toObject()); + if (!WaiveXrayAndWrap(cx, &obj)) { + return false; + } + + vp.setObject(*obj); + return true; +} + +bool WrapperFactory::WaiveXrayAndWrap(JSContext* cx, + MutableHandleObject argObj) { + MOZ_ASSERT(argObj); + RootedObject obj(cx, js::UncheckedUnwrap(argObj)); + MOZ_ASSERT(!js::IsWindow(obj)); + if (js::IsObjectInContextCompartment(obj, cx)) { + argObj.set(obj); + return true; + } + + // Even though waivers have no effect on access by scopes that don't subsume + // the underlying object, good defense-in-depth dictates that we should avoid + // handing out waivers to callers that can't use them. The transitive waiving + // machinery unconditionally calls WaiveXrayAndWrap on return values from + // waived functions, even though the return value might be not be same-origin + // with the function. So if we find ourselves trying to create a waiver for + // |cx|, we should check whether the caller has any business with waivers + // to things in |obj|'s compartment. + JS::Compartment* target = js::GetContextCompartment(cx); + JS::Compartment* origin = JS::GetCompartment(obj); + obj = AllowWaiver(target, origin) ? WaiveXray(cx, obj) : obj; + if (!obj) { + return false; + } + + if (!JS_WrapObject(cx, &obj)) { + return false; + } + argObj.set(obj); + return true; +} + +/* + * Calls to JS_TransplantObject* should go through these helpers here so that + * waivers get fixed up properly. + */ + +static bool FixWaiverAfterTransplant(JSContext* cx, HandleObject oldWaiver, + HandleObject newobj, + bool crossCompartmentTransplant) { + MOZ_ASSERT(Wrapper::wrapperHandler(oldWaiver) == &XrayWaiver); + MOZ_ASSERT(!js::IsCrossCompartmentWrapper(newobj)); + + if (crossCompartmentTransplant) { + // If the new compartment has a CCW for oldWaiver, nuke this CCW. This + // prevents confusing RemapAllWrappersForObject: it would call RemapWrapper + // with two same-compartment objects (the CCW and the new waiver). + // + // This can happen when loading a chrome page in a content frame and there + // exists a CCW from the chrome compartment to oldWaiver wrapping the window + // we just transplanted: + // + // Compartment 1 | Compartment 2 + // ---------------------------------------- + // CCW1 -----------> oldWaiver --> CCW2 --+ + // newWaiver | + // WindowProxy <--------------------------+ + js::NukeCrossCompartmentWrapperIfExists(cx, JS::GetCompartment(newobj), + oldWaiver); + } else { + // We kept the same object identity, so the waiver should be a + // waiver for our object, just in the wrong Realm. + MOZ_ASSERT(newobj == Wrapper::wrappedObject(oldWaiver)); + } + + // Create a waiver in the new compartment. We know there's not one already in + // the crossCompartmentTransplant case because we _just_ transplanted, which + // means that |newobj| was either created from scratch, or was previously + // cross-compartment wrapper (which should have no waiver). On the other hand, + // in the !crossCompartmentTransplant case we know one already exists. + // CreateXrayWaiver asserts all this. + RootedObject newWaiver( + cx, WrapperFactory::CreateXrayWaiver( + cx, newobj, /* allowExisting = */ !crossCompartmentTransplant)); + if (!newWaiver) { + return false; + } + + if (!crossCompartmentTransplant) { + // CreateXrayWaiver should have updated the map to point to the new waiver. + MOZ_ASSERT(WrapperFactory::GetXrayWaiver(newobj) == newWaiver); + } + + // Update all the cross-compartment references to oldWaiver to point to + // newWaiver. + if (!js::RemapAllWrappersForObject(cx, oldWaiver, newWaiver)) { + return false; + } + + if (crossCompartmentTransplant) { + // There should be no same-compartment references to oldWaiver, and we + // just remapped all cross-compartment references. It's dead, so we can + // remove it from the map. + XPCWrappedNativeScope* scope = ObjectScope(oldWaiver); + JSObject* key = Wrapper::wrappedObject(oldWaiver); + MOZ_ASSERT(scope->mWaiverWrapperMap->Find(key)); + scope->mWaiverWrapperMap->Remove(key); + } + + return true; +} + +JSObject* TransplantObject(JSContext* cx, JS::HandleObject origobj, + JS::HandleObject target) { + RootedObject oldWaiver(cx, WrapperFactory::GetXrayWaiver(origobj)); + MOZ_ASSERT_IF(oldWaiver, GetNonCCWObjectRealm(oldWaiver) == + GetNonCCWObjectRealm(origobj)); + RootedObject newIdentity(cx, JS_TransplantObject(cx, origobj, target)); + if (!newIdentity || !oldWaiver) { + return newIdentity; + } + + bool crossCompartmentTransplant = (newIdentity != origobj); + if (!crossCompartmentTransplant) { + // We might still have been transplanted across realms within a single + // compartment. + if (GetNonCCWObjectRealm(oldWaiver) == GetNonCCWObjectRealm(newIdentity)) { + // The old waiver is same-realm with the new object; nothing else to do + // here. + return newIdentity; + } + } + + if (!FixWaiverAfterTransplant(cx, oldWaiver, newIdentity, + crossCompartmentTransplant)) { + return nullptr; + } + return newIdentity; +} + +JSObject* TransplantObjectRetainingXrayExpandos(JSContext* cx, + JS::HandleObject origobj, + JS::HandleObject target) { + // Save the chain of objects that carry origobj's Xray expando properties + // (from all compartments). TransplantObject will blow this away; we'll + // restore it manually afterwards. + RootedObject expandoChain( + cx, GetXrayTraits(origobj)->detachExpandoChain(origobj)); + + RootedObject newIdentity(cx, TransplantObject(cx, origobj, target)); + + // Copy Xray expando properties to the new wrapper. + if (!GetXrayTraits(newIdentity) + ->cloneExpandoChain(cx, newIdentity, expandoChain)) { + // Failure here means some expandos were not copied over. The object graph + // and the Xray machinery are left in a consistent state, but mysteriously + // losing these expandos is too weird to allow. + MOZ_CRASH(); + } + + return newIdentity; +} + +static void NukeXrayWaiver(JSContext* cx, JS::HandleObject obj) { + RootedObject waiver(cx, WrapperFactory::GetXrayWaiver(obj)); + if (!waiver) { + return; + } + + XPCWrappedNativeScope* scope = ObjectScope(waiver); + JSObject* key = Wrapper::wrappedObject(waiver); + MOZ_ASSERT(scope->mWaiverWrapperMap->Find(key)); + scope->mWaiverWrapperMap->Remove(key); + + js::NukeNonCCWProxy(cx, waiver); + + // Get rid of any CCWs the waiver may have had. + if (!JS_RefreshCrossCompartmentWrappers(cx, waiver)) { + MOZ_CRASH(); + } +} + +JSObject* TransplantObjectNukingXrayWaiver(JSContext* cx, + JS::HandleObject origObj, + JS::HandleObject target) { + NukeXrayWaiver(cx, origObj); + return JS_TransplantObject(cx, origObj, target); +} + +nsIGlobalObject* NativeGlobal(JSObject* obj) { + obj = JS::GetNonCCWObjectGlobal(obj); + + // Every global needs to hold a native as its first reserved slot or be a + // WebIDL object with an nsISupports DOM object. + MOZ_ASSERT(JS::GetClass(obj)->slot0IsISupports() || + dom::UnwrapDOMObjectToISupports(obj)); + + nsISupports* native = dom::UnwrapDOMObjectToISupports(obj); + if (!native) { + native = JS::GetObjectISupports<nsISupports>(obj); + MOZ_ASSERT(native); + + // In some cases (like for windows) it is a wrapped native, + // in other cases (sandboxes, backstage passes) it's just + // a direct pointer to the native. If it's a wrapped native + // let's unwrap it first. + if (nsCOMPtr<nsIXPConnectWrappedNative> wn = do_QueryInterface(native)) { + native = wn->Native(); + } + } + + nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(native); + MOZ_ASSERT(global, + "Native held by global needs to implement nsIGlobalObject!"); + + return global; +} + +nsIGlobalObject* CurrentNativeGlobal(JSContext* cx) { + return xpc::NativeGlobal(JS::CurrentGlobalOrNull(cx)); +} + +} // namespace xpc diff --git a/js/xpconnect/wrappers/WrapperFactory.h b/js/xpconnect/wrappers/WrapperFactory.h new file mode 100644 index 0000000000..f1200bf765 --- /dev/null +++ b/js/xpconnect/wrappers/WrapperFactory.h @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _xpc_WRAPPERFACTORY_H +#define _xpc_WRAPPERFACTORY_H + +#include "js/Wrapper.h" + +namespace xpc { + +/** + * A wrapper that's only used for cross-origin objects. This should be + * just like a CrossCompartmentWrapper but (as an implementation + * detail) doesn't actually do any compartment-entering and (as an + * implementation detail) delegates all the security decisions and + * compartment-entering to the target object, which is always a + * proxy. + * + * We could also inherit from CrossCompartmentWrapper but then we + * would need to override all the proxy hooks to avoid the + * compartment-entering bits. + */ +class CrossOriginObjectWrapper : public js::Wrapper { + public: + // We want to claim to have a security policy, so code doesn't just + // CheckedUnwrap us willy-nilly. But we're OK with the BaseProxyHandler + // implementation of enter(), which allows entering. Our target is what + // really does the security checks. + // + // We don't want to inherit from CrossCompartmentWrapper, because we don't + // want the compartment-entering behavior it has. But we do want to set the + // CROSS_COMPARTMENT flag on js::Wrapper so that we test true for + // is<js::CrossCompartmentWrapperObject> and so forth. + constexpr explicit CrossOriginObjectWrapper() + : js::Wrapper(CROSS_COMPARTMENT, /* aHasPrototype = */ false, + /* aHasSecurityPolicy = */ true) {} + + bool dynamicCheckedUnwrapAllowed(JS::Handle<JSObject*> obj, + JSContext* cx) const override; + + // Cross origin objects should not participate in private fields. + virtual bool throwOnPrivateField() const override { return true; } + + static const CrossOriginObjectWrapper singleton; +}; + +class WrapperFactory { + public: + enum { + WAIVE_XRAY_WRAPPER_FLAG = js::Wrapper::LAST_USED_FLAG << 1, + IS_XRAY_WRAPPER_FLAG = WAIVE_XRAY_WRAPPER_FLAG << 1 + }; + + // Return true if any of any of the nested wrappers have the flag set. + static bool HasWrapperFlag(JSObject* wrapper, unsigned flag) { + unsigned flags = 0; + js::UncheckedUnwrap(wrapper, true, &flags); + return !!(flags & flag); + } + + static bool IsXrayWrapper(JSObject* wrapper) { + return HasWrapperFlag(wrapper, IS_XRAY_WRAPPER_FLAG); + } + + static bool IsCrossOriginWrapper(JSObject* obj) { + return (js::IsProxy(obj) && + js::GetProxyHandler(obj) == &CrossOriginObjectWrapper::singleton); + } + + static bool IsOpaqueWrapper(JSObject* obj); + + static bool HasWaiveXrayFlag(JSObject* wrapper) { + return HasWrapperFlag(wrapper, WAIVE_XRAY_WRAPPER_FLAG); + } + + static bool IsCOW(JSObject* wrapper); + + static JSObject* GetXrayWaiver(JS::Handle<JSObject*> obj); + // If allowExisting is true, there is an existing waiver for obj in + // its scope, but we want to replace it with the new one. + static JSObject* CreateXrayWaiver(JSContext* cx, JS::Handle<JSObject*> obj, + bool allowExisting = false); + static JSObject* WaiveXray(JSContext* cx, JSObject* obj); + + // Computes whether we should allow the creation of an Xray waiver from + // |target| to |origin|. + static bool AllowWaiver(JS::Compartment* target, JS::Compartment* origin); + + // Convenience method for the above, operating on a wrapper. + static bool AllowWaiver(JSObject* wrapper); + + // Prepare a given object for wrapping in a new compartment. + static void PrepareForWrapping(JSContext* cx, JS::Handle<JSObject*> scope, + JS::Handle<JSObject*> origObj, + JS::Handle<JSObject*> obj, + JS::Handle<JSObject*> objectPassedToWrap, + JS::MutableHandle<JSObject*> retObj); + + // Rewrap an object that is about to cross compartment boundaries. + static JSObject* Rewrap(JSContext* cx, JS::Handle<JSObject*> existing, + JS::Handle<JSObject*> obj); + + // Wrap wrapped object into a waiver wrapper and then re-wrap it. + static bool WaiveXrayAndWrap(JSContext* cx, JS::MutableHandle<JS::Value> vp); + static bool WaiveXrayAndWrap(JSContext* cx, + JS::MutableHandle<JSObject*> object); +}; + +} // namespace xpc + +#endif /* _xpc_WRAPPERFACTORY_H */ diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp new file mode 100644 index 0000000000..6051e1c6e5 --- /dev/null +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -0,0 +1,2335 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "XrayWrapper.h" +#include "AccessCheck.h" +#include "WrapperFactory.h" + +#include "nsDependentString.h" +#include "nsIConsoleService.h" +#include "nsIScriptError.h" + +#include "xpcprivate.h" + +#include "jsapi.h" +#include "js/CallAndConstruct.h" // JS::Call, JS::Construct, JS::IsCallable +#include "js/experimental/TypedData.h" // JS_GetTypedArrayLength +#include "js/friend/WindowProxy.h" // js::IsWindowProxy +#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo +#include "js/Object.h" // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot +#include "js/PropertyAndElement.h" // JS_AlreadyHasOwnPropertyById, JS_DefineProperty, JS_DefinePropertyById, JS_DeleteProperty, JS_DeletePropertyById, JS_HasProperty, JS_HasPropertyById +#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById, JS_GetPropertyDescriptorById +#include "js/PropertySpec.h" +#include "nsJSUtils.h" +#include "nsPrintfCString.h" + +#include "mozilla/FloatingPoint.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/ProxyHandlerUtils.h" +#include "mozilla/dom/WindowProxyHolder.h" +#include "mozilla/dom/XrayExpandoClass.h" + +using namespace mozilla::dom; +using namespace JS; +using namespace mozilla; + +using js::BaseProxyHandler; +using js::CheckedUnwrapStatic; +using js::IsCrossCompartmentWrapper; +using js::UncheckedUnwrap; +using js::Wrapper; + +namespace xpc { + +#define Between(x, a, b) (a <= x && x <= b) + +static_assert(JSProto_URIError - JSProto_Error == 8, + "New prototype added in error object range"); +#define AssertErrorObjectKeyInBounds(key) \ + static_assert(Between(key, JSProto_Error, JSProto_URIError), \ + "We depend on js/ProtoKey.h ordering here"); +MOZ_FOR_EACH(AssertErrorObjectKeyInBounds, (), + (JSProto_Error, JSProto_InternalError, JSProto_AggregateError, + JSProto_EvalError, JSProto_RangeError, JSProto_ReferenceError, + JSProto_SyntaxError, JSProto_TypeError, JSProto_URIError)); + +static_assert(JSProto_Uint8ClampedArray - JSProto_Int8Array == 8, + "New prototype added in typed array range"); +#define AssertTypedArrayKeyInBounds(key) \ + static_assert(Between(key, JSProto_Int8Array, JSProto_Uint8ClampedArray), \ + "We depend on js/ProtoKey.h ordering here"); +MOZ_FOR_EACH(AssertTypedArrayKeyInBounds, (), + (JSProto_Int8Array, JSProto_Uint8Array, JSProto_Int16Array, + JSProto_Uint16Array, JSProto_Int32Array, JSProto_Uint32Array, + JSProto_Float32Array, JSProto_Float64Array, + JSProto_Uint8ClampedArray)); + +#undef Between + +inline bool IsErrorObjectKey(JSProtoKey key) { + return key >= JSProto_Error && key <= JSProto_URIError; +} + +inline bool IsTypedArrayKey(JSProtoKey key) { + return key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray; +} + +// Whitelist for the standard ES classes we can Xray to. +static bool IsJSXraySupported(JSProtoKey key) { + if (IsTypedArrayKey(key)) { + return true; + } + if (IsErrorObjectKey(key)) { + return true; + } + switch (key) { + case JSProto_Date: + case JSProto_DataView: + case JSProto_Object: + case JSProto_Array: + case JSProto_Function: + case JSProto_BoundFunction: + case JSProto_TypedArray: + case JSProto_SavedFrame: + case JSProto_RegExp: + case JSProto_Promise: + case JSProto_ArrayBuffer: + case JSProto_SharedArrayBuffer: + case JSProto_Map: + case JSProto_Set: + case JSProto_WeakMap: + case JSProto_WeakSet: + return true; + default: + return false; + } +} + +XrayType GetXrayType(JSObject* obj) { + obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false); + if (mozilla::dom::UseDOMXray(obj)) { + return XrayForDOMObject; + } + + MOZ_ASSERT(!js::IsWindowProxy(obj)); + + JSProtoKey standardProto = IdentifyStandardInstanceOrPrototype(obj); + if (IsJSXraySupported(standardProto)) { + return XrayForJSObject; + } + + // Modulo a few exceptions, everything else counts as an XrayWrapper to an + // opaque object, which means that more-privileged code sees nothing from + // the underlying object. This is very important for security. In some cases + // though, we need to make an exception for compatibility. + if (IsSandbox(obj)) { + return NotXray; + } + + return XrayForOpaqueObject; +} + +JSObject* XrayAwareCalleeGlobal(JSObject* fun) { + MOZ_ASSERT(js::IsFunctionObject(fun)); + + if (!js::FunctionHasNativeReserved(fun)) { + // Just a normal function, no Xrays involved. + return JS::GetNonCCWObjectGlobal(fun); + } + + // The functions we expect here have the Xray wrapper they're associated with + // in their XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT and, in a debug build, + // themselves in their XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF. Assert that + // last bit. + MOZ_ASSERT(&js::GetFunctionNativeReserved( + fun, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF) + .toObject() == fun); + + Value v = + js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT); + MOZ_ASSERT(IsXrayWrapper(&v.toObject())); + + JSObject* xrayTarget = js::UncheckedUnwrap(&v.toObject()); + return JS::GetNonCCWObjectGlobal(xrayTarget); +} + +JSObject* XrayTraits::getExpandoChain(HandleObject obj) { + return ObjectScope(obj)->GetExpandoChain(obj); +} + +JSObject* XrayTraits::detachExpandoChain(HandleObject obj) { + return ObjectScope(obj)->DetachExpandoChain(obj); +} + +bool XrayTraits::setExpandoChain(JSContext* cx, HandleObject obj, + HandleObject chain) { + return ObjectScope(obj)->SetExpandoChain(cx, obj, chain); +} + +const JSClass XrayTraits::HolderClass = { + "XrayHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)}; + +const JSClass JSXrayTraits::HolderClass = { + "JSXrayHolder", JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT)}; + +bool OpaqueXrayTraits::resolveOwnProperty( + JSContext* cx, HandleObject wrapper, HandleObject target, + HandleObject holder, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> desc) { + bool ok = + XrayTraits::resolveOwnProperty(cx, wrapper, target, holder, id, desc); + if (!ok || desc.isSome()) { + return ok; + } + + return ReportWrapperDenial(cx, id, WrapperDenialForXray, + "object is not safely Xrayable"); +} + +bool ReportWrapperDenial(JSContext* cx, HandleId id, WrapperDenialType type, + const char* reason) { + RealmPrivate* priv = RealmPrivate::Get(CurrentGlobalOrNull(cx)); + bool alreadyWarnedOnce = priv->wrapperDenialWarnings[type]; + priv->wrapperDenialWarnings[type] = true; + + // The browser console warning is only emitted for the first violation, + // whereas the (debug-only) NS_WARNING is emitted for each violation. +#ifndef DEBUG + if (alreadyWarnedOnce) { + return true; + } +#endif + + nsAutoJSString propertyName; + RootedValue idval(cx); + if (!JS_IdToValue(cx, id, &idval)) { + return false; + } + JSString* str = JS_ValueToSource(cx, idval); + if (!str) { + return false; + } + if (!propertyName.init(cx, str)) { + return false; + } + AutoFilename filename; + unsigned line = 0, column = 0; + DescribeScriptedCaller(cx, &filename, &line, &column); + + // Warn to the terminal for the logs. + NS_WARNING( + nsPrintfCString("Silently denied access to property %s: %s (@%s:%u:%u)", + NS_LossyConvertUTF16toASCII(propertyName).get(), reason, + filename.get(), line, column) + .get()); + + // If this isn't the first warning on this topic for this global, we've + // already bailed out in opt builds. Now that the NS_WARNING is done, bail + // out in debug builds as well. + if (alreadyWarnedOnce) { + return true; + } + + // + // Log a message to the console service. + // + + // Grab the pieces. + nsCOMPtr<nsIConsoleService> consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + NS_ENSURE_TRUE(consoleService, true); + nsCOMPtr<nsIScriptError> errorObject = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); + NS_ENSURE_TRUE(errorObject, true); + + // Compute the current window id if any. + uint64_t windowId = 0; + if (nsGlobalWindowInner* win = CurrentWindowOrNull(cx)) { + windowId = win->WindowID(); + } + + Maybe<nsPrintfCString> errorMessage; + if (type == WrapperDenialForXray) { + errorMessage.emplace( + "XrayWrapper denied access to property %s (reason: %s). " + "See https://developer.mozilla.org/en-US/docs/Xray_vision " + "for more information. Note that only the first denied " + "property access from a given global object will be reported.", + NS_LossyConvertUTF16toASCII(propertyName).get(), reason); + } else { + MOZ_ASSERT(type == WrapperDenialForCOW); + errorMessage.emplace( + "Security wrapper denied access to property %s on privileged " + "Javascript object. Note that only the first denied property " + "access from a given global object will be reported.", + NS_LossyConvertUTF16toASCII(propertyName).get()); + } + nsString filenameStr(NS_ConvertASCIItoUTF16(filename.get())); + nsresult rv = errorObject->InitWithWindowID( + NS_ConvertASCIItoUTF16(errorMessage.ref()), filenameStr, u""_ns, line, + column, nsIScriptError::warningFlag, "XPConnect", windowId); + NS_ENSURE_SUCCESS(rv, true); + rv = consoleService->LogMessage(errorObject); + NS_ENSURE_SUCCESS(rv, true); + + return true; +} + +bool JSXrayTraits::getOwnPropertyFromWrapperIfSafe( + JSContext* cx, HandleObject wrapper, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> outDesc) { + MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); + RootedObject target(cx, getTargetObject(wrapper)); + RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx)); + { + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, wrapperGlobal, id, + outDesc)) { + return false; + } + } + return JS_WrapPropertyDescriptor(cx, outDesc); +} + +bool JSXrayTraits::getOwnPropertyFromTargetIfSafe( + JSContext* cx, HandleObject target, HandleObject wrapper, + HandleObject wrapperGlobal, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> outDesc) { + // Note - This function operates in the target compartment, because it + // avoids a bunch of back-and-forth wrapping in enumerateNames. + MOZ_ASSERT(getTargetObject(wrapper) == target); + MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx)); + MOZ_ASSERT(WrapperFactory::IsXrayWrapper(wrapper)); + MOZ_ASSERT(JS_IsGlobalObject(wrapperGlobal)); + js::AssertSameCompartment(wrapper, wrapperGlobal); + MOZ_ASSERT(outDesc.isNothing()); + + Rooted<Maybe<PropertyDescriptor>> desc(cx); + if (!JS_GetOwnPropertyDescriptorById(cx, target, id, &desc)) { + return false; + } + + // If the property doesn't exist at all, we're done. + if (desc.isNothing()) { + return true; + } + + // Disallow accessor properties. + if (desc->isAccessorDescriptor()) { + JSAutoRealm ar(cx, wrapperGlobal); + JS_MarkCrossZoneId(cx, id); + return ReportWrapperDenial(cx, id, WrapperDenialForXray, + "property has accessor"); + } + + // Apply extra scrutiny to objects. + if (desc->value().isObject()) { + RootedObject propObj(cx, js::UncheckedUnwrap(&desc->value().toObject())); + JSAutoRealm ar(cx, propObj); + + // Disallow non-subsumed objects. + if (!AccessCheck::subsumes(target, propObj)) { + JSAutoRealm ar(cx, wrapperGlobal); + JS_MarkCrossZoneId(cx, id); + return ReportWrapperDenial(cx, id, WrapperDenialForXray, + "value not same-origin with target"); + } + + // Disallow non-Xrayable objects. + XrayType xrayType = GetXrayType(propObj); + if (xrayType == NotXray || xrayType == XrayForOpaqueObject) { + JSAutoRealm ar(cx, wrapperGlobal); + JS_MarkCrossZoneId(cx, id); + return ReportWrapperDenial(cx, id, WrapperDenialForXray, + "value not Xrayable"); + } + + // Disallow callables. + if (JS::IsCallable(propObj)) { + JSAutoRealm ar(cx, wrapperGlobal); + JS_MarkCrossZoneId(cx, id); + return ReportWrapperDenial(cx, id, WrapperDenialForXray, + "value is callable"); + } + } + + // Disallow any property that shadows something on its (Xrayed) + // prototype chain. + JSAutoRealm ar2(cx, wrapperGlobal); + JS_MarkCrossZoneId(cx, id); + RootedObject proto(cx); + bool foundOnProto = false; + if (!JS_GetPrototype(cx, wrapper, &proto) || + (proto && !JS_HasPropertyById(cx, proto, id, &foundOnProto))) { + return false; + } + if (foundOnProto) { + return ReportWrapperDenial( + cx, id, WrapperDenialForXray, + "value shadows a property on the standard prototype"); + } + + // We made it! Assign over the descriptor, and don't forget to wrap. + outDesc.set(desc); + return true; +} + +// Returns true on success (in the JSAPI sense), false on failure. If true is +// returned, desc.object() will indicate whether we actually resolved +// the property. +// +// id is the property id we're looking for. +// holder is the object to define the property on. +// fs is the relevant JSFunctionSpec*. +// ps is the relevant JSPropertySpec*. +// desc is the descriptor we're resolving into. +static bool TryResolvePropertyFromSpecs( + JSContext* cx, HandleId id, HandleObject holder, const JSFunctionSpec* fs, + const JSPropertySpec* ps, MutableHandle<Maybe<PropertyDescriptor>> desc) { + // Scan through the functions. + const JSFunctionSpec* fsMatch = nullptr; + for (; fs && fs->name; ++fs) { + if (PropertySpecNameEqualsId(fs->name, id)) { + fsMatch = fs; + break; + } + } + if (fsMatch) { + // Generate an Xrayed version of the method. + RootedFunction fun(cx, JS::NewFunctionFromSpec(cx, fsMatch, id)); + if (!fun) { + return false; + } + + // The generic Xray machinery only defines non-own properties of the target + // on the holder. This is broken, and will be fixed at some point, but for + // now we need to cache the value explicitly. See the corresponding call to + // JS_GetOwnPropertyDescriptorById at the top of + // JSXrayTraits::resolveOwnProperty. + RootedObject funObj(cx, JS_GetFunctionObject(fun)); + return JS_DefinePropertyById(cx, holder, id, funObj, 0) && + JS_GetOwnPropertyDescriptorById(cx, holder, id, desc); + } + + // Scan through the properties. + const JSPropertySpec* psMatch = nullptr; + for (; ps && ps->name; ++ps) { + if (PropertySpecNameEqualsId(ps->name, id)) { + psMatch = ps; + break; + } + } + if (psMatch) { + // The generic Xray machinery only defines non-own properties on the holder. + // This is broken, and will be fixed at some point, but for now we need to + // cache the value explicitly. See the corresponding call to + // JS_GetPropertyById at the top of JSXrayTraits::resolveOwnProperty. + // + // Note also that the public-facing API here doesn't give us a way to + // pass along JITInfo. It's probably ok though, since Xrays are already + // pretty slow. + + unsigned attrs = psMatch->attributes(); + if (psMatch->isAccessor()) { + if (psMatch->isSelfHosted()) { + JSFunction* getterFun = JS::GetSelfHostedFunction( + cx, psMatch->u.accessors.getter.selfHosted.funname, id, 0); + if (!getterFun) { + return false; + } + RootedObject getterObj(cx, JS_GetFunctionObject(getterFun)); + RootedObject setterObj(cx); + if (psMatch->u.accessors.setter.selfHosted.funname) { + JSFunction* setterFun = JS::GetSelfHostedFunction( + cx, psMatch->u.accessors.setter.selfHosted.funname, id, 0); + if (!setterFun) { + return false; + } + setterObj = JS_GetFunctionObject(setterFun); + } + if (!JS_DefinePropertyById(cx, holder, id, getterObj, setterObj, + attrs)) { + return false; + } + } else { + if (!JS_DefinePropertyById( + cx, holder, id, psMatch->u.accessors.getter.native.op, + psMatch->u.accessors.setter.native.op, attrs)) { + return false; + } + } + } else { + RootedValue v(cx); + if (!psMatch->getValue(cx, &v)) { + return false; + } + if (!JS_DefinePropertyById(cx, holder, id, v, attrs)) { + return false; + } + } + + return JS_GetOwnPropertyDescriptorById(cx, holder, id, desc); + } + + return true; +} + +static bool ShouldResolvePrototypeProperty(JSProtoKey key) { + // Proxy constructors have no "prototype" property. + return key != JSProto_Proxy; +} + +static bool ShouldResolveStaticProperties(JSProtoKey key) { + if (!IsJSXraySupported(key)) { + // If we can't Xray this ES class, then we can't resolve statics on it. + return false; + } + + // Don't try to resolve static properties on RegExp, because they + // have issues. In particular, some of them grab state off the + // global of the RegExp constructor that describes the last regexp + // evaluation in that global, which is not a useful thing to do + // over Xrays. + return key != JSProto_RegExp; +} + +bool JSXrayTraits::resolveOwnProperty( + JSContext* cx, HandleObject wrapper, HandleObject target, + HandleObject holder, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> desc) { + // Call the common code. + bool ok = + XrayTraits::resolveOwnProperty(cx, wrapper, target, holder, id, desc); + if (!ok || desc.isSome()) { + return ok; + } + + // The non-HasPrototypes semantics implemented by traditional Xrays are kind + // of broken with respect to |own|-ness and the holder. The common code + // muddles through by only checking the holder for non-|own| lookups, but + // that doesn't work for us. So we do an explicit holder check here, and hope + // that this mess gets fixed up soon. + if (!JS_GetOwnPropertyDescriptorById(cx, holder, id, desc)) { + return false; + } + if (desc.isSome()) { + return true; + } + + JSProtoKey key = getProtoKey(holder); + if (!isPrototype(holder)) { + // For Object and Array instances, we expose some properties from the + // underlying object, but only after filtering them carefully. + // + // Note that, as far as JS observables go, Arrays are just Objects with + // a different prototype and a magic (own, non-configurable) |.length| that + // serves as a non-tight upper bound on |own| indexed properties. So while + // it's tempting to try to impose some sort of structure on what Arrays + // "should" look like over Xrays, the underlying object is squishy enough + // that it makes sense to just treat them like Objects for Xray purposes. + if (key == JSProto_Object || key == JSProto_Array) { + return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc); + } + if (IsTypedArrayKey(key)) { + if (IsArrayIndex(GetArrayIndexFromId(id))) { + // WebExtensions can't use cloneInto(), so we just let them do + // the slow thing to maximize compatibility. + if (CompartmentPrivate::Get(CurrentGlobalOrNull(cx)) + ->isWebExtensionContentScript) { + Rooted<Maybe<PropertyDescriptor>> innerDesc(cx); + { + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + if (!JS_GetOwnPropertyDescriptorById(cx, target, id, &innerDesc)) { + return false; + } + } + if (innerDesc.isSome() && innerDesc->isDataDescriptor() && + innerDesc->value().isNumber()) { + desc.set(innerDesc); + } + return true; + } + JS_ReportErrorASCII( + cx, + "Accessing TypedArray data over Xrays is slow, and forbidden " + "in order to encourage performant code. To copy TypedArrays " + "across origin boundaries, consider using " + "Components.utils.cloneInto()."); + return false; + } + } else if (key == JSProto_Function) { + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_LENGTH)) { + uint16_t length; + RootedFunction fun(cx, JS_GetObjectFunction(target)); + { + JSAutoRealm ar(cx, target); + if (!JS_GetFunctionLength(cx, fun, &length)) { + return false; + } + } + desc.set(Some(PropertyDescriptor::Data(NumberValue(length), {}))); + return true; + } + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_NAME)) { + RootedString fname(cx, JS_GetFunctionId(JS_GetObjectFunction(target))); + if (fname) { + JS_MarkCrossZoneIdValue(cx, StringValue(fname)); + } + desc.set(Some(PropertyDescriptor::Data( + fname ? StringValue(fname) : JS_GetEmptyStringValue(cx), {}))); + } else { + // Look for various static properties/methods and the + // 'prototype' property. + JSProtoKey standardConstructor = constructorFor(holder); + if (standardConstructor != JSProto_Null) { + // Handle the 'prototype' property to make + // xrayedGlobal.StandardClass.prototype work. + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_PROTOTYPE) && + ShouldResolvePrototypeProperty(standardConstructor)) { + RootedObject standardProto(cx); + { + JSAutoRealm ar(cx, target); + if (!JS_GetClassPrototype(cx, standardConstructor, + &standardProto)) { + return false; + } + MOZ_ASSERT(standardProto); + } + + if (!JS_WrapObject(cx, &standardProto)) { + return false; + } + desc.set(Some( + PropertyDescriptor::Data(ObjectValue(*standardProto), {}))); + return true; + } + + if (ShouldResolveStaticProperties(standardConstructor)) { + const JSClass* clasp = js::ProtoKeyToClass(standardConstructor); + MOZ_ASSERT(clasp->specDefined()); + + if (!TryResolvePropertyFromSpecs( + cx, id, holder, clasp->specConstructorFunctions(), + clasp->specConstructorProperties(), desc)) { + return false; + } + + if (desc.isSome()) { + return true; + } + } + } + } + } else if (IsErrorObjectKey(key)) { + // The useful state of error objects (except for .stack) is + // (unfortunately) represented as own data properties per-spec. This + // means that we can't have a a clean representation of the data + // (free from tampering) without doubling the slots of Error + // objects, which isn't great. So we forward these properties to the + // underlying object and then just censor any values with the wrong + // type. This limits the ability of content to do anything all that + // confusing. + bool isErrorIntProperty = + id == GetJSIDByIndex(cx, XPCJSContext::IDX_LINENUMBER) || + id == GetJSIDByIndex(cx, XPCJSContext::IDX_COLUMNNUMBER); + bool isErrorStringProperty = + id == GetJSIDByIndex(cx, XPCJSContext::IDX_FILENAME) || + id == GetJSIDByIndex(cx, XPCJSContext::IDX_MESSAGE); + if (isErrorIntProperty || isErrorStringProperty) { + RootedObject waiver(cx, wrapper); + if (!WrapperFactory::WaiveXrayAndWrap(cx, &waiver)) { + return false; + } + if (!JS_GetOwnPropertyDescriptorById(cx, waiver, id, desc)) { + return false; + } + if (desc.isSome()) { + // Make sure the property has the expected type. + if (!desc->isDataDescriptor() || + (isErrorIntProperty && !desc->value().isInt32()) || + (isErrorStringProperty && !desc->value().isString())) { + desc.reset(); + } + } + return true; + } + +#if defined(NIGHTLY_BUILD) + // The optional .cause property can have any value. + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_CAUSE)) { + return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc); + } +#endif + + if (key == JSProto_AggregateError && + id == GetJSIDByIndex(cx, XPCJSContext::IDX_ERRORS)) { + return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc); + } + } else if (key == JSProto_RegExp) { + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_LASTINDEX)) { + return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc); + } + } else if (key == JSProto_BoundFunction) { + // Bound functions have configurable .name and .length own data + // properties. Only support string values for .name and number values for + // .length. + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_NAME)) { + if (!getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc)) { + return false; + } + if (desc.isSome() && + (!desc->isDataDescriptor() || !desc->value().isString())) { + desc.reset(); + } + return true; + } + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_LENGTH)) { + if (!getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc)) { + return false; + } + if (desc.isSome() && + (!desc->isDataDescriptor() || !desc->value().isNumber())) { + desc.reset(); + } + return true; + } + } + + // The rest of this function applies only to prototypes. + return true; + } + + // Handle the 'constructor' property. + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_CONSTRUCTOR)) { + RootedObject constructor(cx); + { + JSAutoRealm ar(cx, target); + if (!JS_GetClassObject(cx, key, &constructor)) { + return false; + } + } + if (!JS_WrapObject(cx, &constructor)) { + return false; + } + desc.set(Some(PropertyDescriptor::Data( + ObjectValue(*constructor), + {PropertyAttribute::Configurable, PropertyAttribute::Writable}))); + return true; + } + + if (ShouldIgnorePropertyDefinition(cx, key, id)) { + MOZ_ASSERT(desc.isNothing()); + return true; + } + + // Grab the JSClass. We require all Xrayable classes to have a ClassSpec. + const JSClass* clasp = JS::GetClass(target); + MOZ_ASSERT(clasp->specDefined()); + + // Indexed array properties are handled above, so we can just work with the + // class spec here. + return TryResolvePropertyFromSpecs(cx, id, holder, + clasp->specPrototypeFunctions(), + clasp->specPrototypeProperties(), desc); +} + +bool JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, + ObjectOpResult& result) { + MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); + + RootedObject holder(cx, ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + // If we're using Object Xrays, we allow callers to attempt to delete any + // property from the underlying object that they are able to resolve. Note + // that this deleting may fail if the property is non-configurable. + JSProtoKey key = getProtoKey(holder); + bool isObjectOrArrayInstance = + (key == JSProto_Object || key == JSProto_Array) && !isPrototype(holder); + if (isObjectOrArrayInstance) { + RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx)); + RootedObject target(cx, getTargetObject(wrapper)); + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + Rooted<Maybe<PropertyDescriptor>> desc(cx); + if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, wrapperGlobal, id, + &desc)) { + return false; + } + if (desc.isSome()) { + return JS_DeletePropertyById(cx, target, id, result); + } + } + return result.succeed(); +} + +bool JSXrayTraits::defineProperty( + JSContext* cx, HandleObject wrapper, HandleId id, + Handle<PropertyDescriptor> desc, + Handle<Maybe<PropertyDescriptor>> existingDesc, + Handle<JSObject*> existingHolder, ObjectOpResult& result, bool* defined) { + *defined = false; + RootedObject holder(cx, ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + // Object and Array instances are special. For those cases, we forward + // property definitions to the underlying object if the following + // conditions are met: + // * The property being defined is a value-prop. + // * The property being defined is either a primitive or subsumed by the + // target. + // * As seen from the Xray, any existing property that we would overwrite + // is an |own| value-prop. + // + // To avoid confusion, we disallow expandos on Object and Array instances, and + // therefore raise an exception here if the above conditions aren't met. + JSProtoKey key = getProtoKey(holder); + bool isInstance = !isPrototype(holder); + bool isObjectOrArray = (key == JSProto_Object || key == JSProto_Array); + if (isObjectOrArray && isInstance) { + RootedObject target(cx, getTargetObject(wrapper)); + if (desc.isAccessorDescriptor()) { + JS_ReportErrorASCII(cx, + "Not allowed to define accessor property on [Object] " + "or [Array] XrayWrapper"); + return false; + } + if (desc.value().isObject() && + !AccessCheck::subsumes(target, + js::UncheckedUnwrap(&desc.value().toObject()))) { + JS_ReportErrorASCII(cx, + "Not allowed to define cross-origin object as " + "property on [Object] or [Array] XrayWrapper"); + return false; + } + if (existingDesc.isSome()) { + if (existingDesc->isAccessorDescriptor()) { + JS_ReportErrorASCII(cx, + "Not allowed to overwrite accessor property on " + "[Object] or [Array] XrayWrapper"); + return false; + } + if (existingHolder != wrapper) { + JS_ReportErrorASCII(cx, + "Not allowed to shadow non-own Xray-resolved " + "property on [Object] or [Array] XrayWrapper"); + return false; + } + } + + Rooted<PropertyDescriptor> wrappedDesc(cx, desc); + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + if (!JS_WrapPropertyDescriptor(cx, &wrappedDesc) || + !JS_DefinePropertyById(cx, target, id, wrappedDesc, result)) { + return false; + } + *defined = true; + return true; + } + + // For WebExtensions content scripts, we forward the definition of indexed + // properties. By validating that the key and value are both numbers, we can + // avoid doing any wrapping. + if (isInstance && IsTypedArrayKey(key) && + CompartmentPrivate::Get(JS::CurrentGlobalOrNull(cx)) + ->isWebExtensionContentScript && + desc.isDataDescriptor() && + (desc.value().isNumber() || desc.value().isUndefined()) && + IsArrayIndex(GetArrayIndexFromId(id))) { + RootedObject target(cx, getTargetObject(wrapper)); + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + if (!JS_DefinePropertyById(cx, target, id, desc, result)) { + return false; + } + *defined = true; + return true; + } + + return true; +} + +static bool MaybeAppend(jsid id, unsigned flags, MutableHandleIdVector props) { + MOZ_ASSERT(!(flags & JSITER_SYMBOLSONLY)); + if (!(flags & JSITER_SYMBOLS) && id.isSymbol()) { + return true; + } + return props.append(id); +} + +// Append the names from the given function and property specs to props. +static bool AppendNamesFromFunctionAndPropertySpecs( + JSContext* cx, JSProtoKey key, const JSFunctionSpec* fs, + const JSPropertySpec* ps, unsigned flags, MutableHandleIdVector props) { + // Convert the method and property names to jsids and pass them to the caller. + for (; fs && fs->name; ++fs) { + jsid id; + if (!PropertySpecNameToPermanentId(cx, fs->name, &id)) { + return false; + } + if (!js::ShouldIgnorePropertyDefinition(cx, key, id)) { + if (!MaybeAppend(id, flags, props)) { + return false; + } + } + } + for (; ps && ps->name; ++ps) { + jsid id; + if (!PropertySpecNameToPermanentId(cx, ps->name, &id)) { + return false; + } + if (!js::ShouldIgnorePropertyDefinition(cx, key, id)) { + if (!MaybeAppend(id, flags, props)) { + return false; + } + } + } + + return true; +} + +bool JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, + unsigned flags, MutableHandleIdVector props) { + MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); + + RootedObject target(cx, getTargetObject(wrapper)); + RootedObject holder(cx, ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + JSProtoKey key = getProtoKey(holder); + if (!isPrototype(holder)) { + // For Object and Array instances, we expose some properties from the + // underlying object, but only after filtering them carefully. + if (key == JSProto_Object || key == JSProto_Array) { + MOZ_ASSERT(props.empty()); + RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx)); + { + JSAutoRealm ar(cx, target); + RootedIdVector targetProps(cx); + if (!js::GetPropertyKeys(cx, target, flags | JSITER_OWNONLY, + &targetProps)) { + return false; + } + // Loop over the properties, and only pass along the ones that + // we determine to be safe. + if (!props.reserve(targetProps.length())) { + return false; + } + for (size_t i = 0; i < targetProps.length(); ++i) { + Rooted<Maybe<PropertyDescriptor>> desc(cx); + RootedId id(cx, targetProps[i]); + if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, + wrapperGlobal, id, &desc)) { + return false; + } + if (desc.isSome()) { + props.infallibleAppend(id); + } + } + } + for (size_t i = 0; i < props.length(); ++i) { + JS_MarkCrossZoneId(cx, props[i]); + } + return true; + } + if (IsTypedArrayKey(key)) { + size_t length = JS_GetTypedArrayLength(target); + // TypedArrays enumerate every indexed property in range, but + // |length| is a getter that lives on the proto, like it should be. + + // Fail early if the typed array is enormous, because this will be very + // slow and will likely report OOM. This also means we don't need to + // handle indices greater than PropertyKey::IntMax in the loop below. + static_assert(PropertyKey::IntMax >= INT32_MAX); + if (length > INT32_MAX) { + JS_ReportOutOfMemory(cx); + return false; + } + + if (!props.reserve(length)) { + return false; + } + for (int32_t i = 0; i < int32_t(length); ++i) { + props.infallibleAppend(PropertyKey::Int(i)); + } + } else if (key == JSProto_Function) { + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_LENGTH))) { + return false; + } + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_NAME))) { + return false; + } + // Handle the .prototype property and static properties on standard + // constructors. + JSProtoKey standardConstructor = constructorFor(holder); + if (standardConstructor != JSProto_Null) { + if (ShouldResolvePrototypeProperty(standardConstructor)) { + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_PROTOTYPE))) { + return false; + } + } + + if (ShouldResolveStaticProperties(standardConstructor)) { + const JSClass* clasp = js::ProtoKeyToClass(standardConstructor); + MOZ_ASSERT(clasp->specDefined()); + + if (!AppendNamesFromFunctionAndPropertySpecs( + cx, key, clasp->specConstructorFunctions(), + clasp->specConstructorProperties(), flags, props)) { + return false; + } + } + } + } else if (IsErrorObjectKey(key)) { + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_FILENAME)) || + !props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_LINENUMBER)) || + !props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_COLUMNNUMBER)) || + !props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_STACK)) || + !props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_MESSAGE))) { + return false; + } + } else if (key == JSProto_RegExp) { + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_LASTINDEX))) { + return false; + } + } else if (key == JSProto_BoundFunction) { + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_LENGTH)) || + !props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_NAME))) { + return false; + } + } + + // The rest of this function applies only to prototypes. + return true; + } + + // Add the 'constructor' property. + if (!props.append(GetJSIDByIndex(cx, XPCJSContext::IDX_CONSTRUCTOR))) { + return false; + } + + // Grab the JSClass. We require all Xrayable classes to have a ClassSpec. + const JSClass* clasp = JS::GetClass(target); + MOZ_ASSERT(clasp->specDefined()); + + return AppendNamesFromFunctionAndPropertySpecs( + cx, key, clasp->specPrototypeFunctions(), + clasp->specPrototypeProperties(), flags, props); +} + +bool JSXrayTraits::construct(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance) { + JSXrayTraits& self = JSXrayTraits::singleton; + JS::RootedObject holder(cx, self.ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + const JSProtoKey key = xpc::JSXrayTraits::getProtoKey(holder); + if (key == JSProto_Function) { + JSProtoKey standardConstructor = constructorFor(holder); + if (standardConstructor == JSProto_Null) { + return baseInstance.construct(cx, wrapper, args); + } + + const JSClass* clasp = js::ProtoKeyToClass(standardConstructor); + MOZ_ASSERT(clasp); + if (!(clasp->flags & JSCLASS_HAS_XRAYED_CONSTRUCTOR)) { + return baseInstance.construct(cx, wrapper, args); + } + + // If the JSCLASS_HAS_XRAYED_CONSTRUCTOR flag is set on the Class, + // we don't use the constructor at hand. Instead, we retrieve the + // equivalent standard constructor in the xray compartment and run + // it in that compartment. The newTarget isn't unwrapped, and the + // constructor has to be able to detect and handle this situation. + // See the comments in js/public/Class.h and PromiseConstructor for + // details and an example. + RootedObject ctor(cx); + if (!JS_GetClassObject(cx, standardConstructor, &ctor)) { + return false; + } + + RootedValue ctorVal(cx, ObjectValue(*ctor)); + HandleValueArray vals(args); + RootedObject result(cx); + if (!JS::Construct(cx, ctorVal, wrapper, vals, &result)) { + return false; + } + AssertSameCompartment(cx, result); + args.rval().setObject(*result); + return true; + } + if (key == JSProto_BoundFunction) { + return baseInstance.construct(cx, wrapper, args); + } + + JS::RootedValue v(cx, JS::ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; +} + +JSObject* JSXrayTraits::createHolder(JSContext* cx, JSObject* wrapper) { + RootedObject target(cx, getTargetObject(wrapper)); + RootedObject holder(cx, + JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr)); + if (!holder) { + return nullptr; + } + + // Compute information about the target. + bool isPrototype = false; + JSProtoKey key = IdentifyStandardInstance(target); + if (key == JSProto_Null) { + isPrototype = true; + key = IdentifyStandardPrototype(target); + } + MOZ_ASSERT(key != JSProto_Null); + + // Special case: pretend Arguments objects are arrays for Xrays. + // + // Arguments objects are strange beasts - they inherit Object.prototype, + // and implement iteration by defining an |own| property for + // Symbol.iterator. Since this value is callable, Array/Object Xrays will + // filter it out, causing the Xray view to be non-iterable, which in turn + // breaks consumers. + // + // We can't trust the iterator value from the content compartment, + // but the generic one on Array.prototype works well enough. So we force + // the Xray view of Arguments objects to inherit Array.prototype, which + // in turn allows iteration via the inherited + // Array.prototype[Symbol.iterator]. This doesn't emulate any of the weird + // semantics of Arguments iterators, but is probably good enough. + // + // Note that there are various Xray traps that do other special behavior for + // JSProto_Array, but they also provide that special behavior for + // JSProto_Object, and since Arguments would otherwise get JSProto_Object, + // this does not cause any behavior change at those sites. + if (key == JSProto_Object && js::IsArgumentsObject(target)) { + key = JSProto_Array; + } + + // Store it on the holder. + RootedValue v(cx); + v.setNumber(static_cast<uint32_t>(key)); + JS::SetReservedSlot(holder, SLOT_PROTOKEY, v); + v.setBoolean(isPrototype); + JS::SetReservedSlot(holder, SLOT_ISPROTOTYPE, v); + + // If this is a function, also compute whether it serves as a constructor + // for a standard class. + if (key == JSProto_Function) { + v.setNumber(static_cast<uint32_t>(IdentifyStandardConstructor(target))); + JS::SetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR, v); + } + + return holder; +} + +DOMXrayTraits DOMXrayTraits::singleton; +JSXrayTraits JSXrayTraits::singleton; +OpaqueXrayTraits OpaqueXrayTraits::singleton; + +XrayTraits* GetXrayTraits(JSObject* obj) { + switch (GetXrayType(obj)) { + case XrayForDOMObject: + return &DOMXrayTraits::singleton; + case XrayForJSObject: + return &JSXrayTraits::singleton; + case XrayForOpaqueObject: + return &OpaqueXrayTraits::singleton; + default: + return nullptr; + } +} + +/* + * Xray expando handling. + * + * We hang expandos for Xray wrappers off a reserved slot on the target object + * so that same-origin compartments can share expandos for a given object. We + * have a linked list of expando objects, one per origin. The properties on + * these objects are generally wrappers pointing back to the compartment that + * applied them. + * + * The expando objects should _never_ be exposed to script. The fact that they + * live in the target compartment is a detail of the implementation, and does + * not imply that code in the target compartment should be allowed to inspect + * them. They are private to the origin that placed them. + */ + +// Certain compartments do not share expandos with other compartments. Xrays in +// these compartments cache expandos on the wrapper's holder, as there is only +// one such wrapper which can create or access the expando. This allows for +// faster access to the expando, including through JIT inline caches. +static inline bool CompartmentHasExclusiveExpandos(JSObject* obj) { + JS::Compartment* comp = JS::GetCompartment(obj); + CompartmentPrivate* priv = CompartmentPrivate::Get(comp); + return priv && priv->hasExclusiveExpandos; +} + +static inline JSObject* GetCachedXrayExpando(JSObject* wrapper); + +static inline void SetCachedXrayExpando(JSObject* holder, + JSObject* expandoWrapper); + +static nsIPrincipal* WrapperPrincipal(JSObject* obj) { + // Use the principal stored in CompartmentOriginInfo. That works because + // consumers are only interested in the origin-ignoring-document.domain. + // See expandoObjectMatchesConsumer. + MOZ_ASSERT(IsXrayWrapper(obj)); + JS::Compartment* comp = JS::GetCompartment(obj); + CompartmentPrivate* priv = CompartmentPrivate::Get(comp); + return priv->originInfo.GetPrincipalIgnoringDocumentDomain(); +} + +static nsIPrincipal* GetExpandoObjectPrincipal(JSObject* expandoObject) { + Value v = JS::GetReservedSlot(expandoObject, JSSLOT_EXPANDO_ORIGIN); + return static_cast<nsIPrincipal*>(v.toPrivate()); +} + +static void ExpandoObjectFinalize(JS::GCContext* gcx, JSObject* obj) { + // Release the principal. + nsIPrincipal* principal = GetExpandoObjectPrincipal(obj); + NS_RELEASE(principal); +} + +const JSClassOps XrayExpandoObjectClassOps = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + nullptr, // newEnumerate + nullptr, // resolve + nullptr, // mayResolve + ExpandoObjectFinalize, // finalize + nullptr, // call + nullptr, // construct + nullptr, // trace +}; + +bool XrayTraits::expandoObjectMatchesConsumer(JSContext* cx, + HandleObject expandoObject, + nsIPrincipal* consumerOrigin) { + MOZ_ASSERT(js::IsObjectInContextCompartment(expandoObject, cx)); + + // First, compare the principals. + nsIPrincipal* o = GetExpandoObjectPrincipal(expandoObject); + // Note that it's very important here to ignore document.domain. We + // pull the principal for the expando object off of the first consumer + // for a given origin, and freely share the expandos amongst multiple + // same-origin consumers afterwards. However, this means that we have + // no way to know whether _all_ consumers have opted in to collaboration + // by explicitly setting document.domain. So we just mandate that expando + // sharing is unaffected by it. + if (!consumerOrigin->Equals(o)) { + return false; + } + + // Certain globals exclusively own the associated expandos, in which case + // the caller should have used the cached expando on the wrapper instead. + JSObject* owner = JS::GetReservedSlot(expandoObject, + JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) + .toObjectOrNull(); + return owner == nullptr; +} + +bool XrayTraits::getExpandoObjectInternal(JSContext* cx, JSObject* expandoChain, + HandleObject exclusiveWrapper, + nsIPrincipal* origin, + MutableHandleObject expandoObject) { + MOZ_ASSERT(!JS_IsExceptionPending(cx)); + expandoObject.set(nullptr); + + // Use the cached expando if this wrapper has exclusive access to it. + if (exclusiveWrapper) { + JSObject* expandoWrapper = GetCachedXrayExpando(exclusiveWrapper); + expandoObject.set(expandoWrapper ? UncheckedUnwrap(expandoWrapper) + : nullptr); +#ifdef DEBUG + // Make sure the expando we found is on the target's chain. While we + // don't use this chain to look up expandos for the wrapper, + // the expando still needs to be on the chain to keep the wrapper and + // expando alive. + if (expandoObject) { + JSObject* head = expandoChain; + while (head && head != expandoObject) { + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + } + MOZ_ASSERT(head == expandoObject); + } +#endif + return true; + } + + // The expando object lives in the compartment of the target, so all our + // work needs to happen there. + RootedObject head(cx, expandoChain); + JSAutoRealm ar(cx, head); + + // Iterate through the chain, looking for a same-origin object. + while (head) { + if (expandoObjectMatchesConsumer(cx, head, origin)) { + expandoObject.set(head); + return true; + } + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + } + + // Not found. + return true; +} + +bool XrayTraits::getExpandoObject(JSContext* cx, HandleObject target, + HandleObject consumer, + MutableHandleObject expandoObject) { + // Return early if no expando object has ever been attached, which is + // usually the case. + JSObject* chain = getExpandoChain(target); + if (!chain) { + return true; + } + + bool isExclusive = CompartmentHasExclusiveExpandos(consumer); + return getExpandoObjectInternal(cx, chain, isExclusive ? consumer : nullptr, + WrapperPrincipal(consumer), expandoObject); +} + +// Wrappers which have exclusive access to the expando on their target object +// need to be kept alive as long as the target object exists. This is done by +// keeping the expando in the expando chain on the target (even though it will +// not be used while looking up the expando for the wrapper), and keeping a +// strong reference from that expando to the wrapper itself, via the +// JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER reserved slot. This slot does not +// point to the wrapper itself, because it is a cross compartment edge and we +// can't create a wrapper for a wrapper. Instead, the slot points to an +// instance of the holder class below in the wrapper's compartment, and the +// wrapper is held via this holder object's reserved slot. +static const JSClass gWrapperHolderClass = {"XrayExpandoWrapperHolder", + JSCLASS_HAS_RESERVED_SLOTS(1)}; +static const size_t JSSLOT_WRAPPER_HOLDER_CONTENTS = 0; + +JSObject* XrayTraits::attachExpandoObject(JSContext* cx, HandleObject target, + HandleObject exclusiveWrapper, + HandleObject exclusiveWrapperGlobal, + nsIPrincipal* origin) { + // Make sure the compartments are sane. + MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx)); + if (exclusiveWrapper) { + MOZ_ASSERT(!js::IsObjectInContextCompartment(exclusiveWrapper, cx)); + MOZ_ASSERT(JS_IsGlobalObject(exclusiveWrapperGlobal)); + js::AssertSameCompartment(exclusiveWrapper, exclusiveWrapperGlobal); + } + + // No duplicates allowed. +#ifdef DEBUG + { + JSObject* chain = getExpandoChain(target); + if (chain) { + RootedObject existingExpandoObject(cx); + if (getExpandoObjectInternal(cx, chain, exclusiveWrapper, origin, + &existingExpandoObject)) { + MOZ_ASSERT(!existingExpandoObject); + } else { + JS_ClearPendingException(cx); + } + } + } +#endif + + // Create the expando object. + const JSClass* expandoClass = getExpandoClass(cx, target); + MOZ_ASSERT(!strcmp(expandoClass->name, "XrayExpandoObject")); + RootedObject expandoObject( + cx, JS_NewObjectWithGivenProto(cx, expandoClass, nullptr)); + if (!expandoObject) { + return nullptr; + } + + // AddRef and store the principal. + NS_ADDREF(origin); + JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_ORIGIN, + JS::PrivateValue(origin)); + + // Note the exclusive wrapper, if there is one. + RootedObject wrapperHolder(cx); + if (exclusiveWrapper) { + JSAutoRealm ar(cx, exclusiveWrapperGlobal); + wrapperHolder = + JS_NewObjectWithGivenProto(cx, &gWrapperHolderClass, nullptr); + if (!wrapperHolder) { + return nullptr; + } + JS_SetReservedSlot(wrapperHolder, JSSLOT_WRAPPER_HOLDER_CONTENTS, + ObjectValue(*exclusiveWrapper)); + } + if (!JS_WrapObject(cx, &wrapperHolder)) { + return nullptr; + } + JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER, + ObjectOrNullValue(wrapperHolder)); + + // Store it on the exclusive wrapper, if there is one. + if (exclusiveWrapper) { + RootedObject cachedExpandoObject(cx, expandoObject); + JSAutoRealm ar(cx, exclusiveWrapperGlobal); + if (!JS_WrapObject(cx, &cachedExpandoObject)) { + return nullptr; + } + JSObject* holder = ensureHolder(cx, exclusiveWrapper); + if (!holder) { + return nullptr; + } + SetCachedXrayExpando(holder, cachedExpandoObject); + } + + // If this is our first expando object, take the opportunity to preserve + // the wrapper. This keeps our expandos alive even if the Xray wrapper gets + // collected. + RootedObject chain(cx, getExpandoChain(target)); + if (!chain) { + preserveWrapper(target); + } + + // Insert it at the front of the chain. + JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_NEXT, + ObjectOrNullValue(chain)); + setExpandoChain(cx, target, expandoObject); + + return expandoObject; +} + +JSObject* XrayTraits::ensureExpandoObject(JSContext* cx, HandleObject wrapper, + HandleObject target) { + MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); + RootedObject wrapperGlobal(cx, JS::CurrentGlobalOrNull(cx)); + + // Expando objects live in the target compartment. + JSAutoRealm ar(cx, target); + RootedObject expandoObject(cx); + if (!getExpandoObject(cx, target, wrapper, &expandoObject)) { + return nullptr; + } + if (!expandoObject) { + bool isExclusive = CompartmentHasExclusiveExpandos(wrapper); + expandoObject = + attachExpandoObject(cx, target, isExclusive ? wrapper : nullptr, + wrapperGlobal, WrapperPrincipal(wrapper)); + } + return expandoObject; +} + +bool XrayTraits::cloneExpandoChain(JSContext* cx, HandleObject dst, + HandleObject srcChain) { + MOZ_ASSERT(js::IsObjectInContextCompartment(dst, cx)); + MOZ_ASSERT(getExpandoChain(dst) == nullptr); + + RootedObject oldHead(cx, srcChain); + while (oldHead) { + // If movingIntoXrayCompartment is true, then our new reflector is in a + // compartment that used to have an Xray-with-expandos to the old reflector + // and we should copy the expandos to the new reflector directly. + bool movingIntoXrayCompartment; + + // exclusiveWrapper is only used if movingIntoXrayCompartment ends up true. + RootedObject exclusiveWrapper(cx); + RootedObject exclusiveWrapperGlobal(cx); + RootedObject wrapperHolder( + cx, + JS::GetReservedSlot(oldHead, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) + .toObjectOrNull()); + if (wrapperHolder) { + RootedObject unwrappedHolder(cx, UncheckedUnwrap(wrapperHolder)); + // unwrappedHolder is the compartment of the relevant Xray, so check + // whether that matches the compartment of cx (which matches the + // compartment of dst). + movingIntoXrayCompartment = + js::IsObjectInContextCompartment(unwrappedHolder, cx); + + if (!movingIntoXrayCompartment) { + // The global containing this wrapper holder has an xray for |src| + // with expandos. Create an xray in the global for |dst| which + // will be associated with a clone of |src|'s expando object. + JSAutoRealm ar(cx, unwrappedHolder); + exclusiveWrapper = dst; + if (!JS_WrapObject(cx, &exclusiveWrapper)) { + return false; + } + exclusiveWrapperGlobal = JS::CurrentGlobalOrNull(cx); + } + } else { + JSAutoRealm ar(cx, oldHead); + movingIntoXrayCompartment = + expandoObjectMatchesConsumer(cx, oldHead, GetObjectPrincipal(dst)); + } + + if (movingIntoXrayCompartment) { + // Just copy properties directly onto dst. + if (!JS_CopyOwnPropertiesAndPrivateFields(cx, dst, oldHead)) { + return false; + } + } else { + // Create a new expando object in the compartment of dst to replace + // oldHead. + RootedObject newHead( + cx, + attachExpandoObject(cx, dst, exclusiveWrapper, exclusiveWrapperGlobal, + GetExpandoObjectPrincipal(oldHead))); + if (!JS_CopyOwnPropertiesAndPrivateFields(cx, newHead, oldHead)) { + return false; + } + } + oldHead = + JS::GetReservedSlot(oldHead, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + } + return true; +} + +void ClearXrayExpandoSlots(JSObject* target, size_t slotIndex) { + if (!NS_IsMainThread()) { + // No Xrays + return; + } + + MOZ_ASSERT(slotIndex != JSSLOT_EXPANDO_NEXT); + MOZ_ASSERT(slotIndex != JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER); + MOZ_ASSERT(GetXrayTraits(target) == &DOMXrayTraits::singleton); + RootingContext* rootingCx = RootingCx(); + RootedObject rootedTarget(rootingCx, target); + RootedObject head(rootingCx, + DOMXrayTraits::singleton.getExpandoChain(rootedTarget)); + while (head) { + MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(head)) > slotIndex); + JS::SetReservedSlot(head, slotIndex, UndefinedValue()); + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + } +} + +JSObject* EnsureXrayExpandoObject(JSContext* cx, JS::HandleObject wrapper) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(GetXrayTraits(wrapper) == &DOMXrayTraits::singleton); + MOZ_ASSERT(IsXrayWrapper(wrapper)); + + RootedObject target(cx, DOMXrayTraits::getTargetObject(wrapper)); + return DOMXrayTraits::singleton.ensureExpandoObject(cx, wrapper, target); +} + +const JSClass* XrayTraits::getExpandoClass(JSContext* cx, + HandleObject target) const { + return &DefaultXrayExpandoObjectClass; +} + +static const size_t JSSLOT_XRAY_HOLDER = 0; + +/* static */ +JSObject* XrayTraits::getHolder(JSObject* wrapper) { + MOZ_ASSERT(WrapperFactory::IsXrayWrapper(wrapper)); + JS::Value v = js::GetProxyReservedSlot(wrapper, JSSLOT_XRAY_HOLDER); + return v.isObject() ? &v.toObject() : nullptr; +} + +JSObject* XrayTraits::ensureHolder(JSContext* cx, HandleObject wrapper) { + RootedObject holder(cx, getHolder(wrapper)); + if (holder) { + return holder; + } + holder = createHolder(cx, wrapper); // virtual trap. + if (holder) { + js::SetProxyReservedSlot(wrapper, JSSLOT_XRAY_HOLDER, ObjectValue(*holder)); + } + return holder; +} + +static inline JSObject* GetCachedXrayExpando(JSObject* wrapper) { + JSObject* holder = XrayTraits::getHolder(wrapper); + if (!holder) { + return nullptr; + } + Value v = JS::GetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO); + return v.isObject() ? &v.toObject() : nullptr; +} + +static inline void SetCachedXrayExpando(JSObject* holder, + JSObject* expandoWrapper) { + MOZ_ASSERT(JS::GetCompartment(holder) == JS::GetCompartment(expandoWrapper)); + JS_SetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO, + ObjectValue(*expandoWrapper)); +} + +static nsGlobalWindowInner* AsWindow(JSContext* cx, JSObject* wrapper) { + // We want to use our target object here, since we don't want to be + // doing a security check while unwrapping. + JSObject* target = XrayTraits::getTargetObject(wrapper); + return WindowOrNull(target); +} + +static bool IsWindow(JSContext* cx, JSObject* wrapper) { + return !!AsWindow(cx, wrapper); +} + +static bool wrappedJSObject_getter(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + if (!args.thisv().isObject()) { + JS_ReportErrorASCII(cx, "This value not an object"); + return false; + } + RootedObject wrapper(cx, &args.thisv().toObject()); + if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper) || + !WrapperFactory::AllowWaiver(wrapper)) { + JS_ReportErrorASCII(cx, "Unexpected object"); + return false; + } + + args.rval().setObject(*wrapper); + + return WrapperFactory::WaiveXrayAndWrap(cx, args.rval()); +} + +bool XrayTraits::resolveOwnProperty( + JSContext* cx, HandleObject wrapper, HandleObject target, + HandleObject holder, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> desc) { + desc.reset(); + + RootedObject expando(cx); + if (!getExpandoObject(cx, target, wrapper, &expando)) { + return false; + } + + // Check for expando properties first. Note that the expando object lives + // in the target compartment. + if (expando) { + JSAutoRealm ar(cx, expando); + JS_MarkCrossZoneId(cx, id); + if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) { + return false; + } + } + + // Next, check for ES builtins. + if (!desc.isSome() && JS_IsGlobalObject(target)) { + JSProtoKey key = JS_IdToProtoKey(cx, id); + JSAutoRealm ar(cx, target); + if (key != JSProto_Null) { + MOZ_ASSERT(key < JSProto_LIMIT); + RootedObject constructor(cx); + if (!JS_GetClassObject(cx, key, &constructor)) { + return false; + } + MOZ_ASSERT(constructor); + + desc.set(Some(PropertyDescriptor::Data( + ObjectValue(*constructor), + {PropertyAttribute::Configurable, PropertyAttribute::Writable}))); + } else if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_EVAL)) { + RootedObject eval(cx); + if (!js::GetRealmOriginalEval(cx, &eval)) { + return false; + } + desc.set(Some(PropertyDescriptor::Data( + ObjectValue(*eval), + {PropertyAttribute::Configurable, PropertyAttribute::Writable}))); + } else if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_INFINITY)) { + desc.set(Some(PropertyDescriptor::Data( + DoubleValue(PositiveInfinity<double>()), {}))); + } else if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_NAN)) { + desc.set(Some(PropertyDescriptor::Data(NaNValue(), {}))); + } + } + + if (desc.isSome()) { + return JS_WrapPropertyDescriptor(cx, desc); + } + + // Handle .wrappedJSObject for subsuming callers. This should move once we + // sort out own-ness for the holder. + if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_WRAPPED_JSOBJECT) && + WrapperFactory::AllowWaiver(wrapper)) { + bool found = false; + if (!JS_AlreadyHasOwnPropertyById(cx, holder, id, &found)) { + return false; + } + if (!found && !JS_DefinePropertyById(cx, holder, id, wrappedJSObject_getter, + nullptr, JSPROP_ENUMERATE)) { + return false; + } + return JS_GetOwnPropertyDescriptorById(cx, holder, id, desc); + } + + return true; +} + +bool DOMXrayTraits::resolveOwnProperty( + JSContext* cx, HandleObject wrapper, HandleObject target, + HandleObject holder, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> desc) { + // Call the common code. + bool ok = + XrayTraits::resolveOwnProperty(cx, wrapper, target, holder, id, desc); + if (!ok || desc.isSome()) { + return ok; + } + + // Check for indexed access on a window. + uint32_t index = GetArrayIndexFromId(id); + if (IsArrayIndex(index)) { + nsGlobalWindowInner* win = AsWindow(cx, wrapper); + // Note: As() unwraps outer windows to get to the inner window. + if (win) { + Nullable<WindowProxyHolder> subframe = win->IndexedGetter(index); + if (!subframe.IsNull()) { + Rooted<Value> value(cx); + if (MOZ_UNLIKELY(!WrapObject(cx, subframe.Value(), &value))) { + // It's gone? + return xpc::Throw(cx, NS_ERROR_FAILURE); + } + desc.set(Some(PropertyDescriptor::Data( + value, + {PropertyAttribute::Configurable, PropertyAttribute::Enumerable}))); + return JS_WrapPropertyDescriptor(cx, desc); + } + } + } + + if (!JS_GetOwnPropertyDescriptorById(cx, holder, id, desc)) { + return false; + } + if (desc.isSome()) { + return true; + } + + bool cacheOnHolder; + if (!XrayResolveOwnProperty(cx, wrapper, target, id, desc, cacheOnHolder)) { + return false; + } + + if (desc.isNothing() || !cacheOnHolder) { + return true; + } + + Rooted<PropertyDescriptor> defineDesc(cx, *desc); + return JS_DefinePropertyById(cx, holder, id, defineDesc) && + JS_GetOwnPropertyDescriptorById(cx, holder, id, desc); +} + +bool DOMXrayTraits::delete_(JSContext* cx, JS::HandleObject wrapper, + JS::HandleId id, JS::ObjectOpResult& result) { + RootedObject target(cx, getTargetObject(wrapper)); + return XrayDeleteNamedProperty(cx, wrapper, target, id, result); +} + +bool DOMXrayTraits::defineProperty( + JSContext* cx, HandleObject wrapper, HandleId id, + Handle<PropertyDescriptor> desc, + Handle<Maybe<PropertyDescriptor>> existingDesc, + Handle<JSObject*> existingHolder, JS::ObjectOpResult& result, bool* done) { + // Check for an indexed property on a Window. If that's happening, do + // nothing but set done to true so it won't get added as an expando. + if (IsWindow(cx, wrapper)) { + if (IsArrayIndex(GetArrayIndexFromId(id))) { + *done = true; + return result.succeed(); + } + } + + JS::Rooted<JSObject*> obj(cx, getTargetObject(wrapper)); + return XrayDefineProperty(cx, wrapper, obj, id, desc, result, done); +} + +bool DOMXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, + unsigned flags, + MutableHandleIdVector props) { + // Put the indexed properties for a window first. + nsGlobalWindowInner* win = AsWindow(cx, wrapper); + if (win) { + uint32_t length = win->Length(); + if (!props.reserve(props.length() + length)) { + return false; + } + JS::RootedId indexId(cx); + for (uint32_t i = 0; i < length; ++i) { + if (!JS_IndexToId(cx, i, &indexId)) { + return false; + } + props.infallibleAppend(indexId); + } + } + + JS::Rooted<JSObject*> obj(cx, getTargetObject(wrapper)); + if (JS_IsGlobalObject(obj)) { + // We could do this in a shared enumerateNames with JSXrayTraits, but we + // don't really have globals we expose via those. + JSAutoRealm ar(cx, obj); + if (!JS_NewEnumerateStandardClassesIncludingResolved( + cx, obj, props, !(flags & JSITER_HIDDEN))) { + return false; + } + } + return XrayOwnPropertyKeys(cx, wrapper, obj, flags, props); +} + +bool DOMXrayTraits::call(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance) { + RootedObject obj(cx, getTargetObject(wrapper)); + const JSClass* clasp = JS::GetClass(obj); + // What we have is either a WebIDL interface object, a WebIDL prototype + // object, or a WebIDL instance object. WebIDL prototype objects never have + // a clasp->call. WebIDL interface objects we want to invoke on the xray + // compartment. WebIDL instance objects either don't have a clasp->call or + // are using "legacycaller". At this time for all the legacycaller users it + // makes more sense to invoke on the xray compartment, so we just go ahead + // and do that for everything. + if (JSNative call = clasp->getCall()) { + // call it on the Xray compartment + return call(cx, args.length(), args.base()); + } + + RootedValue v(cx, ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; +} + +bool DOMXrayTraits::construct(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance) { + RootedObject obj(cx, getTargetObject(wrapper)); + MOZ_ASSERT(mozilla::dom::HasConstructor(obj)); + const JSClass* clasp = JS::GetClass(obj); + // See comments in DOMXrayTraits::call() explaining what's going on here. + if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) { + if (JSNative construct = clasp->getConstruct()) { + if (!construct(cx, args.length(), args.base())) { + return false; + } + } else { + RootedValue v(cx, ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; + } + } else { + if (!baseInstance.construct(cx, wrapper, args)) { + return false; + } + } + if (!args.rval().isObject() || !JS_WrapValue(cx, args.rval())) { + return false; + } + return true; +} + +bool DOMXrayTraits::getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject target, + JS::MutableHandleObject protop) { + return mozilla::dom::XrayGetNativeProto(cx, target, protop); +} + +void DOMXrayTraits::preserveWrapper(JSObject* target) { + nsISupports* identity = mozilla::dom::UnwrapDOMObjectToISupports(target); + if (!identity) { + return; + } + nsWrapperCache* cache = nullptr; + CallQueryInterface(identity, &cache); + if (cache) { + cache->PreserveWrapper(identity); + } +} + +JSObject* DOMXrayTraits::createHolder(JSContext* cx, JSObject* wrapper) { + return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr); +} + +const JSClass* DOMXrayTraits::getExpandoClass(JSContext* cx, + HandleObject target) const { + return XrayGetExpandoClass(cx, target); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::preventExtensions( + JSContext* cx, HandleObject wrapper, ObjectOpResult& result) const { + // Xray wrappers are supposed to provide a clean view of the target + // reflector, hiding any modifications by script in the target scope. So + // even if that script freezes the reflector, we don't want to make that + // visible to the caller. DOM reflectors are always extensible by default, + // so we can just return failure here. + return result.failCantPreventExtensions(); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::isExtensible(JSContext* cx, + JS::Handle<JSObject*> wrapper, + bool* extensible) const { + // See above. + *extensible = true; + return true; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getOwnPropertyDescriptor( + JSContext* cx, HandleObject wrapper, HandleId id, + MutableHandle<Maybe<PropertyDescriptor>> desc) const { + assertEnteredPolicy(cx, wrapper, id, + BaseProxyHandler::GET | BaseProxyHandler::SET | + BaseProxyHandler::GET_PROPERTY_DESCRIPTOR); + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + return Traits::singleton.resolveOwnProperty(cx, wrapper, target, holder, id, + desc); +} + +// Consider what happens when chrome does |xray.expando = xray.wrappedJSObject|. +// +// Since the expando comes from the target compartment, wrapping it back into +// the target compartment to define it on the expando object ends up stripping +// off the Xray waiver that gives |xray| and |xray.wrappedJSObject| different +// identities. This is generally the right thing to do when wrapping across +// compartments, but is incorrect in the special case of the Xray expando +// object. Manually re-apply Xrays if necessary. +// +// NB: In order to satisfy the invariants of WaiveXray, we need to pass +// in an object sans security wrapper, which means we need to strip off any +// potential same-compartment security wrapper that may have been applied +// to the content object. This is ok, because the the expando object is only +// ever accessed by code across the compartment boundary. +static bool RecreateLostWaivers(JSContext* cx, const PropertyDescriptor* orig, + MutableHandle<PropertyDescriptor> wrapped) { + // Compute whether the original objects were waived, and implicitly, whether + // they were objects at all. + bool valueWasWaived = + orig->hasValue() && orig->value().isObject() && + WrapperFactory::HasWaiveXrayFlag(&orig->value().toObject()); + bool getterWasWaived = orig->hasGetter() && orig->getter() && + WrapperFactory::HasWaiveXrayFlag(orig->getter()); + bool setterWasWaived = orig->hasSetter() && orig->setter() && + WrapperFactory::HasWaiveXrayFlag(orig->setter()); + + // Recreate waivers. Note that for value, we need an extra UncheckedUnwrap + // to handle same-compartment security wrappers (see above). This should + // never happen for getters/setters. + + RootedObject rewaived(cx); + if (valueWasWaived && + !IsCrossCompartmentWrapper(&wrapped.value().toObject())) { + rewaived = &wrapped.value().toObject(); + rewaived = WrapperFactory::WaiveXray(cx, UncheckedUnwrap(rewaived)); + NS_ENSURE_TRUE(rewaived, false); + wrapped.value().set(ObjectValue(*rewaived)); + } + if (getterWasWaived && !IsCrossCompartmentWrapper(wrapped.getter())) { + // We can't end up with WindowProxy or Location as getters. + MOZ_ASSERT(CheckedUnwrapStatic(wrapped.getter())); + rewaived = WrapperFactory::WaiveXray(cx, wrapped.getter()); + NS_ENSURE_TRUE(rewaived, false); + wrapped.setGetter(rewaived); + } + if (setterWasWaived && !IsCrossCompartmentWrapper(wrapped.setter())) { + // We can't end up with WindowProxy or Location as setters. + MOZ_ASSERT(CheckedUnwrapStatic(wrapped.setter())); + rewaived = WrapperFactory::WaiveXray(cx, wrapped.setter()); + NS_ENSURE_TRUE(rewaived, false); + wrapped.setSetter(rewaived); + } + + return true; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, + HandleObject wrapper, + HandleId id, + Handle<PropertyDescriptor> desc, + ObjectOpResult& result) const { + assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET); + + Rooted<Maybe<PropertyDescriptor>> existingDesc(cx); + Rooted<JSObject*> existingHolder(cx); + if (!JS_GetPropertyDescriptorById(cx, wrapper, id, &existingDesc, + &existingHolder)) { + return false; + } + + // Note that the check here is intended to differentiate between own and + // non-own properties, since the above lookup is not limited to own + // properties. At present, this may not always do the right thing because + // we often lie (sloppily) about where we found properties and set + // existingHolder to |wrapper|. Once we fully fix our Xray prototype + // semantics, this should work as intended. + if (existingDesc.isSome() && existingHolder == wrapper && + !existingDesc->configurable()) { + // We have a non-configurable property. See if the caller is trying to + // re-configure it in any way other than making it non-writable. + if (existingDesc->isAccessorDescriptor() || desc.isAccessorDescriptor() || + (desc.hasEnumerable() && + existingDesc->enumerable() != desc.enumerable()) || + (desc.hasWritable() && !existingDesc->writable() && desc.writable())) { + // We should technically report non-configurability in strict mode, but + // doing that via JSAPI used to be a lot of trouble. See bug 1135997. + return result.succeed(); + } + if (!existingDesc->writable()) { + // Same as the above for non-writability. + return result.succeed(); + } + } + + bool done = false; + if (!Traits::singleton.defineProperty(cx, wrapper, id, desc, existingDesc, + existingHolder, result, &done)) { + return false; + } + if (done) { + return true; + } + + // Grab the relevant expando object. + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject expandoObject( + cx, Traits::singleton.ensureExpandoObject(cx, wrapper, target)); + if (!expandoObject) { + return false; + } + + // We're placing an expando. The expando objects live in the target + // compartment, so we need to enter it. + JSAutoRealm ar(cx, target); + JS_MarkCrossZoneId(cx, id); + + // Wrap the property descriptor for the target compartment. + Rooted<PropertyDescriptor> wrappedDesc(cx, desc); + if (!JS_WrapPropertyDescriptor(cx, &wrappedDesc)) { + return false; + } + + // Fix up Xray waivers. + if (!RecreateLostWaivers(cx, desc.address(), &wrappedDesc)) { + return false; + } + + return JS_DefinePropertyById(cx, expandoObject, id, wrappedDesc, result); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::ownPropertyKeys( + JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const { + assertEnteredPolicy(cx, wrapper, JS::PropertyKey::Void(), + BaseProxyHandler::ENUMERATE); + return getPropertyKeys( + cx, wrapper, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::delete_(JSContext* cx, HandleObject wrapper, + HandleId id, + ObjectOpResult& result) const { + assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET); + + // Check the expando object. + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject expando(cx); + if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando)) { + return false; + } + + if (expando) { + JSAutoRealm ar(cx, expando); + JS_MarkCrossZoneId(cx, id); + bool hasProp; + if (!JS_HasPropertyById(cx, expando, id, &hasProp)) { + return false; + } + if (hasProp) { + return JS_DeletePropertyById(cx, expando, id, result); + } + } + + return Traits::singleton.delete_(cx, wrapper, id, result); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::get(JSContext* cx, HandleObject wrapper, + HandleValue receiver, HandleId id, + MutableHandleValue vp) const { + // This is called by Proxy::get, but since we return true for hasPrototype() + // it's only called for properties that hasOwn() claims we have as own + // properties. Since we only need to worry about own properties, we can use + // getOwnPropertyDescriptor here. + Rooted<Maybe<PropertyDescriptor>> desc(cx); + if (!getOwnPropertyDescriptor(cx, wrapper, id, &desc)) { + return false; + } + + MOZ_ASSERT(desc.isSome(), + "hasOwn() claimed we have this property, so why would we not get " + "a descriptor here?"); + desc->assertComplete(); + + // Everything after here follows [[Get]] for ordinary objects. + if (desc->isDataDescriptor()) { + vp.set(desc->value()); + return true; + } + + MOZ_ASSERT(desc->isAccessorDescriptor()); + RootedObject getter(cx, desc->getter()); + + if (!getter) { + vp.setUndefined(); + return true; + } + + return Call(cx, receiver, getter, HandleValueArray::empty(), vp); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::set(JSContext* cx, HandleObject wrapper, + HandleId id, HandleValue v, + HandleValue receiver, + ObjectOpResult& result) const { + MOZ_CRASH("Shouldn't be called: we return true for hasPrototype()"); + return false; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::has(JSContext* cx, HandleObject wrapper, + HandleId id, bool* bp) const { + MOZ_CRASH("Shouldn't be called: we return true for hasPrototype()"); + return false; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::hasOwn(JSContext* cx, HandleObject wrapper, + HandleId id, bool* bp) const { + // Skip our Base if it isn't already ProxyHandler. + return js::BaseProxyHandler::hasOwn(cx, wrapper, id, bp); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getOwnEnumerablePropertyKeys( + JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const { + // Skip our Base if it isn't already ProxyHandler. + return js::BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, wrapper, props); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::enumerate( + JSContext* cx, HandleObject wrapper, + JS::MutableHandleIdVector props) const { + MOZ_CRASH("Shouldn't be called: we return true for hasPrototype()"); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::call(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args) const { + assertEnteredPolicy(cx, wrapper, JS::PropertyKey::Void(), + BaseProxyHandler::CALL); + // Hard cast the singleton since SecurityWrapper doesn't have one. + return Traits::call(cx, wrapper, args, Base::singleton); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::construct(JSContext* cx, HandleObject wrapper, + const JS::CallArgs& args) const { + assertEnteredPolicy(cx, wrapper, JS::PropertyKey::Void(), + BaseProxyHandler::CALL); + // Hard cast the singleton since SecurityWrapper doesn't have one. + return Traits::construct(cx, wrapper, args, Base::singleton); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getBuiltinClass(JSContext* cx, + JS::HandleObject wrapper, + js::ESClass* cls) const { + return Traits::getBuiltinClass(cx, wrapper, Base::singleton, cls); +} + +template <typename Base, typename Traits> +const char* XrayWrapper<Base, Traits>::className(JSContext* cx, + HandleObject wrapper) const { + return Traits::className(cx, wrapper, Base::singleton); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getPrototype( + JSContext* cx, JS::HandleObject wrapper, + JS::MutableHandleObject protop) const { + // We really only want this override for non-SecurityWrapper-inheriting + // |Base|. But doing that statically with templates requires partial method + // specializations (and therefore a helper class), which is all more trouble + // than it's worth. Do a dynamic check. + if (Base::hasSecurityPolicy()) { + return Base::getPrototype(cx, wrapper, protop); + } + + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject expando(cx); + if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando)) { + return false; + } + + // We want to keep the Xray's prototype distinct from that of content, but + // only if there's been a set. If there's not an expando, or the expando + // slot is |undefined|, hand back the default proto, appropriately wrapped. + + if (expando) { + RootedValue v(cx); + { // Scope for JSAutoRealm + JSAutoRealm ar(cx, expando); + v = JS::GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE); + } + if (!v.isUndefined()) { + protop.set(v.toObjectOrNull()); + return JS_WrapObject(cx, protop); + } + } + + // Check our holder, and cache there if we don't have it cached already. + RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + + Value cached = JS::GetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO); + if (cached.isUndefined()) { + if (!Traits::singleton.getPrototype(cx, wrapper, target, protop)) { + return false; + } + + JS::SetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO, + ObjectOrNullValue(protop)); + } else { + protop.set(cached.toObjectOrNull()); + } + return true; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::setPrototype(JSContext* cx, + JS::HandleObject wrapper, + JS::HandleObject proto, + JS::ObjectOpResult& result) const { + // Do this only for non-SecurityWrapper-inheriting |Base|. See the comment + // in getPrototype(). + if (Base::hasSecurityPolicy()) { + return Base::setPrototype(cx, wrapper, proto, result); + } + + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject expando( + cx, Traits::singleton.ensureExpandoObject(cx, wrapper, target)); + if (!expando) { + return false; + } + + // The expando lives in the target's realm, so do our installation there. + JSAutoRealm ar(cx, target); + + RootedValue v(cx, ObjectOrNullValue(proto)); + if (!JS_WrapValue(cx, &v)) { + return false; + } + JS_SetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE, v); + return result.succeed(); +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getPrototypeIfOrdinary( + JSContext* cx, JS::HandleObject wrapper, bool* isOrdinary, + JS::MutableHandleObject protop) const { + // We want to keep the Xray's prototype distinct from that of content, but + // only if there's been a set. This different-prototype-over-time behavior + // means that the [[GetPrototypeOf]] trap *can't* be ECMAScript's ordinary + // [[GetPrototypeOf]]. This also covers cross-origin Window behavior that + // per + // <https://html.spec.whatwg.org/multipage/browsers.html#windowproxy-getprototypeof> + // must be non-ordinary. + *isOrdinary = false; + return true; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::setImmutablePrototype(JSContext* cx, + JS::HandleObject wrapper, + bool* succeeded) const { + // For now, lacking an obvious place to store a bit, prohibit making an + // Xray's [[Prototype]] immutable. We can revisit this (or maybe give all + // Xrays immutable [[Prototype]], because who does this, really?) later if + // necessary. + *succeeded = false; + return true; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getPropertyKeys( + JSContext* cx, HandleObject wrapper, unsigned flags, + MutableHandleIdVector props) const { + assertEnteredPolicy(cx, wrapper, JS::PropertyKey::Void(), + BaseProxyHandler::ENUMERATE); + + // Enumerate expando properties first. Note that the expando object lives + // in the target compartment. + RootedObject target(cx, Traits::getTargetObject(wrapper)); + RootedObject expando(cx); + if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando)) { + return false; + } + + if (expando) { + JSAutoRealm ar(cx, expando); + if (!js::GetPropertyKeys(cx, expando, flags, props)) { + return false; + } + } + for (size_t i = 0; i < props.length(); ++i) { + JS_MarkCrossZoneId(cx, props[i]); + } + + return Traits::singleton.enumerateNames(cx, wrapper, flags, props); +} + +/* + * The Permissive / Security variants should be used depending on whether the + * compartment of the wrapper is guranteed to subsume the compartment of the + * wrapped object (i.e. - whether it is safe from a security perspective to + * unwrap the wrapper). + */ + +template <typename Base, typename Traits> +const xpc::XrayWrapper<Base, Traits> xpc::XrayWrapper<Base, Traits>::singleton( + 0); + +template class PermissiveXrayDOM; +template class PermissiveXrayJS; +template class PermissiveXrayOpaque; + +/* + * This callback is used by the JS engine to test if a proxy handler is for a + * cross compartment xray with no security requirements. + */ +static bool IsCrossCompartmentXrayCallback( + const js::BaseProxyHandler* handler) { + return handler == &PermissiveXrayDOM::singleton; +} + +JS::XrayJitInfo gXrayJitInfo = { + IsCrossCompartmentXrayCallback, CompartmentHasExclusiveExpandos, + JSSLOT_XRAY_HOLDER, XrayTraits::HOLDER_SLOT_EXPANDO, + JSSLOT_EXPANDO_PROTOTYPE}; + +} // namespace xpc diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h new file mode 100644 index 0000000000..fb0c8b36c6 --- /dev/null +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -0,0 +1,495 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef XrayWrapper_h +#define XrayWrapper_h + +#include "mozilla/Maybe.h" + +#include "WrapperFactory.h" + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo +#include "js/Object.h" // JS::GetReservedSlot +#include "js/Proxy.h" +#include "js/Wrapper.h" + +// Slot where Xray functions for Web IDL methods store a pointer to +// the Xray wrapper they're associated with. +#define XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT 0 +// Slot where in debug builds Xray functions for Web IDL methods store +// a pointer to their themselves, just so we can assert that they're the +// sort of functions we expect. +#define XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF 1 + +// Xray wrappers re-resolve the original native properties on the native +// object and always directly access to those properties. +// Because they work so differently from the rest of the wrapper hierarchy, +// we pull them out of the Wrapper inheritance hierarchy and create a +// little world around them. + +class nsIPrincipal; + +namespace xpc { + +enum XrayType { + XrayForDOMObject, + XrayForJSObject, + XrayForOpaqueObject, + NotXray +}; + +class XrayTraits { + public: + constexpr XrayTraits() = default; + + static JSObject* getTargetObject(JSObject* wrapper) { + JSObject* target = + js::UncheckedUnwrap(wrapper, /* stopAtWindowProxy = */ false); + if (target) { + JS::ExposeObjectToActiveJS(target); + } + return target; + } + + // NB: resolveOwnProperty may decide whether or not to cache what it finds + // on the holder. If the result is not cached, the lookup will happen afresh + // for each access, which is the right thing for things like dynamic NodeList + // properties. + virtual bool resolveOwnProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, + JS::HandleObject holder, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc); + + bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::ObjectOpResult& result) { + return result.succeed(); + } + + static bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, + const js::Wrapper& baseInstance, + js::ESClass* cls) { + return baseInstance.getBuiltinClass(cx, wrapper, cls); + } + + static const char* className(JSContext* cx, JS::HandleObject wrapper, + const js::Wrapper& baseInstance) { + return baseInstance.className(cx, wrapper); + } + + virtual void preserveWrapper(JSObject* target) = 0; + + bool getExpandoObject(JSContext* cx, JS::HandleObject target, + JS::HandleObject consumer, + JS::MutableHandleObject expandObject); + JSObject* ensureExpandoObject(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject target); + + // Slots for holder objects. + enum { + HOLDER_SLOT_CACHED_PROTO = 0, + HOLDER_SLOT_EXPANDO = 1, + HOLDER_SHARED_SLOT_COUNT + }; + + static JSObject* getHolder(JSObject* wrapper); + JSObject* ensureHolder(JSContext* cx, JS::HandleObject wrapper); + virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) = 0; + + JSObject* getExpandoChain(JS::HandleObject obj); + JSObject* detachExpandoChain(JS::HandleObject obj); + bool setExpandoChain(JSContext* cx, JS::HandleObject obj, + JS::HandleObject chain); + bool cloneExpandoChain(JSContext* cx, JS::HandleObject dst, + JS::HandleObject srcChain); + + protected: + static const JSClass HolderClass; + + // Get the JSClass we should use for our expando object. + virtual const JSClass* getExpandoClass(JSContext* cx, + JS::HandleObject target) const; + + private: + bool expandoObjectMatchesConsumer(JSContext* cx, + JS::HandleObject expandoObject, + nsIPrincipal* consumerOrigin); + + // |expandoChain| is the expando chain in the wrapped object's compartment. + // |exclusiveWrapper| is any xray that has exclusive use of the expando. + // |cx| may be in any compartment. + bool getExpandoObjectInternal(JSContext* cx, JSObject* expandoChain, + JS::HandleObject exclusiveWrapper, + nsIPrincipal* origin, + JS::MutableHandleObject expandoObject); + + // |cx| is in the target's compartment, and |exclusiveWrapper| is any xray + // that has exclusive use of the expando. |exclusiveWrapperGlobal| is the + // caller's global and must be same-compartment with |exclusiveWrapper|. + JSObject* attachExpandoObject(JSContext* cx, JS::HandleObject target, + JS::HandleObject exclusiveWrapper, + JS::HandleObject exclusiveWrapperGlobal, + nsIPrincipal* origin); + + XrayTraits(XrayTraits&) = delete; + const XrayTraits& operator=(XrayTraits&) = delete; +}; + +class DOMXrayTraits : public XrayTraits { + public: + constexpr DOMXrayTraits() = default; + + static const XrayType Type = XrayForDOMObject; + + virtual bool resolveOwnProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, + JS::HandleObject holder, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) override; + + bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::ObjectOpResult& result); + + bool defineProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::Handle<JS::PropertyDescriptor> desc, + JS::Handle<mozilla::Maybe<JS::PropertyDescriptor>> existingDesc, + JS::Handle<JSObject*> existingHolder, JS::ObjectOpResult& result, + bool* done); + virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, + unsigned flags, JS::MutableHandleIdVector props); + static bool call(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, const js::Wrapper& baseInstance); + static bool construct(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance); + + static bool getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject target, + JS::MutableHandleObject protop); + + virtual void preserveWrapper(JSObject* target) override; + + virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override; + + static DOMXrayTraits singleton; + + protected: + virtual const JSClass* getExpandoClass( + JSContext* cx, JS::HandleObject target) const override; +}; + +class JSXrayTraits : public XrayTraits { + public: + static const XrayType Type = XrayForJSObject; + + virtual bool resolveOwnProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, + JS::HandleObject holder, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) override; + + bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::ObjectOpResult& result); + + bool defineProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::Handle<JS::PropertyDescriptor> desc, + JS::Handle<mozilla::Maybe<JS::PropertyDescriptor>> existingDesc, + JS::Handle<JSObject*> existingHolder, JS::ObjectOpResult& result, + bool* defined); + + virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, + unsigned flags, JS::MutableHandleIdVector props); + + static bool call(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, const js::Wrapper& baseInstance) { + JSXrayTraits& self = JSXrayTraits::singleton; + JS::RootedObject holder(cx, self.ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + JSProtoKey key = xpc::JSXrayTraits::getProtoKey(holder); + if (key == JSProto_Function || key == JSProto_BoundFunction) { + return baseInstance.call(cx, wrapper, args); + } + + JS::RootedValue v(cx, JS::ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; + } + + static bool construct(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance); + + bool getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject target, JS::MutableHandleObject protop) { + JS::RootedObject holder(cx, ensureHolder(cx, wrapper)); + if (!holder) { + return false; + } + JSProtoKey key = getProtoKey(holder); + if (isPrototype(holder)) { + JSProtoKey protoKey = js::InheritanceProtoKeyForStandardClass(key); + if (protoKey == JSProto_Null) { + protop.set(nullptr); + return true; + } + key = protoKey; + } + + { + JSAutoRealm ar(cx, target); + if (!JS_GetClassPrototype(cx, key, protop)) { + return false; + } + } + return JS_WrapObject(cx, protop); + } + + virtual void preserveWrapper(JSObject* target) override { + // In the case of pure JS objects, there is no underlying object, and + // the target is the canonical representation of state. If it gets + // collected, then expandos and such should be collected too. So there's + // nothing to do here. + } + + enum { + SLOT_PROTOKEY = HOLDER_SHARED_SLOT_COUNT, + SLOT_ISPROTOTYPE, + SLOT_CONSTRUCTOR_FOR, + SLOT_COUNT + }; + virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override; + + static JSProtoKey getProtoKey(JSObject* holder) { + int32_t key = JS::GetReservedSlot(holder, SLOT_PROTOKEY).toInt32(); + return static_cast<JSProtoKey>(key); + } + + static bool isPrototype(JSObject* holder) { + return JS::GetReservedSlot(holder, SLOT_ISPROTOTYPE).toBoolean(); + } + + static JSProtoKey constructorFor(JSObject* holder) { + int32_t key = JS::GetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR).toInt32(); + return static_cast<JSProtoKey>(key); + } + + // Operates in the wrapper compartment. + static bool getOwnPropertyFromWrapperIfSafe( + JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc); + + // Like the above, but operates in the target compartment. wrapperGlobal is + // the caller's global (must be in the wrapper compartment). + static bool getOwnPropertyFromTargetIfSafe( + JSContext* cx, JS::HandleObject target, JS::HandleObject wrapper, + JS::HandleObject wrapperGlobal, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc); + + static const JSClass HolderClass; + static JSXrayTraits singleton; +}; + +// These traits are used when the target is not Xrayable and we therefore want +// to make it opaque modulo the usual Xray machinery (like expandos and +// .wrappedJSObject). +class OpaqueXrayTraits : public XrayTraits { + public: + static const XrayType Type = XrayForOpaqueObject; + + virtual bool resolveOwnProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target, + JS::HandleObject holder, JS::HandleId id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) override; + + bool defineProperty( + JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, + JS::Handle<JS::PropertyDescriptor> desc, + JS::Handle<mozilla::Maybe<JS::PropertyDescriptor>> existingDesc, + JS::Handle<JSObject*> existingHolder, JS::ObjectOpResult& result, + bool* defined) { + *defined = false; + return true; + } + + virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, + unsigned flags, JS::MutableHandleIdVector props) { + return true; + } + + static bool call(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, const js::Wrapper& baseInstance) { + JS::RootedValue v(cx, JS::ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; + } + + static bool construct(JSContext* cx, JS::HandleObject wrapper, + const JS::CallArgs& args, + const js::Wrapper& baseInstance) { + JS::RootedValue v(cx, JS::ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, v); + return false; + } + + bool getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject target, JS::MutableHandleObject protop) { + // Opaque wrappers just get targetGlobal.Object.prototype as their + // prototype. This is preferable to using a null prototype because it + // lets things like |toString| and |__proto__| work. + { + JSAutoRealm ar(cx, target); + if (!JS_GetClassPrototype(cx, JSProto_Object, protop)) { + return false; + } + } + return JS_WrapObject(cx, protop); + } + + static bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, + const js::Wrapper& baseInstance, + js::ESClass* cls) { + *cls = js::ESClass::Other; + return true; + } + + static const char* className(JSContext* cx, JS::HandleObject wrapper, + const js::Wrapper& baseInstance) { + return "Opaque"; + } + + virtual void preserveWrapper(JSObject* target) override {} + + virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override { + return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr); + } + + static OpaqueXrayTraits singleton; +}; + +XrayType GetXrayType(JSObject* obj); +XrayTraits* GetXrayTraits(JSObject* obj); + +template <typename Base, typename Traits> +class XrayWrapper : public Base { + static_assert(std::is_base_of_v<js::BaseProxyHandler, Base>, + "Base *must* derive from js::BaseProxyHandler"); + + public: + constexpr explicit XrayWrapper(unsigned flags) + : Base(flags | WrapperFactory::IS_XRAY_WRAPPER_FLAG, + /* aHasPrototype = */ true){}; + + /* Standard internal methods. */ + virtual bool getOwnPropertyDescriptor( + JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, + JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) + const override; + virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, + JS::Handle<JS::PropertyDescriptor> desc, + JS::ObjectOpResult& result) const override; + virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + virtual bool delete_(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, + JS::ObjectOpResult& result) const override; + virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::MutableHandleObject protop) const override; + virtual bool setPrototype(JSContext* cx, JS::HandleObject wrapper, + JS::HandleObject proto, + JS::ObjectOpResult& result) const override; + virtual bool getPrototypeIfOrdinary( + JSContext* cx, JS::HandleObject wrapper, bool* isOrdinary, + JS::MutableHandleObject protop) const override; + virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject wrapper, + bool* succeeded) const override; + virtual bool preventExtensions(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::ObjectOpResult& result) const override; + virtual bool isExtensible(JSContext* cx, JS::Handle<JSObject*> wrapper, + bool* extensible) const override; + virtual bool has(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, bool* bp) const override; + virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::HandleValue receiver, JS::Handle<jsid> id, + JS::MutableHandle<JS::Value> vp) const override; + virtual bool set(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, JS::Handle<JS::Value> v, + JS::Handle<JS::Value> receiver, + JS::ObjectOpResult& result) const override; + virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper, + const JS::CallArgs& args) const override; + + /* SpiderMonkey extensions. */ + virtual bool hasOwn(JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::Handle<jsid> id, bool* bp) const override; + virtual bool getOwnEnumerablePropertyKeys( + JSContext* cx, JS::Handle<JSObject*> wrapper, + JS::MutableHandleIdVector props) const override; + + virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject wapper, + js::ESClass* cls) const override; + virtual const char* className(JSContext* cx, + JS::HandleObject proxy) const override; + + static const XrayWrapper singleton; + + protected: + bool getPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper, + unsigned flags, JS::MutableHandleIdVector props) const; +}; + +#define PermissiveXrayDOM \ + xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits> +#define PermissiveXrayJS \ + xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits> +#define PermissiveXrayOpaque \ + xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::OpaqueXrayTraits> + +extern template class PermissiveXrayDOM; +extern template class PermissiveXrayJS; +extern template class PermissiveXrayOpaque; + +/* + * Slots for Xray expando objects. See comments in XrayWrapper.cpp for details + * of how these get used; we mostly want the value of JSSLOT_EXPANDO_COUNT here. + */ +enum ExpandoSlots { + JSSLOT_EXPANDO_NEXT = 0, + JSSLOT_EXPANDO_ORIGIN, + JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER, + JSSLOT_EXPANDO_PROTOTYPE, + JSSLOT_EXPANDO_COUNT +}; + +extern const JSClassOps XrayExpandoObjectClassOps; + +/* + * Clear the given slot on all Xray expandos for the given object. + * + * No-op when called on non-main threads (where Xrays don't exist). + */ +void ClearXrayExpandoSlots(JSObject* target, size_t slotIndex); + +/* + * Ensure the given wrapper has an expando object and return it. This can + * return null on failure. Will only be called when "wrapper" is an Xray for a + * DOM object. + */ +JSObject* EnsureXrayExpandoObject(JSContext* cx, JS::HandleObject wrapper); + +// Information about xrays for use by the JITs. +extern JS::XrayJitInfo gXrayJitInfo; + +} // namespace xpc + +#endif diff --git a/js/xpconnect/wrappers/moz.build b/js/xpconnect/wrappers/moz.build new file mode 100644 index 0000000000..fcf07a0181 --- /dev/null +++ b/js/xpconnect/wrappers/moz.build @@ -0,0 +1,32 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS += [ + "WrapperFactory.h", +] + +UNIFIED_SOURCES += [ + "AccessCheck.cpp", + "ChromeObjectWrapper.cpp", + "FilteringWrapper.cpp", + "WaiveXrayWrapper.cpp", + "WrapperFactory.cpp", +] + +# XrayWrapper needs to be built separately because of template instantiations. +SOURCES += [ + "XrayWrapper.cpp", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" + +LOCAL_INCLUDES += [ + "../../../dom/base", + "../src", + "/caps", +] |