summaryrefslogtreecommitdiffstats
path: root/js/xpconnect
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/xpconnect
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/xpconnect')
-rw-r--r--js/xpconnect/crashtests/117307-1.html20
-rw-r--r--js/xpconnect/crashtests/1577573.html6
-rw-r--r--js/xpconnect/crashtests/193710.html11
-rw-r--r--js/xpconnect/crashtests/290162-1.html5
-rw-r--r--js/xpconnect/crashtests/326615-1.html16
-rw-r--r--js/xpconnect/crashtests/328553-1.html13
-rw-r--r--js/xpconnect/crashtests/346258-1.html12
-rw-r--r--js/xpconnect/crashtests/346512-1-frame1.xhtml16
-rw-r--r--js/xpconnect/crashtests/346512-1-frame2.xhtml15
-rw-r--r--js/xpconnect/crashtests/346512-1.xhtml30
-rw-r--r--js/xpconnect/crashtests/382133-1.html3
-rw-r--r--js/xpconnect/crashtests/386680-1.html22
-rw-r--r--js/xpconnect/crashtests/394810-1.html4
-rw-r--r--js/xpconnect/crashtests/400349-1.html20
-rw-r--r--js/xpconnect/crashtests/403356-1.html13
-rw-r--r--js/xpconnect/crashtests/418139-1.svg22
-rw-r--r--js/xpconnect/crashtests/420513-1.html11
-rw-r--r--js/xpconnect/crashtests/453935-1.html37
-rw-r--r--js/xpconnect/crashtests/467693-1.html16
-rw-r--r--js/xpconnect/crashtests/468552-1.html18
-rw-r--r--js/xpconnect/crashtests/475185-1.html13
-rw-r--r--js/xpconnect/crashtests/475291-1.html14
-rw-r--r--js/xpconnect/crashtests/503286-1.html23
-rw-r--r--js/xpconnect/crashtests/504000-1.html21
-rw-r--r--js/xpconnect/crashtests/509075-1.html28
-rw-r--r--js/xpconnect/crashtests/512815-1.html21
-rw-r--r--js/xpconnect/crashtests/515726-1.html26
-rw-r--r--js/xpconnect/crashtests/545291-1.html12
-rw-r--r--js/xpconnect/crashtests/558979.html13
-rw-r--r--js/xpconnect/crashtests/601284-1.html22
-rw-r--r--js/xpconnect/crashtests/603146-1.html7
-rw-r--r--js/xpconnect/crashtests/603858-1.html8
-rw-r--r--js/xpconnect/crashtests/608963.html5
-rw-r--r--js/xpconnect/crashtests/616930-1.html15
-rw-r--r--js/xpconnect/crashtests/639737-1.html19
-rw-r--r--js/xpconnect/crashtests/648206-1.html7
-rw-r--r--js/xpconnect/crashtests/720305-1.html8
-rw-r--r--js/xpconnect/crashtests/721910.html14
-rw-r--r--js/xpconnect/crashtests/723465.html19
-rw-r--r--js/xpconnect/crashtests/732870.html23
-rw-r--r--js/xpconnect/crashtests/751995.html36
-rw-r--r--js/xpconnect/crashtests/752038-iframe.html11
-rw-r--r--js/xpconnect/crashtests/752038.html28
-rw-r--r--js/xpconnect/crashtests/753162.html23
-rw-r--r--js/xpconnect/crashtests/754311-iframe.html21
-rw-r--r--js/xpconnect/crashtests/754311.html16
-rw-r--r--js/xpconnect/crashtests/761831.html23
-rw-r--r--js/xpconnect/crashtests/786142-iframe.html84
-rw-r--r--js/xpconnect/crashtests/786142.html16
-rw-r--r--js/xpconnect/crashtests/797583.html6
-rw-r--r--js/xpconnect/crashtests/806751.html26
-rw-r--r--js/xpconnect/crashtests/833856.html14
-rw-r--r--js/xpconnect/crashtests/851418.html23
-rw-r--r--js/xpconnect/crashtests/854139.html10
-rw-r--r--js/xpconnect/crashtests/854604.html10
-rw-r--r--js/xpconnect/crashtests/898939.html18
-rw-r--r--js/xpconnect/crashtests/905523.html24904
-rw-r--r--js/xpconnect/crashtests/938297.html24
-rw-r--r--js/xpconnect/crashtests/977538.html20
-rw-r--r--js/xpconnect/crashtests/crashtests.list55
-rw-r--r--js/xpconnect/idl/moz.build14
-rw-r--r--js/xpconnect/idl/mozIJSSubScriptLoader.idl55
-rw-r--r--js/xpconnect/idl/nsIXPCScriptable.idl121
-rw-r--r--js/xpconnect/idl/xpcIJSWeakReference.idl17
-rw-r--r--js/xpconnect/idl/xpccomponents.idl886
-rw-r--r--js/xpconnect/loader/AutoMemMap.cpp157
-rw-r--r--js/xpconnect/loader/AutoMemMap.h100
-rw-r--r--js/xpconnect/loader/ChromeScriptLoader.cpp379
-rw-r--r--js/xpconnect/loader/ComponentModuleLoader.cpp272
-rw-r--r--js/xpconnect/loader/ComponentModuleLoader.h119
-rw-r--r--js/xpconnect/loader/ComponentUtils.sys.mjs33
-rw-r--r--js/xpconnect/loader/IOBuffers.h148
-rw-r--r--js/xpconnect/loader/JSMEnvironmentProxy.cpp260
-rw-r--r--js/xpconnect/loader/JSMEnvironmentProxy.h31
-rw-r--r--js/xpconnect/loader/ModuleEnvironmentProxy.cpp238
-rw-r--r--js/xpconnect/loader/ModuleEnvironmentProxy.h30
-rw-r--r--js/xpconnect/loader/PScriptCache.ipdl36
-rw-r--r--js/xpconnect/loader/PrecompiledScript.h63
-rw-r--r--js/xpconnect/loader/ScriptCacheActors.cpp92
-rw-r--r--js/xpconnect/loader/ScriptCacheActors.h59
-rw-r--r--js/xpconnect/loader/ScriptPreloader-inl.h167
-rw-r--r--js/xpconnect/loader/ScriptPreloader.cpp1319
-rw-r--r--js/xpconnect/loader/ScriptPreloader.h543
-rw-r--r--js/xpconnect/loader/SkipCheckForBrokenURLOrZeroSized.h22
-rw-r--r--js/xpconnect/loader/URLPreloader.cpp707
-rw-r--r--js/xpconnect/loader/URLPreloader.h318
-rw-r--r--js/xpconnect/loader/XPCOMUtils.sys.mjs580
-rw-r--r--js/xpconnect/loader/moz.build67
-rw-r--r--js/xpconnect/loader/mozJSLoaderUtils.cpp75
-rw-r--r--js/xpconnect/loader/mozJSLoaderUtils.h30
-rw-r--r--js/xpconnect/loader/mozJSModuleLoader.cpp1936
-rw-r--r--js/xpconnect/loader/mozJSModuleLoader.h264
-rw-r--r--js/xpconnect/loader/mozJSSubScriptLoader.cpp476
-rw-r--r--js/xpconnect/loader/mozJSSubScriptLoader.h50
-rw-r--r--js/xpconnect/loader/nsImportModule.cpp113
-rw-r--r--js/xpconnect/loader/nsImportModule.h240
-rwxr-xr-xjs/xpconnect/loader/script_cache.py92
-rw-r--r--js/xpconnect/mach_commands.py40
-rw-r--r--js/xpconnect/moz.build12
-rw-r--r--js/xpconnect/public/moz.build10
-rw-r--r--js/xpconnect/public/xpc_make_class.h120
-rw-r--r--js/xpconnect/public/xpc_map_end.h114
-rw-r--r--js/xpconnect/shell/moz.build77
-rw-r--r--js/xpconnect/shell/xpcshell.cpp94
-rw-r--r--js/xpconnect/shell/xpcshell.exe.manifest40
-rw-r--r--js/xpconnect/shell/xpcshellMacUtils.h9
-rw-r--r--js/xpconnect/shell/xpcshellMacUtils.mm13
-rw-r--r--js/xpconnect/src/BackstagePass.h87
-rw-r--r--js/xpconnect/src/ExportHelpers.cpp598
-rw-r--r--js/xpconnect/src/JSServices.cpp172
-rw-r--r--js/xpconnect/src/JSServices.h18
-rw-r--r--js/xpconnect/src/README3
-rw-r--r--js/xpconnect/src/Sandbox.cpp2256
-rw-r--r--js/xpconnect/src/SandboxPrivate.h118
-rw-r--r--js/xpconnect/src/XPCCallContext.cpp218
-rw-r--r--js/xpconnect/src/XPCComponents.cpp2665
-rw-r--r--js/xpconnect/src/XPCConvert.cpp1649
-rw-r--r--js/xpconnect/src/XPCDebug.cpp58
-rw-r--r--js/xpconnect/src/XPCException.cpp77
-rw-r--r--js/xpconnect/src/XPCForwards.h51
-rw-r--r--js/xpconnect/src/XPCInlines.h367
-rw-r--r--js/xpconnect/src/XPCJSContext.cpp1500
-rw-r--r--js/xpconnect/src/XPCJSID.cpp626
-rw-r--r--js/xpconnect/src/XPCJSMemoryReporter.h31
-rw-r--r--js/xpconnect/src/XPCJSRuntime.cpp3174
-rw-r--r--js/xpconnect/src/XPCJSWeakReference.cpp89
-rw-r--r--js/xpconnect/src/XPCJSWeakReference.h28
-rw-r--r--js/xpconnect/src/XPCLocale.cpp153
-rw-r--r--js/xpconnect/src/XPCLog.cpp84
-rw-r--r--js/xpconnect/src/XPCLog.h69
-rw-r--r--js/xpconnect/src/XPCMaps.cpp191
-rw-r--r--js/xpconnect/src/XPCMaps.h386
-rw-r--r--js/xpconnect/src/XPCModule.cpp19
-rw-r--r--js/xpconnect/src/XPCModule.h25
-rw-r--r--js/xpconnect/src/XPCRuntimeService.cpp215
-rw-r--r--js/xpconnect/src/XPCSelfHostedShmem.cpp116
-rw-r--r--js/xpconnect/src/XPCSelfHostedShmem.h89
-rw-r--r--js/xpconnect/src/XPCShellImpl.cpp1539
-rw-r--r--js/xpconnect/src/XPCString.cpp134
-rw-r--r--js/xpconnect/src/XPCThrower.cpp188
-rw-r--r--js/xpconnect/src/XPCVariant.cpp764
-rw-r--r--js/xpconnect/src/XPCWrappedJS.cpp686
-rw-r--r--js/xpconnect/src/XPCWrappedJSClass.cpp1094
-rw-r--r--js/xpconnect/src/XPCWrappedJSIterator.cpp91
-rw-r--r--js/xpconnect/src/XPCWrappedNative.cpp1839
-rw-r--r--js/xpconnect/src/XPCWrappedNativeInfo.cpp728
-rw-r--r--js/xpconnect/src/XPCWrappedNativeJSOps.cpp1236
-rw-r--r--js/xpconnect/src/XPCWrappedNativeProto.cpp151
-rw-r--r--js/xpconnect/src/XPCWrappedNativeScope.cpp497
-rw-r--r--js/xpconnect/src/XPCWrapper.cpp90
-rw-r--r--js/xpconnect/src/XPCWrapper.h29
-rw-r--r--js/xpconnect/src/components.conf16
-rw-r--r--js/xpconnect/src/jsshell.msg12
-rw-r--r--js/xpconnect/src/moz.build79
-rw-r--r--js/xpconnect/src/nsIXPConnect.h291
-rw-r--r--js/xpconnect/src/nsXPConnect.cpp1160
-rw-r--r--js/xpconnect/src/xpc.msg255
-rw-r--r--js/xpconnect/src/xpcObjectHelper.h68
-rw-r--r--js/xpconnect/src/xpcprivate.h2842
-rw-r--r--js/xpconnect/src/xpcpublic.h835
-rw-r--r--js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.cpp162
-rw-r--r--js/xpconnect/src/xpcrtfuzzing/xpcrtfuzzing.h25
-rw-r--r--js/xpconnect/tests/browser/browser.ini17
-rw-r--r--js/xpconnect/tests/browser/browser_consoleStack.html21
-rw-r--r--js/xpconnect/tests/browser/browser_deadObjectOnUnload.html18
-rw-r--r--js/xpconnect/tests/browser/browser_dead_object.js36
-rw-r--r--js/xpconnect/tests/browser/browser_exception_leak.js76
-rw-r--r--js/xpconnect/tests/browser/browser_freeze_builtins.js27
-rw-r--r--js/xpconnect/tests/browser/browser_import_mapped_jsm.js62
-rw-r--r--js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js60
-rw-r--r--js/xpconnect/tests/browser/browser_promise_userInteractionHandling.html10
-rw-r--r--js/xpconnect/tests/browser/browser_promise_userInteractionHandling.js50
-rw-r--r--js/xpconnect/tests/browser/browser_realm_key_and_document_domain.js28
-rw-r--r--js/xpconnect/tests/browser/browser_realm_key_object_prototype_frame.html11
-rw-r--r--js/xpconnect/tests/browser/browser_realm_key_object_prototype_top.html12
-rw-r--r--js/xpconnect/tests/browser/browser_realm_key_promise_frame.html17
-rw-r--r--js/xpconnect/tests/browser/browser_realm_key_promise_top.html7
-rw-r--r--js/xpconnect/tests/browser/browser_weak_xpcwjs.js238
-rw-r--r--js/xpconnect/tests/browser/moz.build7
-rw-r--r--js/xpconnect/tests/chrome/bug503926.xhtml30
-rw-r--r--js/xpconnect/tests/chrome/chrome.ini128
-rw-r--r--js/xpconnect/tests/chrome/file_bug1281071.html13
-rw-r--r--js/xpconnect/tests/chrome/file_bug1530146.html6
-rw-r--r--js/xpconnect/tests/chrome/file_bug1530146_inner.html4
-rw-r--r--js/xpconnect/tests/chrome/file_bug484459.html10
-rw-r--r--js/xpconnect/tests/chrome/file_bug618176.xhtml48
-rw-r--r--js/xpconnect/tests/chrome/file_bug996069.html11
-rw-r--r--js/xpconnect/tests/chrome/file_discardSystemSource.html19
-rw-r--r--js/xpconnect/tests/chrome/file_empty.html2
-rw-r--r--js/xpconnect/tests/chrome/file_evalInSandbox.html1
-rw-r--r--js/xpconnect/tests/chrome/file_expandosharing.jsm12
-rw-r--r--js/xpconnect/tests/chrome/moz.build12
-rw-r--r--js/xpconnect/tests/chrome/outoflinexulscript.js5
-rw-r--r--js/xpconnect/tests/chrome/subscript.js4
-rw-r--r--js/xpconnect/tests/chrome/test_APIExposer.xhtml48
-rw-r--r--js/xpconnect/tests/chrome/test_bug1041626.xhtml60
-rw-r--r--js/xpconnect/tests/chrome/test_bug1042436.xhtml54
-rw-r--r--js/xpconnect/tests/chrome/test_bug1065185.html64
-rw-r--r--js/xpconnect/tests/chrome/test_bug1074863.html31
-rw-r--r--js/xpconnect/tests/chrome/test_bug1092477.xhtml33
-rw-r--r--js/xpconnect/tests/chrome/test_bug1124898.html52
-rw-r--r--js/xpconnect/tests/chrome/test_bug1126911.html40
-rw-r--r--js/xpconnect/tests/chrome/test_bug1281071.xhtml32
-rw-r--r--js/xpconnect/tests/chrome/test_bug1390159.xhtml44
-rw-r--r--js/xpconnect/tests/chrome/test_bug1430164.html31
-rw-r--r--js/xpconnect/tests/chrome/test_bug1516237.html50
-rw-r--r--js/xpconnect/tests/chrome/test_bug1530146.html58
-rw-r--r--js/xpconnect/tests/chrome/test_bug361111.xhtml33
-rw-r--r--js/xpconnect/tests/chrome/test_bug448587.xhtml35
-rw-r--r--js/xpconnect/tests/chrome/test_bug484459.xhtml37
-rw-r--r--js/xpconnect/tests/chrome/test_bug500931.xhtml40
-rw-r--r--js/xpconnect/tests/chrome/test_bug503926.xhtml58
-rw-r--r--js/xpconnect/tests/chrome/test_bug533596.xhtml58
-rw-r--r--js/xpconnect/tests/chrome/test_bug571849.xhtml44
-rw-r--r--js/xpconnect/tests/chrome/test_bug610390.xhtml32
-rw-r--r--js/xpconnect/tests/chrome/test_bug614757.xhtml33
-rw-r--r--js/xpconnect/tests/chrome/test_bug616992.xhtml30
-rw-r--r--js/xpconnect/tests/chrome/test_bug618176.xhtml30
-rw-r--r--js/xpconnect/tests/chrome/test_bug654370.xhtml27
-rw-r--r--js/xpconnect/tests/chrome/test_bug658560.xhtml38
-rw-r--r--js/xpconnect/tests/chrome/test_bug658909.xhtml92
-rw-r--r--js/xpconnect/tests/chrome/test_bug664689.xhtml28
-rw-r--r--js/xpconnect/tests/chrome/test_bug679861.xhtml38
-rw-r--r--js/xpconnect/tests/chrome/test_bug706301.xhtml52
-rw-r--r--js/xpconnect/tests/chrome/test_bug720619.xhtml46
-rw-r--r--js/xpconnect/tests/chrome/test_bug726949.xhtml41
-rw-r--r--js/xpconnect/tests/chrome/test_bug732665.xhtml92
-rw-r--r--js/xpconnect/tests/chrome/test_bug732665_meta.js34
-rw-r--r--js/xpconnect/tests/chrome/test_bug738244.xhtml58
-rw-r--r--js/xpconnect/tests/chrome/test_bug743843.xhtml39
-rw-r--r--js/xpconnect/tests/chrome/test_bug760076.xhtml49
-rw-r--r--js/xpconnect/tests/chrome/test_bug760131.html48
-rw-r--r--js/xpconnect/tests/chrome/test_bug763343.xhtml35
-rw-r--r--js/xpconnect/tests/chrome/test_bug771429.xhtml66
-rw-r--r--js/xpconnect/tests/chrome/test_bug773962.xhtml88
-rw-r--r--js/xpconnect/tests/chrome/test_bug792280.xhtml43
-rw-r--r--js/xpconnect/tests/chrome/test_bug793433.xhtml44
-rw-r--r--js/xpconnect/tests/chrome/test_bug795275.xhtml80
-rw-r--r--js/xpconnect/tests/chrome/test_bug799348.xhtml47
-rw-r--r--js/xpconnect/tests/chrome/test_bug801241.xhtml48
-rw-r--r--js/xpconnect/tests/chrome/test_bug812415.xhtml90
-rw-r--r--js/xpconnect/tests/chrome/test_bug853283.xhtml40
-rw-r--r--js/xpconnect/tests/chrome/test_bug853571.xhtml62
-rw-r--r--js/xpconnect/tests/chrome/test_bug858101.xhtml55
-rw-r--r--js/xpconnect/tests/chrome/test_bug860494.xhtml57
-rw-r--r--js/xpconnect/tests/chrome/test_bug865948.xhtml35
-rw-r--r--js/xpconnect/tests/chrome/test_bug866823.xhtml49
-rw-r--r--js/xpconnect/tests/chrome/test_bug895340.xhtml50
-rw-r--r--js/xpconnect/tests/chrome/test_bug932906.xhtml69
-rw-r--r--js/xpconnect/tests/chrome/test_bug996069.xhtml52
-rw-r--r--js/xpconnect/tests/chrome/test_chrometoSource.xhtml68
-rw-r--r--js/xpconnect/tests/chrome/test_cloneInto.xhtml194
-rw-r--r--js/xpconnect/tests/chrome/test_cows.xhtml207
-rw-r--r--js/xpconnect/tests/chrome/test_discardSystemSource.xhtml81
-rw-r--r--js/xpconnect/tests/chrome/test_documentdomain.xhtml100
-rw-r--r--js/xpconnect/tests/chrome/test_doublewrappedcompartments.xhtml41
-rw-r--r--js/xpconnect/tests/chrome/test_envChain_event_handler.html137
-rw-r--r--js/xpconnect/tests/chrome/test_evalInSandbox.xhtml205
-rw-r--r--js/xpconnect/tests/chrome/test_evalInWindow.xhtml71
-rw-r--r--js/xpconnect/tests/chrome/test_exnstack.xhtml68
-rw-r--r--js/xpconnect/tests/chrome/test_expandosharing.xhtml147
-rw-r--r--js/xpconnect/tests/chrome/test_exposeInDerived.xhtml45
-rw-r--r--js/xpconnect/tests/chrome/test_inlineScripts.html53
-rw-r--r--js/xpconnect/tests/chrome/test_localstorage_with_nsEp.xhtml37
-rw-r--r--js/xpconnect/tests/chrome/test_matches.xhtml49
-rw-r--r--js/xpconnect/tests/chrome/test_nodelists.xhtml49
-rw-r--r--js/xpconnect/tests/chrome/test_nsScriptErrorWithStack.html59
-rw-r--r--js/xpconnect/tests/chrome/test_onGarbageCollection.html48
-rw-r--r--js/xpconnect/tests/chrome/test_precisegc.xhtml26
-rw-r--r--js/xpconnect/tests/chrome/test_private_field_cows.xhtml131
-rw-r--r--js/xpconnect/tests/chrome/test_sandboxImport.xhtml37
-rw-r--r--js/xpconnect/tests/chrome/test_scriptSettings.xhtml128
-rw-r--r--js/xpconnect/tests/chrome/test_scripterror.html87
-rw-r--r--js/xpconnect/tests/chrome/test_secureContexts.html58
-rw-r--r--js/xpconnect/tests/chrome/test_sharedChromeCompartment.html63
-rw-r--r--js/xpconnect/tests/chrome/test_weakmap_keys_preserved.xhtml33
-rw-r--r--js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xhtml80
-rw-r--r--js/xpconnect/tests/chrome/test_weakref.xhtml32
-rw-r--r--js/xpconnect/tests/chrome/test_windowProxyDeadWrapper.html76
-rw-r--r--js/xpconnect/tests/chrome/test_wrappers.xhtml85
-rw-r--r--js/xpconnect/tests/chrome/test_xrayLargeTypedArray.html47
-rw-r--r--js/xpconnect/tests/chrome/test_xrayToJS.xhtml1191
-rw-r--r--js/xpconnect/tests/chrome/test_xrayic.xhtml81
-rw-r--r--js/xpconnect/tests/chrome/utf8_subscript.js5
-rw-r--r--js/xpconnect/tests/chrome/worker_discardSystemSource.js6
-rw-r--r--js/xpconnect/tests/components/native/moz.build24
-rw-r--r--js/xpconnect/tests/components/native/xpctest_attributes.cpp136
-rw-r--r--js/xpconnect/tests/components/native/xpctest_cenums.cpp67
-rw-r--r--js/xpconnect/tests/components/native/xpctest_esmreturncode.cpp20
-rw-r--r--js/xpconnect/tests/components/native/xpctest_module.cpp45
-rw-r--r--js/xpconnect/tests/components/native/xpctest_params.cpp413
-rw-r--r--js/xpconnect/tests/components/native/xpctest_private.h102
-rw-r--r--js/xpconnect/tests/components/native/xpctest_returncode.cpp20
-rw-r--r--js/xpconnect/tests/idl/moz.build17
-rw-r--r--js/xpconnect/tests/idl/xpctest_attributes.idl33
-rw-r--r--js/xpconnect/tests/idl/xpctest_bug809674.idl47
-rw-r--r--js/xpconnect/tests/idl/xpctest_cenums.idl39
-rw-r--r--js/xpconnect/tests/idl/xpctest_esmreturncode.idl45
-rw-r--r--js/xpconnect/tests/idl/xpctest_interfaces.idl27
-rw-r--r--js/xpconnect/tests/idl/xpctest_params.idl120
-rw-r--r--js/xpconnect/tests/idl/xpctest_returncode.idl45
-rw-r--r--js/xpconnect/tests/idl/xpctest_utils.idl19
-rw-r--r--js/xpconnect/tests/mochitest/bug1681664_helper.js1
-rw-r--r--js/xpconnect/tests/mochitest/bug500931_helper.html8
-rw-r--r--js/xpconnect/tests/mochitest/bug571849_helper.html7
-rw-r--r--js/xpconnect/tests/mochitest/bug589028_helper.html27
-rw-r--r--js/xpconnect/tests/mochitest/bug92773_helper.html7
-rw-r--r--js/xpconnect/tests/mochitest/chrome_wrappers_helper.html29
-rw-r--r--js/xpconnect/tests/mochitest/class_static_worker.js13
-rw-r--r--js/xpconnect/tests/mochitest/file1_bug629227.html32
-rw-r--r--js/xpconnect/tests/mochitest/file2_bug629227.html11
-rw-r--r--js/xpconnect/tests/mochitest/file_bug505915.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug605167.html7
-rw-r--r--js/xpconnect/tests/mochitest/file_bug650273.html31
-rw-r--r--js/xpconnect/tests/mochitest/file_bug658560.html4
-rw-r--r--js/xpconnect/tests/mochitest/file_bug706301.html27
-rw-r--r--js/xpconnect/tests/mochitest/file_bug720619.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug731471.html5
-rw-r--r--js/xpconnect/tests/mochitest/file_bug738244.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug760131.html23
-rw-r--r--js/xpconnect/tests/mochitest/file_bug781476.html15
-rw-r--r--js/xpconnect/tests/mochitest/file_bug789713.html51
-rw-r--r--js/xpconnect/tests/mochitest/file_bug795275.html14
-rw-r--r--js/xpconnect/tests/mochitest/file_bug799348.html11
-rw-r--r--js/xpconnect/tests/mochitest/file_bug802557.html62
-rw-r--r--js/xpconnect/tests/mochitest/file_bug860494.html16
-rw-r--r--js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html8
-rw-r--r--js/xpconnect/tests/mochitest/file_documentdomain.html41
-rw-r--r--js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_empty.html3
-rw-r--r--js/xpconnect/tests/mochitest/file_evalInSandbox.html8
-rw-r--r--js/xpconnect/tests/mochitest/file_exnstack.html23
-rw-r--r--js/xpconnect/tests/mochitest/file_expandosharing.html34
-rw-r--r--js/xpconnect/tests/mochitest/file_matches.html1
-rw-r--r--js/xpconnect/tests/mochitest/file_nodelists.html7
-rw-r--r--js/xpconnect/tests/mochitest/file_wrappers-2.html13
-rw-r--r--js/xpconnect/tests/mochitest/file_xrayic.html15
-rw-r--r--js/xpconnect/tests/mochitest/finalizationRegistry_worker.js96
-rw-r--r--js/xpconnect/tests/mochitest/hasinstance/mochitest.ini7
-rw-r--r--js/xpconnect/tests/mochitest/hasinstance/test_bug870423.html58
-rw-r--r--js/xpconnect/tests/mochitest/inner.html7
-rw-r--r--js/xpconnect/tests/mochitest/mochitest.ini178
-rw-r--r--js/xpconnect/tests/mochitest/moz.build7
-rw-r--r--js/xpconnect/tests/mochitest/private_field_worker.js21
-rw-r--r--js/xpconnect/tests/mochitest/shadow_realm_module.js1
-rw-r--r--js/xpconnect/tests/mochitest/shadow_realm_worker.js81
-rw-r--r--js/xpconnect/tests/mochitest/test1_bug629331.html19
-rw-r--r--js/xpconnect/tests/mochitest/test2_bug629331.html18
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1005806.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1094930.html29
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1158558.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1448048.html33
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1681664.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug384632.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_bug390488.html64
-rw-r--r--js/xpconnect/tests/mochitest/test_bug393269.html46
-rw-r--r--js/xpconnect/tests/mochitest/test_bug396851.html53
-rw-r--r--js/xpconnect/tests/mochitest/test_bug428021.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_bug446584.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug462428.html51
-rw-r--r--js/xpconnect/tests/mochitest/test_bug478438.html65
-rw-r--r--js/xpconnect/tests/mochitest/test_bug484107.html99
-rw-r--r--js/xpconnect/tests/mochitest/test_bug500691.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_bug505915.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug560351.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_bug585745.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug589028.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug601299.html18
-rw-r--r--js/xpconnect/tests/mochitest/test_bug605167.html56
-rw-r--r--js/xpconnect/tests/mochitest/test_bug618017.html28
-rw-r--r--js/xpconnect/tests/mochitest/test_bug623437.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug628410.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_bug628794.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug629227.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug629331.html37
-rw-r--r--js/xpconnect/tests/mochitest/test_bug636097.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug650273.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug655297-1.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug655297-2.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug661980.html61
-rw-r--r--js/xpconnect/tests/mochitest/test_bug691059.html59
-rw-r--r--js/xpconnect/tests/mochitest/test_bug720619.html55
-rw-r--r--js/xpconnect/tests/mochitest/test_bug731471.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug764389.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_bug772288.html50
-rw-r--r--js/xpconnect/tests/mochitest/test_bug781476.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_bug789713.html39
-rw-r--r--js/xpconnect/tests/mochitest/test_bug790732.html55
-rw-r--r--js/xpconnect/tests/mochitest/test_bug793969.html53
-rw-r--r--js/xpconnect/tests/mochitest/test_bug800864.html51
-rw-r--r--js/xpconnect/tests/mochitest/test_bug802557.html116
-rw-r--r--js/xpconnect/tests/mochitest/test_bug803730.html41
-rw-r--r--js/xpconnect/tests/mochitest/test_bug809547.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug829872.html52
-rw-r--r--js/xpconnect/tests/mochitest/test_bug862380.html54
-rw-r--r--js/xpconnect/tests/mochitest/test_bug865260.html33
-rw-r--r--js/xpconnect/tests/mochitest/test_bug871887.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug912322.html35
-rw-r--r--js/xpconnect/tests/mochitest/test_bug916945.html78
-rw-r--r--js/xpconnect/tests/mochitest/test_bug92773.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug940783.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug960820.html56
-rw-r--r--js/xpconnect/tests/mochitest/test_bug965082.html39
-rw-r--r--js/xpconnect/tests/mochitest/test_bug993423.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_class_static_block_worker.html32
-rw-r--r--js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_enable_privilege.html26
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry.html168
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html13
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_frameWrapping.html37
-rw-r--r--js/xpconnect/tests/mochitest/test_getWebIDLCaller.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_getweakmapkeys.html59
-rw-r--r--js/xpconnect/tests/mochitest/test_isRemoteProxy.html53
-rw-r--r--js/xpconnect/tests/mochitest/test_nukeContentWindow.html75
-rw-r--r--js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html94
-rw-r--r--js/xpconnect/tests/mochitest/test_private_field_dom.html221
-rw-r--r--js/xpconnect/tests/mochitest/test_private_field_worker.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_sameOriginPolicy.html109
-rw-r--r--js/xpconnect/tests/mochitest/test_sandbox_fetch.html54
-rw-r--r--js/xpconnect/tests/mochitest/test_shadowRealm.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_shadowRealm_worker.html63
-rw-r--r--js/xpconnect/tests/mochitest/test_spectre_mitigations.html29
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs.html80
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html52
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html68
-rw-r--r--js/xpconnect/tests/mochitest/test_weakmaps.html264
-rw-r--r--js/xpconnect/tests/moz.build21
-rw-r--r--js/xpconnect/tests/unit/CatBackgroundTaskRegistrationComponents.manifest4
-rw-r--r--js/xpconnect/tests/unit/CatRegistrationComponents.manifest2
-rw-r--r--js/xpconnect/tests/unit/ReturnCodeChild.jsm51
-rw-r--r--js/xpconnect/tests/unit/ReturnCodeChild.sys.mjs49
-rw-r--r--js/xpconnect/tests/unit/TestBlob.jsm48
-rw-r--r--js/xpconnect/tests/unit/TestFile.jsm78
-rw-r--r--js/xpconnect/tests/unit/api_script.js26
-rw-r--r--js/xpconnect/tests/unit/bogus_element_type.jsm1
-rw-r--r--js/xpconnect/tests/unit/bogus_exports_type.jsm1
-rw-r--r--js/xpconnect/tests/unit/bug451678_subscript.js5
-rw-r--r--js/xpconnect/tests/unit/envChain.jsm20
-rw-r--r--js/xpconnect/tests/unit/envChain_subscript.jsm27
-rw-r--r--js/xpconnect/tests/unit/environment_checkscript.jsm13
-rw-r--r--js/xpconnect/tests/unit/environment_loadscript.jsm16
-rw-r--r--js/xpconnect/tests/unit/environment_script.js14
-rw-r--r--js/xpconnect/tests/unit/error_export.sys.mjs2
-rw-r--r--js/xpconnect/tests/unit/error_import.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/error_other.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/es6import.js1
-rw-r--r--js/xpconnect/tests/unit/es6module.js6
-rw-r--r--js/xpconnect/tests/unit/es6module_absolute.js4
-rw-r--r--js/xpconnect/tests/unit/es6module_absolute2.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_cycle_a.js9
-rw-r--r--js/xpconnect/tests/unit/es6module_cycle_b.js9
-rw-r--r--js/xpconnect/tests/unit/es6module_cycle_c.js9
-rw-r--r--js/xpconnect/tests/unit/es6module_devtoolsLoader.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs29
-rw-r--r--js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_dynamic_import.js7
-rw-r--r--js/xpconnect/tests/unit/es6module_dynamic_import2.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_import_error.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_import_error2.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_loaded-1.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/es6module_loaded-2.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/es6module_loaded-3.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/es6module_missing_import.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_parse_error.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_parse_error_in_import.js1
-rw-r--r--js/xpconnect/tests/unit/es6module_throws.js4
-rw-r--r--js/xpconnect/tests/unit/es6module_top_level_await.js1
-rw-r--r--js/xpconnect/tests/unit/esm_lazy-1.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esm_lazy-2.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-1.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-2.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-3.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-4.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-5.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-6.sys.mjs4
-rw-r--r--js/xpconnect/tests/unit/esmified-not-exported.sys.mjs13
-rw-r--r--js/xpconnect/tests/unit/file_simple_script.js1
-rw-r--r--js/xpconnect/tests/unit/frame.js1
-rw-r--r--js/xpconnect/tests/unit/head.js15
-rw-r--r--js/xpconnect/tests/unit/head_ongc.js35
-rw-r--r--js/xpconnect/tests/unit/head_watchdog.js116
-rw-r--r--js/xpconnect/tests/unit/import_stack.jsm2
-rw-r--r--js/xpconnect/tests/unit/import_stack.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/import_stack_static_1.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/import_stack_static_2.sys.mjs2
-rw-r--r--js/xpconnect/tests/unit/import_stack_static_3.sys.mjs2
-rw-r--r--js/xpconnect/tests/unit/import_stack_static_4.sys.mjs1
-rw-r--r--js/xpconnect/tests/unit/importer.jsm1
-rw-r--r--js/xpconnect/tests/unit/jsm_loaded-1.jsm2
-rw-r--r--js/xpconnect/tests/unit/jsm_loaded-2.jsm2
-rw-r--r--js/xpconnect/tests/unit/jsm_loaded-3.jsm2
-rw-r--r--js/xpconnect/tests/unit/not-esmified-not-exported.jsm20
-rw-r--r--js/xpconnect/tests/unit/recursive_importA.jsm12
-rw-r--r--js/xpconnect/tests/unit/recursive_importB.jsm13
-rw-r--r--js/xpconnect/tests/unit/syntax_error.jsm1
-rw-r--r--js/xpconnect/tests/unit/test_ComponentEnvironment.js20
-rw-r--r--js/xpconnect/tests/unit/test_FrameScriptEnvironment.js46
-rw-r--r--js/xpconnect/tests/unit/test_SubscriptLoaderEnvironment.js38
-rw-r--r--js/xpconnect/tests/unit/test_SubscriptLoaderJSMEnvironment.js32
-rw-r--r--js/xpconnect/tests/unit/test_SubscriptLoaderSandboxEnvironment.js35
-rw-r--r--js/xpconnect/tests/unit/test_URLSearchParams.js12
-rw-r--r--js/xpconnect/tests/unit/test_allowWaivers.js29
-rw-r--r--js/xpconnect/tests/unit/test_allowedDomains.js41
-rw-r--r--js/xpconnect/tests/unit/test_allowedDomainsXHR.js135
-rw-r--r--js/xpconnect/tests/unit/test_attributes.js103
-rw-r--r--js/xpconnect/tests/unit/test_blob.js8
-rw-r--r--js/xpconnect/tests/unit/test_blob2.js34
-rw-r--r--js/xpconnect/tests/unit/test_bogus_files.js32
-rw-r--r--js/xpconnect/tests/unit/test_bug1001094.js4
-rw-r--r--js/xpconnect/tests/unit/test_bug1021312.js15
-rw-r--r--js/xpconnect/tests/unit/test_bug1033253.js5
-rw-r--r--js/xpconnect/tests/unit/test_bug1033920.js6
-rw-r--r--js/xpconnect/tests/unit/test_bug1033927.js8
-rw-r--r--js/xpconnect/tests/unit/test_bug1034262.js8
-rw-r--r--js/xpconnect/tests/unit/test_bug1081990.js9
-rw-r--r--js/xpconnect/tests/unit/test_bug1110546.js4
-rw-r--r--js/xpconnect/tests/unit/test_bug1131707.js20
-rw-r--r--js/xpconnect/tests/unit/test_bug1150771.js12
-rw-r--r--js/xpconnect/tests/unit/test_bug1151385.js9
-rw-r--r--js/xpconnect/tests/unit/test_bug1170311.js4
-rw-r--r--js/xpconnect/tests/unit/test_bug1244222.js31
-rw-r--r--js/xpconnect/tests/unit/test_bug1617527.js17
-rw-r--r--js/xpconnect/tests/unit/test_bug267645.js62
-rw-r--r--js/xpconnect/tests/unit/test_bug408412.js12
-rw-r--r--js/xpconnect/tests/unit/test_bug451678.js15
-rw-r--r--js/xpconnect/tests/unit/test_bug604362.js10
-rw-r--r--js/xpconnect/tests/unit/test_bug677864.js9
-rw-r--r--js/xpconnect/tests/unit/test_bug711404.js7
-rw-r--r--js/xpconnect/tests/unit/test_bug742444.js16
-rw-r--r--js/xpconnect/tests/unit/test_bug778409.js10
-rw-r--r--js/xpconnect/tests/unit/test_bug780370.js16
-rw-r--r--js/xpconnect/tests/unit/test_bug809652.js62
-rw-r--r--js/xpconnect/tests/unit/test_bug809674.js76
-rw-r--r--js/xpconnect/tests/unit/test_bug813901.js23
-rw-r--r--js/xpconnect/tests/unit/test_bug845201.js18
-rw-r--r--js/xpconnect/tests/unit/test_bug845862.js7
-rw-r--r--js/xpconnect/tests/unit/test_bug849730.js5
-rw-r--r--js/xpconnect/tests/unit/test_bug851895.js9
-rw-r--r--js/xpconnect/tests/unit/test_bug853709.js30
-rw-r--r--js/xpconnect/tests/unit/test_bug856067.js8
-rw-r--r--js/xpconnect/tests/unit/test_bug867486.js8
-rw-r--r--js/xpconnect/tests/unit/test_bug868675.js29
-rw-r--r--js/xpconnect/tests/unit/test_bug872772.js33
-rw-r--r--js/xpconnect/tests/unit/test_bug885800.js11
-rw-r--r--js/xpconnect/tests/unit/test_bug930091.js27
-rw-r--r--js/xpconnect/tests/unit/test_bug976151.js23
-rw-r--r--js/xpconnect/tests/unit/test_bug_442086.js36
-rw-r--r--js/xpconnect/tests/unit/test_callFunctionWithAsyncStack.js28
-rw-r--r--js/xpconnect/tests/unit/test_cenums.js58
-rw-r--r--js/xpconnect/tests/unit/test_compileScript.js99
-rw-r--r--js/xpconnect/tests/unit/test_components.js24
-rw-r--r--js/xpconnect/tests/unit/test_crypto.js28
-rw-r--r--js/xpconnect/tests/unit/test_css.js9
-rw-r--r--js/xpconnect/tests/unit/test_deepFreezeClone.js31
-rw-r--r--js/xpconnect/tests/unit/test_defineESModuleGetters.js76
-rw-r--r--js/xpconnect/tests/unit/test_defineModuleGetter.js115
-rw-r--r--js/xpconnect/tests/unit/test_envChain_JSM.js40
-rw-r--r--js/xpconnect/tests/unit/test_envChain_frameScript.js211
-rw-r--r--js/xpconnect/tests/unit/test_envChain_subscript.js72
-rw-r--r--js/xpconnect/tests/unit/test_envChain_subscript_in_JSM.js58
-rw-r--r--js/xpconnect/tests/unit/test_eventSource.js6
-rw-r--r--js/xpconnect/tests/unit/test_exportFunction.js152
-rw-r--r--js/xpconnect/tests/unit/test_file.js11
-rw-r--r--js/xpconnect/tests/unit/test_file2.js60
-rw-r--r--js/xpconnect/tests/unit/test_fileReader.js12
-rw-r--r--js/xpconnect/tests/unit/test_function_names.js37
-rw-r--r--js/xpconnect/tests/unit/test_generateQI.js29
-rw-r--r--js/xpconnect/tests/unit/test_getCallerLocation.js86
-rw-r--r--js/xpconnect/tests/unit/test_getObjectPrincipal.js6
-rw-r--r--js/xpconnect/tests/unit/test_import.js72
-rw-r--r--js/xpconnect/tests/unit/test_import_devtools_loader.js85
-rw-r--r--js/xpconnect/tests/unit/test_import_es6_modules.js180
-rw-r--r--js/xpconnect/tests/unit/test_import_fail.js10
-rw-r--r--js/xpconnect/tests/unit/test_import_from_sandbox.js82
-rw-r--r--js/xpconnect/tests/unit/test_import_shim.js377
-rw-r--r--js/xpconnect/tests/unit/test_import_stack.js39
-rw-r--r--js/xpconnect/tests/unit/test_import_syntax_error.js23
-rw-r--r--js/xpconnect/tests/unit/test_isModuleLoaded.js20
-rw-r--r--js/xpconnect/tests/unit/test_isProxy.js26
-rw-r--r--js/xpconnect/tests/unit/test_js_memory_telemetry.js53
-rw-r--r--js/xpconnect/tests/unit/test_js_weak_references.js45
-rw-r--r--js/xpconnect/tests/unit/test_lazyproxy.js113
-rw-r--r--js/xpconnect/tests/unit/test_loadedESModules.js127
-rw-r--r--js/xpconnect/tests/unit/test_localeCompare.js6
-rw-r--r--js/xpconnect/tests/unit/test_messageChannel.js29
-rw-r--r--js/xpconnect/tests/unit/test_nuke_sandbox.js50
-rw-r--r--js/xpconnect/tests/unit/test_nuke_sandbox_event_listeners.js89
-rw-r--r--js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js71
-rw-r--r--js/xpconnect/tests/unit/test_onGarbageCollection-01.js69
-rw-r--r--js/xpconnect/tests/unit/test_onGarbageCollection-02.js99
-rw-r--r--js/xpconnect/tests/unit/test_onGarbageCollection-03.js39
-rw-r--r--js/xpconnect/tests/unit/test_onGarbageCollection-04.js72
-rw-r--r--js/xpconnect/tests/unit/test_onGarbageCollection-05.js42
-rw-r--r--js/xpconnect/tests/unit/test_params.js384
-rw-r--r--js/xpconnect/tests/unit/test_print_stderr.js14
-rw-r--r--js/xpconnect/tests/unit/test_private_field_xrays.js58
-rw-r--r--js/xpconnect/tests/unit/test_promise.js7
-rw-r--r--js/xpconnect/tests/unit/test_recursive_import.js17
-rw-r--r--js/xpconnect/tests/unit/test_reflect_parse.js27
-rw-r--r--js/xpconnect/tests/unit/test_resolve_dead_promise.js39
-rw-r--r--js/xpconnect/tests/unit/test_returncode.js74
-rw-r--r--js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js31
-rw-r--r--js/xpconnect/tests/unit/test_rtcIdentityProvider.js34
-rw-r--r--js/xpconnect/tests/unit/test_sandbox_DOMException.js10
-rw-r--r--js/xpconnect/tests/unit/test_sandbox_atob.js9
-rw-r--r--js/xpconnect/tests/unit/test_sandbox_metadata.js57
-rw-r--r--js/xpconnect/tests/unit/test_sandbox_name.js26
-rw-r--r--js/xpconnect/tests/unit/test_storage.js12
-rw-r--r--js/xpconnect/tests/unit/test_structuredClone.js33
-rw-r--r--js/xpconnect/tests/unit/test_subScriptLoader.js16
-rw-r--r--js/xpconnect/tests/unit/test_tearoffs.js115
-rw-r--r--js/xpconnect/tests/unit/test_textDecoder.js11
-rw-r--r--js/xpconnect/tests/unit/test_uawidget_scope.js56
-rw-r--r--js/xpconnect/tests/unit/test_uninitialized_lexical.js7
-rw-r--r--js/xpconnect/tests/unit/test_unload.js28
-rw-r--r--js/xpconnect/tests/unit/test_url.js9
-rw-r--r--js/xpconnect/tests/unit/test_want_components.js16
-rw-r--r--js/xpconnect/tests/unit/test_watchdog_default.js9
-rw-r--r--js/xpconnect/tests/unit/test_watchdog_disable.js8
-rw-r--r--js/xpconnect/tests/unit/test_watchdog_enable.js8
-rw-r--r--js/xpconnect/tests/unit/test_watchdog_hibernate.js49
-rw-r--r--js/xpconnect/tests/unit/test_watchdog_toggle.js10
-rw-r--r--js/xpconnect/tests/unit/test_weak_keys.js45
-rw-r--r--js/xpconnect/tests/unit/test_wrapped_js_enumerator.js71
-rw-r--r--js/xpconnect/tests/unit/test_xpcomutils.js275
-rw-r--r--js/xpconnect/tests/unit/test_xpcwn_instanceof.js23
-rw-r--r--js/xpconnect/tests/unit/test_xpcwn_tamperproof.js180
-rw-r--r--js/xpconnect/tests/unit/test_xray_SavedFrame-02.js71
-rw-r--r--js/xpconnect/tests/unit/test_xray_SavedFrame.js104
-rw-r--r--js/xpconnect/tests/unit/test_xray_instanceof.js206
-rw-r--r--js/xpconnect/tests/unit/test_xray_named_element_access.js23
-rw-r--r--js/xpconnect/tests/unit/test_xray_regexp.js7
-rw-r--r--js/xpconnect/tests/unit/test_xrayed_arguments.js16
-rw-r--r--js/xpconnect/tests/unit/test_xrayed_iterator.js40
-rw-r--r--js/xpconnect/tests/unit/uninitialized_lexical.jsm2
-rw-r--r--js/xpconnect/tests/unit/xpcshell.ini223
-rw-r--r--js/xpconnect/wrappers/AccessCheck.cpp172
-rw-r--r--js/xpconnect/wrappers/AccessCheck.h115
-rw-r--r--js/xpconnect/wrappers/ChromeObjectWrapper.cpp41
-rw-r--r--js/xpconnect/wrappers/ChromeObjectWrapper.h42
-rw-r--r--js/xpconnect/wrappers/FilteringWrapper.cpp172
-rw-r--r--js/xpconnect/wrappers/FilteringWrapper.h57
-rw-r--r--js/xpconnect/wrappers/WaiveXrayWrapper.cpp95
-rw-r--r--js/xpconnect/wrappers/WaiveXrayWrapper.h48
-rw-r--r--js/xpconnect/wrappers/WrapperFactory.cpp818
-rw-r--r--js/xpconnect/wrappers/WrapperFactory.h114
-rw-r--r--js/xpconnect/wrappers/XrayWrapper.cpp2335
-rw-r--r--js/xpconnect/wrappers/XrayWrapper.h495
-rw-r--r--js/xpconnect/wrappers/moz.build32
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, &current, 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, &current) ||
+ !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(), &registered);
+ 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, &param_iid) ||
+ !GetArraySizeFromParam(info, type, nativeParams, &array_count))
+ goto pre_call_clean_up;
+
+ if (!XPCConvert::NativeData2JS(cx, &val, pv, type, &param_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 (&param == 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,
+ &param_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 (&param == 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, &param_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,
+ &param_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, &param.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 = &param->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 = &paramInfo == 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, &param_iid) ||
+ !GetArraySizeFromParam(type, UndefinedHandleValue, &array_count))
+ return false;
+
+ nsresult err;
+ if (!XPCConvert::NativeData2JS(mCallContext, &v, &dp->val, type, &param_iid,
+ array_count, &err)) {
+ ThrowBadParam(err, i, mCallContext);
+ return false;
+ }
+
+ if (&paramInfo == 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, &param_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, &param_iid) ||
+ !GetArraySizeFromParam(type, src, &array_count))
+ return false;
+
+ nsresult err;
+
+ if (!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type, &param_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, &param.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,&lt;script&gt;var x=3&lt;/script&gt;"
+ 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",
+]