mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Merge m-c to fx-team
This commit is contained in:
commit
1c27a70a5e
@ -26,7 +26,7 @@ function hookScreen(window) {
|
||||
let nodePrincipal = window.document.nodePrincipal;
|
||||
let origin = nodePrincipal.origin;
|
||||
if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
|
||||
Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed');
|
||||
// Only inject screen mock for apps
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,12 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
|
@ -17,9 +17,9 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
@ -131,6 +131,6 @@
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="efd87a5797ca40fa2df256630c07e0dfb2f762dc"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="832f4acaf481a19031e479a40b03d9ce5370ddee"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
</manifest>
|
||||
|
@ -15,11 +15,11 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
|
@ -19,12 +19,12 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
|
@ -17,9 +17,9 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
@ -143,7 +143,7 @@
|
||||
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||
<project name="platform/system/core" path="system/core" revision="bbf7212289fc8311e43f9d11e10788e310d36a08"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "278dd1b102a39cf2c48f11fe3038eaf8f0779d7d",
|
||||
"revision": "02f96bd32a7d77bc1684f3ca745f0e810871159b",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -15,11 +15,11 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -17,9 +17,9 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
@ -127,7 +127,7 @@
|
||||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||
|
@ -17,11 +17,11 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -264,6 +264,7 @@ Toolbox.prototype = {
|
||||
// Load the toolbox-level actor fronts and utilities now
|
||||
this._target.makeRemote().then(() => {
|
||||
iframe.setAttribute("src", this._URL);
|
||||
iframe.setAttribute("aria-label", toolboxStrings("toolbox.label"))
|
||||
let domHelper = new DOMHelpers(iframe.contentWindow);
|
||||
domHelper.onceDOMReady(domReady);
|
||||
});
|
||||
@ -814,6 +815,9 @@ Toolbox.prototype = {
|
||||
};
|
||||
|
||||
iframe.setAttribute("src", definition.url);
|
||||
if (definition.panelLabel) {
|
||||
iframe.setAttribute("aria-label", definition.panelLabel);
|
||||
}
|
||||
|
||||
// Depending on the host, iframe.contentWindow is not always
|
||||
// defined at this moment. If it is not defined, we use an
|
||||
|
@ -70,6 +70,7 @@ Tools.options = {
|
||||
icon: "chrome://browser/skin/devtools/tool-options.svg",
|
||||
invertIconForLightTheme: true,
|
||||
bgTheme: "theme-body",
|
||||
panelLabel: l10n("options.panelLabel", toolboxStrings),
|
||||
tooltip: l10n("optionsButton.tooltip", toolboxStrings),
|
||||
inMenu: false,
|
||||
isTargetSupported: function(target) {
|
||||
@ -92,6 +93,7 @@ Tools.webConsole = {
|
||||
url: "chrome://browser/content/devtools/webconsole.xul",
|
||||
label: l10n("ToolboxTabWebconsole.label", webConsoleStrings),
|
||||
menuLabel: l10n("MenuWebconsole.label", webConsoleStrings),
|
||||
panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings),
|
||||
tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings),
|
||||
inMenu: true,
|
||||
commands: "devtools/webconsole/console-commands",
|
||||
@ -123,6 +125,7 @@ Tools.inspector = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/inspector/inspector.xul",
|
||||
label: l10n("inspector.label", inspectorStrings),
|
||||
panelLabel: l10n("inspector.panelLabel", inspectorStrings),
|
||||
tooltip: l10n("inspector.tooltip", inspectorStrings),
|
||||
inMenu: true,
|
||||
commands: [
|
||||
@ -157,6 +160,7 @@ Tools.jsdebugger = {
|
||||
highlightedicon: "chrome://browser/skin/devtools/tool-debugger-paused.svg",
|
||||
url: "chrome://browser/content/devtools/debugger.xul",
|
||||
label: l10n("ToolboxDebugger.label", debuggerStrings),
|
||||
panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings),
|
||||
tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings),
|
||||
inMenu: true,
|
||||
commands: "devtools/debugger/debugger-commands",
|
||||
@ -181,6 +185,7 @@ Tools.styleEditor = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/styleeditor.xul",
|
||||
label: l10n("ToolboxStyleEditor.label", styleEditorStrings),
|
||||
panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings),
|
||||
tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings),
|
||||
inMenu: true,
|
||||
commands: "devtools/styleeditor/styleeditor-commands",
|
||||
@ -203,6 +208,7 @@ Tools.shaderEditor = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/shadereditor.xul",
|
||||
label: l10n("ToolboxShaderEditor.label", shaderEditorStrings),
|
||||
panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings),
|
||||
tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings),
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
@ -223,6 +229,7 @@ Tools.canvasDebugger = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/canvasdebugger.xul",
|
||||
label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),
|
||||
panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings),
|
||||
tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
|
||||
isTargetSupported: function(target) {
|
||||
return !target.isAddon;
|
||||
@ -241,6 +248,7 @@ Tools.webAudioEditor = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/webaudioeditor.xul",
|
||||
label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings),
|
||||
panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings),
|
||||
tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings),
|
||||
isTargetSupported: function(target) {
|
||||
return !target.isAddon;
|
||||
@ -262,6 +270,7 @@ Tools.jsprofiler = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/profiler.xul",
|
||||
label: l10n("profiler.label", profilerStrings),
|
||||
panelLabel: l10n("profiler.panelLabel", profilerStrings),
|
||||
tooltip: l10n("profiler.tooltip2", profilerStrings),
|
||||
inMenu: true,
|
||||
commands: "devtools/profiler/commands",
|
||||
@ -287,6 +296,7 @@ Tools.netMonitor = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/netmonitor.xul",
|
||||
label: l10n("netmonitor.label", netMonitorStrings),
|
||||
panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings),
|
||||
tooltip: l10n("netmonitor.tooltip", netMonitorStrings),
|
||||
inMenu: true,
|
||||
|
||||
@ -309,6 +319,7 @@ Tools.scratchpad = {
|
||||
invertIconForLightTheme: true,
|
||||
url: "chrome://browser/content/devtools/scratchpad.xul",
|
||||
label: l10n("scratchpad.label", scratchpadStrings),
|
||||
panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings),
|
||||
tooltip: l10n("scratchpad.tooltip", scratchpadStrings),
|
||||
inMenu: false,
|
||||
commands: "devtools/scratchpad/scratchpad-commands",
|
||||
|
@ -15,6 +15,10 @@
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxCanvasDebugger.label=Canvas
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxCanvasDebugger.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxCanvasDebugger.panelLabel=Canvas Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxCanvasDebugger.tooltip):
|
||||
# This string is displayed in the tooltip of the tab when the Shader Editor is
|
||||
# displayed inside the developer tools window.
|
||||
|
@ -15,6 +15,10 @@
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxDebugger.label=Debugger
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxDebugger.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxDebugger.panelLabel=Debugger Panel
|
||||
|
||||
# LOCALIZATION NOTE (DebuggerWindowTitle):
|
||||
# The title displayed for the debugger window.
|
||||
DebuggerWindowTitle=Browser Debugger
|
||||
|
@ -36,6 +36,7 @@ nodeMenu.tooltiptext=Node operations
|
||||
inspector.label=Inspector
|
||||
inspector.commandkey=C
|
||||
inspector.accesskey=I
|
||||
inspector.panelLabel=Inspector Panel
|
||||
|
||||
# LOCALIZATION NOTE (markupView.more.*)
|
||||
# When there are too many nodes to load at once, we will offer to
|
||||
|
@ -15,6 +15,10 @@
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
netmonitor.label=Network
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
netmonitor.panelLabel=Network Panel
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.commandkey, netmonitor.accesskey)
|
||||
# Used for the menuitem in the tool menu
|
||||
netmonitor.commandkey=Q
|
||||
|
@ -15,6 +15,10 @@
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
profiler.label=Profiler
|
||||
|
||||
# LOCALIZATION NOTE (profiler.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
profiler.panelLabel=Profiler Panel
|
||||
|
||||
# LOCALIZATION NOTE (profiler2.commandkey, profiler.accesskey)
|
||||
# Used for the menuitem in the tool menu
|
||||
profiler2.commandkey=VK_F5
|
||||
|
@ -95,6 +95,10 @@ connectionTimeout=Connection timeout. Check the Error Console on both ends for p
|
||||
# in the Developer Tools Menu.
|
||||
scratchpad.label=Scratchpad
|
||||
|
||||
# LOCALIZATION NOTE (scratchpad.panelLabel): this is used as the
|
||||
# label for the toolbox panel.
|
||||
scratchpad.panelLabel=Scratchpad Panel
|
||||
|
||||
# LOCALIZATION NOTE (scratchpad.tooltip): This string is displayed in the
|
||||
# tooltip of the tab when the Scratchpad is displayed inside the developer tools
|
||||
# window.
|
||||
|
@ -15,6 +15,10 @@
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxShaderEditor.label=Shader Editor
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxShaderEditor.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxShaderEditor.panelLabel=Shader Editor Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxShaderEditor.tooltip):
|
||||
# This string is displayed in the tooltip of the tab when the Shader Editor is
|
||||
# displayed inside the developer tools window.
|
||||
|
@ -73,6 +73,10 @@ saveStyleSheet.commandkey=S
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxStyleEditor.label=Style Editor
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxStyleEditor.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxStyleEditor.panelLabel=Style Editor Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxStyleEditor.tooltip2):
|
||||
# This string is displayed in the tooltip of the tab when the style editor is
|
||||
# displayed inside the developer tools window.
|
||||
|
@ -35,10 +35,18 @@ toolbox.titleTemplate=%1$S - %2$S
|
||||
# name when no tool is selected.
|
||||
toolbox.defaultTitle=Developer Tools
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.label): This is used as the label for the
|
||||
# toolbox as a whole
|
||||
toolbox.label=Developer Tools
|
||||
|
||||
# LOCALIZATION NOTE (optionsButton.tooltip): This is used as the tooltip
|
||||
# for the options panel tab.
|
||||
optionsButton.tooltip=Toolbox Options
|
||||
|
||||
# LOCALIZATION NOTE (options.panelLabel): This is used as the label for the
|
||||
# toolbox panel.
|
||||
options.panelLabel=Toolbox Options Panel
|
||||
|
||||
# LOCALIZATION NOTE (options.toolNotSupported): This is the template
|
||||
# used to add a * marker to the label for the Options Panel tool checkbox for the
|
||||
# tool which is not supported for the current toolbox target.
|
||||
|
@ -16,6 +16,10 @@
|
||||
# is displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxWebAudioEditor1.label=Web Audio
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxWebAudioEditor1.panelLabel=Web Audio Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.tooltip):
|
||||
# This string is displayed in the tooltip of the tab when the Web Audio Editor is
|
||||
# displayed inside the developer tools window.
|
||||
|
@ -167,6 +167,10 @@ MenuWebconsole.label=Web Console
|
||||
# label of the tab in the devtools window.
|
||||
ToolboxTabWebconsole.label=Console
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxWebConsole.panelLabel): the string used as the
|
||||
# label for the toolbox panel.
|
||||
ToolboxWebConsole.panelLabel=Console Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxWebconsole.tooltip): the string displayed in the
|
||||
# tooltip of the tab when the Web Console is displayed inside the developer
|
||||
# tools window.
|
||||
|
@ -819,7 +819,7 @@ class Automation(object):
|
||||
xrePath = None, certPath = None,
|
||||
debuggerInfo = None, symbolsPath = None,
|
||||
timeout = -1, maxTime = None, onLaunch = None,
|
||||
webapprtChrome = False, screenshotOnFail=False, testPath=None):
|
||||
webapprtChrome = False, screenshotOnFail=False, testPath=None, bisectChunk=None):
|
||||
"""
|
||||
Run the app, log the duration it took to execute, return the status code.
|
||||
Kills the app if it runs for longer than |maxTime| seconds, or outputs nothing for |timeout| seconds.
|
||||
|
@ -47,10 +47,12 @@ VideoChunk::~VideoChunk()
|
||||
void
|
||||
VideoSegment::AppendFrame(already_AddRefed<Image>&& aImage,
|
||||
TrackTicks aDuration,
|
||||
const IntSize& aIntrinsicSize)
|
||||
const IntSize& aIntrinsicSize,
|
||||
bool aForceBlack)
|
||||
{
|
||||
VideoChunk* chunk = AppendChunk(aDuration);
|
||||
VideoFrame frame(aImage, ThebesIntSize(aIntrinsicSize));
|
||||
frame.SetForceBlack(aForceBlack);
|
||||
chunk->mFrame.TakeFrom(&frame);
|
||||
}
|
||||
|
||||
|
@ -96,8 +96,10 @@ public:
|
||||
VideoSegment();
|
||||
~VideoSegment();
|
||||
|
||||
void AppendFrame(already_AddRefed<Image>&& aImage, TrackTicks aDuration,
|
||||
const IntSize& aIntrinsicSize);
|
||||
void AppendFrame(already_AddRefed<Image>&& aImage,
|
||||
TrackTicks aDuration,
|
||||
const IntSize& aIntrinsicSize,
|
||||
bool aForceBlack = false);
|
||||
const VideoFrame* GetFrameAt(TrackTicks aOffset, TrackTicks* aStart = nullptr)
|
||||
{
|
||||
VideoChunk* c = FindChunkContaining(aOffset, aStart);
|
||||
|
@ -207,8 +207,10 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
|
||||
while (!iter.IsEnded()) {
|
||||
VideoChunk chunk = *iter;
|
||||
nsRefPtr<layers::Image> image = chunk.mFrame.GetImage();
|
||||
mRawSegment.AppendFrame(image.forget(), chunk.GetDuration(),
|
||||
chunk.mFrame.GetIntrinsicSize().ToIntSize());
|
||||
mRawSegment.AppendFrame(image.forget(),
|
||||
chunk.GetDuration(),
|
||||
chunk.mFrame.GetIntrinsicSize().ToIntSize(),
|
||||
chunk.mFrame.GetForceBlack());
|
||||
iter.Next();
|
||||
}
|
||||
|
||||
|
@ -129,12 +129,12 @@ nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffe
|
||||
|
||||
data.mYChannel = GST_BUFFER_DATA(aBuffer);
|
||||
data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width);
|
||||
data.mYSize = gfx::IntSize(data.mYStride,
|
||||
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
|
||||
data.mYSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 0, mPicture.width),
|
||||
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
|
||||
data.mYSkip = 0;
|
||||
data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width);
|
||||
data.mCbCrSize = gfx::IntSize(data.mCbCrStride,
|
||||
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
|
||||
data.mCbCrSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 1, mPicture.width),
|
||||
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
|
||||
data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1,
|
||||
mPicture.width, mPicture.height);
|
||||
data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2,
|
||||
|
49
content/media/gtest/TestVideoSegment.cpp
Normal file
49
content/media/gtest/TestVideoSegment.cpp
Normal file
@ -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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "VideoSegment.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layer {
|
||||
class Image;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VideoSegment, TestAppendFrameForceBlack)
|
||||
{
|
||||
nsRefPtr<layers::Image> testImage = nullptr;
|
||||
|
||||
VideoSegment segment;
|
||||
segment.AppendFrame(testImage.forget(),
|
||||
mozilla::TrackTicks(90000),
|
||||
mozilla::gfx::IntSize(640, 480),
|
||||
true);
|
||||
|
||||
VideoSegment::ChunkIterator iter(segment);
|
||||
while (!iter.IsEnded()) {
|
||||
VideoChunk chunk = *iter;
|
||||
EXPECT_TRUE(chunk.mFrame.GetForceBlack());
|
||||
iter.Next();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VideoSegment, TestAppendFrameNotForceBlack)
|
||||
{
|
||||
nsRefPtr<layers::Image> testImage = nullptr;
|
||||
|
||||
VideoSegment segment;
|
||||
segment.AppendFrame(testImage.forget(),
|
||||
mozilla::TrackTicks(90000),
|
||||
mozilla::gfx::IntSize(640, 480));
|
||||
|
||||
VideoSegment::ChunkIterator iter(segment);
|
||||
while (!iter.IsEnded()) {
|
||||
VideoChunk chunk = *iter;
|
||||
EXPECT_FALSE(chunk.mFrame.GetForceBlack());
|
||||
iter.Next();
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "nestegg/nestegg.h"
|
||||
#include "VorbisTrackEncoder.h"
|
||||
#include "VP8TrackEncoder.h"
|
||||
#include "WebMWriter.h"
|
||||
@ -224,3 +227,149 @@ TEST(WebMWriter, FLUSH_NEEDED)
|
||||
// Have data because the previous cluster is closed.
|
||||
EXPECT_TRUE(writer.HaveValidCluster());
|
||||
}
|
||||
|
||||
struct WebMioData {
|
||||
nsTArray<uint8_t> data;
|
||||
CheckedInt<size_t> offset;
|
||||
};
|
||||
|
||||
static int webm_read(void* aBuffer, size_t aLength, void* aUserData)
|
||||
{
|
||||
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
|
||||
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
|
||||
|
||||
// Check the read length.
|
||||
if (aLength > ioData->data.Length()) {
|
||||
NS_ERROR("Invalid read length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check eos.
|
||||
if (ioData->offset.value() >= ioData->data.Length()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t oldOffset = ioData->offset.value();
|
||||
ioData->offset += aLength;
|
||||
if (!ioData->offset.isValid() ||
|
||||
(ioData->offset.value() > ioData->data.Length())) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(aBuffer, ioData->data.Elements()+oldOffset, aLength);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int webm_seek(int64_t aOffset, int aWhence, void* aUserData)
|
||||
{
|
||||
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
|
||||
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
|
||||
|
||||
if (Abs(aOffset) > ioData->data.Length()) {
|
||||
NS_ERROR("Invalid aOffset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (aWhence) {
|
||||
case NESTEGG_SEEK_END:
|
||||
{
|
||||
CheckedInt<size_t> tempOffset = ioData->data.Length();
|
||||
ioData->offset = tempOffset + aOffset;
|
||||
break;
|
||||
}
|
||||
case NESTEGG_SEEK_CUR:
|
||||
ioData->offset += aOffset;
|
||||
break;
|
||||
case NESTEGG_SEEK_SET:
|
||||
ioData->offset = aOffset;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown whence");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ioData->offset.isValid()) {
|
||||
NS_ERROR("Invalid offset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int64_t webm_tell(void* aUserData)
|
||||
{
|
||||
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
|
||||
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
|
||||
return ioData->offset.isValid() ? ioData->offset.value() : -1;
|
||||
}
|
||||
|
||||
TEST(WebMWriter, bug970774_aspect_ratio)
|
||||
{
|
||||
TestWebMWriter writer(ContainerWriter::CREATE_AUDIO_TRACK |
|
||||
ContainerWriter::CREATE_VIDEO_TRACK);
|
||||
// Set vorbis metadata.
|
||||
int channel = 1;
|
||||
int sampleRate = 44100;
|
||||
writer.SetVorbisMetadata(channel, sampleRate);
|
||||
// Set vp8 metadata
|
||||
int32_t width = 640;
|
||||
int32_t height = 480;
|
||||
int32_t displayWidth = 1280;
|
||||
int32_t displayHeight = 960;
|
||||
TrackRate aTrackRate = 90000;
|
||||
writer.SetVP8Metadata(width, height, displayWidth,
|
||||
displayHeight, aTrackRate);
|
||||
|
||||
// write the first I-Frame.
|
||||
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);
|
||||
|
||||
// write the second I-Frame.
|
||||
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);
|
||||
|
||||
// Get the metadata and the first cluster.
|
||||
nsTArray<nsTArray<uint8_t> > encodedBuf;
|
||||
writer.GetContainerData(&encodedBuf, 0);
|
||||
// Flatten the encodedBuf.
|
||||
WebMioData ioData;
|
||||
ioData.offset = 0;
|
||||
for(uint32_t i = 0 ; i < encodedBuf.Length(); ++i) {
|
||||
ioData.data.AppendElements(encodedBuf[i]);
|
||||
}
|
||||
|
||||
// Use nestegg to verify the information in metadata.
|
||||
nestegg* context = nullptr;
|
||||
nestegg_io io;
|
||||
io.read = webm_read;
|
||||
io.seek = webm_seek;
|
||||
io.tell = webm_tell;
|
||||
io.userdata = static_cast<void*>(&ioData);
|
||||
int rv = nestegg_init(&context, io, nullptr, -1);
|
||||
EXPECT_EQ(rv, 0);
|
||||
unsigned int ntracks = 0;
|
||||
rv = nestegg_track_count(context, &ntracks);
|
||||
EXPECT_EQ(rv, 0);
|
||||
EXPECT_EQ(ntracks, (unsigned int)2);
|
||||
for (unsigned int track = 0; track < ntracks; ++track) {
|
||||
int id = nestegg_track_codec_id(context, track);
|
||||
EXPECT_NE(id, -1);
|
||||
int type = nestegg_track_type(context, track);
|
||||
if (type == NESTEGG_TRACK_VIDEO) {
|
||||
nestegg_video_params params;
|
||||
rv = nestegg_track_video_params(context, track, ¶ms);
|
||||
EXPECT_EQ(rv, 0);
|
||||
EXPECT_EQ(width, static_cast<int32_t>(params.width));
|
||||
EXPECT_EQ(height, static_cast<int32_t>(params.height));
|
||||
EXPECT_EQ(displayWidth, static_cast<int32_t>(params.display_width));
|
||||
EXPECT_EQ(displayHeight, static_cast<int32_t>(params.display_height));
|
||||
} else if (type == NESTEGG_TRACK_AUDIO) {
|
||||
nestegg_audio_params params;
|
||||
rv = nestegg_track_audio_params(context, track, ¶ms);
|
||||
EXPECT_EQ(rv, 0);
|
||||
EXPECT_EQ(channel, static_cast<int>(params.channels));
|
||||
EXPECT_EQ(static_cast<double>(sampleRate), params.rate);
|
||||
}
|
||||
}
|
||||
if (context) {
|
||||
nestegg_destroy(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ LIBRARY_NAME = 'media_gtest'
|
||||
UNIFIED_SOURCES += [
|
||||
'TestAudioCompactor.cpp',
|
||||
'TestTrackEncoder.cpp',
|
||||
'TestVideoSegment.cpp'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WEBM_ENCODER']:
|
||||
|
@ -66,15 +66,22 @@ nsresult MediaOmxReader::Init(MediaDecoderReader* aCloneDonor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void MediaOmxReader::Shutdown()
|
||||
void MediaOmxReader::ReleaseDecoder()
|
||||
{
|
||||
ReleaseMediaResources();
|
||||
if (mOmxDecoder.get()) {
|
||||
mOmxDecoder->ReleaseDecoder();
|
||||
}
|
||||
mOmxDecoder.clear();
|
||||
}
|
||||
|
||||
void MediaOmxReader::Shutdown()
|
||||
{
|
||||
ReleaseMediaResources();
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &MediaOmxReader::ReleaseDecoder);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
bool MediaOmxReader::IsWaitingMediaResources()
|
||||
{
|
||||
if (!mOmxDecoder.get()) {
|
||||
|
@ -104,6 +104,8 @@ public:
|
||||
// ANDROID_VERSION < 19
|
||||
void CheckAudioOffload();
|
||||
#endif
|
||||
|
||||
void ReleaseDecoder();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -4,17 +4,29 @@
|
||||
navigator.mozGetUserMedia({audio: true}, function(stream) {
|
||||
stream.getAudioTracks()[0].enabled = false;
|
||||
var testAudio = document.getElementById('testAudio');
|
||||
// temporary log for bug 1031137.
|
||||
["abort", "canplay", "canplaythrough", "durationchange", "emptied", "ended",
|
||||
"error", "loadeddata", "loadedmetadata", "loadstart", "pause", "play",
|
||||
"playing", "progress", "ratechange", "seeked", "seeking", "stalled", "suspend",
|
||||
"timeupdate", "volumechange", "waiting"].forEach(function(v) {
|
||||
testAudio.addEventListener(v, function() {
|
||||
dump("event received: " + v + "\n");
|
||||
});
|
||||
});
|
||||
|
||||
// Wait some time for good measure
|
||||
var eventReceived = 0;
|
||||
testAudio.addEventListener("timeupdate", function() {
|
||||
dump("timeupdate received (index:" + eventReceived + ")\n");
|
||||
if (++eventReceived == 3) {
|
||||
document.querySelector("html").className = "";
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
testAudio.mozSrcObject = stream;
|
||||
testAudio.play();
|
||||
}, function(err) {
|
||||
console.log(err);
|
||||
dump(err + "\n");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -879,12 +879,8 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
|
||||
wheelEvent.deltaMode = aDeltaMode;
|
||||
wheelEvent.isMomentum =
|
||||
(aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
|
||||
wheelEvent.isPixelOnlyDevice =
|
||||
(aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
|
||||
NS_ENSURE_TRUE(
|
||||
!wheelEvent.isPixelOnlyDevice ||
|
||||
aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
wheelEvent.mIsNoLineOrPageDelta =
|
||||
(aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0;
|
||||
wheelEvent.customizedByUserPrefs =
|
||||
(aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
|
||||
wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
|
||||
|
@ -248,6 +248,20 @@ CameraControlImpl::OnPreviewStateChange(CameraControlListener::PreviewState aNew
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraControlImpl::OnRateLimitPreview(bool aLimit)
|
||||
{
|
||||
// This function runs on neither the Main Thread nor the Camera Thread.
|
||||
RwLockAutoEnterRead lock(mListenerLock);
|
||||
|
||||
DOM_CAMERA_LOGI("OnRateLimitPreview: %d\n", aLimit);
|
||||
|
||||
for (uint32_t i = 0; i < mListeners.Length(); ++i) {
|
||||
CameraControlListener* l = mListeners[i];
|
||||
l->OnRateLimitPreview(aLimit);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
|
@ -67,6 +67,7 @@ protected:
|
||||
void OnFacesDetected(const nsTArray<Face>& aFaces);
|
||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
|
||||
|
||||
void OnRateLimitPreview(bool aLimit);
|
||||
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
|
||||
void OnRecorderStateChange(CameraControlListener::RecorderState aState,
|
||||
int32_t aStatus = -1, int32_t aTrackNumber = -1);
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) { }
|
||||
|
||||
virtual void OnShutter() { }
|
||||
virtual void OnRateLimitPreview(bool aLimit) { }
|
||||
virtual bool OnNewPreviewFrame(layers::Image* aFrame, uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
return false;
|
||||
|
@ -4,6 +4,15 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CameraPreviewMediaStream.h"
|
||||
#include "CameraCommon.h"
|
||||
|
||||
/**
|
||||
* Maximum number of outstanding invalidates before we start to drop frames;
|
||||
* if we hit this threshold, it is an indicator that the main thread is
|
||||
* either very busy or the device is busy elsewhere (e.g. encoding or
|
||||
* persisting video data).
|
||||
*/
|
||||
#define MAX_INVALIDATE_PENDING 4
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::dom;
|
||||
@ -13,7 +22,9 @@ namespace mozilla {
|
||||
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
|
||||
: MediaStream(aWrapper)
|
||||
, mMutex("mozilla::camera::CameraPreviewMediaStream")
|
||||
, mFrameCallback(nullptr)
|
||||
, mInvalidatePending(0)
|
||||
, mDiscardedFrames(0)
|
||||
, mRateLimit(false)
|
||||
{
|
||||
SetGraphImpl(MediaStreamGraph::GetInstance());
|
||||
mIsConsumed = false;
|
||||
@ -103,22 +114,53 @@ CameraPreviewMediaStream::Destroy()
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
|
||||
CameraPreviewMediaStream::Invalidate()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
--mInvalidatePending;
|
||||
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
VideoFrameContainer* output = mVideoOutputs[i];
|
||||
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(output, &VideoFrameContainer::Invalidate);
|
||||
NS_DispatchToMainThread(event);
|
||||
output->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::RateLimit(bool aLimit)
|
||||
{
|
||||
mRateLimit = aLimit;
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (mInvalidatePending > 0) {
|
||||
if (mRateLimit || mInvalidatePending > MAX_INVALIDATE_PENDING) {
|
||||
++mDiscardedFrames;
|
||||
DOM_CAMERA_LOGW("Discard preview frame %d, %d invalidation(s) pending",
|
||||
mDiscardedFrames, mInvalidatePending);
|
||||
return;
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGI("Update preview frame, %d invalidation(s) pending",
|
||||
mInvalidatePending);
|
||||
}
|
||||
mDiscardedFrames = 0;
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
VideoFrameContainer* output = mVideoOutputs[i];
|
||||
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
|
||||
}
|
||||
|
||||
++mInvalidatePending;
|
||||
}
|
||||
|
||||
if (mFrameCallback) {
|
||||
mFrameCallback->OnNewFrame(aIntrinsicSize, aImage);
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &CameraPreviewMediaStream::Invalidate);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
@ -126,7 +168,7 @@ CameraPreviewMediaStream::ClearCurrentFrame()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
|
||||
VideoFrameContainer* output = mVideoOutputs[i];
|
||||
output->ClearCurrentFrame();
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
|
@ -11,13 +11,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class CameraPreviewFrameCallback {
|
||||
public:
|
||||
virtual void OnNewFrame(const gfxIntSize& aIntrinsicSize, layers::Image* aImage) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a stream for camere preview.
|
||||
* This is a stream for camera preview.
|
||||
*
|
||||
* XXX It is a temporary fix of SourceMediaStream.
|
||||
* A camera preview requests no delay and no buffering stream.
|
||||
@ -40,20 +35,21 @@ public:
|
||||
virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
|
||||
virtual void Destroy();
|
||||
|
||||
void Invalidate();
|
||||
|
||||
// Call these on any thread.
|
||||
void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage);
|
||||
void ClearCurrentFrame();
|
||||
|
||||
void SetFrameCallback(CameraPreviewFrameCallback* aCallback) {
|
||||
mFrameCallback = aCallback;
|
||||
}
|
||||
void RateLimit(bool aLimit);
|
||||
|
||||
protected:
|
||||
// mMutex protects all the class' fields.
|
||||
// This class is not registered to MediaStreamGraph.
|
||||
// It needs to protect all the fields.
|
||||
Mutex mMutex;
|
||||
CameraPreviewFrameCallback* mFrameCallback;
|
||||
int32_t mInvalidatePending;
|
||||
uint32_t mDiscardedFrames;
|
||||
bool mRateLimit;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ protected:
|
||||
DOMCameraControlListener* mListener;
|
||||
|
||||
// our viewfinder stream
|
||||
CameraPreviewMediaStream* mInput;
|
||||
nsRefPtr<CameraPreviewMediaStream> mInput;
|
||||
|
||||
// set once when this object is created
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
|
@ -287,6 +287,12 @@ DOMCameraControlListener::OnShutter()
|
||||
NS_DispatchToMainThread(new Callback(mDOMCameraControl));
|
||||
}
|
||||
|
||||
void
|
||||
DOMCameraControlListener::OnRateLimitPreview(bool aLimit)
|
||||
{
|
||||
mStream->RateLimit(aLimit);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) MOZ_OVERRIDE;
|
||||
virtual void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration) MOZ_OVERRIDE;
|
||||
virtual void OnShutter() MOZ_OVERRIDE;
|
||||
virtual void OnRateLimitPreview(bool aLimit) MOZ_OVERRIDE;
|
||||
virtual bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) MOZ_OVERRIDE;
|
||||
virtual void OnUserError(UserContext aContext, nsresult aError) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -1682,6 +1682,12 @@ nsGonkCameraControl::GetRecorderProfileManagerImpl()
|
||||
return profileMgr.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsGonkCameraControl::OnRateLimitPreview(bool aLimit)
|
||||
{
|
||||
CameraControlImpl::OnRateLimitPreview(aLimit);
|
||||
}
|
||||
|
||||
void
|
||||
nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
||||
{
|
||||
@ -1744,6 +1750,12 @@ OnFacesDetected(nsGonkCameraControl* gc, camera_frame_metadata_t* aMetaData)
|
||||
gc->OnFacesDetected(aMetaData);
|
||||
}
|
||||
|
||||
void
|
||||
OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit)
|
||||
{
|
||||
gc->OnRateLimitPreview(aLimit);
|
||||
}
|
||||
|
||||
void
|
||||
OnNewPreviewFrame(nsGonkCameraControl* gc, layers::TextureClient* aBuffer)
|
||||
{
|
||||
|
@ -52,10 +52,11 @@ public:
|
||||
void OnFacesDetected(camera_frame_metadata_t* aMetaData);
|
||||
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength);
|
||||
void OnTakePictureError();
|
||||
void OnRateLimitPreview(bool aLimit);
|
||||
void OnNewPreviewFrame(layers::TextureClient* aBuffer);
|
||||
void OnRecorderEvent(int msg, int ext1, int ext2);
|
||||
void OnSystemError(CameraControlListener::SystemContext aWhere, nsresult aError);
|
||||
|
||||
|
||||
// See ICameraControl.h for getter/setter return values.
|
||||
virtual nsresult Set(uint32_t aKey, const nsAString& aValue) MOZ_OVERRIDE;
|
||||
virtual nsresult Get(uint32_t aKey, nsAString& aValue) MOZ_OVERRIDE;
|
||||
@ -84,6 +85,7 @@ public:
|
||||
protected:
|
||||
~nsGonkCameraControl();
|
||||
|
||||
using CameraControlImpl::OnRateLimitPreview;
|
||||
using CameraControlImpl::OnNewPreviewFrame;
|
||||
using CameraControlImpl::OnAutoFocusComplete;
|
||||
using CameraControlImpl::OnFacesDetected;
|
||||
@ -178,6 +180,7 @@ private:
|
||||
};
|
||||
|
||||
// camera driver callbacks
|
||||
void OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit);
|
||||
void OnTakePictureComplete(nsGonkCameraControl* gc, uint8_t* aData, uint32_t aLength);
|
||||
void OnTakePictureError(nsGonkCameraControl* gc);
|
||||
void OnAutoFocusComplete(nsGonkCameraControl* gc, bool aSuccess);
|
||||
|
@ -44,6 +44,12 @@ GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, ui
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
|
||||
}
|
||||
|
||||
void
|
||||
GonkCameraHardware::OnRateLimitPreview(bool aLimit)
|
||||
{
|
||||
::OnRateLimitPreview(mTarget, aLimit);
|
||||
}
|
||||
|
||||
void
|
||||
GonkCameraHardware::OnNewFrame()
|
||||
{
|
||||
|
@ -55,6 +55,8 @@ public:
|
||||
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
|
||||
virtual void Close();
|
||||
|
||||
virtual void OnRateLimitPreview(bool aLimit);
|
||||
|
||||
// derived from GonkNativeWindowNewFrameCallback
|
||||
virtual void OnNewFrame() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -170,6 +170,7 @@ GonkCameraSource::GonkCameraSource(
|
||||
mStarted(false),
|
||||
mNumFramesEncoded(0),
|
||||
mTimeBetweenFrameCaptureUs(0),
|
||||
mRateLimit(false),
|
||||
mFirstFrameTimeUs(0),
|
||||
mNumFramesDropped(0),
|
||||
mNumGlitches(0),
|
||||
@ -589,6 +590,10 @@ status_t GonkCameraSource::reset() {
|
||||
}
|
||||
}
|
||||
stopCameraRecording();
|
||||
if (mRateLimit) {
|
||||
mRateLimit = false;
|
||||
mCameraHw->OnRateLimitPreview(false);
|
||||
}
|
||||
releaseCamera();
|
||||
|
||||
if (mCollectStats) {
|
||||
@ -692,51 +697,65 @@ status_t GonkCameraSource::read(
|
||||
|
||||
void GonkCameraSource::dataCallbackTimestamp(int64_t timestampUs,
|
||||
int32_t msgType, const sp<IMemory> &data) {
|
||||
bool rateLimit;
|
||||
bool prevRateLimit;
|
||||
CS_LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
|
||||
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNumFramesReceived > 0) {
|
||||
CHECK(timestampUs > mLastFrameTimestampUs);
|
||||
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
|
||||
++mNumGlitches;
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
|
||||
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// May need to skip frame or modify timestamp. Currently implemented
|
||||
// by the subclass CameraSourceTimeLapse.
|
||||
if (skipCurrentFrame(timestampUs)) {
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
}
|
||||
|
||||
mLastFrameTimestampUs = timestampUs;
|
||||
if (mNumFramesReceived == 0) {
|
||||
mFirstFrameTimeUs = timestampUs;
|
||||
// Initial delay
|
||||
if (mStartTimeUs > 0) {
|
||||
if (timestampUs < mStartTimeUs) {
|
||||
// Frame was captured before recording was started
|
||||
// Drop it without updating the statistical data.
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
if (mNumFramesReceived > 0) {
|
||||
CHECK(timestampUs > mLastFrameTimestampUs);
|
||||
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
|
||||
++mNumGlitches;
|
||||
}
|
||||
mStartTimeUs = timestampUs - mStartTimeUs;
|
||||
}
|
||||
}
|
||||
++mNumFramesReceived;
|
||||
|
||||
CHECK(data != NULL && data->size() > 0);
|
||||
mFramesReceived.push_back(data);
|
||||
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
|
||||
mFrameTimes.push_back(timeUs);
|
||||
CS_LOGV("initial delay: %lld, current time stamp: %lld",
|
||||
mStartTimeUs, timeUs);
|
||||
mFrameAvailableCondition.signal();
|
||||
// May need to skip frame or modify timestamp. Currently implemented
|
||||
// by the subclass CameraSourceTimeLapse.
|
||||
if (skipCurrentFrame(timestampUs)) {
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
}
|
||||
|
||||
mLastFrameTimestampUs = timestampUs;
|
||||
if (mNumFramesReceived == 0) {
|
||||
mFirstFrameTimeUs = timestampUs;
|
||||
// Initial delay
|
||||
if (mStartTimeUs > 0) {
|
||||
if (timestampUs < mStartTimeUs) {
|
||||
// Frame was captured before recording was started
|
||||
// Drop it without updating the statistical data.
|
||||
releaseOneRecordingFrame(data);
|
||||
return;
|
||||
}
|
||||
mStartTimeUs = timestampUs - mStartTimeUs;
|
||||
}
|
||||
}
|
||||
++mNumFramesReceived;
|
||||
|
||||
// If a backlog is building up in the receive queue, we are likely
|
||||
// resource constrained and we need to throttle
|
||||
prevRateLimit = mRateLimit;
|
||||
rateLimit = mFramesReceived.empty();
|
||||
mRateLimit = rateLimit;
|
||||
|
||||
CHECK(data != NULL && data->size() > 0);
|
||||
mFramesReceived.push_back(data);
|
||||
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
|
||||
mFrameTimes.push_back(timeUs);
|
||||
CS_LOGV("initial delay: %lld, current time stamp: %lld",
|
||||
mStartTimeUs, timeUs);
|
||||
mFrameAvailableCondition.signal();
|
||||
}
|
||||
|
||||
if(prevRateLimit != rateLimit) {
|
||||
mCameraHw->OnRateLimitPreview(rateLimit);
|
||||
}
|
||||
}
|
||||
|
||||
bool GonkCameraSource::isMetaDataStoredInVideoBuffers() const {
|
||||
|
@ -127,6 +127,7 @@ private:
|
||||
List<sp<IMemory> > mFramesReceived;
|
||||
List<sp<IMemory> > mFramesBeingEncoded;
|
||||
List<int64_t> mFrameTimes;
|
||||
bool mRateLimit;
|
||||
|
||||
int64_t mFirstFrameTimeUs;
|
||||
int32_t mNumFramesDropped;
|
||||
|
@ -1397,7 +1397,7 @@ private:
|
||||
default: return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
SECKEYPublicKey* pubKey;
|
||||
SECKEYPublicKey* pubKey = nullptr;
|
||||
mPrivateKey = PK11_GenerateKeyPair(slot.get(), mMechanism, param, &pubKey,
|
||||
PR_FALSE, PR_FALSE, nullptr);
|
||||
mPublicKey = pubKey;
|
||||
|
@ -349,7 +349,8 @@ private:
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsString mLastStatus;
|
||||
void DispatchMountChangeEvent(nsAString& aVolumeStatus);
|
||||
void DispatchStatusChangeEvent(nsAString& aStatus);
|
||||
void DispatchStorageStatusChangeEvent(nsAString& aVolumeStatus);
|
||||
#endif
|
||||
|
||||
// nsIDOMDeviceStorage.type
|
||||
|
@ -4194,14 +4194,32 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void
|
||||
nsDOMDeviceStorage::DispatchMountChangeEvent(nsAString& aVolumeStatus)
|
||||
nsDOMDeviceStorage::DispatchStatusChangeEvent(nsAString& aStatus)
|
||||
{
|
||||
if (aVolumeStatus == mLastStatus) {
|
||||
if (aStatus == mLastStatus) {
|
||||
// We've already sent this status, don't bother sending it again.
|
||||
return;
|
||||
}
|
||||
mLastStatus = aVolumeStatus;
|
||||
mLastStatus = aStatus;
|
||||
|
||||
DeviceStorageChangeEventInit init;
|
||||
init.mBubbles = true;
|
||||
init.mCancelable = false;
|
||||
init.mPath = mStorageName;
|
||||
init.mReason = aStatus;
|
||||
|
||||
nsRefPtr<DeviceStorageChangeEvent> event =
|
||||
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
|
||||
init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
bool ignore;
|
||||
DispatchEvent(event, &ignore);
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDeviceStorage::DispatchStorageStatusChangeEvent(nsAString& aVolumeStatus)
|
||||
{
|
||||
DeviceStorageChangeEventInit init;
|
||||
init.mBubbles = true;
|
||||
init.mCancelable = false;
|
||||
@ -4209,7 +4227,7 @@ nsDOMDeviceStorage::DispatchMountChangeEvent(nsAString& aVolumeStatus)
|
||||
init.mReason = aVolumeStatus;
|
||||
|
||||
nsRefPtr<DeviceStorageChangeEvent> event =
|
||||
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
|
||||
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("storage-state-change"),
|
||||
init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
@ -4268,9 +4286,15 @@ nsDOMDeviceStorage::Observe(nsISupports *aSubject,
|
||||
}
|
||||
|
||||
DeviceStorageFile dsf(mStorageType, mStorageName);
|
||||
nsString status;
|
||||
nsString status, storageStatus;
|
||||
|
||||
// Get Status (one of "available, unavailable, shared")
|
||||
dsf.GetStatus(status);
|
||||
DispatchMountChangeEvent(status);
|
||||
DispatchStatusChangeEvent(status);
|
||||
|
||||
// Get real volume status (defined in dom/system/gonk/nsIVolume.idl)
|
||||
dsf.GetStorageStatus(storageStatus);
|
||||
DispatchStorageStatusChangeEvent(storageStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -5096,7 +5096,7 @@ EventStateManager::DeltaAccumulator::InitLineOrPageDelta(
|
||||
if (IsInTransaction()) {
|
||||
// If wheel event type is changed, reset the values.
|
||||
if (mHandlingDeltaMode != aEvent->deltaMode ||
|
||||
mHandlingPixelOnlyDevice != aEvent->isPixelOnlyDevice) {
|
||||
mIsNoLineOrPageDeltaDevice != aEvent->mIsNoLineOrPageDelta) {
|
||||
Reset();
|
||||
} else {
|
||||
// If the delta direction is changed, we should reset only the
|
||||
@ -5111,13 +5111,12 @@ EventStateManager::DeltaAccumulator::InitLineOrPageDelta(
|
||||
}
|
||||
|
||||
mHandlingDeltaMode = aEvent->deltaMode;
|
||||
mHandlingPixelOnlyDevice = aEvent->isPixelOnlyDevice;
|
||||
mIsNoLineOrPageDeltaDevice = aEvent->mIsNoLineOrPageDelta;
|
||||
|
||||
// If it's handling neither pixel scroll mode for pixel only device nor
|
||||
// delta values multiplied by prefs, we must not modify lineOrPageDelta
|
||||
// If it's handling neither a device that does not provide line or page deltas
|
||||
// nor delta values multiplied by prefs, we must not modify lineOrPageDelta
|
||||
// values.
|
||||
if (!(mHandlingDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL &&
|
||||
mHandlingPixelOnlyDevice) &&
|
||||
if (!mIsNoLineOrPageDeltaDevice &&
|
||||
!EventStateManager::WheelPrefs::GetInstance()->
|
||||
NeedToComputeLineOrPageDelta(aEvent)) {
|
||||
// Set the delta values to mX and mY. They would be used when above block
|
||||
@ -5178,7 +5177,7 @@ EventStateManager::DeltaAccumulator::Reset()
|
||||
mX = mY = 0.0;
|
||||
mPendingScrollAmountX = mPendingScrollAmountY = 0.0;
|
||||
mHandlingDeltaMode = UINT32_MAX;
|
||||
mHandlingPixelOnlyDevice = false;
|
||||
mIsNoLineOrPageDeltaDevice = false;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
|
@ -702,7 +702,7 @@ protected:
|
||||
private:
|
||||
DeltaAccumulator() :
|
||||
mX(0.0), mY(0.0), mPendingScrollAmountX(0.0), mPendingScrollAmountY(0.0),
|
||||
mHandlingDeltaMode(UINT32_MAX), mHandlingPixelOnlyDevice(false)
|
||||
mHandlingDeltaMode(UINT32_MAX), mIsNoLineOrPageDeltaDevice(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -718,7 +718,7 @@ protected:
|
||||
TimeStamp mLastTime;
|
||||
|
||||
uint32_t mHandlingDeltaMode;
|
||||
bool mHandlingPixelOnlyDevice;
|
||||
bool mIsNoLineOrPageDeltaDevice;
|
||||
|
||||
static DeltaAccumulator* sInstance;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -104,6 +104,7 @@ function MozInputMethod() { }
|
||||
|
||||
MozInputMethod.prototype = {
|
||||
_inputcontext: null,
|
||||
_wrappedInputContext: null,
|
||||
_layouts: {},
|
||||
_window: null,
|
||||
_isSystem: false,
|
||||
@ -211,7 +212,7 @@ MozInputMethod.prototype = {
|
||||
if (!WindowMap.isActive(this._window)) {
|
||||
return null;
|
||||
}
|
||||
return this._inputcontext;
|
||||
return this._wrappedInputContext;
|
||||
},
|
||||
|
||||
set oninputcontextchange(handler) {
|
||||
@ -226,6 +227,7 @@ MozInputMethod.prototype = {
|
||||
if (this._inputcontext) {
|
||||
this._inputcontext.destroy();
|
||||
this._inputcontext = null;
|
||||
this._wrappedInputContext = null;
|
||||
this._mgmt._supportsSwitching = false;
|
||||
}
|
||||
|
||||
@ -236,6 +238,10 @@ MozInputMethod.prototype = {
|
||||
|
||||
this._inputcontext = new MozInputContext(data);
|
||||
this._inputcontext.init(this._window);
|
||||
// inputcontext will be exposed as a WebIDL object. Create its
|
||||
// content-side object explicitly to avoid Bug 1001325.
|
||||
this._wrappedInputContext =
|
||||
this._window.MozInputContext._create(this._window, this._inputcontext);
|
||||
}
|
||||
|
||||
let event = new this._window.Event("inputcontextchange",
|
||||
|
@ -48,7 +48,7 @@ interface nsIRunnable;
|
||||
interface nsICompositionStringSynthesizer;
|
||||
interface nsITranslationNodeList;
|
||||
|
||||
[scriptable, uuid(6f10cbf8-bd4e-4c56-8a5a-35641efcf286)]
|
||||
[scriptable, uuid(46e3f206-9a8f-4d66-8248-7ec6a37de45a)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -468,9 +468,11 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* scroll.
|
||||
* @param aOptions Set following flags.
|
||||
*/
|
||||
const unsigned long WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE = 0x0001;
|
||||
const unsigned long WHEEL_EVENT_CAUSED_BY_MOMENTUM = 0x0002;
|
||||
const unsigned long WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS = 0x0004;
|
||||
const unsigned long WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE = 0x0001;
|
||||
// @deprecated Use WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE.
|
||||
const unsigned long WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE = 0x0001;
|
||||
const unsigned long WHEEL_EVENT_CAUSED_BY_MOMENTUM = 0x0002;
|
||||
const unsigned long WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS = 0x0004;
|
||||
// If any of the following flags is specified this method will throw an
|
||||
// exception in case the relevant overflowDelta has an unexpected value.
|
||||
const unsigned long WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO = 0x0010;
|
||||
|
@ -12,8 +12,15 @@ function peerReadyCb(evt) {
|
||||
let peer = nfc.getNFCPeer(evt.detail);
|
||||
ok(peer instanceof MozNFCPeer, "Should get a NFCPeer object.");
|
||||
|
||||
// reset callback and NFC Hardware.
|
||||
// reset callback.
|
||||
nfc.onpeerready = null;
|
||||
emulator.deactivate();
|
||||
}
|
||||
|
||||
function peerLostCb() {
|
||||
log("peerLostCb called");
|
||||
ok(true);
|
||||
nfc.onpeerlost = null;
|
||||
toggleNFC(false).then(runNextTest);
|
||||
}
|
||||
|
||||
@ -23,6 +30,7 @@ function handleTechnologyDiscoveredRE0(msg) {
|
||||
is(msg.techList[0], "P2P", "check for correct tech type");
|
||||
|
||||
nfc.onpeerready = peerReadyCb;
|
||||
nfc.onpeerlost = peerLostCb;
|
||||
|
||||
let request = nfc.checkP2PRegistration(MANIFEST_URL);
|
||||
request.onsuccess = function (evt) {
|
||||
|
@ -286,7 +286,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
||||
isRegisteredP2PTarget: function isRegisteredP2PTarget(appId, event) {
|
||||
let targetInfo = this.peerTargetsMap[appId];
|
||||
// Check if it is a registered target for the 'event'
|
||||
return ((targetInfo != null) && (targetInfo.event & event !== 0));
|
||||
return ((targetInfo != null) && ((targetInfo.event & event) !== 0));
|
||||
},
|
||||
|
||||
notifyPeerEvent: function notifyPeerEvent(appId, event) {
|
||||
@ -527,7 +527,7 @@ Nfc.prototype = {
|
||||
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-tech-lost", message);
|
||||
// Notify 'PeerLost' to appropriate registered target, if any
|
||||
gMessageManager.notifyPeerEvent(this.currentPeerAppId, NFC.NFC_PEER_EVENT_LOST);
|
||||
gMessageManager.notifyPeerEvent(gMessageManager.currentPeerAppId, NFC.NFC_PEER_EVENT_LOST);
|
||||
delete this.sessionTokenMap[this._currentSessionId];
|
||||
this._currentSessionId = null;
|
||||
this.currentPeerAppId = null;
|
||||
|
@ -315,7 +315,7 @@ interface MozWifiManager : EventTarget {
|
||||
* An event listener that is called with information about the signal
|
||||
* strength and link speed every 5 seconds.
|
||||
*/
|
||||
attribute EventHandler onconnectionInfoUpdate;
|
||||
attribute EventHandler onconnectioninfoupdate;
|
||||
|
||||
/**
|
||||
* These two events fire when the wifi system is brought online or taken
|
||||
@ -328,5 +328,5 @@ interface MozWifiManager : EventTarget {
|
||||
* An event listener that is called with information about the number
|
||||
* of wifi stations connected to wifi hotspot every 5 seconds.
|
||||
*/
|
||||
attribute EventHandler onstationInfoUpdate;
|
||||
attribute EventHandler onstationinfoupdate;
|
||||
};
|
||||
|
@ -77,10 +77,10 @@ MozWifiCapabilities.prototype = {
|
||||
|
||||
function DOMWifiManager() {
|
||||
this.defineEventHandlerGetterSetter("onstatuschange");
|
||||
this.defineEventHandlerGetterSetter("onconnectionInfoUpdate");
|
||||
this.defineEventHandlerGetterSetter("onconnectioninfoupdate");
|
||||
this.defineEventHandlerGetterSetter("onenabled");
|
||||
this.defineEventHandlerGetterSetter("ondisabled");
|
||||
this.defineEventHandlerGetterSetter("onstationInfoUpdate");
|
||||
this.defineEventHandlerGetterSetter("onstationinfoupdate");
|
||||
}
|
||||
|
||||
DOMWifiManager.prototype = {
|
||||
@ -117,9 +117,9 @@ DOMWifiManager.prototype = {
|
||||
"WifiManager:onconnecting", "WifiManager:onassociate",
|
||||
"WifiManager:onconnect", "WifiManager:ondisconnect",
|
||||
"WifiManager:onwpstimeout", "WifiManager:onwpsfail",
|
||||
"WifiManager:onwpsoverlap", "WifiManager:connectionInfoUpdate",
|
||||
"WifiManager:onwpsoverlap", "WifiManager:connectioninfoupdate",
|
||||
"WifiManager:onauthenticating", "WifiManager:onconnectingfailed",
|
||||
"WifiManager:stationInfoUpdate"];
|
||||
"WifiManager:stationinfoupdate"];
|
||||
this.initDOMRequestHelper(aWindow, messages);
|
||||
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
|
||||
|
||||
@ -379,7 +379,7 @@ DOMWifiManager.prototype = {
|
||||
this._fireStatusChangeEvent();
|
||||
break;
|
||||
|
||||
case "WifiManager:connectionInfoUpdate":
|
||||
case "WifiManager:connectioninfoupdate":
|
||||
this._lastConnectionInfo = this._convertConnectionInfo(msg);
|
||||
this._fireConnectionInfoUpdate(msg);
|
||||
break;
|
||||
@ -394,7 +394,7 @@ DOMWifiManager.prototype = {
|
||||
this._connectionStatus = "authenticating";
|
||||
this._fireStatusChangeEvent();
|
||||
break;
|
||||
case "WifiManager:stationInfoUpdate":
|
||||
case "WifiManager:stationinfoupdate":
|
||||
this._stationNumber = msg.station;
|
||||
this._fireStationInfoUpdate(msg);
|
||||
break;
|
||||
@ -426,7 +426,7 @@ DOMWifiManager.prototype = {
|
||||
},
|
||||
|
||||
_fireStationInfoUpdate: function onStationInfoUpdate(info) {
|
||||
var evt = new this._window.MozWifiStationInfoEvent("stationInfoUpdate",
|
||||
var evt = new this._window.MozWifiStationInfoEvent("stationinfoupdate",
|
||||
{ station: this._stationNumber}
|
||||
);
|
||||
this.__DOM_IMPL__.dispatchEvent(evt);
|
||||
|
@ -1112,7 +1112,7 @@ var WifiManager = (function() {
|
||||
|
||||
function getWifiHotspotStatus() {
|
||||
wifiCommand.hostapdGetStations(function(result) {
|
||||
notify("stationInfoUpdate", {station: result});
|
||||
notify("stationinfoupdate", {station: result});
|
||||
});
|
||||
}
|
||||
|
||||
@ -2324,8 +2324,8 @@ function WifiWorker() {
|
||||
});
|
||||
};
|
||||
|
||||
WifiManager.onstationInfoUpdate = function() {
|
||||
self._fireEvent("stationInfoUpdate", { station: this.station });
|
||||
WifiManager.onstationinfoupdate = function() {
|
||||
self._fireEvent("stationinfoupdate", { station: this.station });
|
||||
};
|
||||
|
||||
// Read the 'wifi.enabled' setting in order to start with a known
|
||||
@ -2511,8 +2511,8 @@ WifiWorker.prototype = {
|
||||
}
|
||||
|
||||
self._lastConnectionInfo = info;
|
||||
debug("Firing connectionInfoUpdate: " + uneval(info));
|
||||
self._fireEvent("connectionInfoUpdate", info);
|
||||
debug("Firing connectioninfoupdate: " + uneval(info));
|
||||
self._fireEvent("connectioninfoupdate", info);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -954,6 +954,7 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
int *tx, int *ty)
|
||||
{
|
||||
const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
|
||||
cairo_rectangle_int_t surface_extents;
|
||||
cairo_bool_t need_translate;
|
||||
cairo_surface_t *surface;
|
||||
cairo_clip_path_t *prev;
|
||||
@ -967,27 +968,36 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
}
|
||||
|
||||
clip_extents = &clip_path->extents;
|
||||
if (_cairo_surface_get_extents (target, &surface_extents))
|
||||
{
|
||||
_cairo_rectangle_intersect(&surface_extents, clip_extents);
|
||||
}
|
||||
else
|
||||
{
|
||||
surface_extents = *clip_extents;
|
||||
}
|
||||
|
||||
if (clip_path->surface != NULL &&
|
||||
clip_path->surface->backend == target->backend)
|
||||
{
|
||||
*tx = clip_extents->x;
|
||||
*ty = clip_extents->y;
|
||||
*tx = surface_extents.x;
|
||||
*ty = surface_extents.y;
|
||||
return clip_path->surface;
|
||||
}
|
||||
|
||||
surface = _cairo_surface_create_similar_scratch (target,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
clip_extents->width,
|
||||
clip_extents->height);
|
||||
surface_extents.width,
|
||||
surface_extents.height);
|
||||
if (surface == NULL) {
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
|
||||
clip_extents->width,
|
||||
clip_extents->height);
|
||||
surface_extents.width,
|
||||
surface_extents.height);
|
||||
}
|
||||
if (unlikely (surface->status))
|
||||
return surface;
|
||||
|
||||
need_translate = clip_extents->x | clip_extents->y;
|
||||
need_translate = surface_extents.x | surface_extents.y;
|
||||
if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
|
||||
clip_path->path.maybe_fill_region)
|
||||
{
|
||||
@ -1009,8 +1019,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (-clip_extents->x),
|
||||
_cairo_fixed_from_int (-clip_extents->y));
|
||||
_cairo_fixed_from_int (-surface_extents.x),
|
||||
_cairo_fixed_from_int (-surface_extents.y));
|
||||
}
|
||||
status = _cairo_surface_fill (surface,
|
||||
CAIRO_OPERATOR_ADD,
|
||||
@ -1022,8 +1032,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
NULL);
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (clip_extents->x),
|
||||
_cairo_fixed_from_int (clip_extents->y));
|
||||
_cairo_fixed_from_int (surface_extents.x),
|
||||
_cairo_fixed_from_int (surface_extents.y));
|
||||
}
|
||||
|
||||
if (unlikely (status))
|
||||
@ -1043,8 +1053,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
{
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&prev->path,
|
||||
_cairo_fixed_from_int (-clip_extents->x),
|
||||
_cairo_fixed_from_int (-clip_extents->y));
|
||||
_cairo_fixed_from_int (-surface_extents.x),
|
||||
_cairo_fixed_from_int (-surface_extents.y));
|
||||
}
|
||||
status = _cairo_surface_fill (surface,
|
||||
CAIRO_OPERATOR_IN,
|
||||
@ -1056,8 +1066,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
NULL);
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&prev->path,
|
||||
_cairo_fixed_from_int (clip_extents->x),
|
||||
_cairo_fixed_from_int (clip_extents->y));
|
||||
_cairo_fixed_from_int (surface_extents.x),
|
||||
_cairo_fixed_from_int (surface_extents.y));
|
||||
}
|
||||
|
||||
if (unlikely (status))
|
||||
@ -1077,8 +1087,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
_cairo_pattern_init_for_surface (&pattern, prev_surface);
|
||||
pattern.base.filter = CAIRO_FILTER_NEAREST;
|
||||
cairo_matrix_init_translate (&pattern.base.matrix,
|
||||
clip_extents->x - prev_tx,
|
||||
clip_extents->y - prev_ty);
|
||||
surface_extents.x - prev_tx,
|
||||
surface_extents.y - prev_ty);
|
||||
status = _cairo_surface_paint (surface,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
@ -1094,8 +1104,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
prev = prev->prev;
|
||||
}
|
||||
|
||||
*tx = clip_extents->x;
|
||||
*ty = clip_extents->y;
|
||||
*tx = surface_extents.x;
|
||||
*ty = surface_extents.y;
|
||||
cairo_surface_destroy (clip_path->surface);
|
||||
return clip_path->surface = surface;
|
||||
|
||||
|
@ -3565,9 +3565,11 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
|
||||
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
if (_cairo_operator_bounded_by_mask(op)) {
|
||||
_cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
|
||||
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (antialias != CAIRO_ANTIALIAS_NONE) {
|
||||
composite_spans_info_t info;
|
||||
|
@ -489,7 +489,7 @@ public:
|
||||
return false;
|
||||
|
||||
// then the image data
|
||||
if (mCompresseddata.get() && !WriteToStream(mCompresseddata.get(), mDatasize))
|
||||
if (mCompresseddata.get() && !WriteToStream(mCompresseddata, mDatasize))
|
||||
return false;
|
||||
|
||||
// then pad out to 4 bytes
|
||||
@ -518,12 +518,12 @@ private:
|
||||
mPacket.stride = aImage->Stride();
|
||||
mPacket.dataSize = aImage->GetSize().height * aImage->Stride();
|
||||
|
||||
mCompresseddata = std::auto_ptr<char>(
|
||||
(char*)moz_malloc(LZ4::maxCompressedSize(mPacket.dataSize)));
|
||||
mCompresseddata =
|
||||
new char[LZ4::maxCompressedSize(mPacket.dataSize)];
|
||||
if (mCompresseddata.get()) {
|
||||
int ndatasize = LZ4::compress((char*)aImage->GetData(),
|
||||
mPacket.dataSize,
|
||||
mCompresseddata.get());
|
||||
mCompresseddata);
|
||||
if (ndatasize > 0) {
|
||||
mDatasize = ndatasize;
|
||||
|
||||
@ -550,7 +550,7 @@ protected:
|
||||
|
||||
// Packet data
|
||||
DebugGLData::TexturePacket mPacket;
|
||||
std::auto_ptr<char> mCompresseddata;
|
||||
nsAutoArrayPtr<char> mCompresseddata;
|
||||
uint32_t mDatasize;
|
||||
};
|
||||
|
||||
@ -651,7 +651,7 @@ public:
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
while ((d = mList.popFirst()) != nullptr) {
|
||||
std::auto_ptr<DebugGLData> cleaner(d);
|
||||
nsAutoPtr<DebugGLData> cleaner(d);
|
||||
if (!d->Write()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"expect-hazards": 2
|
||||
"expect-hazards": 4
|
||||
}
|
||||
|
@ -419,6 +419,7 @@ void
|
||||
ForkJoinNursery::forwardFromTenured(ForkJoinNurseryCollectionTracer *trc)
|
||||
{
|
||||
JSObject *objs[ArenaCellCount];
|
||||
ArenaLists &lists = tenured_->arenas;
|
||||
for (size_t k=0; k < FINALIZE_LIMIT; k++) {
|
||||
AllocKind kind = (AllocKind)k;
|
||||
if (!IsFJNurseryAllocable(kind))
|
||||
@ -429,22 +430,21 @@ ForkJoinNursery::forwardFromTenured(ForkJoinNurseryCollectionTracer *trc)
|
||||
// handled.
|
||||
JS_ASSERT(kind <= FINALIZE_OBJECT_LAST);
|
||||
|
||||
// Clear the free list that we're currently allocating out of.
|
||||
lists.purge(kind);
|
||||
|
||||
// Since we only purge once, there must not currently be any partially
|
||||
// full arenas left to allocate out of, or we would break out early.
|
||||
JS_ASSERT(!lists.getArenaAfterCursor(kind));
|
||||
|
||||
ArenaIter ai;
|
||||
ai.init(const_cast<Allocator *>(tenured_), kind);
|
||||
for (; !ai.done(); ai.next()) {
|
||||
// Do the walk in two steps to avoid problems resulting from allocating
|
||||
// into the arena that's being walked: ArenaCellIter is not safe for that.
|
||||
// It can happen during evacuation.
|
||||
//
|
||||
// ArenaCellIterUnderFinalize requires any free list to be flushed into
|
||||
// its arena, and since we may allocate within traceObject() we must
|
||||
// purge before each arena scan. This is probably not very expensive,
|
||||
// it's constant work, and inlined.
|
||||
//
|
||||
if (isEvacuating_ && lists.arenaIsInUse(ai.get(), kind))
|
||||
break;
|
||||
// Use ArenaCellIterUnderFinalize, not ...UnderGC, because that side-steps
|
||||
// some assertions in the latter that are wrong for PJS collection.
|
||||
size_t numObjs = 0;
|
||||
tenured_->arenas.purge(kind);
|
||||
for (ArenaCellIterUnderFinalize i(ai.get()); !i.done(); i.next())
|
||||
objs[numObjs++] = i.get<JSObject>();
|
||||
for (size_t i=0; i < numObjs; i++)
|
||||
|
28
js/src/jit-test/tests/ion/bug1034400.js
Normal file
28
js/src/jit-test/tests/ion/bug1034400.js
Normal file
@ -0,0 +1,28 @@
|
||||
var countG = 0;
|
||||
function g() {
|
||||
switch(countG++) {
|
||||
case 0: return 42;
|
||||
case 1: return "yo";
|
||||
case 2: return {};
|
||||
}
|
||||
}
|
||||
|
||||
var countFault = 0;
|
||||
function uceFault() {
|
||||
if (countFault++ == 4)
|
||||
uceFault = function() { return true }
|
||||
return false;
|
||||
}
|
||||
|
||||
function f() {
|
||||
var x = !g();
|
||||
if (uceFault() || uceFault()) {
|
||||
assertEq(x, false);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
f();
|
||||
f();
|
||||
f();
|
@ -321,6 +321,40 @@ function rstring_length(i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_arguments_length_1 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arguments_length_1'));
|
||||
function rarguments_length_1(i) {
|
||||
var x = arguments.length;
|
||||
if (uceFault_arguments_length_1(i) || uceFault_arguments_length_1(i))
|
||||
assertEq(x, 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_arguments_length_3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arguments_length_3'));
|
||||
function rarguments_length_3(i) {
|
||||
var x = arguments.length;
|
||||
if (uceFault_arguments_length_3(i) || uceFault_arguments_length_3(i))
|
||||
assertEq(x, 3);
|
||||
return i;
|
||||
}
|
||||
|
||||
function ret_argumentsLength() { return arguments.length; }
|
||||
|
||||
var uceFault_inline_arguments_length_1 = eval(uneval(uceFault).replace('uceFault', 'uceFault_inline_arguments_length_1'));
|
||||
function rinline_arguments_length_1(i) {
|
||||
var x = ret_argumentsLength.apply(this, arguments);
|
||||
if (uceFault_inline_arguments_length_1(i) || uceFault_inline_arguments_length_1(i))
|
||||
assertEq(x, 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_inline_arguments_length_3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_inline_arguments_length_3'));
|
||||
function rinline_arguments_length_3(i) {
|
||||
var x = ret_argumentsLength.apply(this, arguments);
|
||||
if (uceFault_inline_arguments_length_3(i) || uceFault_inline_arguments_length_3(i))
|
||||
assertEq(x, 3);
|
||||
return i;
|
||||
}
|
||||
|
||||
var uceFault_floor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_floor_number'));
|
||||
function rfloor_number(i) {
|
||||
var x = Math.floor(i + 0.1111);
|
||||
@ -510,6 +544,10 @@ for (i = 0; i < 100; i++) {
|
||||
rconcat_string(i);
|
||||
rconcat_number(i);
|
||||
rstring_length(i);
|
||||
rarguments_length_1(i);
|
||||
rarguments_length_3(i, 0, 1);
|
||||
rinline_arguments_length_1(i);
|
||||
rinline_arguments_length_3(i, 0, 1);
|
||||
rfloor_number(i);
|
||||
rfloor_object(i);
|
||||
rround_number(i);
|
||||
|
@ -815,18 +815,18 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
public:
|
||||
class Func
|
||||
{
|
||||
PropertyName *name_;
|
||||
bool defined_;
|
||||
uint32_t srcOffset_;
|
||||
uint32_t endOffset_;
|
||||
Signature sig_;
|
||||
PropertyName *name_;
|
||||
Label *code_;
|
||||
unsigned compileTime_;
|
||||
uint32_t srcBegin_;
|
||||
uint32_t srcEnd_;
|
||||
uint32_t compileTime_;
|
||||
bool defined_;
|
||||
|
||||
public:
|
||||
Func(PropertyName *name, Signature &&sig, Label *code)
|
||||
: name_(name), defined_(false), srcOffset_(0), endOffset_(0), sig_(Move(sig)),
|
||||
code_(code), compileTime_(0)
|
||||
: sig_(Move(sig)), name_(name), code_(code), srcBegin_(0), srcEnd_(0),
|
||||
compileTime_(0), defined_(false)
|
||||
{}
|
||||
|
||||
PropertyName *name() const { return name_; }
|
||||
@ -838,19 +838,19 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
// The begin/end char range is relative to the beginning of the module.
|
||||
// hence the assertions.
|
||||
JS_ASSERT(fn->pn_pos.begin > m.moduleStart());
|
||||
JS_ASSERT(fn->pn_pos.begin > m.srcStart());
|
||||
JS_ASSERT(fn->pn_pos.begin <= fn->pn_pos.end);
|
||||
srcOffset_ = fn->pn_pos.begin - m.moduleStart();
|
||||
endOffset_ = fn->pn_pos.end - m.moduleStart();
|
||||
srcBegin_ = fn->pn_pos.begin - m.srcStart();
|
||||
srcEnd_ = fn->pn_pos.end - m.srcStart();
|
||||
}
|
||||
|
||||
uint32_t srcOffset() const { JS_ASSERT(defined_); return srcOffset_; }
|
||||
uint32_t endOffset() const { JS_ASSERT(defined_); return endOffset_; }
|
||||
uint32_t srcBegin() const { JS_ASSERT(defined_); return srcBegin_; }
|
||||
uint32_t srcEnd() const { JS_ASSERT(defined_); return srcEnd_; }
|
||||
Signature &sig() { return sig_; }
|
||||
const Signature &sig() const { return sig_; }
|
||||
Label *code() const { return code_; }
|
||||
unsigned compileTime() const { return compileTime_; }
|
||||
void accumulateCompileTime(unsigned ms) { compileTime_ += ms; }
|
||||
uint32_t compileTime() const { return compileTime_; }
|
||||
void accumulateCompileTime(uint32_t ms) { compileTime_ += ms; }
|
||||
};
|
||||
|
||||
class Global
|
||||
@ -1137,15 +1137,15 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t funcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
|
||||
uint32_t offsetToEndOfUseAsm = tokenStream().currentToken().pos.end;
|
||||
uint32_t srcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
|
||||
uint32_t srcBodyStart = tokenStream().currentToken().pos.end;
|
||||
|
||||
// "use strict" should be added to the source if we are in an implicit
|
||||
// strict context, see also comment above addUseStrict in
|
||||
// js::FunctionToString.
|
||||
bool strict = parser_.pc->sc->strict && !parser_.pc->sc->hasExplicitUseStrict();
|
||||
|
||||
module_ = cx_->new_<AsmJSModule>(parser_.ss, funcStart, offsetToEndOfUseAsm, strict);
|
||||
module_ = cx_->new_<AsmJSModule>(parser_.ss, srcStart, srcBodyStart, strict);
|
||||
if (!module_)
|
||||
return false;
|
||||
|
||||
@ -1212,7 +1212,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
SlowFunction sf;
|
||||
sf.name = func.name();
|
||||
sf.ms = func.compileTime();
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &sf.line, &sf.column);
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &sf.line, &sf.column);
|
||||
return slowFunctions_.append(sf);
|
||||
}
|
||||
|
||||
@ -1226,7 +1226,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
Label &interruptLabel() { return interruptLabel_; }
|
||||
bool hasError() const { return errorString_ != nullptr; }
|
||||
const AsmJSModule &module() const { return *module_.get(); }
|
||||
uint32_t moduleStart() const { return module_->funcStart(); }
|
||||
uint32_t srcStart() const { return module_->srcStart(); }
|
||||
|
||||
ParseNode *moduleFunctionNode() const { return moduleFunctionNode_; }
|
||||
PropertyName *moduleFunctionName() const { return moduleFunctionName_; }
|
||||
@ -1394,7 +1394,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
for (unsigned i = 0; i < args.length(); i++)
|
||||
argCoercions[i] = args[i].toCoercion();
|
||||
AsmJSModule::ReturnType retType = func->sig().retType().toModuleReturnType();
|
||||
return module_->addExportedFunction(func->name(), func->srcOffset(), func->endOffset(),
|
||||
return module_->addExportedFunction(func->name(), func->srcBegin(), func->srcEnd(),
|
||||
maybeFieldName, Move(argCoercions), retType);
|
||||
}
|
||||
bool addExit(unsigned ffiIndex, PropertyName *name, Signature &&sig, unsigned *exitIndex) {
|
||||
@ -1439,9 +1439,10 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
bool finishGeneratingFunction(Func &func, MIRGenerator &mir, CodeGenerator &codegen) {
|
||||
JS_ASSERT(func.defined() && func.code()->bound());
|
||||
|
||||
uint32_t beginOffset = func.code()->offset();
|
||||
uint32_t endOffset = masm_.currentOffset();
|
||||
if (!module_->addFunctionCodeRange(func.name(), beginOffset, endOffset))
|
||||
PropertyName *name = func.name();
|
||||
uint32_t codeBegin = func.code()->offset();
|
||||
uint32_t codeEnd = masm_.currentOffset();
|
||||
if (!module_->addFunctionCodeRange(name, codeBegin, codeEnd))
|
||||
return false;
|
||||
|
||||
jit::IonScriptCounts *counts = codegen.extractScriptCounts();
|
||||
@ -1452,22 +1453,18 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
unsigned line = 0, column = 0;
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &line, &column);
|
||||
unsigned startCodeOffset = func.code()->offset();
|
||||
unsigned endCodeOffset = masm_.currentOffset();
|
||||
if (!module_->addProfiledFunction(func.name(), startCodeOffset, endCodeOffset, line, column))
|
||||
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &line, &column);
|
||||
if (!module_->addProfiledFunction(name, codeBegin, codeEnd, line, column))
|
||||
return false;
|
||||
# ifdef JS_ION_PERF
|
||||
// Per-block profiling info uses significantly more memory so only store
|
||||
// this information if it is actively requested.
|
||||
if (PerfBlockEnabled()) {
|
||||
// Per-block profiling info uses significantly more memory so only
|
||||
// store this information if it is actively requested.
|
||||
mir.perfSpewer().noteBlocksOffsets();
|
||||
unsigned endInlineCodeOffset = mir.perfSpewer().endInlineCode.offset();
|
||||
if (!module_->addPerfProfiledBlocks(func.name(), startCodeOffset, endInlineCodeOffset,
|
||||
endCodeOffset, mir.perfSpewer().basicBlocks()))
|
||||
{
|
||||
AsmJSPerfSpewer &ps = mir.perfSpewer();
|
||||
ps.noteBlocksOffsets();
|
||||
unsigned inlineEnd = ps.endInlineCode.offset();
|
||||
if (!module_->addProfiledBlocks(name, codeBegin, inlineEnd, codeEnd, ps.basicBlocks()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
@ -5423,11 +5420,11 @@ CheckFunctionsSequential(ModuleCompiler &m)
|
||||
IonSpewNewFunction(&mir->graph(), NullPtr());
|
||||
|
||||
if (!OptimizeMIR(mir))
|
||||
return m.failOffset(func->srcOffset(), "internal compiler failure (probably out of memory)");
|
||||
return m.failOffset(func->srcBegin(), "internal compiler failure (probably out of memory)");
|
||||
|
||||
LIRGraph *lir = GenerateLIR(mir);
|
||||
if (!lir)
|
||||
return m.failOffset(func->srcOffset(), "internal compiler failure (probably out of memory)");
|
||||
return m.failOffset(func->srcBegin(), "internal compiler failure (probably out of memory)");
|
||||
|
||||
func->accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
|
||||
|
||||
@ -5687,7 +5684,7 @@ CheckFunctionsParallel(ModuleCompiler &m)
|
||||
// If failure was triggered by a helper thread, report error.
|
||||
if (void *maybeFunc = HelperThreadState().maybeAsmJSFailedFunction()) {
|
||||
ModuleCompiler::Func *func = reinterpret_cast<ModuleCompiler::Func *>(maybeFunc);
|
||||
return m.failOffset(func->srcOffset(), "allocation failure during compilation");
|
||||
return m.failOffset(func->srcBegin(), "allocation failure during compilation");
|
||||
}
|
||||
|
||||
// Otherwise, the error occurred on the main thread and was already reported.
|
||||
@ -5872,7 +5869,7 @@ AssertStackAlignment(MacroAssembler &masm)
|
||||
Label ok;
|
||||
JS_ASSERT(IsPowerOfTwo(StackAlignment));
|
||||
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(StackAlignment - 1), &ok);
|
||||
masm.assumeUnreachable("Stack should be aligned.");
|
||||
masm.breakpoint();
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
@ -5927,16 +5924,6 @@ static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * siz
|
||||
NonVolatileRegs.fpus().size() * sizeof(double);
|
||||
#endif
|
||||
|
||||
// On ARM/MIPS, we need to include an extra word of space at the top of the
|
||||
// stack so we can explicitly store the return address before making the call
|
||||
// to C++ or Ion. On x86/x64, this isn't necessary since the call instruction
|
||||
// pushes the return address.
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
static const unsigned MaybeRetAddr = sizeof(void*);
|
||||
#else
|
||||
static const unsigned MaybeRetAddr = 0;
|
||||
#endif
|
||||
|
||||
static bool
|
||||
GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFunc)
|
||||
{
|
||||
@ -6229,10 +6216,10 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
invokeArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
|
||||
// At the point of the call, the stack layout shall be (sp grows to the left):
|
||||
// | retaddr | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
|
||||
// The first padding ensures double-alignment of argv; the second ensures
|
||||
// sp is aligned.
|
||||
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes) + MaybeRetAddr, StackAlignment);
|
||||
// | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
|
||||
// The padding between stack args and argv ensures that sp is aligned. The
|
||||
// padding between argv and retaddr ensures that argv is aligned.
|
||||
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes), StackAlignment);
|
||||
unsigned argvBytes = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned stackDec = StackDecrementForCall(masm, offsetToArgv + argvBytes);
|
||||
masm.reserveStack(stackDec);
|
||||
@ -6313,67 +6300,15 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
masm.ret();
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateOOLConvert(ModuleCompiler &m, RetType retType, Label *throwLabel)
|
||||
{
|
||||
MacroAssembler &masm = m.masm();
|
||||
|
||||
MIRType typeArray[] = { MIRType_Pointer, // cx
|
||||
MIRType_Pointer }; // argv
|
||||
MIRTypeVector callArgTypes(m.cx());
|
||||
callArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
|
||||
// The stack is assumed to be aligned. The frame is allocated by GenerateFFIIonExit and
|
||||
// the stack usage here needs to kept in sync with GenerateFFIIonExit.
|
||||
|
||||
// Store value
|
||||
unsigned offsetToArgv = StackArgBytes(callArgTypes) + MaybeRetAddr;
|
||||
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
|
||||
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
|
||||
// Store real arguments
|
||||
ABIArgMIRTypeIter i(callArgTypes);
|
||||
|
||||
// argument 0: cx
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
LoadJSContextFromActivation(masm, activation, i->gpr());
|
||||
} else {
|
||||
LoadJSContextFromActivation(masm, activation, scratch);
|
||||
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
|
||||
}
|
||||
i++;
|
||||
|
||||
// argument 1: argv
|
||||
Address argv(StackPointer, offsetToArgv);
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
masm.computeEffectiveAddress(argv, i->gpr());
|
||||
} else {
|
||||
masm.computeEffectiveAddress(argv, scratch);
|
||||
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
|
||||
}
|
||||
i++;
|
||||
JS_ASSERT(i.done());
|
||||
|
||||
// Call
|
||||
AssertStackAlignment(masm);
|
||||
switch (retType.which()) {
|
||||
case RetType::Signed:
|
||||
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToInt32));
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
|
||||
break;
|
||||
case RetType::Double:
|
||||
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
|
||||
}
|
||||
}
|
||||
// On ARM/MIPS, we need to include an extra word of space at the top of the
|
||||
// stack so we can explicitly store the return address before making the call
|
||||
// to C++ or Ion. On x86/x64, this isn't necessary since the call instruction
|
||||
// pushes the return address.
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
static const unsigned MaybeRetAddr = sizeof(void*);
|
||||
#else
|
||||
static const unsigned MaybeRetAddr = 0;
|
||||
#endif
|
||||
|
||||
static void
|
||||
GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit,
|
||||
@ -6391,60 +6326,64 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
masm.push(ra);
|
||||
#endif
|
||||
|
||||
// Store the frame pointer in AsmJSActivation::exitFP for stack unwinding.
|
||||
Register activation = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitFP()));
|
||||
// 'callee' stays live throughout much of the Ion exit and 'scratch' is
|
||||
// constantly clobbered.
|
||||
Register callee = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
|
||||
// Ion does not preserve nonvolatile registers, so we have to preserve them.
|
||||
// Store the frame pointer in AsmJSActivation::exitFP for stack unwinding.
|
||||
LoadAsmJSActivationIntoRegister(masm, scratch);
|
||||
masm.storePtr(StackPointer, Address(scratch, AsmJSActivation::offsetOfExitFP()));
|
||||
|
||||
// Even though the caller has saved volatile registers, we still need to
|
||||
// save/restore globally-pinned asm.js registers at Ion calls since Ion does
|
||||
// not preserve non-volatile registers.
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.Push(HeapReg);
|
||||
unsigned savedRegBytes = 1 * sizeof(void*); // HeapReg
|
||||
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
masm.PushRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
|
||||
unsigned savedRegBytes = 2 * sizeof(void*); // HeapReg, GlobalReg
|
||||
#else
|
||||
unsigned savedRegBytes = 0;
|
||||
#endif
|
||||
|
||||
// The stack frame is used for the call into Ion and also for calls into C for OOL
|
||||
// conversion of the result. A frame large enough for both is allocated.
|
||||
//
|
||||
// Arguments to the Ion function are in the following order on the stack:
|
||||
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
|
||||
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned offsetToArgs = MaybeRetAddr;
|
||||
unsigned stackDecForIonCall = StackDecrementForCall(masm, argBytes + offsetToArgs);
|
||||
// The same stack frame is used for the call into Ion and (possibly) a call
|
||||
// into C++ to coerce the return type. To do this, we compute the amount of
|
||||
// space required for both calls and take the maximum. In both cases,
|
||||
// include space for savedRegBytes, since these go below the Ion/coerce.
|
||||
|
||||
// Reserve space for a call to AsmJSImm_CoerceInPlace_* and an array of values used by
|
||||
// OOLConvert which reuses the same frame. This code needs to be kept in sync with the
|
||||
// stack usage in GenerateOOLConvert.
|
||||
MIRType typeArray[] = { MIRType_Pointer, MIRType_Pointer }; // cx, argv
|
||||
MIRTypeVector callArgTypes(m.cx());
|
||||
callArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
unsigned oolExtraBytes = sizeof(Value) + MaybeRetAddr;
|
||||
unsigned stackDecForOOLCall = StackDecrementForCall(masm, callArgTypes, oolExtraBytes);
|
||||
// Ion calls use the following stack layout (sp grows to the left):
|
||||
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
|
||||
unsigned offsetToArgs = MaybeRetAddr;
|
||||
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned totalIonBytes = offsetToArgs + argBytes + savedRegBytes;
|
||||
unsigned ionFrameSize = StackDecrementForCall(masm, totalIonBytes);
|
||||
|
||||
// Coercion calls use the following stack layout (sp grows to the left):
|
||||
// | stack args | Value argv[1] | ...
|
||||
MIRTypeVector coerceArgTypes(m.cx());
|
||||
coerceArgTypes.infallibleAppend(MIRType_Pointer); // cx
|
||||
coerceArgTypes.infallibleAppend(MIRType_Pointer); // argv
|
||||
unsigned bytesAfterArgs = sizeof(Value) + savedRegBytes;
|
||||
unsigned coerceFrameSize = StackDecrementForCall(masm, coerceArgTypes, bytesAfterArgs);
|
||||
|
||||
// Allocate a frame large enough for both of the above calls.
|
||||
unsigned stackDec = Max(stackDecForIonCall, stackDecForOOLCall);
|
||||
|
||||
masm.reserveStack(stackDec);
|
||||
AssertStackAlignment(masm);
|
||||
unsigned framePushed = Max(ionFrameSize, coerceFrameSize);
|
||||
masm.reserveStack(framePushed);
|
||||
|
||||
// 1. Descriptor
|
||||
size_t argOffset = offsetToArgs;
|
||||
uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_Entry);
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed, JitFrame_Entry);
|
||||
masm.storePtr(ImmWord(uintptr_t(descriptor)), Address(StackPointer, argOffset));
|
||||
argOffset += sizeof(size_t);
|
||||
|
||||
// 2. Callee
|
||||
Register callee = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
|
||||
|
||||
// 2.1. Get ExitDatum
|
||||
unsigned globalDataOffset = m.module().exitIndexToGlobalDataOffset(exitIndex);
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
CodeOffsetLabel label2 = masm.leaRipRelative(callee);
|
||||
m.masm().append(AsmJSGlobalAccess(CodeOffsetLabel(label2.offset()), globalDataOffset));
|
||||
m.masm().append(AsmJSGlobalAccess(masm.leaRipRelative(callee), globalDataOffset));
|
||||
#elif defined(JS_CODEGEN_X86)
|
||||
CodeOffsetLabel label2 = masm.movlWithPatch(Imm32(0), callee);
|
||||
m.masm().append(AsmJSGlobalAccess(CodeOffsetLabel(label2.offset()), globalDataOffset));
|
||||
m.masm().append(AsmJSGlobalAccess(masm.movlWithPatch(Imm32(0), callee), globalDataOffset));
|
||||
#else
|
||||
masm.lea(Operand(GlobalReg, globalDataOffset), callee);
|
||||
#endif
|
||||
@ -6456,6 +6395,10 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
masm.storePtr(callee, Address(StackPointer, argOffset));
|
||||
argOffset += sizeof(size_t);
|
||||
|
||||
// 2.4. Load callee executable entry point
|
||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
|
||||
masm.loadBaselineOrIonNoArgCheck(callee, callee, SequentialExecution, nullptr);
|
||||
|
||||
// 3. Argc
|
||||
unsigned argc = exit.sig().args().length();
|
||||
masm.storePtr(ImmWord(uintptr_t(argc)), Address(StackPointer, argOffset));
|
||||
@ -6466,26 +6409,22 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
argOffset += sizeof(Value);
|
||||
|
||||
// 5. Fill the arguments
|
||||
unsigned offsetToCallerStackArgs = masm.framePushed() + AsmJSFrameSize;
|
||||
unsigned offsetToCallerStackArgs = framePushed + AsmJSFrameSize;
|
||||
FillArgumentArray(m, exit.sig().args(), argOffset, offsetToCallerStackArgs, scratch);
|
||||
argOffset += exit.sig().args().length() * sizeof(Value);
|
||||
JS_ASSERT(argOffset == offsetToArgs + argBytes);
|
||||
|
||||
// Get the pointer to the ion code
|
||||
Label done, oolConvert;
|
||||
Label *maybeDebugBreakpoint = nullptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
Label ionFailed;
|
||||
maybeDebugBreakpoint = &ionFailed;
|
||||
masm.branchIfFunctionHasNoScript(callee, &ionFailed);
|
||||
// 6. Store asm.js pinned registers
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
unsigned savedHeapOffset = framePushed - sizeof(void*);
|
||||
masm.storePtr(HeapReg, Address(StackPointer, savedHeapOffset));
|
||||
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
unsigned savedHeapOffset = framePushed - 1 * sizeof(void*);
|
||||
unsigned savedGlobalOffset = framePushed - 2 * sizeof(void*);
|
||||
masm.storePtr(HeapReg, Address(StackPointer, savedHeapOffset));
|
||||
masm.storePtr(GlobalReg, Address(StackPointer, savedGlobalOffset));
|
||||
#endif
|
||||
|
||||
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
|
||||
masm.loadBaselineOrIonNoArgCheck(callee, callee, SequentialExecution, maybeDebugBreakpoint);
|
||||
|
||||
AssertStackAlignment(masm);
|
||||
|
||||
{
|
||||
// Enable Activation.
|
||||
//
|
||||
@ -6557,14 +6496,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
masm.storePtr(reg2, Address(reg0, offsetOfJitJSContext));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
masm.branchTestMagicValue(Assembler::Equal, JSReturnOperand, JS_ION_ERROR, throwLabel);
|
||||
masm.branchTestMagic(Assembler::Equal, JSReturnOperand, &ionFailed);
|
||||
#else
|
||||
masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel);
|
||||
#endif
|
||||
|
||||
uint32_t oolConvertFramePushed = masm.framePushed();
|
||||
Label oolConvert;
|
||||
switch (exit.sig().retType().which()) {
|
||||
case RetType::Void:
|
||||
break;
|
||||
@ -6580,37 +6514,79 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
break;
|
||||
}
|
||||
|
||||
Label done;
|
||||
masm.bind(&done);
|
||||
masm.freeStack(stackDec);
|
||||
|
||||
// Restore non-volatile registers saved in the prologue.
|
||||
JS_ASSERT(masm.framePushed() == framePushed);
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.Pop(HeapReg);
|
||||
masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg);
|
||||
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
masm.loadConstantDouble(GenericNaN(), NANReg);
|
||||
masm.PopRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
|
||||
masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg);
|
||||
masm.loadPtr(Address(StackPointer, savedGlobalOffset), GlobalReg);
|
||||
#endif
|
||||
|
||||
masm.freeStack(framePushed);
|
||||
|
||||
// Clear exitFP before the frame is destroyed.
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
masm.storePtr(ImmWord(0), Address(activation, AsmJSActivation::offsetOfExitFP()));
|
||||
LoadAsmJSActivationIntoRegister(masm, scratch);
|
||||
masm.storePtr(ImmWord(0), Address(scratch, AsmJSActivation::offsetOfExitFP()));
|
||||
|
||||
masm.ret();
|
||||
JS_ASSERT(masm.framePushed() == 0);
|
||||
|
||||
// oolConvert
|
||||
if (oolConvert.used()) {
|
||||
masm.bind(&oolConvert);
|
||||
masm.setFramePushed(oolConvertFramePushed);
|
||||
GenerateOOLConvert(m, exit.sig().retType(), throwLabel);
|
||||
masm.setFramePushed(0);
|
||||
masm.setFramePushed(framePushed);
|
||||
|
||||
// Store return value into argv[0]
|
||||
unsigned offsetToArgv = StackArgBytes(coerceArgTypes);
|
||||
JS_ASSERT(offsetToArgv % sizeof(Value) == 0);
|
||||
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
|
||||
|
||||
ABIArgMIRTypeIter i(coerceArgTypes);
|
||||
|
||||
// argument 0: cx
|
||||
LoadAsmJSActivationIntoRegister(masm, scratch);
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
LoadJSContextFromActivation(masm, scratch, i->gpr());
|
||||
} else {
|
||||
LoadJSContextFromActivation(masm, scratch, scratch);
|
||||
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
|
||||
}
|
||||
i++;
|
||||
|
||||
// argument 1: argv
|
||||
Address argv(StackPointer, offsetToArgv);
|
||||
if (i->kind() == ABIArg::GPR) {
|
||||
masm.computeEffectiveAddress(argv, i->gpr());
|
||||
} else {
|
||||
masm.computeEffectiveAddress(argv, scratch);
|
||||
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
|
||||
}
|
||||
i++;
|
||||
JS_ASSERT(i.done());
|
||||
|
||||
// Call coercion function
|
||||
AssertStackAlignment(masm);
|
||||
switch (exit.sig().retType().which()) {
|
||||
case RetType::Signed:
|
||||
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToInt32));
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
|
||||
break;
|
||||
case RetType::Double:
|
||||
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
|
||||
}
|
||||
|
||||
masm.jump(&done);
|
||||
masm.setFramePushed(0);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
masm.bind(&ionFailed);
|
||||
masm.assumeUnreachable("AsmJS to IonMonkey call failed.");
|
||||
#endif
|
||||
JS_ASSERT(masm.framePushed() == 0);
|
||||
}
|
||||
|
||||
// See "asm.js FFI calls" comment above.
|
||||
@ -6646,7 +6622,7 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
|
||||
MIRTypeVector argTypes(m.cx());
|
||||
argTypes.infallibleAppend(MIRType_Pointer); // cx
|
||||
|
||||
unsigned stackDec = StackDecrementForCall(masm, argTypes, MaybeRetAddr);
|
||||
unsigned stackDec = StackDecrementForCall(masm, argTypes);
|
||||
masm.reserveStack(stackDec);
|
||||
|
||||
ABIArgMIRTypeIter i(argTypes);
|
||||
|
@ -468,8 +468,8 @@ HandleDynamicLinkFailure(JSContext *cx, CallArgs args, AsmJSModule &module, Hand
|
||||
if (cx->isExceptionPending())
|
||||
return false;
|
||||
|
||||
uint32_t begin = module.offsetToEndOfUseAsm();
|
||||
uint32_t end = module.funcEndBeforeCurly();
|
||||
uint32_t begin = module.srcBodyStart(); // starts right after 'use asm'
|
||||
uint32_t end = module.srcEndBeforeCurly();
|
||||
Rooted<JSFlatString*> src(cx, module.scriptSource()->substring(cx, begin, end));
|
||||
if (!src)
|
||||
return false;
|
||||
@ -818,8 +818,8 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
|
||||
{
|
||||
AsmJSModule &module = ModuleFunctionToModuleObject(fun).module();
|
||||
|
||||
uint32_t begin = module.funcStart();
|
||||
uint32_t end = module.funcEndAfterCurly();
|
||||
uint32_t begin = module.srcStart();
|
||||
uint32_t end = module.srcEndAfterCurly();
|
||||
ScriptSource *source = module.scriptSource();
|
||||
StringBuffer out(cx);
|
||||
|
||||
@ -917,8 +917,8 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
|
||||
{
|
||||
AsmJSModule &module = FunctionToEnclosingModule(fun);
|
||||
const AsmJSModule::ExportedFunction &f = FunctionToExportedFunction(fun, module);
|
||||
uint32_t begin = module.funcStart() + f.startOffsetInModule();
|
||||
uint32_t end = module.funcStart() + f.endOffsetInModule();
|
||||
uint32_t begin = module.srcStart() + f.startOffsetInModule();
|
||||
uint32_t end = module.srcStart() + f.endOffsetInModule();
|
||||
|
||||
ScriptSource *source = module.scriptSource();
|
||||
StringBuffer out(cx);
|
||||
|
@ -75,10 +75,10 @@ DeallocateExecutableMemory(uint8_t *code, size_t totalBytes)
|
||||
#endif
|
||||
}
|
||||
|
||||
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t funcStart,
|
||||
uint32_t offsetToEndOfUseAsm, bool strict)
|
||||
: funcStart_(funcStart),
|
||||
offsetToEndOfUseAsm_(offsetToEndOfUseAsm),
|
||||
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t srcStart, uint32_t srcBodyStart,
|
||||
bool strict)
|
||||
: srcStart_(srcStart),
|
||||
srcBodyStart_(srcBodyStart),
|
||||
scriptSource_(scriptSource),
|
||||
globalArgumentName_(nullptr),
|
||||
importArgumentName_(nullptr),
|
||||
@ -278,10 +278,10 @@ AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembl
|
||||
|
||||
uint32_t endBeforeCurly = tokenStream.currentToken().pos.end;
|
||||
uint32_t endAfterCurly = tokenStream.peekTokenPos().end;
|
||||
JS_ASSERT(endBeforeCurly >= offsetToEndOfUseAsm_);
|
||||
JS_ASSERT(endAfterCurly >= offsetToEndOfUseAsm_);
|
||||
pod.funcLength_ = endBeforeCurly - funcStart_;
|
||||
pod.funcLengthWithRightBrace_ = endAfterCurly - funcStart_;
|
||||
JS_ASSERT(endBeforeCurly >= srcBodyStart_);
|
||||
JS_ASSERT(endAfterCurly >= srcBodyStart_);
|
||||
pod.srcLength_ = endBeforeCurly - srcStart_;
|
||||
pod.srcLengthWithRightBrace_ = endAfterCurly - srcStart_;
|
||||
|
||||
// The global data section sits immediately after the executable (and
|
||||
// other) data allocated by the MacroAssembler, so ensure it is
|
||||
@ -337,6 +337,8 @@ AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembl
|
||||
CodeRange &c = codeRanges_[i];
|
||||
c.begin_ = masm.actualOffset(c.begin_);
|
||||
c.end_ = masm.actualOffset(c.end_);
|
||||
JS_ASSERT(c.begin_ <= c.end_);
|
||||
JS_ASSERT_IF(i > 0, codeRanges_[i - 1].end_ <= c.begin_);
|
||||
}
|
||||
#endif
|
||||
JS_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);
|
||||
@ -510,14 +512,6 @@ RedirectCall(void *fun, ABIFunctionType type)
|
||||
return fun;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
AssumeUnreachable()
|
||||
{
|
||||
MOZ_CRASH("Reached unreachable code in asm.js");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
|
||||
{
|
||||
@ -578,10 +572,6 @@ AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
|
||||
return RedirectCall(FuncCast(ecmaPow), Args_Double_DoubleDouble);
|
||||
case AsmJSImm_ATan2D:
|
||||
return RedirectCall(FuncCast(ecmaAtan2), Args_Double_DoubleDouble);
|
||||
#ifdef DEBUG
|
||||
case AsmJSImm_AssumeUnreachable:
|
||||
return RedirectCall(FuncCast(AssumeUnreachable), Args_General0);
|
||||
#endif
|
||||
case AsmJSImm_Invalid:
|
||||
break;
|
||||
}
|
||||
@ -1224,7 +1214,7 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
|
||||
{
|
||||
AutoUnprotectCodeForClone cloneGuard(cx, *this);
|
||||
|
||||
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, funcStart_, offsetToEndOfUseAsm_, pod.strict_);
|
||||
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, srcStart_, srcBodyStart_, pod.strict_);
|
||||
if (!*moduleOut)
|
||||
return false;
|
||||
|
||||
@ -1681,11 +1671,11 @@ js::LookupAsmJSModuleInCache(ExclusiveContext *cx,
|
||||
if (!moduleChars.match(parser))
|
||||
return true;
|
||||
|
||||
uint32_t funcStart = parser.pc->maybeFunction->pn_body->pn_pos.begin;
|
||||
uint32_t offsetToEndOfUseAsm = parser.tokenStream.currentToken().pos.end;
|
||||
uint32_t srcStart = parser.pc->maybeFunction->pn_body->pn_pos.begin;
|
||||
uint32_t srcBodyStart = parser.tokenStream.currentToken().pos.end;
|
||||
bool strict = parser.pc->sc->strict && !parser.pc->sc->hasExplicitUseStrict();
|
||||
ScopedJSDeletePtr<AsmJSModule> module(
|
||||
cx->new_<AsmJSModule>(parser.ss, funcStart, offsetToEndOfUseAsm, strict));
|
||||
cx->new_<AsmJSModule>(parser.ss, srcStart, srcBodyStart, strict));
|
||||
if (!module)
|
||||
return false;
|
||||
cursor = module->deserialize(cx, cursor);
|
||||
@ -1706,7 +1696,7 @@ js::LookupAsmJSModuleInCache(ExclusiveContext *cx,
|
||||
|
||||
module->staticallyLink(cx);
|
||||
|
||||
parser.tokenStream.advance(module->funcEndBeforeCurly());
|
||||
parser.tokenStream.advance(module->srcEndBeforeCurly());
|
||||
|
||||
int64_t usecAfter = PRMJ_Now();
|
||||
int ms = (usecAfter - usecBefore) / PRMJ_USEC_PER_MSEC;
|
||||
|
@ -490,8 +490,8 @@ class AsmJSModule
|
||||
uint32_t minHeapLength_;
|
||||
uint32_t numGlobalVars_;
|
||||
uint32_t numFFIs_;
|
||||
uint32_t funcLength_;
|
||||
uint32_t funcLengthWithRightBrace_;
|
||||
uint32_t srcLength_;
|
||||
uint32_t srcLengthWithRightBrace_;
|
||||
bool strict_;
|
||||
bool hasArrayView_;
|
||||
} pod;
|
||||
@ -499,8 +499,8 @@ class AsmJSModule
|
||||
// These two fields need to be kept out pod as they depend on the position
|
||||
// of the module within the ScriptSource and thus aren't invariant with
|
||||
// respect to caching.
|
||||
const uint32_t funcStart_;
|
||||
const uint32_t offsetToEndOfUseAsm_;
|
||||
const uint32_t srcStart_;
|
||||
const uint32_t srcBodyStart_;
|
||||
|
||||
Vector<Global, 0, SystemAllocPolicy> globals_;
|
||||
Vector<Exit, 0, SystemAllocPolicy> exits_;
|
||||
@ -533,8 +533,8 @@ class AsmJSModule
|
||||
mutable bool codeIsProtected_;
|
||||
|
||||
public:
|
||||
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t functStart,
|
||||
uint32_t offsetToEndOfUseAsm, bool strict);
|
||||
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t srcStart, uint32_t srcBodyStart,
|
||||
bool strict);
|
||||
void trace(JSTracer *trc);
|
||||
~AsmJSModule();
|
||||
|
||||
@ -559,18 +559,19 @@ class AsmJSModule
|
||||
return loadedFromCache_;
|
||||
}
|
||||
|
||||
// funcStart() refers to the offset in the ScriptSource to the beginning
|
||||
// of the function. If the function has been created with the Function
|
||||
// constructor, this will be the first character in the function source.
|
||||
// Otherwise, it will be the opening parenthesis of the arguments list.
|
||||
uint32_t funcStart() const {
|
||||
return funcStart_;
|
||||
// srcStart() refers to the offset in the ScriptSource to the beginning of
|
||||
// the asm.js module function. If the function has been created with the
|
||||
// Function constructor, this will be the first character in the function
|
||||
// source. Otherwise, it will be the opening parenthesis of the arguments
|
||||
// list.
|
||||
uint32_t srcStart() const {
|
||||
return srcStart_;
|
||||
}
|
||||
|
||||
// offsetToEndOfUseAsm() refers to the offset in the ScriptSource to the end
|
||||
// srcBodyStart() refers to the offset in the ScriptSource to the end
|
||||
// of the 'use asm' string-literal token.
|
||||
uint32_t offsetToEndOfUseAsm() const {
|
||||
return offsetToEndOfUseAsm_;
|
||||
uint32_t srcBodyStart() const {
|
||||
return srcBodyStart_;
|
||||
}
|
||||
|
||||
// While these functions may be accessed at any time, their values will
|
||||
@ -697,8 +698,6 @@ class AsmJSModule
|
||||
bool addFunctionCodeRange(PropertyName *name, uint32_t begin, uint32_t end) {
|
||||
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
|
||||
JS_ASSERT(name->isTenured());
|
||||
JS_ASSERT(begin <= end);
|
||||
JS_ASSERT_IF(!codeRanges_.empty(), codeRanges_.back().end() <= begin);
|
||||
if (functionNames_.length() >= UINT32_MAX)
|
||||
return false;
|
||||
CodeRange codeRange(CodeRange::Function, begin, end, functionNames_.length());
|
||||
@ -745,11 +744,11 @@ class AsmJSModule
|
||||
return functionCounts_.append(counts);
|
||||
}
|
||||
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
|
||||
bool addProfiledFunction(PropertyName *name, unsigned startCodeOffset, unsigned endCodeOffset,
|
||||
bool addProfiledFunction(PropertyName *name, unsigned codeStart, unsigned codeEnd,
|
||||
unsigned line, unsigned column)
|
||||
{
|
||||
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
|
||||
ProfiledFunction func(name, startCodeOffset, endCodeOffset, line, column);
|
||||
ProfiledFunction func(name, codeStart, codeEnd, line, column);
|
||||
return profiledFunctions_.append(func);
|
||||
}
|
||||
unsigned numProfiledFunctions() const {
|
||||
@ -762,13 +761,11 @@ class AsmJSModule
|
||||
}
|
||||
#endif
|
||||
#ifdef JS_ION_PERF
|
||||
bool addPerfProfiledBlocks(PropertyName *name, unsigned startCodeOffset,
|
||||
unsigned endInlineCodeOffset, unsigned endCodeOffset,
|
||||
jit::BasicBlocksVector &basicBlocks)
|
||||
bool addProfiledBlocks(PropertyName *name, unsigned codeBegin, unsigned inlineEnd,
|
||||
unsigned codeEnd, jit::BasicBlocksVector &basicBlocks)
|
||||
{
|
||||
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
|
||||
ProfiledBlocksFunction func(name, startCodeOffset, endInlineCodeOffset, endCodeOffset,
|
||||
basicBlocks);
|
||||
ProfiledBlocksFunction func(name, codeBegin, inlineEnd, codeEnd, basicBlocks);
|
||||
return perfProfiledBlocksFunctions_.append(mozilla::Move(func));
|
||||
}
|
||||
unsigned numPerfBlocksFunctions() const {
|
||||
@ -845,13 +842,13 @@ class AsmJSModule
|
||||
JS_ASSERT(isFinished());
|
||||
return pod.numFFIs_;
|
||||
}
|
||||
uint32_t funcEndBeforeCurly() const {
|
||||
uint32_t srcEndBeforeCurly() const {
|
||||
JS_ASSERT(isFinished());
|
||||
return funcStart_ + pod.funcLength_;
|
||||
return srcStart_ + pod.srcLength_;
|
||||
}
|
||||
uint32_t funcEndAfterCurly() const {
|
||||
uint32_t srcEndAfterCurly() const {
|
||||
JS_ASSERT(isFinished());
|
||||
return funcStart_ + pod.funcLengthWithRightBrace_;
|
||||
return srcStart_ + pod.srcLengthWithRightBrace_;
|
||||
}
|
||||
uint8_t *codeBase() const {
|
||||
JS_ASSERT(isFinished());
|
||||
|
@ -8570,7 +8570,7 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
|
||||
Label ok;
|
||||
JS_ASSERT(IsPowerOfTwo(StackAlignment));
|
||||
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(StackAlignment - 1), &ok);
|
||||
masm.assumeUnreachable("Stack should be aligned.");
|
||||
masm.breakpoint();
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
|
||||
|
@ -1429,6 +1429,12 @@ SnapshotIterator::SnapshotIterator()
|
||||
{
|
||||
}
|
||||
|
||||
int32_t
|
||||
SnapshotIterator::readOuterNumActualArgs() const
|
||||
{
|
||||
return fp_->numActualArgs();
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
SnapshotIterator::fromStack(int32_t offset) const
|
||||
{
|
||||
|
@ -1339,24 +1339,18 @@ void
|
||||
MacroAssembler::assumeUnreachable(const char *output)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
Register temp = regs.takeGeneral();
|
||||
if (!IsCompilingAsmJS()) {
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
Register temp = regs.takeGeneral();
|
||||
|
||||
// With ASLR, we can't rely on 'output' to point to the
|
||||
// same char array after serialization/deserialization.
|
||||
// It is not possible until we modify AsmJsImmPtr and
|
||||
// the underlying "patching" mechanism.
|
||||
if (IsCompilingAsmJS()) {
|
||||
setupUnalignedABICall(0, temp);
|
||||
callWithABINoProfiling(AsmJSImm_AssumeUnreachable);
|
||||
} else {
|
||||
setupUnalignedABICall(1, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
passABIArg(temp);
|
||||
callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
#endif
|
||||
|
||||
breakpoint();
|
||||
|
@ -329,6 +329,8 @@ class SnapshotIterator
|
||||
return snapshot_.numAllocationsRead() < numAllocations();
|
||||
}
|
||||
|
||||
int32_t readOuterNumActualArgs() const;
|
||||
|
||||
public:
|
||||
// Exhibits frame properties contained in the snapshot.
|
||||
uint32_t pcOffset() const;
|
||||
|
@ -6255,11 +6255,7 @@ class MNot
|
||||
}
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
bool canRecoverOnBailout() const {
|
||||
// Non objects are recoverable and objects that cannot emulate
|
||||
// undefined get folded into 'true' by GVN.
|
||||
// So the only way to reach this function with an operand that
|
||||
// is an object is when that object might emulate undefined.
|
||||
return !operandMightEmulateUndefined_;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -9362,6 +9358,12 @@ class MArgumentsLength : public MNullaryInstruction
|
||||
}
|
||||
|
||||
void computeRange(TempAllocator &alloc);
|
||||
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
|
||||
bool canRecoverOnBailout() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// This MIR instruction is used to get an argument from the actual arguments.
|
||||
|
@ -501,7 +501,6 @@ RNot::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
RootedValue v(cx, iter.read());
|
||||
RootedValue result(cx);
|
||||
|
||||
MOZ_ASSERT(!v.isObject());
|
||||
result.setBoolean(!ToBoolean(v));
|
||||
|
||||
iter.storeInstructionResult(result);
|
||||
@ -559,6 +558,28 @@ MStringLength::writeRecoverData(CompactBufferWriter &writer) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MArgumentsLength::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
MOZ_ASSERT(canRecoverOnBailout());
|
||||
writer.writeUnsigned(uint32_t(RInstruction::Recover_ArgumentsLength));
|
||||
return true;
|
||||
}
|
||||
|
||||
RArgumentsLength::RArgumentsLength(CompactBufferReader &reader)
|
||||
{ }
|
||||
|
||||
bool
|
||||
RArgumentsLength::recover(JSContext *cx, SnapshotIterator &iter) const
|
||||
{
|
||||
RootedValue result(cx);
|
||||
|
||||
result.setInt32(iter.readOuterNumActualArgs());
|
||||
|
||||
iter.storeInstructionResult(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MFloor::writeRecoverData(CompactBufferWriter &writer) const
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ namespace jit {
|
||||
_(Not) \
|
||||
_(Concat) \
|
||||
_(StringLength) \
|
||||
_(ArgumentsLength) \
|
||||
_(Floor) \
|
||||
_(Round) \
|
||||
_(CharCodeAt) \
|
||||
@ -292,7 +293,7 @@ class RConcat MOZ_FINAL : public RInstruction
|
||||
|
||||
class RStringLength MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RINSTRUCTION_HEADER_(StringLength)
|
||||
|
||||
virtual uint32_t numOperands() const {
|
||||
@ -302,6 +303,19 @@ public:
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
class RArgumentsLength MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
RINSTRUCTION_HEADER_(ArgumentsLength)
|
||||
|
||||
virtual uint32_t numOperands() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool recover(JSContext *cx, SnapshotIterator &iter) const;
|
||||
};
|
||||
|
||||
|
||||
class RFloor MOZ_FINAL : public RInstruction
|
||||
{
|
||||
public:
|
||||
|
@ -1849,7 +1849,8 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
|
||||
masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual);
|
||||
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below);
|
||||
}
|
||||
return masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1916,7 +1917,8 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
|
||||
ToRegister(ins->value()), Offset, Assembler::Below);
|
||||
}
|
||||
return masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2067,7 +2067,7 @@ MacroAssemblerARMCompat::movePtr(AsmJSImmPtr imm, Register dest)
|
||||
else
|
||||
rs = L_LDR;
|
||||
|
||||
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
|
||||
append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
|
||||
ma_movPatchable(Imm32(-1), dest, Always, rs);
|
||||
}
|
||||
void
|
||||
|
@ -566,11 +566,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
}
|
||||
void call(const CallSiteDesc &desc, const Register reg) {
|
||||
call(reg);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
void call(const CallSiteDesc &desc, Label *label) {
|
||||
call(label);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
|
||||
void branch(JitCode *c) {
|
||||
|
@ -1985,7 +1985,8 @@ CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
|
||||
}
|
||||
masm.bind(&done);
|
||||
|
||||
return masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2061,7 +2062,8 @@ CodeGeneratorMIPS::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
}
|
||||
masm.bind(&rejoin);
|
||||
|
||||
return masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
masm.append(AsmJSHeapAccess(bo.getOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1795,8 +1795,7 @@ MacroAssemblerMIPSCompat::movePtr(ImmPtr imm, Register dest)
|
||||
void
|
||||
MacroAssemblerMIPSCompat::movePtr(AsmJSImmPtr imm, Register dest)
|
||||
{
|
||||
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()),
|
||||
imm.kind()));
|
||||
append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
|
||||
ma_liPatchable(dest, Imm32(-1));
|
||||
}
|
||||
|
||||
|
@ -414,11 +414,11 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
}
|
||||
void call(const CallSiteDesc &desc, const Register reg) {
|
||||
call(reg);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
void call(const CallSiteDesc &desc, Label *label) {
|
||||
call(label);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
|
||||
void branch(JitCode *c) {
|
||||
|
@ -737,9 +737,6 @@ enum AsmJSImmKind
|
||||
AsmJSImm_LogD,
|
||||
AsmJSImm_PowD,
|
||||
AsmJSImm_ATan2D,
|
||||
#ifdef DEBUG
|
||||
AsmJSImm_AssumeUnreachable,
|
||||
#endif
|
||||
AsmJSImm_Invalid
|
||||
};
|
||||
|
||||
@ -800,21 +797,22 @@ class AssemblerShared
|
||||
return !enoughMemory_;
|
||||
}
|
||||
|
||||
bool append(const CallSiteDesc &desc, size_t currentOffset, size_t framePushed) {
|
||||
void append(const CallSiteDesc &desc, size_t currentOffset, size_t framePushed) {
|
||||
// framePushed does not include AsmJSFrameSize, so add it in here (see
|
||||
// CallSite::stackDepth).
|
||||
return callsites_.append(CallSite(desc, currentOffset, framePushed + AsmJSFrameSize));
|
||||
CallSite callsite(desc, currentOffset, framePushed + AsmJSFrameSize);
|
||||
enoughMemory_ &= callsites_.append(callsite);
|
||||
}
|
||||
CallSiteVector &&extractCallSites() { return Move(callsites_); }
|
||||
|
||||
bool append(AsmJSHeapAccess access) { return asmJSHeapAccesses_.append(access); }
|
||||
void append(AsmJSHeapAccess access) { enoughMemory_ &= asmJSHeapAccesses_.append(access); }
|
||||
AsmJSHeapAccessVector &&extractAsmJSHeapAccesses() { return Move(asmJSHeapAccesses_); }
|
||||
|
||||
bool append(AsmJSGlobalAccess access) { return asmJSGlobalAccesses_.append(access); }
|
||||
void append(AsmJSGlobalAccess access) { enoughMemory_ &= asmJSGlobalAccesses_.append(access); }
|
||||
size_t numAsmJSGlobalAccesses() const { return asmJSGlobalAccesses_.length(); }
|
||||
AsmJSGlobalAccess asmJSGlobalAccess(size_t i) const { return asmJSGlobalAccesses_[i]; }
|
||||
|
||||
bool append(AsmJSAbsoluteLink link) { return asmJSAbsoluteLinks_.append(link); }
|
||||
void append(AsmJSAbsoluteLink link) { enoughMemory_ &= asmJSAbsoluteLinks_.append(link); }
|
||||
size_t numAsmJSAbsoluteLinks() const { return asmJSAbsoluteLinks_.length(); }
|
||||
AsmJSAbsoluteLink asmJSAbsoluteLink(size_t i) const { return asmJSAbsoluteLinks_[i]; }
|
||||
};
|
||||
|
@ -669,11 +669,11 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
|
||||
void call(const CallSiteDesc &desc, Label *label) {
|
||||
call(label);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
void call(const CallSiteDesc &desc, Register reg) {
|
||||
call(reg);
|
||||
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
|
||||
append(desc, currentOffset(), framePushed_);
|
||||
}
|
||||
void callIon(Register callee) {
|
||||
call(callee);
|
||||
|
@ -545,7 +545,7 @@ class Assembler : public AssemblerX86Shared
|
||||
}
|
||||
void mov(AsmJSImmPtr imm, Register dest) {
|
||||
masm.movq_i64r(-1, dest.code());
|
||||
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
|
||||
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
|
||||
}
|
||||
void mov(const Operand &src, Register dest) {
|
||||
movq(src, dest);
|
||||
|
@ -274,7 +274,9 @@ CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
|
||||
default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
|
||||
}
|
||||
uint32_t after = masm.size();
|
||||
return skipNote || masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(ins->output())));
|
||||
if (!skipNote)
|
||||
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(ins->output())));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -322,7 +324,9 @@ CodeGeneratorX64::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
}
|
||||
}
|
||||
uint32_t after = masm.size();
|
||||
return skipNote || masm.append(AsmJSHeapAccess(before, after));
|
||||
if (!skipNote)
|
||||
masm.append(AsmJSHeapAccess(before, after));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -335,8 +339,8 @@ CodeGeneratorX64::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins)
|
||||
label = masm.loadRipRelativeInt32(ToRegister(ins->output()));
|
||||
else
|
||||
label = masm.loadRipRelativeDouble(ToFloatRegister(ins->output()));
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -352,8 +356,8 @@ CodeGeneratorX64::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins)
|
||||
label = masm.storeRipRelativeInt32(ToRegister(ins->value()));
|
||||
else
|
||||
label = masm.storeRipRelativeDouble(ToFloatRegister(ins->value()));
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -367,8 +371,8 @@ CodeGeneratorX64::visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins)
|
||||
|
||||
CodeOffsetLabel label = masm.leaRipRelative(tmp);
|
||||
masm.loadPtr(Operand(tmp, index, TimesEight, 0), out);
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -377,8 +381,8 @@ CodeGeneratorX64::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins)
|
||||
MAsmJSLoadFFIFunc *mir = ins->mir();
|
||||
|
||||
CodeOffsetLabel label = masm.loadRipRelativeInt64(ToRegister(ins->output()));
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -260,7 +260,7 @@ class Assembler : public AssemblerX86Shared
|
||||
}
|
||||
void mov(AsmJSImmPtr imm, Register dest) {
|
||||
masm.movl_i32r(-1, dest.code());
|
||||
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
|
||||
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
|
||||
}
|
||||
void mov(const Operand &src, Register dest) {
|
||||
movl(src, dest);
|
||||
@ -341,7 +341,7 @@ class Assembler : public AssemblerX86Shared
|
||||
}
|
||||
void cmpl(AsmJSAbsoluteAddress lhs, Register rhs) {
|
||||
masm.cmpl_rm_force32(rhs.code(), (void*)-1);
|
||||
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind()));
|
||||
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind()));
|
||||
}
|
||||
CodeOffsetLabel cmplWithPatch(Register lhs, Imm32 rhs) {
|
||||
masm.cmpl_ir_force32(rhs.value, lhs.code());
|
||||
|
@ -308,7 +308,8 @@ CodeGeneratorX86::loadAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const
|
||||
uint32_t before = masm.size();
|
||||
loadViewTypeElement(vt, srcAddr, out);
|
||||
uint32_t after = masm.size();
|
||||
return masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out)));
|
||||
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -381,7 +382,8 @@ CodeGeneratorX86::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
|
||||
loadViewTypeElement(vt, srcAddr, out);
|
||||
uint32_t after = masm.size();
|
||||
masm.bind(ool->rejoin());
|
||||
return masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out), cmp.offset()));
|
||||
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out), cmp.offset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -420,14 +422,14 @@ CodeGeneratorX86::storeViewTypeElement(ArrayBufferView::ViewType vt, const LAllo
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
void
|
||||
CodeGeneratorX86::storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
|
||||
const T &dstAddr)
|
||||
{
|
||||
uint32_t before = masm.size();
|
||||
storeViewTypeElement(vt, value, dstAddr);
|
||||
uint32_t after = masm.size();
|
||||
return masm.append(AsmJSHeapAccess(before, after));
|
||||
masm.append(AsmJSHeapAccess(before, after));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -463,14 +465,17 @@ CodeGeneratorX86::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
// immediate in the instruction. This displacement will fixed up when the
|
||||
// base address is known during dynamic linking (AsmJSModule::initHeap).
|
||||
PatchedAbsoluteAddress dstAddr((void *) ptr->toConstant()->toInt32());
|
||||
return storeAndNoteViewTypeElement(vt, value, dstAddr);
|
||||
storeAndNoteViewTypeElement(vt, value, dstAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Register ptrReg = ToRegister(ptr);
|
||||
Address dstAddr(ptrReg, 0);
|
||||
|
||||
if (mir->skipBoundsCheck())
|
||||
return storeAndNoteViewTypeElement(vt, value, dstAddr);
|
||||
if (mir->skipBoundsCheck()) {
|
||||
storeAndNoteViewTypeElement(vt, value, dstAddr);
|
||||
return true;
|
||||
}
|
||||
|
||||
CodeOffsetLabel cmp = masm.cmplWithPatch(ptrReg, Imm32(0));
|
||||
Label rejoin;
|
||||
@ -480,7 +485,8 @@ CodeGeneratorX86::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
|
||||
storeViewTypeElement(vt, value, dstAddr);
|
||||
uint32_t after = masm.size();
|
||||
masm.bind(&rejoin);
|
||||
return masm.append(AsmJSHeapAccess(before, after, cmp.offset()));
|
||||
masm.append(AsmJSHeapAccess(before, after, cmp.offset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -497,8 +503,8 @@ CodeGeneratorX86::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins)
|
||||
label = masm.movssWithPatch(PatchedAbsoluteAddress(), ToFloatRegister(ins->output()));
|
||||
else
|
||||
label = masm.movsdWithPatch(PatchedAbsoluteAddress(), ToFloatRegister(ins->output()));
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -516,8 +522,8 @@ CodeGeneratorX86::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins)
|
||||
label = masm.movssWithPatch(ToFloatRegister(ins->value()), PatchedAbsoluteAddress());
|
||||
else
|
||||
label = masm.movsdWithPatch(ToFloatRegister(ins->value()), PatchedAbsoluteAddress());
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -528,8 +534,8 @@ CodeGeneratorX86::visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins)
|
||||
Register index = ToRegister(ins->index());
|
||||
Register out = ToRegister(ins->output());
|
||||
CodeOffsetLabel label = masm.movlWithPatch(PatchedAbsoluteAddress(), index, TimesFour, out);
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -539,8 +545,8 @@ CodeGeneratorX86::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins)
|
||||
|
||||
Register out = ToRegister(ins->output());
|
||||
CodeOffsetLabel label = masm.movlWithPatch(PatchedAbsoluteAddress(), out);
|
||||
|
||||
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
|
||||
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -36,8 +36,8 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
|
||||
void loadViewTypeElement(ArrayBufferView::ViewType vt, const T &srcAddr,
|
||||
const LDefinition *out);
|
||||
template<typename T>
|
||||
bool storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
|
||||
const T &dstAddr);
|
||||
void storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
|
||||
const T &dstAddr);
|
||||
template<typename T>
|
||||
void storeViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
|
||||
const T &dstAddr);
|
||||
|
@ -1195,9 +1195,6 @@ JS_InitStandardClasses(JSContext *cx, HandleObject obj)
|
||||
|
||||
#define EAGER_ATOM(name) NAME_OFFSET(name)
|
||||
|
||||
static js::Class DummyClass;
|
||||
static js::Class SentinelClass;
|
||||
|
||||
typedef struct JSStdName {
|
||||
size_t atomOffset; /* offset of atom pointer in JSAtomState */
|
||||
JSProtoKey key;
|
||||
|
@ -667,6 +667,10 @@ class ArenaLists
|
||||
return arenaListsToSweep[thingKind];
|
||||
}
|
||||
|
||||
ArenaHeader *getArenaAfterCursor(AllocKind thingKind) const {
|
||||
return arenaLists[thingKind].arenaAfterCursor();
|
||||
}
|
||||
|
||||
bool arenaListsAreEmpty() const {
|
||||
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
|
||||
/*
|
||||
@ -780,6 +784,15 @@ class ArenaLists
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if |aheader|'s arena is in use. */
|
||||
bool arenaIsInUse(ArenaHeader *aheader, AllocKind kind) const {
|
||||
JS_ASSERT(aheader);
|
||||
const FreeList &freeList = freeLists[kind];
|
||||
if (freeList.isEmpty())
|
||||
return false;
|
||||
return aheader == freeList.arenaHeader();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void *allocateFromFreeList(AllocKind thingKind, size_t thingSize) {
|
||||
return freeLists[thingKind].allocate(thingSize);
|
||||
}
|
||||
|
@ -176,6 +176,20 @@ nsInlineFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
nsFrameList* overflowFrames = GetOverflowFrames();
|
||||
if (overflowFrames) {
|
||||
// Fixup the parent pointers for any child frames on the OverflowList.
|
||||
// nsIFrame::DestroyFrom depends on that to find the sticky scroll
|
||||
// container (an ancestor).
|
||||
nsIFrame* lineContainer = nsLayoutUtils::FindNearestBlockAncestor(this);
|
||||
DrainSelfOverflowListInternal(eForDestroy, lineContainer);
|
||||
}
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
@ -422,11 +436,12 @@ nsInlineFrame::DrainSelfOverflowListInternal(DrainFlags aFlags,
|
||||
if (aLineContainer && aLineContainer->GetPrevContinuation()) {
|
||||
ReparentFloatsForInlineChild(aLineContainer, firstChild, true);
|
||||
}
|
||||
const bool inFirstLine = (aFlags & eInFirstLine);
|
||||
const bool doReparentSC =
|
||||
(aFlags & eInFirstLine) && !(aFlags & eForDestroy);
|
||||
RestyleManager* restyleManager = PresContext()->RestyleManager();
|
||||
for (nsIFrame* f = firstChild; f; f = f->GetNextSibling()) {
|
||||
f->SetParent(this);
|
||||
if (inFirstLine) {
|
||||
if (doReparentSC) {
|
||||
restyleManager->ReparentStyleContext(f);
|
||||
nsLayoutUtils::MarkDescendantsDirty(f);
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
|
||||
bool aRespectClusters = true) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||
|
||||
// nsIHTMLReflow overrides
|
||||
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
|
||||
InlineMinWidthData *aData) MOZ_OVERRIDE;
|
||||
@ -165,6 +167,9 @@ private:
|
||||
enum DrainFlags {
|
||||
eDontReparentFrames = 1, // skip reparenting the overflow list frames
|
||||
eInFirstLine = 2, // the request is for an inline descendant of a nsFirstLineFrame
|
||||
eForDestroy = 4, // the request is from DestroyFrom; in this case we do the
|
||||
// minimal work required since the frame is about to be
|
||||
// destroyed (just fixup parent pointers)
|
||||
};
|
||||
/**
|
||||
* Move any frames on our overflow list to the end of our principal list.
|
||||
|
@ -1959,7 +1959,7 @@ pref("layout.css.overflow-clip-box.enabled", false);
|
||||
pref("layout.css.grid.enabled", false);
|
||||
|
||||
// Is support for CSS box-decoration-break enabled?
|
||||
pref("layout.css.box-decoration-break.enabled", false);
|
||||
pref("layout.css.box-decoration-break.enabled", true);
|
||||
|
||||
// Is layout of CSS outline-style:auto enabled?
|
||||
pref("layout.css.outline-style-auto.enabled", false);
|
||||
|
@ -1 +1 @@
|
||||
NSPR_4_10_7_BETA2
|
||||
NSPR_4_10_7_BETA3
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user