From 4d40d56ea300617e7ad86e9bcb14c99e0f99fab2 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 03:35:24 -0800 Subject: [PATCH 01/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/5c8b55b95dd9 Author: gitmai Desc: Merge pull request #16735 from gitmai/bug-858017-final-patch Bug 858017 - [COST CONTROL] Use Gecko native support for data usage alar... r=salva ======== https://hg.mozilla.org/integration/gaia-central/rev/3d98ab3248df Author: mai Desc: Bug 858017 - [COST CONTROL] Use Gecko native support for data usage alarms provided by NetworkStats API 2.0 --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index ece5c7e6230a..6937fed60d74 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "3d294ffa51afd8a8daafcdaa97cda8e38de81cb8", + "revision": "5c8b55b95dd9a30501992862b052696de8762494", "repo_path": "/integration/gaia-central" } From 9af62d68a9db62ad8f3cc16cdbeabbd1295915e7 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 03:41:11 -0800 Subject: [PATCH 02/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index fdc91885b4ba..d9af660ccd29 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 921ae49afd1f..ad1a4c91fb68 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index fdc91885b4ba..d9af660ccd29 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index ea35e19c1397..fbaacec055f4 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 6c781f868bca..705bb78af1c8 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 874a55758f0b..d186211d198c 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 8a2daca9c8a9..f87c0adc69f4 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 2c7bf418e310..4cedf12db12f 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index bd8374314906..27130f64fc15 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From a27735235a650c0aac1ed74ff8e0d06f5b610012 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 03:45:27 -0800 Subject: [PATCH 03/69] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/9ada9e6a6c2e Author: vingtetun <21@vingtetun.org> Desc: Merge pull request #16782 from vingtetun/bug978632 Bug 978632 - Prevent a click to fire when the home button is pressed on ... ======== https://hg.mozilla.org/integration/gaia-central/rev/9a38bcdb6891 Author: Vivien Nicolas <21@vingtetun.org> Desc: Bug 978632 - Prevent a click to fire when the home button is pressed on some devices. r=alive ======== https://hg.mozilla.org/integration/gaia-central/rev/58369bc13102 Author: vingtetun <21@vingtetun.org> Desc: Merge pull request #16784 from vingtetun/bug978569 Bug 978569 - Can not use APP=homescreen anymore. r=crdlc ======== https://hg.mozilla.org/integration/gaia-central/rev/8f3b15bea0fe Author: Vivien Nicolas <21@vingtetun.org> Desc: Bug 978569 - Can not use APP=homescreen anymore. r=crdlc --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 6937fed60d74..5b35a76e4d91 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "5c8b55b95dd9a30501992862b052696de8762494", + "revision": "9ada9e6a6c2ecd04f915e7f1a618d5ecf6e2d3ca", "repo_path": "/integration/gaia-central" } From 2cfb3c7f66916836902405d937c3caaf770c307f Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 03:46:44 -0800 Subject: [PATCH 04/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index d9af660ccd29..3eda32758297 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index ad1a4c91fb68..9e34676ebbda 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index d9af660ccd29..3eda32758297 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index fbaacec055f4..9ae54d0e7768 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 705bb78af1c8..38cbd6340271 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index d186211d198c..3344410f22b2 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index f87c0adc69f4..f217440d8eab 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 4cedf12db12f..e0de86792de1 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 27130f64fc15..ddab03364822 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From d3e5381cea0f717911a1b1a1c6d897377bcb550e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Mar 2014 13:07:16 +0100 Subject: [PATCH 05/69] Bug 977146: Set PROP_BLUETOOTH_ENABLED in ToggleBtAck, r=echou PROP_BLUETOOTH_ENABLED signals the Bluetooth state to other components in the system. Setting its value in ToggleBtAck on the main thread avoids duplicated code in the upcoming patches. --- dom/bluetooth/BluetoothService.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dom/bluetooth/BluetoothService.cpp b/dom/bluetooth/BluetoothService.cpp index 3699517f32f9..0b31ef6b7d65 100644 --- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -145,6 +145,19 @@ public: { MOZ_ASSERT(NS_IsMainThread()); + // This is requested in Bug 836516. With settings this property, WLAN + // firmware could be aware of Bluetooth has been turned on/off, so that the + // mecahnism of handling coexistence of WIFI and Bluetooth could be started. + // + // In the future, we may have our own way instead of setting a system + // property to let firmware developers be able to sense that Bluetooth has + // been toggled. +#if defined(MOZ_WIDGET_GONK) + if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) { + BT_WARNING("Failed to set bluetooth enabled property"); + } +#endif + NS_ENSURE_TRUE(sBluetoothService, NS_OK); if (sInShutdown) { @@ -215,19 +228,6 @@ public: } } - // This is requested in Bug 836516. With settings this property, WLAN - // firmware could be aware of Bluetooth has been turned on/off, so that the - // mecahnism of handling coexistence of WIFI and Bluetooth could be started. - // - // In the future, we may have our own way instead of setting a system - // property to let firmware developers be able to sense that Bluetooth has - // been toggled. -#if defined(MOZ_WIDGET_GONK) - if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) { - BT_WARNING("Failed to set bluetooth enabled property"); - } -#endif - nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(mEnabled); if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { BT_WARNING("Failed to dispatch to main thread!"); From bb87fe4d2804c9f6253e99cd8817bff16474a822 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Mar 2014 13:07:17 +0100 Subject: [PATCH 06/69] Bug 977146: Declare ToggleBtAck in header file, r=echou Declaring ToggleBtAck in the header file of BluetoothService makes it available ot others classes. --- dom/bluetooth/BluetoothService.cpp | 81 ++++++++++++++---------------- dom/bluetooth/BluetoothService.h | 15 ++++-- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/dom/bluetooth/BluetoothService.cpp b/dom/bluetooth/BluetoothService.cpp index 0b31ef6b7d65..7db4e2659d62 100644 --- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -34,7 +34,6 @@ #include "nsISystemMessagesInternal.h" #include "nsITimer.h" #include "nsServiceManagerUtils.h" -#include "nsThreadUtils.h" #include "nsXPCOM.h" #if defined(MOZ_WIDGET_GONK) @@ -132,59 +131,53 @@ GetAllBluetoothActors(InfallibleTArray& aActors) } // anonymous namespace -class BluetoothService::ToggleBtAck : public nsRunnable +BluetoothService::ToggleBtAck::ToggleBtAck(bool aEnabled) + : mEnabled(aEnabled) { -public: - ToggleBtAck(bool aEnabled) - : mEnabled(aEnabled) - { - MOZ_ASSERT(!NS_IsMainThread()); - } + MOZ_ASSERT(!NS_IsMainThread()); +} - NS_IMETHOD Run() - { - MOZ_ASSERT(NS_IsMainThread()); +NS_METHOD +BluetoothService::ToggleBtAck::Run() +{ + MOZ_ASSERT(NS_IsMainThread()); - // This is requested in Bug 836516. With settings this property, WLAN - // firmware could be aware of Bluetooth has been turned on/off, so that the - // mecahnism of handling coexistence of WIFI and Bluetooth could be started. - // - // In the future, we may have our own way instead of setting a system - // property to let firmware developers be able to sense that Bluetooth has - // been toggled. + // This is requested in Bug 836516. With settings this property, WLAN + // firmware could be aware of Bluetooth has been turned on/off, so that the + // mecahnism of handling coexistence of WIFI and Bluetooth could be started. + // + // In the future, we may have our own way instead of setting a system + // property to let firmware developers be able to sense that Bluetooth has + // been toggled. #if defined(MOZ_WIDGET_GONK) - if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) { - BT_WARNING("Failed to set bluetooth enabled property"); - } + if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) { + BT_WARNING("Failed to set bluetooth enabled property"); + } #endif - NS_ENSURE_TRUE(sBluetoothService, NS_OK); - - if (sInShutdown) { - sBluetoothService = nullptr; - return NS_OK; - } - - // Update mEnabled of BluetoothService object since - // StartInternal/StopInternal have been already done. - sBluetoothService->SetEnabled(mEnabled); - sToggleInProgress = false; - - nsAutoString signalName; - signalName = mEnabled ? NS_LITERAL_STRING("Enabled") - : NS_LITERAL_STRING("Disabled"); - BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), true); - sBluetoothService->DistributeSignal(signal); - - // Event 'AdapterAdded' has to be fired after firing 'Enabled' - sBluetoothService->TryFiringAdapterAdded(); + NS_ENSURE_TRUE(sBluetoothService, NS_OK); + if (sInShutdown) { + sBluetoothService = nullptr; return NS_OK; } -private: - bool mEnabled; -}; + // Update mEnabled of BluetoothService object since + // StartInternal/StopInternal have been already done. + sBluetoothService->SetEnabled(mEnabled); + sToggleInProgress = false; + + nsAutoString signalName; + signalName = mEnabled ? NS_LITERAL_STRING("Enabled") + : NS_LITERAL_STRING("Disabled"); + BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), true); + sBluetoothService->DistributeSignal(signal); + + // Event 'AdapterAdded' has to be fired after firing 'Enabled' + sBluetoothService->TryFiringAdapterAdded(); + + return NS_OK; +} class BluetoothService::ToggleBtTask : public nsRunnable { diff --git a/dom/bluetooth/BluetoothService.h b/dom/bluetooth/BluetoothService.h index a20995ec83b2..6a93a4ed55ea 100644 --- a/dom/bluetooth/BluetoothService.h +++ b/dom/bluetooth/BluetoothService.h @@ -16,6 +16,7 @@ #include "nsIObserver.h" #include "nsIThread.h" #include "nsTObserverArray.h" +#include "nsThreadUtils.h" namespace mozilla { namespace ipc { @@ -35,9 +36,6 @@ typedef mozilla::ObserverList BluetoothSignalObserverList; class BluetoothService : public nsIObserver , public BluetoothSignalObserver { - class ToggleBtAck; - friend class ToggleBtAck; - class ToggleBtTask; friend class ToggleBtTask; @@ -45,6 +43,17 @@ class BluetoothService : public nsIObserver friend class StartupTask; public: + class ToggleBtAck : public nsRunnable + { + public: + ToggleBtAck(bool aEnabled); + NS_IMETHOD Run(); + + private: + bool mEnabled; + }; + friend class ToggleBtAck; + NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER From 3f6340544d30780888fc9f408cf99c763c049cd8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 3 Mar 2014 13:07:17 +0100 Subject: [PATCH 07/69] Bug 977146: Push ToggleBtAck into implementations of {Start|Stop}Internal, r=echou The methods {Start|Stop}Internal for BlueZ and Bluedroid now send ToggleBtAck to signal completeness of the operation. The current patch allows for further cleanups in the BlueZ code. It does not change the semantics or code flow. --- dom/bluetooth/BluetoothService.cpp | 9 +++-- .../bluedroid/BluetoothServiceBluedroid.cpp | 18 ++++++++++ dom/bluetooth/bluez/BluetoothDBusService.cpp | 33 +++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/dom/bluetooth/BluetoothService.cpp b/dom/bluetooth/BluetoothService.cpp index 7db4e2659d62..b29d505f09ab 100644 --- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -206,6 +206,10 @@ public: */ if (!mIsStartup && mEnabled == sBluetoothService->IsEnabledInternal()) { BT_WARNING("Bluetooth has already been enabled/disabled before."); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(mEnabled); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } } else { // Switch on/off bluetooth if (mEnabled) { @@ -221,11 +225,6 @@ public: } } - nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(mEnabled); - if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { - BT_WARNING("Failed to dispatch to main thread!"); - } - return NS_OK; } diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 560f165c3c0c..780dee06ad21 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -741,9 +741,18 @@ BluetoothServiceBluedroid::StartInternal() nsresult ret = StartStopGonkBluetooth(true); if (NS_FAILED(ret)) { + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } BT_LOGR("Error"); } + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + return ret; } @@ -754,9 +763,18 @@ BluetoothServiceBluedroid::StopInternal() nsresult ret = StartStopGonkBluetooth(false); if (NS_FAILED(ret)) { + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } BT_LOGR("Error"); } + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + return ret; } diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp index c5872a3b3f38..f8a21885e9c5 100644 --- a/dom/bluetooth/bluez/BluetoothDBusService.cpp +++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp @@ -1889,12 +1889,20 @@ BluetoothDBusService::StartInternal() if (sDBusConnection) { // This should actually not happen. BT_WARNING("Bluetooth is already running"); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_OK; } #ifdef MOZ_WIDGET_GONK if (!sBluedroid.Enable()) { BT_WARNING("Bluetooth not available."); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_ERROR_FAILURE; } #endif @@ -1903,6 +1911,10 @@ BluetoothDBusService::StartInternal() nsresult rv = connection->EstablishDBusConnection(); if (NS_FAILED(rv)) { BT_WARNING("Failed to establish connection to BlueZ daemon"); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_ERROR_FAILURE; } @@ -1926,6 +1938,10 @@ BluetoothDBusService::StartInternal() if (!dbus_connection_add_filter(connection->GetConnection(), EventFilter, nullptr, nullptr)) { BT_WARNING("Cannot create DBus Event Filter for DBus Thread!"); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_ERROR_FAILURE; } @@ -1938,6 +1954,11 @@ BluetoothDBusService::StartInternal() Task* task = new StartDBusConnectionTask(connection, sAdapterPath.IsEmpty()); DispatchToDBusThread(task); + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + return NS_OK; } @@ -1985,6 +2006,10 @@ BluetoothDBusService::StopInternal() } if (!sDBusConnection) { + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_OK; } @@ -2032,10 +2057,18 @@ BluetoothDBusService::StopInternal() #ifdef MOZ_WIDGET_GONK MOZ_ASSERT(sBluedroid.IsEnabled()); if (!sBluedroid.Disable()) { + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_ERROR_FAILURE; } #endif + nsCOMPtr ackTask = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(ackTask))) { + BT_WARNING("Failed to dispatch to main thread!"); + } return NS_OK; } From 4f529efb1fd78480c303d3e641afc8c1f3aeaa21 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 04:10:31 -0800 Subject: [PATCH 08/69] Bumping gaia.json for 3 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/0ce660ecc56b Author: Zac Desc: Merge pull request #16565 from bebef1987/test_clock Bug 971640 - Intermittents in all clock tests ======== https://hg.mozilla.org/integration/gaia-central/rev/1f3e31dcced3 Author: Bebe Desc: wip ======== https://hg.mozilla.org/integration/gaia-central/rev/b90481be5dec Author: Dale Harvey Desc: Bug 978038 - Add verbose flag to make test-integration. r=gaye --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 5b35a76e4d91..8a6b246dabab 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "9ada9e6a6c2ecd04f915e7f1a618d5ecf6e2d3ca", + "revision": "0ce660ecc56b6efe77d88ba6573aab6b804e25b1", "repo_path": "/integration/gaia-central" } From ed403725f33004f3f932cc5046cfaa38b410f314 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 04:15:59 -0800 Subject: [PATCH 09/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 3eda32758297..a0585ce25ff0 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 9e34676ebbda..ea479174747a 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 3eda32758297..a0585ce25ff0 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 9ae54d0e7768..33411d097d04 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 38cbd6340271..7c48565a14b1 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 3344410f22b2..0d7f66bc95ac 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index f217440d8eab..d24fa1f03b22 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index e0de86792de1..47907d567896 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index ddab03364822..b20c30267db3 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 6b0c83b7f8de15922df0dffe13015a5926c25abc Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:00:23 -0800 Subject: [PATCH 10/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/613b95012e02 Author: vingtetun <21@vingtetun.org> Desc: Merge pull request #16783 from vingtetun/bug978546 Bug 978546 - Do not dispatch touch events to the current app while dragg... ======== https://hg.mozilla.org/integration/gaia-central/rev/7af15c7e4156 Author: Vivien Nicolas <21@vingtetun.org> Desc: Bug 978546 - Do not dispatch touch events to the current app while dragging the utility-tray. r=etienne --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 8a6b246dabab..9ca9718a73db 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "0ce660ecc56b6efe77d88ba6573aab6b804e25b1", + "revision": "613b95012e024fd7355fbdaeb24895d38bd17a20", "repo_path": "/integration/gaia-central" } From c43ebb041397bcc878c796629fd5b3157660173e Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:06:15 -0800 Subject: [PATCH 11/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index a0585ce25ff0..2aa096b88c75 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index ea479174747a..496184c2b41b 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index a0585ce25ff0..2aa096b88c75 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 33411d097d04..e099f78deb3b 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 7c48565a14b1..4a44fae8056a 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 0d7f66bc95ac..a7ceb25f3bb8 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index d24fa1f03b22..74189127551c 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 47907d567896..dbcd015f81a4 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index b20c30267db3..c03881c584fc 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 4d8b05c1f1d47bf76be833f7f2293ad1396be174 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:40:22 -0800 Subject: [PATCH 12/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/3a3c79436baa Author: Zac Desc: Merge pull request #16781 from viorelaioia/bug_978099 Bug 978099 - Better wait in test_video_empty.TestVideoEmpty ======== https://hg.mozilla.org/integration/gaia-central/rev/f10812ad3ca8 Author: Viorela Ioia Desc: Bug 978099 - Better wait in test_video_empty.TestVideoEmpty --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 9ca9718a73db..9d52f10a15a3 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "613b95012e024fd7355fbdaeb24895d38bd17a20", + "revision": "3a3c79436baa9c00f9664289456bb6864fa82c40", "repo_path": "/integration/gaia-central" } From 21bc9172fad832a0c165b9ab795243ec197da239 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:41:28 -0800 Subject: [PATCH 13/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2aa096b88c75..1cecd86cd249 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 496184c2b41b..24a5a4a06150 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2aa096b88c75..1cecd86cd249 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index e099f78deb3b..c7fa6c846562 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 4a44fae8056a..6a5fe68fc75c 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index a7ceb25f3bb8..b2bf5b045b74 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 74189127551c..71fe52fc912f 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index dbcd015f81a4..d011cbea1127 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index c03881c584fc..ac02d4282c6c 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From f42d8ffae26c1e370b42096d1f3ecc6bba28fe76 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:50:23 -0800 Subject: [PATCH 14/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/601a368b2665 Author: Andrew Sutherland Desc: Merge pull request #16793 from asutherland/email-gelam-cleanup Bug 978012 - [email] Remove dead/obsolete GELAM-built JS blobs and fix GELAM to clean out ext/ before installing. r=mcav ======== https://hg.mozilla.org/integration/gaia-central/rev/b1231f4dee15 Author: Andrew Sutherland Desc: Bug 978012 - [email] Remove dead/obsolete GELAM-built JS blobs and fix GELAM to clean out ext/ before installing. r=mcav land https://github.com/mozilla-b2g/gaia-email-libs-and-more/pull/289 --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 9d52f10a15a3..e53553785cff 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "3a3c79436baa9c00f9664289456bb6864fa82c40", + "revision": "601a368b2665f9c7d3442463fe0dd834033912f0", "repo_path": "/integration/gaia-central" } From 8dc2d71bf279c16132f107dd877a629e3f7159a2 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 05:51:29 -0800 Subject: [PATCH 15/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 1cecd86cd249..b6ee78a45a6c 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 24a5a4a06150..568627fab72a 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 1cecd86cd249..b6ee78a45a6c 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index c7fa6c846562..75655078f7a5 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 6a5fe68fc75c..623bf72df52c 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index b2bf5b045b74..8a81fcc7f736 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 71fe52fc912f..f410228857f5 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index d011cbea1127..0e919a219cbf 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index ac02d4282c6c..23de5b394b68 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 5a2804b5afcb985275c546298abd876f9278d39a Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 06:55:51 -0800 Subject: [PATCH 16/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/3bafd28fc904 Author: Jose Antonio Olivera Ortega Desc: Merge pull request #16631 from jaoo/971816 Bug 971816 - [OTA][Data Migration] Voicemail number will restored back default setting in SIM card after updating from v1.1 to v1.3. r=qDot ======== https://hg.mozilla.org/integration/gaia-central/rev/069f2e7ca4e0 Author: Jose Antonio Olivera Ortega Desc: Bug 971816 - [OTA][Data Migration] Voicemail number will restored back default setting in SIM card after updating from v1.1 to v1.3 --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index e53553785cff..2b53b603600f 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "601a368b2665f9c7d3442463fe0dd834033912f0", + "revision": "3bafd28fc904536eb1f1f9b2a7a2cefb0c99afde", "repo_path": "/integration/gaia-central" } From d1e559fec2efe78f73e5f44fe66b649216a2a2f3 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 07:01:10 -0800 Subject: [PATCH 17/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index b6ee78a45a6c..aae4793da7ab 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 568627fab72a..64068402c330 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index b6ee78a45a6c..aae4793da7ab 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 75655078f7a5..2acc5cd08a00 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 623bf72df52c..5dd216a307d9 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 8a81fcc7f736..88f88fd9914f 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index f410228857f5..f2110b0ae739 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 0e919a219cbf..3d56df12f440 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 23de5b394b68..37edea70c69b 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From c26e3d45984e33772384c56d79d8ef41f4a64996 Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Mon, 3 Mar 2014 07:12:52 -0800 Subject: [PATCH 18/69] Bug 977777 - Add fence handling to GonkNativeWindowKK r=pchang,schiu --- .../gonk/nativewindow/GonkNativeWindowKK.cpp | 34 +++++++++++++++---- widget/gonk/nativewindow/GonkNativeWindowKK.h | 20 ++--------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/widget/gonk/nativewindow/GonkNativeWindowKK.cpp b/widget/gonk/nativewindow/GonkNativeWindowKK.cpp index 888d8cdfd974..341bb5e2d720 100644 --- a/widget/gonk/nativewindow/GonkNativeWindowKK.cpp +++ b/widget/gonk/nativewindow/GonkNativeWindowKK.cpp @@ -133,17 +133,20 @@ GonkNativeWindow::getCurrentBuffer() } bool -GonkNativeWindow::returnBuffer(uint32_t aIndex, uint32_t aGeneration) { - BI_LOGD("GonkNativeWindow::returnBuffer: slot=%d (generation=%d)", aIndex, aGeneration); +GonkNativeWindow::returnBuffer(uint32_t index, uint32_t generation, const sp& fence) { + BI_LOGD("GonkNativeWindow::returnBuffer: slot=%d (generation=%d)", index, generation); Mutex::Autolock lock(mMutex); - if (aGeneration != mConsumer->getGeneration()) { + if (generation != mConsumer->getGeneration()) { BI_LOGD("returnBuffer: buffer is from generation %d (current is %d)", - aGeneration, mConsumer->getGeneration()); + generation, mConsumer->getGeneration()); return false; } - status_t err = releaseBufferLocked(aIndex, mSlots[aIndex].mGraphicBuffer); + status_t err; + err = addReleaseFenceLocked(index, mSlots[index].mGraphicBuffer, fence); + + err = releaseBufferLocked(index, mSlots[index].mGraphicBuffer); if (err != NO_ERROR) { return false; } @@ -151,8 +154,7 @@ GonkNativeWindow::returnBuffer(uint32_t aIndex, uint32_t aGeneration) { } mozilla::layers::SurfaceDescriptor * -GonkNativeWindow::getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer) -{ +GonkNativeWindow::getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer) { Mutex::Autolock lock(mMutex); return mConsumer->getSurfaceDescriptorFromBuffer(buffer); @@ -172,4 +174,22 @@ void GonkNativeWindow::onFrameAvailable() { } } +void CameraGraphicBuffer::Unlock() { + if (mLocked) { + android::sp fence; + fence = mReleaseFenceHandle.IsValid() ? mReleaseFenceHandle.mFence : Fence::NO_FENCE; + // The window might have been destroyed. The buffer is no longer + // valid at that point. + sp window = mNativeWindow.promote(); + if (window.get() && window->returnBuffer(mIndex, mGeneration, fence)) { + mLocked = false; + } else { + // If the window doesn't exist any more, release the buffer + // directly. + ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton(); + ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor); + } + } +} + } // namespace android diff --git a/widget/gonk/nativewindow/GonkNativeWindowKK.h b/widget/gonk/nativewindow/GonkNativeWindowKK.h index 5ef0be60b0fc..3837d3e56b46 100644 --- a/widget/gonk/nativewindow/GonkNativeWindowKK.h +++ b/widget/gonk/nativewindow/GonkNativeWindowKK.h @@ -117,7 +117,7 @@ class GonkNativeWindow: public GonkConsumerBase // Return the buffer to the queue and mark it as FREE. After that // the buffer is useable again for the decoder. - bool returnBuffer(uint32_t index, uint32_t generation); + bool returnBuffer(uint32_t index, uint32_t generation, const sp& fence); SurfaceDescriptor* getSurfaceDescriptorFromBuffer(ANativeWindowBuffer* buffer); @@ -155,24 +155,10 @@ public: DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); } +protected: // Unlock either returns the buffer to the native window or // destroys the buffer if the window is already released. - virtual void Unlock() MOZ_OVERRIDE - { - if (mLocked) { - // The window might have been destroyed. The buffer is no longer - // valid at that point. - sp window = mNativeWindow.promote(); - if (window.get() && window->returnBuffer(mIndex, mGeneration)) { - mLocked = false; - } else { - // If the window doesn't exist any more, release the buffer - // directly. - ImageBridgeChild *ibc = ImageBridgeChild::GetSingleton(); - ibc->DeallocSurfaceDescriptorGralloc(mSurfaceDescriptor); - } - } - } + virtual void Unlock() MOZ_OVERRIDE; protected: wp mNativeWindow; From 98714c3135c029e242cc9e1ca0b083e33f33fcfe Mon Sep 17 00:00:00 2001 From: Jamin Liu Date: Mon, 3 Mar 2014 10:20:24 -0500 Subject: [PATCH 19/69] Bug 972730 - Avoid disabling BT before the BT adapter is initialized in marionette test. r=echou, f=vicamo The current Bluetooth API can't allow user to disable BT before the BT adapter is initialized. In practice, We block the clicking event in gaia layer to prevent user to turn off BT before BT enable procedure complete. If we use marionette test to force emulator turn on and turn off BT in a short period of time, it may crash emulator. Listen to 'adapteradded' event rather than 'enabled' as the end of BT enable to make sure we wouldn't disable BT when it's not ready. --- .../marionette/test_dom_BluetoothManager_enabled.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dom/bluetooth/tests/marionette/test_dom_BluetoothManager_enabled.js b/dom/bluetooth/tests/marionette/test_dom_BluetoothManager_enabled.js index 48054bfd35db..005cbfcb248c 100644 --- a/dom/bluetooth/tests/marionette/test_dom_BluetoothManager_enabled.js +++ b/dom/bluetooth/tests/marionette/test_dom_BluetoothManager_enabled.js @@ -11,14 +11,18 @@ function waitEitherEnabledOrDisabled() { let deferred = Promise.defer(); function onEnabledDisabled(aEvent) { - bluetoothManager.removeEventListener("enabled", onEnabledDisabled); + bluetoothManager.removeEventListener("adapteradded", onEnabledDisabled); bluetoothManager.removeEventListener("disabled", onEnabledDisabled); ok(true, "Got event " + aEvent.type); - deferred.resolve(aEvent.type === "enabled"); + deferred.resolve(aEvent.type === "adapteradded"); } - bluetoothManager.addEventListener("enabled", onEnabledDisabled); + // Listen 'adapteradded' rather than 'enabled' since the current API can't + // disable BT before the BT adapter is initialized. + // We should listen to 'enabled' when gecko can handle the case I mentioned + // above, please refer to the follow-up bug 973482. + bluetoothManager.addEventListener("adapteradded", onEnabledDisabled); bluetoothManager.addEventListener("disabled", onEnabledDisabled); return deferred.promise; @@ -39,7 +43,7 @@ function test(aEnabled) { log(" Examine results " + JSON.stringify(aResults)); is(bluetoothManager.enabled, aEnabled, "bluetoothManager.enabled"); - is(aResults[1], aEnabled, "'enabled' event received"); + is(aResults[1], aEnabled, "'adapteradded' event received"); if (bluetoothManager.enabled === aEnabled && aResults[1] === aEnabled) { deferred.resolve(); From ab9e7fd8693b711c944c8759ea93bc98b60c31d2 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 07:20:39 -0800 Subject: [PATCH 20/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/c8c6a86eeecf Author: Cristian Rodriguez Desc: Merge pull request #16794 from crdlc/bug-978739 Bug 978739 - After rebooting users are not able to delete/open bookmarks from... ======== https://hg.mozilla.org/integration/gaia-central/rev/129f294dcb2b Author: crdlc Desc: Bug 978739 - After rebooting users are not able to delete bookmarks from homescreen --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 2b53b603600f..7cc100696796 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "3bafd28fc904536eb1f1f9b2a7a2cefb0c99afde", + "revision": "c8c6a86eeecfa6c1383b303ad44d28ee216ae20e", "repo_path": "/integration/gaia-central" } From eae160f4c71b5ae67c735cefa235b1ca5668283d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 07:25:57 -0800 Subject: [PATCH 21/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index aae4793da7ab..6922135c31e1 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 64068402c330..945e2033c73b 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index aae4793da7ab..6922135c31e1 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 2acc5cd08a00..e8d6a95f23e7 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 5dd216a307d9..140f842df4ec 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 88f88fd9914f..ef6382b1c98c 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index f2110b0ae739..be855365ef21 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 3d56df12f440..fd1235e3a293 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 37edea70c69b..efa9f39c7a2a 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 2fb219428c99e562b8da914e88db8a2a8d232e3b Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 07:35:24 -0800 Subject: [PATCH 22/69] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/a1b1c4183f9a Author: vingtetun <21@vingtetun.org> Desc: Merge pull request #16795 from vingtetun/bug978632.tests Bug 978632 - Prevent a click to fire when the home button is pressed on ... ======== https://hg.mozilla.org/integration/gaia-central/rev/3df6e3e8ce4b Author: Vivien Nicolas <21@vingtetun.org> Desc: Bug 978632 - Prevent a click to fire when the home button is pressed on some devices. Tests. r=etienne ======== https://hg.mozilla.org/integration/gaia-central/rev/c83ba238fe73 Author: Kevin Grandon Desc: Merge pull request #16547 from KevinGrandon/bug_952415_search_deduplication Bug 952415 - [Rocketbar] Duplicate results should not appear. ======== https://hg.mozilla.org/integration/gaia-central/rev/8cbf3c593906 Author: Kevin Grandon Desc: Bug 952415 - [Rocketbar] Duplicate results should not appear. r=armin --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7cc100696796..21d9f369e750 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "c8c6a86eeecfa6c1383b303ad44d28ee216ae20e", + "revision": "a1b1c4183f9abe01f9b9a2d9c8b5cee935127592", "repo_path": "/integration/gaia-central" } From 55f1c6f3782a9c231f1614ad5138404b443ad4c1 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 07:41:15 -0800 Subject: [PATCH 23/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 6922135c31e1..c2873ffa7ce9 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 945e2033c73b..ca86e2829c75 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 6922135c31e1..c2873ffa7ce9 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index e8d6a95f23e7..a606aea85052 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 140f842df4ec..9bb58a7c0da6 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index ef6382b1c98c..5bd827d41c72 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index be855365ef21..a1a02f955215 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index fd1235e3a293..76e9678621bb 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index efa9f39c7a2a..fa1035934bec 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 7cf6076538e712a9f9c5c6543dd9248c484fba21 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 08:25:23 -0800 Subject: [PATCH 24/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/8b0bebc9fe09 Author: Fernando Campo Desc: Merge pull request #16626 from fcampo/fix-ftu-email-scroll Bug 969230 - [FTE] Email address field is covered by keyboard in about B2G OS page (r=arcturus) ======== https://hg.mozilla.org/integration/gaia-central/rev/8e35de08a128 Author: Fernando Campo Desc: Bug 969230 - [FTE] Email address field is covered by keyboard in about B2G OS page --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 21d9f369e750..1928ee92d030 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "a1b1c4183f9abe01f9b9a2d9c8b5cee935127592", + "revision": "8b0bebc9fe09fae4e7c33f0eb43eed5cd00b050e", "repo_path": "/integration/gaia-central" } From b0274a62ca33fac4253a2b76aa1bed6de4fac224 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 08:31:16 -0800 Subject: [PATCH 25/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index c2873ffa7ce9..5b2941158f6e 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index ca86e2829c75..1b035d1071bc 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index c2873ffa7ce9..5b2941158f6e 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index a606aea85052..b84c7ec2989d 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 9bb58a7c0da6..9213f24bbadf 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 5bd827d41c72..0583457c0faf 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index a1a02f955215..487a268e85fe 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 76e9678621bb..d9a54d01b848 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index fa1035934bec..4365dbd2ecdb 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From f6d0d6ba202443cfa77bb7878a451529c2f538e9 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 18 Feb 2014 21:59:34 -0500 Subject: [PATCH 26/69] Bug 958596 - Allow gfx/2d/Logging.h to be used outside of gfx/2d. r=Bas --- configure.in | 1 + gfx/2d/Factory.cpp | 6 +++--- gfx/2d/Logging.h | 17 ++++++++++++----- gfx/2d/Rect.h | 2 +- gfx/2d/Types.h | 2 +- gfx/2d/moz.build | 1 + 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/configure.in b/configure.in index 7bdc6c4a332a..526cc0752411 100644 --- a/configure.in +++ b/configure.in @@ -7740,6 +7740,7 @@ XPCOM_LIBS="$LIBXUL_LIBS" if test "$OS_ARCH" = "WINNT"; then GKMEDIAS_SHARED_LIBRARY=1 + AC_DEFINE(GKMEDIAS_SHARED_LIBRARY) fi AC_SUBST(GKMEDIAS_SHARED_LIBRARY) diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 86f740c235eb..2e3d3b14bce6 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -53,8 +53,8 @@ #include "mozilla/CheckedInt.h" -#ifdef PR_LOGGING -PRLogModuleInfo * +#if defined(DEBUG) || defined(PR_LOGGING) +GFX2D_API PRLogModuleInfo * GetGFX2DLog() { static PRLogModuleInfo *sLog; @@ -156,7 +156,7 @@ namespace mozilla { namespace gfx { // XXX - Need to define an API to set this. -int sGfxLogLevel = LOG_DEBUG; +GFX2D_API int sGfxLogLevel = LOG_DEBUG; #ifdef WIN32 ID3D10Device1 *Factory::mD3D10Device; diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 4b6bda276aac..c452a924f5e7 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -14,13 +14,20 @@ #include "Matrix.h" #ifdef WIN32 -#include +// This file gets included from nsGlobalWindow.cpp, which doesn't like +// having windows.h included in it. Since OutputDebugStringA is the only +// thing we need from windows.h, we just declare it here directly. +// Note: the function's documented signature is +// WINBASEAPI void WINAPI OutputDebugStringA(LPCSTR lpOutputString) +// but if we don't include windows.h, the macros WINBASEAPI, WINAPI, and +// LPCSTR are not defined, so we need to replace them with their expansions. +extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString); #endif -#ifdef PR_LOGGING +#if defined(DEBUG) || defined(PR_LOGGING) #include -extern PRLogModuleInfo *GetGFX2DLog(); +extern GFX2D_API PRLogModuleInfo *GetGFX2DLog(); #endif namespace mozilla { @@ -29,7 +36,7 @@ namespace gfx { const int LOG_DEBUG = 1; const int LOG_WARNING = 2; -#ifdef PR_LOGGING +#if defined(DEBUG) || defined(PR_LOGGING) inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) { switch (aLevel) { @@ -43,7 +50,7 @@ inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) { #endif -extern int sGfxLogLevel; +extern GFX2D_API int sGfxLogLevel; static inline void OutputMessage(const std::string &aString, int aLevel) { #if defined(WIN32) && !defined(PR_LOGGING) diff --git a/gfx/2d/Rect.h b/gfx/2d/Rect.h index 647244284357..7f52af898351 100644 --- a/gfx/2d/Rect.h +++ b/gfx/2d/Rect.h @@ -97,7 +97,7 @@ struct RectTyped : Super(float(rect.x), float(rect.y), float(rect.width), float(rect.height)) {} - GFX2D_API void NudgeToIntegers() + void NudgeToIntegers() { NudgeToInteger(&(this->x)); NudgeToInteger(&(this->y)); diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h index ec0943334470..f59e8956d737 100644 --- a/gfx/2d/Types.h +++ b/gfx/2d/Types.h @@ -246,7 +246,7 @@ struct GradientStop } } -#if defined(XP_WIN) && defined(MOZ_GFX) +#if defined(XP_WIN) && defined(GKMEDIAS_SHARED_LIBRARY) #ifdef GFX2D_INTERNAL #define GFX2D_API __declspec(dllexport) #else diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build index 45d9bb554840..54bbcbcf2ad0 100644 --- a/gfx/2d/moz.build +++ b/gfx/2d/moz.build @@ -21,6 +21,7 @@ EXPORTS.mozilla.gfx += [ 'DataSurfaceHelpers.h', 'Filters.h', 'Helpers.h', + 'Logging.h', 'Matrix.h', 'PathHelpers.h', 'Point.h', From c021a65b4fa24ff7a8b6f220a8908d6337a132a5 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 20:11:52 -0500 Subject: [PATCH 27/69] Bug 958596 - Add support for gfx logging on android and b2g. r=Bas --- gfx/2d/Logging.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index c452a924f5e7..788ad32de203 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -10,6 +10,7 @@ #include #include +#include "nsDebug.h" #include "Point.h" #include "Matrix.h" @@ -57,13 +58,13 @@ static inline void OutputMessage(const std::string &aString, int aLevel) { if (aLevel >= sGfxLogLevel) { ::OutputDebugStringA(aString.c_str()); } -#elif defined(PR_LOGGING) +#elif defined(PR_LOGGING) && !(defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)) if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) { PR_LogPrint(aString.c_str()); } #else if (aLevel >= sGfxLogLevel) { - printf("%s", aString.c_str()); + printf_stderr("%s", aString.c_str()); } #endif } From af90204ad92cd27ca35d2d5ef636a1d9eca9b916 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 20:26:00 -0500 Subject: [PATCH 28/69] Bug 958596 - Add gfx logging support for 'char'. r=Bas --- gfx/2d/Logging.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 788ad32de203..32b49c443caa 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -86,6 +86,7 @@ public: Log() {} ~Log() { mMessage << '\n'; WriteLog(mMessage.str()); } + Log &operator <<(char aChar) { mMessage << aChar; return *this; } Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; } Log &operator <<(const char aStr[]) { mMessage << static_cast(aStr); return *this; } Log &operator <<(bool aBool) { mMessage << (aBool ? "true" : "false"); return *this; } From fb245221ef14c48ca60c58b2a544e14c3c8efcee Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 18:38:34 -0500 Subject: [PATCH 29/69] Bug 958596 - Allow gfx logging of any rect, size, and point. r=Bas --- gfx/2d/Logging.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 32b49c443caa..4a85bf45e000 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -12,6 +12,7 @@ #include "nsDebug.h" #include "Point.h" +#include "BaseRect.h" #include "Matrix.h" #ifdef WIN32 @@ -96,13 +97,14 @@ public: Log &operator <<(unsigned long aLong) { mMessage << aLong; return *this; } Log &operator <<(Float aFloat) { mMessage << aFloat; return *this; } Log &operator <<(double aDouble) { mMessage << aDouble; return *this; } - Log &operator <<(const Point &aPoint) + template + Log &operator <<(const BasePoint& aPoint) { mMessage << "Point(" << aPoint.x << "," << aPoint.y << ")"; return *this; } - Log &operator <<(const Size &aSize) + template + Log &operator <<(const BaseSize& aSize) { mMessage << "Size(" << aSize.width << "," << aSize.height << ")"; return *this; } - Log &operator <<(const IntSize &aSize) - { mMessage << "IntSize(" << aSize.width << "," << aSize.height << ")"; return *this; } - Log &operator <<(const Rect &aRect) + template + Log &operator <<(const BaseRect& aRect) { mMessage << "Rect(" << aRect.x << "," << aRect.y << "," << aRect.width << "," << aRect.height << ")"; return *this; } Log &operator<<(const Matrix& aMatrix) { mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")"; return *this; } From 7412571303980c64becd563f1402f28351c765f3 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 18:59:17 -0500 Subject: [PATCH 30/69] Bug 958596 - Allow writing a log statement that does not end in a newline. r=Bas --- gfx/2d/Logging.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 4a85bf45e000..8eae4937386d 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -14,6 +14,7 @@ #include "Point.h" #include "BaseRect.h" #include "Matrix.h" +#include "mozilla/TypedEnum.h" #ifdef WIN32 // This file gets included from nsGlobalWindow.cpp, which doesn't like @@ -80,12 +81,20 @@ public: NoLog &operator <<(const T &aLogText) { return *this; } }; +MOZ_BEGIN_ENUM_CLASS(LogOptions, int) + NoNewline = 0x01 +MOZ_END_ENUM_CLASS(LogOptions) + template class Log { public: - Log() {} - ~Log() { mMessage << '\n'; WriteLog(mMessage.str()); } + Log(LogOptions aOptions = LogOptions(0)) : mOptions(aOptions) {} + ~Log() { + if (!(int(mOptions) & int(LogOptions::NoNewline))) + mMessage << '\n'; + WriteLog(mMessage.str()); + } Log &operator <<(char aChar) { mMessage << aChar; return *this; } Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; } @@ -117,6 +126,7 @@ private: } std::stringstream mMessage; + LogOptions mOptions; }; typedef Log DebugLog; From ecd9186cdcf1ad0a93cb392c3e1ea8485c4dd82d Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Tue, 21 Jan 2014 20:14:47 -0500 Subject: [PATCH 31/69] Bug 958596 - Add support a tree logging utility. r=Bas --- gfx/2d/Logging.h | 80 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 8eae4937386d..07326e3cbf24 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -91,9 +91,19 @@ class Log public: Log(LogOptions aOptions = LogOptions(0)) : mOptions(aOptions) {} ~Log() { - if (!(int(mOptions) & int(LogOptions::NoNewline))) + Flush(); + } + + void Flush() { + if (!(int(mOptions) & int(LogOptions::NoNewline))) { mMessage << '\n'; - WriteLog(mMessage.str()); + } + std::string str = mMessage.str(); + if (!str.empty()) { + WriteLog(str); + } + mMessage.str(""); + mMessage.clear(); } Log &operator <<(char aChar) { mMessage << aChar; return *this; } @@ -143,6 +153,72 @@ typedef Log WarningLog; #define gfxWarning if (1) ; else NoLog #endif +const int INDENT_PER_LEVEL = 2; + +class TreeLog +{ +public: + TreeLog(const std::string& aPrefix = "") + : mLog(LogOptions::NoNewline), + mPrefix(aPrefix), + mDepth(0), + mStartOfLine(true) {} + + template + TreeLog& operator<<(const T& aObject) { + if (mStartOfLine) { + mLog << '[' << mPrefix << "] " << std::string(mDepth * INDENT_PER_LEVEL, ' '); + mStartOfLine = false; + } + mLog << aObject; + if (EndsInNewline(aObject)) { + // Don't indent right here as the user may change the indent + // between now and the first output to the next line. + mLog.Flush(); + mStartOfLine = true; + } + return *this; + } + + void IncreaseIndent() { ++mDepth; } + void DecreaseIndent() { --mDepth; } +private: + Log mLog; + std::string mPrefix; + uint32_t mDepth; + bool mStartOfLine; + + template + static bool EndsInNewline(const T& aObject) { + return false; + } + + static bool EndsInNewline(const std::string& aString) { + return !aString.empty() && aString[aString.length() - 1] == '\n'; + } + + static bool EndsInNewline(char aChar) { + return aChar == '\n'; + } + + static bool EndsInNewline(const char* aString) { + return EndsInNewline(std::string(aString)); + } +}; + +class TreeAutoIndent +{ +public: + TreeAutoIndent(TreeLog& aTreeLog) : mTreeLog(aTreeLog) { + mTreeLog.IncreaseIndent(); + } + ~TreeAutoIndent() { + mTreeLog.DecreaseIndent(); + } +private: + TreeLog& mTreeLog; +}; + } } From f04e5271855dc3be1428dc0f3df705a8194ea522 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 15:19:01 -0500 Subject: [PATCH 32/69] Bug 958596 - Allow TreeLog logging to be conditioned on a pref. r=Bas --- gfx/2d/Logging.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 07326e3cbf24..9feeeb3b05c1 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -162,10 +162,15 @@ public: : mLog(LogOptions::NoNewline), mPrefix(aPrefix), mDepth(0), - mStartOfLine(true) {} + mStartOfLine(true), + mConditionedOnPref(false), + mPref(nullptr) {} template TreeLog& operator<<(const T& aObject) { + if (mConditionedOnPref && !*mPref) { + return *this; + } if (mStartOfLine) { mLog << '[' << mPrefix << "] " << std::string(mDepth * INDENT_PER_LEVEL, ' '); mStartOfLine = false; @@ -182,11 +187,18 @@ public: void IncreaseIndent() { ++mDepth; } void DecreaseIndent() { --mDepth; } + + void ConditionOnPref(bool* aPref) { + mConditionedOnPref = true; + mPref = aPref; + } private: Log mLog; std::string mPrefix; uint32_t mDepth; bool mStartOfLine; + bool mConditionedOnPref; + bool* mPref; template static bool EndsInNewline(const T& aObject) { From a15bf53545de4152b6e33301de38a38d9d9f87ff Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 16:15:05 -0500 Subject: [PATCH 33/69] Bug 958596 - Add a Describe() method to nsIContent. r=bz --- content/base/public/Element.h | 4 +++ content/base/public/nsIContent.h | 9 ++++++ content/base/src/Element.cpp | 52 ++++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 53a16e43e771..b55b851c8290 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -492,6 +492,8 @@ public: void ListAttributes(FILE* out) const; #endif + void Describe(nsAString& aOutDescription) const MOZ_OVERRIDE; + /* * Attribute Mapping Helpers */ @@ -514,6 +516,8 @@ public: } private: + void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const; + static bool FindAttributeDependence(const nsIAtom* aAttribute, const MappedAttributeEntry* const aMaps[], diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 58dd158284c4..7c73a16c8b19 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -950,6 +950,15 @@ public: bool aDumpAll = true) const = 0; #endif + /** + * Append to aOutDescription a short (preferably one line) string + * describing the content. + * Currently implemented for elements only. + */ + virtual void Describe(nsAString& aOutDescription) const { + aOutDescription = NS_LITERAL_STRING("(not an element)"); + } + enum ETabFocusType { //eTabFocus_textControlsMask = (1<<0), // unused - textboxes always tabbable eTabFocus_formElementsMask = (1<<1), // non-text form elements diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index b9695a12fa45..d0d57d61e860 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -2132,30 +2132,35 @@ Element::GetAttrCount() const return mAttrsAndChildren.AttrCount(); } +void +Element::DescribeAttribute(uint32_t index, nsAString& aOutDescription) const +{ + // name + mAttrsAndChildren.AttrNameAt(index)->GetQualifiedName(aOutDescription); + + // value + aOutDescription.AppendLiteral("=\""); + nsAutoString value; + mAttrsAndChildren.AttrAt(index)->ToString(value); + for (int i = value.Length(); i >= 0; --i) { + if (value[i] == char16_t('"')) + value.Insert(char16_t('\\'), uint32_t(i)); + } + aOutDescription.Append(value); + aOutDescription.AppendLiteral("\""); +} + #ifdef DEBUG void Element::ListAttributes(FILE* out) const { uint32_t index, count = mAttrsAndChildren.AttrCount(); for (index = 0; index < count; index++) { - nsAutoString buffer; - - // name - mAttrsAndChildren.AttrNameAt(index)->GetQualifiedName(buffer); - - // value - buffer.AppendLiteral("=\""); - nsAutoString value; - mAttrsAndChildren.AttrAt(index)->ToString(value); - for (int i = value.Length(); i >= 0; --i) { - if (value[i] == char16_t('"')) - value.Insert(char16_t('\\'), uint32_t(i)); - } - buffer.Append(value); - buffer.AppendLiteral("\""); + nsAutoString attributeDescription; + DescribeAttribute(index, attributeDescription); fputs(" ", out); - fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out); + fputs(NS_LossyConvertUTF16toASCII(attributeDescription).get(), out); } } @@ -2279,6 +2284,21 @@ Element::DumpContent(FILE* out, int32_t aIndent, } #endif +void +Element::Describe(nsAString& aOutDescription) const +{ + aOutDescription.Append(mNodeInfo->QualifiedName()); + aOutDescription.AppendPrintf("@%p", (void *)this); + + uint32_t index, count = mAttrsAndChildren.AttrCount(); + for (index = 0; index < count; index++) { + aOutDescription.Append(' '); + nsAutoString attributeDescription; + DescribeAttribute(index, attributeDescription); + aOutDescription.Append(attributeDescription); + } +} + bool Element::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor, nsIURI** aURI) const From 47e99a4731bf2ae7d42aefb771c1635d0de9d905 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 16:37:57 -0500 Subject: [PATCH 34/69] Bug 958596 - Add a content description field to FrameMetrics and populate it if the apz.printtree pref is on. r=kats,tn --- gfx/ipc/GfxMessageUtils.h | 4 +++- gfx/layers/FrameMetrics.h | 17 +++++++++++++++++ gfx/layers/composite/APZCTreeManager.cpp | 5 +++++ layout/base/nsDisplayList.cpp | 19 +++++++++++++++++++ modules/libpref/src/init/all.js | 3 +++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index 0130e5845c28..d525c2e5ef57 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -623,6 +623,7 @@ struct ParamTraits WriteParam(aMsg, aParam.mDisableScrollingY); WriteParam(aMsg, aParam.mUpdateScrollOffset); WriteParam(aMsg, aParam.mScrollGeneration); + WriteParam(aMsg, aParam.mContentDescription); } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) @@ -645,7 +646,8 @@ struct ParamTraits ReadParam(aMsg, aIter, &aResult->mDisableScrollingX) && ReadParam(aMsg, aIter, &aResult->mDisableScrollingY) && ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) && - ReadParam(aMsg, aIter, &aResult->mScrollGeneration)); + ReadParam(aMsg, aIter, &aResult->mScrollGeneration) && + ReadParam(aMsg, aIter, &aResult->mContentDescription)); } }; diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index f34299a0ca18..c60b7eeff0d9 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -7,6 +7,7 @@ #define GFX_FRAMEMETRICS_H #include // for uint32_t, uint64_t +#include // for std::string #include "Units.h" // for CSSRect, CSSPixel, etc #include "mozilla/gfx/BasePoint.h" // for BasePoint #include "mozilla/gfx/Rect.h" // for RoundedIn @@ -70,6 +71,8 @@ public: bool operator==(const FrameMetrics& aOther) const { + // mContentDescription is not compared on purpose as it's only used + // for debugging. return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) && mDisplayPort.IsEqualEdges(aOther.mDisplayPort) && mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) && @@ -336,6 +339,16 @@ public: return mScrollGeneration; } + const std::string& GetContentDescription() const + { + return mContentDescription; + } + + void SetContentDescription(const std::string& aContentDescription) + { + mContentDescription = aContentDescription; + } + private: // New fields from now on should be made private and old fields should // be refactored to be private. @@ -350,6 +363,10 @@ private: bool mUpdateScrollOffset; // The scroll generation counter used to acknowledge the scroll offset update. uint32_t mScrollGeneration; + + // A description of the content element corresponding to this frame. + // This is empty unless the apz.printtree pref is turned on. + std::string mContentDescription; }; /** diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index e0cf9209d161..716aadbf8b4e 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -16,6 +16,7 @@ #include "mozilla/MouseEvents.h" #include "mozilla/mozalloc.h" // for operator new #include "mozilla/TouchEvents.h" +#include "mozilla/Preferences.h" // for Preferences #include "nsDebug.h" // for NS_WARNING #include "nsPoint.h" // for nsIntPoint #include "nsThreadUtils.h" // for NS_IsMainThread @@ -30,12 +31,16 @@ namespace layers { float APZCTreeManager::sDPI = 160.0; +// Pref that enables printing of the APZC tree for debugging. +static bool gPrintApzcTree = false; + APZCTreeManager::APZCTreeManager() : mTreeLock("APZCTreeLock"), mTouchCount(0) { MOZ_ASSERT(NS_IsMainThread()); AsyncPanZoomController::InitializeGlobalState(); + Preferences::AddBoolVarCache(&gPrintApzcTree, "apz.printtree", gPrintApzcTree); } APZCTreeManager::~APZCTreeManager() diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index a9f35604af2b..18c21d937f1b 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -600,6 +600,17 @@ static void AdjustForScrollBars(ScreenIntRect& aToAdjust, nsIScrollableFrame* aS } } +static bool gPrintApzcTree = false; + +static bool GetApzcTreePrintPref() { + static bool initialized = false; + if (!initialized) { + Preferences::AddBoolVarCache(&gPrintApzcTree, "apz.printtree", gPrintApzcTree); + initialized = true; + } + return gPrintApzcTree; +} + static void RecordFrameMetrics(nsIFrame* aForFrame, nsIFrame* aScrollFrame, const nsIFrame* aReferenceFrame, @@ -741,6 +752,14 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, AdjustForScrollBars(metrics.mCompositionBounds, scrollableFrame); } + if (GetApzcTreePrintPref()) { + if (nsIContent* content = frameForCompositionBoundsCalculation->GetContent()) { + nsAutoString contentDescription; + content->Describe(contentDescription); + metrics.SetContentDescription(NS_LossyConvertUTF16toASCII(contentDescription).get()); + } + } + metrics.mPresShellId = presShell->GetPresShellId(); // If the scroll frame's content is marked 'scrollgrab', record this diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 78a1bd0bdc61..eca1de3e8c9e 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -321,6 +321,9 @@ pref("media.audio_data.enabled", false); // 2 = STICKY (Allow lock to be broken, with hysteresis) pref("apz.axis_lock_mode", 0); +// Whether to print the APZC tree for debugging +pref("apz.printtree", false); + #ifdef XP_MACOSX // Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display; // <= 0 : hidpi mode disabled, display will just use pixel-based upscaling From fdae9a67f98ffabe93f79c0277eba2fb36cc5990 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 15:09:03 -0500 Subject: [PATCH 35/69] Bug 958596 - Print the APZC tree for debugging. r=kats --- gfx/layers/composite/APZCTreeManager.cpp | 14 +++++++++++++- gfx/layers/composite/APZCTreeManager.h | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 716aadbf8b4e..89bed1584276 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -36,11 +36,13 @@ static bool gPrintApzcTree = false; APZCTreeManager::APZCTreeManager() : mTreeLock("APZCTreeLock"), - mTouchCount(0) + mTouchCount(0), + mApzcTreeLog("apzctree") { MOZ_ASSERT(NS_IsMainThread()); AsyncPanZoomController::InitializeGlobalState(); Preferences::AddBoolVarCache(&gPrintApzcTree, "apz.printtree", gPrintApzcTree); + mApzcTreeLog.ConditionOnPref(&gPrintApzcTree); } APZCTreeManager::~APZCTreeManager() @@ -121,6 +123,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Laye mRootApzc = nullptr; if (aRoot) { + mApzcTreeLog << "[start]\n"; UpdatePanZoomControllerTree(aCompositor, aRoot, // aCompositor is null in gtest scenarios @@ -128,6 +131,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Laye gfx3DMatrix(), nullptr, nullptr, aIsFirstPaint, aFirstPaintLayersId, &apzcsToDestroy); + mApzcTreeLog << "[end]\n"; } for (size_t i = 0; i < apzcsToDestroy.Length(); i++) { @@ -149,6 +153,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, ContainerLayer* container = aLayer->AsContainerLayer(); AsyncPanZoomController* apzc = nullptr; + mApzcTreeLog << aLayer->Name() << '\t'; if (container) { if (container->GetFrameMetrics().IsScrollable()) { const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId); @@ -227,6 +232,11 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, visible.width, visible.height, apzc); + mApzcTreeLog << "APZC " + << "\tcb=" << visible + << "\tsr=" << container->GetFrameMetrics().mScrollableRect + << "\t" << container->GetFrameMetrics().GetContentDescription(); + // Bind the APZC instance into the tree of APZCs if (aNextSibling) { aNextSibling->SetPrevSibling(apzc); @@ -261,6 +271,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, container->SetAsyncPanZoomController(apzc); } + mApzcTreeLog << '\n'; // Accumulate the CSS transform between layers that have an APZC, but exclude any // any layers that do have an APZC, and reset the accumulation at those layers. @@ -278,6 +289,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // have our siblings as siblings. AsyncPanZoomController* next = apzc ? nullptr : aNextSibling; for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) { + gfx::TreeAutoIndent indent(mApzcTreeLog); next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, aTransform, aParent, next, aIsFirstPaint, aFirstPaintLayersId, aApzcsToDestroy); } diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index 2a98b7b0c156..b9437335f3a6 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -19,6 +19,7 @@ #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "mozilla/Vector.h" // for mozilla::Vector #include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc +#include "mozilla/gfx/Logging.h" // for gfx::TreeLog class gfx3DMatrix; template class nsTArray; @@ -340,6 +341,9 @@ private: * the next APZC in the chain. */ Vector< nsRefPtr > mOverscrollHandoffChain; + /* For logging the APZC tree for debugging (enabled by the apz.printtree + * pref). */ + gfx::TreeLog mApzcTreeLog; static float sDPI; }; From e2ac4d85b65cf153f5b04d5fdb6f03441a339d50 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 18:38:31 -0500 Subject: [PATCH 36/69] Bug 958596 - Allow gfx logging of long long. r=Bas --- gfx/2d/Logging.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 9feeeb3b05c1..bc7c19486ffc 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -110,10 +110,10 @@ public: Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; } Log &operator <<(const char aStr[]) { mMessage << static_cast(aStr); return *this; } Log &operator <<(bool aBool) { mMessage << (aBool ? "true" : "false"); return *this; } - Log &operator <<(int aInt) { mMessage << aInt; return *this; } - Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; } - Log &operator <<(long aLong) { mMessage << aLong; return *this; } - Log &operator <<(unsigned long aLong) { mMessage << aLong; return *this; } + Log &operator <<(int32_t aInt) { mMessage << aInt; return *this; } + Log &operator <<(uint32_t aInt) { mMessage << aInt; return *this; } + Log &operator <<(int64_t aLong) { mMessage << aLong; return *this; } + Log &operator <<(uint64_t aLong) { mMessage << aLong; return *this; } Log &operator <<(Float aFloat) { mMessage << aFloat; return *this; } Log &operator <<(double aDouble) { mMessage << aDouble; return *this; } template From 0028367a68ca2b55d2f9f1e8c073aff8dcaf3d52 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 22 Jan 2014 18:44:59 -0500 Subject: [PATCH 37/69] Bug 958596 - Print ScrollableLayerGuids of APZCs when printing the tree. r=kats --- gfx/layers/FrameMetrics.h | 6 ++++++ gfx/layers/composite/APZCTreeManager.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index c60b7eeff0d9..363972d5fbbe 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -12,6 +12,7 @@ #include "mozilla/gfx/BasePoint.h" // for BasePoint #include "mozilla/gfx/Rect.h" // for RoundedIn #include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor +#include "mozilla/gfx/Logging.h" // for Log namespace IPC { template struct ParamTraits; @@ -425,6 +426,11 @@ struct ScrollableLayerGuid { } }; +template +gfx::Log& operator<<(gfx::Log& log, const ScrollableLayerGuid& aGuid) { + return log << '(' << aGuid.mLayersId << ',' << aGuid.mPresShellId << ',' << aGuid.mScrollId << ')'; +} + struct ZoomConstraints { bool mAllowZoom; bool mAllowDoubleTapZoom; diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 89bed1584276..c7635aaaaae3 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -168,7 +168,8 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // be possible because of DLBI heuristics) then we don't want to keep using // the same old APZC for the new content. Null it out so we run through the // code to find another one or create one. - if (apzc && !apzc->Matches(ScrollableLayerGuid(aLayersId, container->GetFrameMetrics()))) { + ScrollableLayerGuid guid(aLayersId, container->GetFrameMetrics()); + if (apzc && !apzc->Matches(guid)) { apzc = nullptr; } @@ -179,9 +180,8 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, // underlying content for which the APZC was originally created is still // there. So it makes sense to pick up that APZC instance again and use it here. if (apzc == nullptr) { - ScrollableLayerGuid target(aLayersId, container->GetFrameMetrics()); for (size_t i = 0; i < aApzcsToDestroy->Length(); i++) { - if (aApzcsToDestroy->ElementAt(i)->Matches(target)) { + if (aApzcsToDestroy->ElementAt(i)->Matches(guid)) { apzc = aApzcsToDestroy->ElementAt(i); break; } @@ -232,7 +232,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, visible.width, visible.height, apzc); - mApzcTreeLog << "APZC " + mApzcTreeLog << "APZC " << guid << "\tcb=" << visible << "\tsr=" << container->GetFrameMetrics().mScrollableRect << "\t" << container->GetFrameMetrics().GetContentDescription(); From efeee0915213ced3402a1ce294040ca6ae351894 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Mon, 3 Mar 2014 14:31:27 +0100 Subject: [PATCH 38/69] Bug 975773 - Filter primitives in error states can have inputs. r=roc --- gfx/src/FilterSupport.cpp | 4 +++- layout/svg/crashtests/975773-1.svg | 10 ++++++++++ layout/svg/crashtests/crashtests.list | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 layout/svg/crashtests/975773-1.svg diff --git a/gfx/src/FilterSupport.cpp b/gfx/src/FilterSupport.cpp index 3f3f3af8bca0..5b489e8f4ad0 100644 --- a/gfx/src/FilterSupport.cpp +++ b/gfx/src/FilterSupport.cpp @@ -1408,13 +1408,15 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription, const AttributeMap& atts = aDescription.Attributes(); switch (aDescription.Type()) { - case FilterPrimitiveDescription::eNone: case FilterPrimitiveDescription::eFlood: case FilterPrimitiveDescription::eTurbulence: case FilterPrimitiveDescription::eImage: MOZ_CRASH("this shouldn't be called for filters without inputs"); return nsIntRegion(); + case FilterPrimitiveDescription::eNone: + return nsIntRegion(); + case FilterPrimitiveDescription::eBlend: case FilterPrimitiveDescription::eComposite: case FilterPrimitiveDescription::eMerge: diff --git a/layout/svg/crashtests/975773-1.svg b/layout/svg/crashtests/975773-1.svg new file mode 100644 index 000000000000..dd225eb2ae5a --- /dev/null +++ b/layout/svg/crashtests/975773-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list index e937d0aa0329..7e0ae66155d7 100644 --- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -178,4 +178,5 @@ load 898909-1.svg load 898951-1.svg load 919371-1.xhtml load 952270-1.svg +load 975773-1.svg load 974746-1.svg From ff2ce5302509daa67e3140cb5de33229f99c8d5d Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 3 Mar 2014 09:42:16 -0500 Subject: [PATCH 39/69] Bug 977418 - Special case opacity:0.99 to treat it as opacity:1 for display purposes; r=roc This helps avoid significant costs in our graphics code when websites use opacity:0.99 as a hint for creating a stacking context only. --- layout/generic/nsFrame.cpp | 7 ++++--- layout/generic/nsIFrame.h | 23 +++++++++++++++++++++-- layout/reftests/bugs/reftest.list | 6 +++--- layout/reftests/transform-3d/reftest.list | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index c647148c7dc6..dfe91ef96100 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -999,10 +999,11 @@ nsIFrame::IsTransformed() const } bool -nsIFrame::HasOpacity() const +nsIFrame::HasOpacityInternal(float aThreshold) const { + MOZ_ASSERT(0.0 <= aThreshold && aThreshold <= 1.0, "Invalid argument"); const nsStyleDisplay* displayStyle = StyleDisplay(); - return StyleDisplay()->mOpacity < 1.0f || + return StyleDisplay()->mOpacity < aThreshold || (displayStyle->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) || (mContent && nsLayoutUtils::HasAnimationsForCompositor(mContent, @@ -1863,7 +1864,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, inTransform = true; } - bool useOpacity = HasOpacity() && !nsSVGUtils::CanOptimizeOpacity(this); + bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this); bool useBlendMode = disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL; bool usingSVGEffects = nsSVGIntegrationUtils::UsingEffectsForFrame(this); bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY && diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 80e5277befbf..9218bc12acf3 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1136,8 +1136,25 @@ public: * an SVG viewBox attribute). */ bool IsTransformed() const; - - bool HasOpacity() const; + + /** + * Returns true if the frame is translucent for the purposes of creating a + * stacking context. + */ + bool HasOpacity() const + { + return HasOpacityInternal(1.0f); + } + /** + * Returns true if the frame is translucent for display purposes. + */ + bool HasVisualOpacity() const + { + // Treat an opacity value of 0.99 and above as opaque. This is an + // optimization aimed at Web content which use opacity:0.99 as a hint for + // creating a stacking context only. + return HasOpacityInternal(0.99f); + } /** * Return true if this frame might be using a transform getter. @@ -3050,6 +3067,8 @@ private: template static nsIFrame* MergeSort(nsIFrame *aSource); + bool HasOpacityInternal(float aThreshold) const; + #ifdef DEBUG_FRAME_DUMP public: static void IndentBy(FILE* out, int32_t aIndent) { diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index ccc90196c73c..d1e06eb44737 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1562,14 +1562,14 @@ random-if(!winWidget) == 574907-2.html 574907-2-ref.html random-if(!winWidget) fails-if(winWidget&&!d2d) random-if(winWidget&&d2d) != 574907-3.html 574907-3-notref.html == 577838-1.html 577838-1-ref.html == 577838-2.html 577838-2-ref.html -fails-if(Android&&AndroidVersion!=17) == 579323-1.html 579323-1-ref.html +== 579323-1.html 579323-1-ref.html == 579349-1.html 579349-1-ref.html == 579655-1.html 579655-1-ref.html skip-if(B2G) fails-if(Android) == 579808-1.html 579808-1-ref.html skip-if(B2G) fails-if(Android) random-if(layersGPUAccelerated) == 579985-1.html 579985-1-ref.html # bug 623452 for WinXP; this bug was only for a regression in BasicLayers anyway skip-if(B2G) skip-if(Android) == 580160-1.html 580160-1-ref.html # bug 920927 for Android; issues without the test-plugin HTTP(..) == 580863-1.html 580863-1-ref.html -skip-if(B2G) fails-if(Android) random-if(layersGPUAccelerated) fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == 581317-1.html 581317-1-ref.html # bug 623456 for WinXP +skip-if(B2G) fails-if(Android) random-if(layersGPUAccelerated) == 581317-1.html 581317-1-ref.html == 581579-1.html 581579-1-ref.html == 582037-1a.html 582037-1-ref.html == 582037-1b.html 582037-1-ref.html @@ -1607,7 +1607,7 @@ skip-if(B2G) == 600803-1.html 600803-1-ref.html == 602200-1.html 602200-1-ref.html == 602200-2.html 602200-2-ref.html fuzzy-if(Android&&AndroidVersion>=15,8,20) == 602200-3.html 602200-3-ref.html -fails-if(Android&&AndroidVersion!=17) == 602200-4.html 602200-4-ref.html +== 602200-4.html 602200-4-ref.html == 603423-1.html 603423-1-ref.html == 604737.html 604737-ref.html == 605138-1.html 605138-1-ref.html diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index 447369b3adc9..e8fe1fb70405 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -9,7 +9,7 @@ != rotatex-perspective-1b.html rotatex-1-ref.html # -moz-perspective should only apply to child elements == rotatex-perspective-1c.html rotatex-1-ref.html -fails-if(Android&&AndroidVersion!=17) == rotatex-perspective-3a.html rotatex-perspective-3-ref.html # bug 755543 +== rotatex-perspective-3a.html rotatex-perspective-3-ref.html == scalez-1a.html scalez-1-ref.html == preserve3d-1a.html preserve3d-1-ref.html == preserve3d-1b.html about:blank From 1b08b28b9cf3413353696065714d1601da33ce64 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 3 Mar 2014 15:45:44 +0100 Subject: [PATCH 40/69] Bug 978456 - Fix --no-fpu shell flag. r=luke --- js/src/shell/js.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index e7d7bd49cd44..9005601ced69 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5775,22 +5775,6 @@ SetRuntimeOptions(JSRuntime *rt, const OptionParser &op) rt->setParallelIonCompilationEnabled(parallelCompilation); #endif -#if defined(JS_CODEGEN_X86) && defined(DEBUG) - if (op.getBoolOption("no-fpu")) - JSC::MacroAssembler::SetFloatingPointDisabled(); -#endif - -#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(DEBUG) - if (op.getBoolOption("no-sse3")) { - JSC::MacroAssembler::SetSSE3Disabled(); - PropagateFlagToNestedShells("--no-sse3"); - } - if (op.getBoolOption("no-sse4")) { - JSC::MacroAssembler::SetSSE4Disabled(); - PropagateFlagToNestedShells("--no-sse4"); - } -#endif - #endif // JS_ION #ifdef JS_ARM_SIMULATOR @@ -6048,8 +6032,25 @@ main(int argc, char **argv, char **envp) * allocations as possible. */ OOM_printAllocationCount = op.getBoolOption('O'); + +#if defined(JS_CODEGEN_X86) && defined(JS_ION) + if (op.getBoolOption("no-fpu")) + JSC::MacroAssembler::SetFloatingPointDisabled(); #endif +#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(JS_ION) + if (op.getBoolOption("no-sse3")) { + JSC::MacroAssembler::SetSSE3Disabled(); + PropagateFlagToNestedShells("--no-sse3"); + } + if (op.getBoolOption("no-sse4")) { + JSC::MacroAssembler::SetSSE4Disabled(); + PropagateFlagToNestedShells("--no-sse4"); + } +#endif + +#endif // DEBUG + // Start the engine. if (!JS_Init()) return 1; From dacf8886281b5484f6d24dd834b6e7be0e099fea Mon Sep 17 00:00:00 2001 From: David Major Date: Mon, 3 Mar 2014 10:27:21 -0500 Subject: [PATCH 41/69] Bug 951827 - Force a detour-style hook for LdrLoadDll. r=ehsan --- mozglue/build/WindowsDllBlocklist.cpp | 5 ++++- toolkit/xre/nsWindowsDllInterceptor.h | 22 +++++++++++++++------ toolkit/xre/test/win/TestDllInterceptor.cpp | 21 +++++++++++++++++++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp index 9f3dff61049e..393eda361374 100644 --- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -614,7 +614,10 @@ DllBlocklist_Initialize() ReentrancySentinel::InitializeStatics(); - bool ok = NtDllIntercept.AddHook("LdrLoadDll", reinterpret_cast(patched_LdrLoadDll), (void**) &stub_LdrLoadDll); + // We specifically use a detour, because there are cases where external + // code also tries to hook LdrLoadDll, and doesn't know how to relocate our + // nop space patches. (Bug 951827) + bool ok = NtDllIntercept.AddDetour("LdrLoadDll", reinterpret_cast(patched_LdrLoadDll), (void**) &stub_LdrLoadDll); if (!ok) { sBlocklistInitFailed = true; diff --git a/toolkit/xre/nsWindowsDllInterceptor.h b/toolkit/xre/nsWindowsDllInterceptor.h index 04aba4eb0397..9c6e3300dd24 100644 --- a/toolkit/xre/nsWindowsDllInterceptor.h +++ b/toolkit/xre/nsWindowsDllInterceptor.h @@ -671,24 +671,34 @@ public: bool AddHook(const char *pname, intptr_t hookDest, void **origFunc) { + // Use a nop space patch if possible, otherwise fall back to a detour. + // This should be the preferred method for adding hooks. + if (!mModuleName) { - // printf("AddHook before initialized?\n"); return false; } if (mNopSpacePatcher.AddHook(pname, hookDest, origFunc)) { - // printf("nopSpacePatcher succeeded.\n"); return true; } + return AddDetour(pname, hookDest, origFunc); + } + + bool AddDetour(const char *pname, intptr_t hookDest, void **origFunc) + { + // Generally, code should not call this method directly. Use AddHook unless + // there is a specific need to avoid nop space patches. + + if (!mModuleName) { + return false; + } + if (!mDetourPatcher.Initialized()) { - // printf("Initializing detour patcher.\n"); mDetourPatcher.Init(mModuleName, mNHooks); } - bool rv = mDetourPatcher.AddHook(pname, hookDest, origFunc); - // printf("detourPatcher returned %d\n", rv); - return rv; + return mDetourPatcher.AddHook(pname, hookDest, origFunc); } }; diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp index 31171dbedb5c..0883ca853646 100644 --- a/toolkit/xre/test/win/TestDllInterceptor.cpp +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp @@ -57,6 +57,25 @@ bool TestHook(const char *dll, const char *func) } } +bool TestDetour(const char *dll, const char *func) +{ + void *orig_func; + bool successful = false; + { + WindowsDllInterceptor TestIntercept; + TestIntercept.Init(dll); + successful = TestIntercept.AddDetour(func, 0, &orig_func); + } + + if (successful) { + printf("TEST-PASS | WindowsDllInterceptor | Could detour %s from %s\n", func, dll); + return true; + } else { + printf("TEST-UNEXPECTED-FAIL | WindowsDllInterceptor | Failed to detour %s from %s\n", func, dll); + return false; + } +} + int main() { payload initial = { 0x12345678, 0xfc4e9d31, 0x87654321 }; @@ -139,7 +158,7 @@ int main() TestHook("kernel32.dll", "MapViewOfFile") && TestHook("gdi32.dll", "CreateDIBSection") && #endif - TestHook("ntdll.dll", "LdrLoadDll")) { + TestDetour("ntdll.dll", "LdrLoadDll")) { printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n"); return 0; } From 4376c01b11655225ee3fbd405fecce6666055627 Mon Sep 17 00:00:00 2001 From: Benjamin Chen Date: Mon, 10 Feb 2014 11:22:03 +0800 Subject: [PATCH 42/69] Bug 969289 - Treat the null image pointer as a muted frame. r=rillian --- content/media/encoder/VP8TrackEncoder.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/content/media/encoder/VP8TrackEncoder.cpp b/content/media/encoder/VP8TrackEncoder.cpp index 641011749a42..4fd0ff04d7ee 100644 --- a/content/media/encoder/VP8TrackEncoder.cpp +++ b/content/media/encoder/VP8TrackEncoder.cpp @@ -246,13 +246,10 @@ void VP8TrackEncoder::PrepareMutedFrame() nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk) { - if (aChunk.mFrame.GetForceBlack()) { + if (aChunk.mFrame.GetForceBlack() || aChunk.IsNull()) { PrepareMutedFrame(); } else { layers::Image* img = aChunk.mFrame.GetImage(); - if (NS_WARN_IF(!img)) { - return NS_ERROR_NULL_POINTER; - } ImageFormat format = img->GetFormat(); if (format != ImageFormat::PLANAR_YCBCR) { VP8LOG("Unsupported video format\n"); From 679a21fa8a7b4d204658a97e9cac7cd9b95d2311 Mon Sep 17 00:00:00 2001 From: Benjamin Chen Date: Tue, 18 Feb 2014 11:11:18 +0800 Subject: [PATCH 43/69] Bug 969289 - Add new test_mediarecorder_record_gum_video_timeslice.html test case. r=jsmith --- content/media/test/mochitest.ini | 1 + ...iarecorder_record_gum_video_timeslice.html | 89 +++++++++++++++++++ testing/mochitest/android.json | 1 + testing/mochitest/androidx86.json | 1 + testing/mochitest/b2g-debug.json | 1 + testing/mochitest/b2g-desktop.json | 1 + testing/mochitest/b2g.json | 1 + 7 files changed, 95 insertions(+) create mode 100644 content/media/test/test_mediarecorder_record_gum_video_timeslice.html diff --git a/content/media/test/mochitest.ini b/content/media/test/mochitest.ini index 5d0de99031d2..cf4607b19c66 100644 --- a/content/media/test/mochitest.ini +++ b/content/media/test/mochitest.ini @@ -387,6 +387,7 @@ support-files = [test_mediarecorder_record_startstopstart.html] [test_mediarecorder_getencodeddata.html] [test_mediarecorder_unsupported_src.html] +[test_mediarecorder_record_gum_video_timeslice.html] [test_playback.html] [test_seekLies.html] [test_media_sniffer.html] diff --git a/content/media/test/test_mediarecorder_record_gum_video_timeslice.html b/content/media/test/test_mediarecorder_record_gum_video_timeslice.html new file mode 100644 index 000000000000..142aabaed533 --- /dev/null +++ b/content/media/test/test_mediarecorder_record_gum_video_timeslice.html @@ -0,0 +1,89 @@ + + + + Test MediaRecorder Record gUM video with Timeslice + + + + +
+
+
+
+ + diff --git a/testing/mochitest/android.json b/testing/mochitest/android.json index 04bc575031f8..d2ced0d01a02 100644 --- a/testing/mochitest/android.json +++ b/testing/mochitest/android.json @@ -1,6 +1,7 @@ { "runtests": {}, "excludetests": { + "content/media/test/test_mediarecorder_record_gum_video_timeslice.html": "mimetype check, bug 969289", "dom/tests/mochitest/dom-level0": "bug 910229", "dom/imptests/html/webgl": "WebGL", "content/base/test/test_copypaste.xul": "bug 904183", diff --git a/testing/mochitest/androidx86.json b/testing/mochitest/androidx86.json index d34bd0747883..75a828562277 100644 --- a/testing/mochitest/androidx86.json +++ b/testing/mochitest/androidx86.json @@ -1,6 +1,7 @@ { "runtests": {}, "excludetests": { + "content/media/test/test_mediarecorder_record_gum_video_timeslice.html": "mimetype check, bug 969289", "dom/tests/mochitest/dom-level0": "bug 910229", "dom/imptests/html/webgl": "WebGL", "content/base/test/test_copypaste.xul": "bug 904183", diff --git a/testing/mochitest/b2g-debug.json b/testing/mochitest/b2g-debug.json index 6578559658b3..96425d7033db 100644 --- a/testing/mochitest/b2g-debug.json +++ b/testing/mochitest/b2g-debug.json @@ -43,6 +43,7 @@ "content/media/test/test_load_same_resource.html": "", "content/media/test/test_media_selection.html": "timed out", "content/media/test/test_metadata.html": "", + "content/media/test/test_mediarecorder_record_gum_video_timeslice.html": "mimetype check, bug 969289", "content/media/test/test_mozHasAudio.html": "", "content/media/test/test_play_events.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough", "content/media/test/test_play_events_2.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough", diff --git a/testing/mochitest/b2g-desktop.json b/testing/mochitest/b2g-desktop.json index 2a7c299ba89f..c95269bf31f8 100644 --- a/testing/mochitest/b2g-desktop.json +++ b/testing/mochitest/b2g-desktop.json @@ -42,6 +42,7 @@ "content/media/test/test_load_candidates.html": "timed out", "content/media/test/test_load_same_resource.html": "", "content/media/test/test_media_selection.html": "timed out", + "content/media/test/test_mediarecorder_record_gum_video_timeslice.html": "mimetype check, bug 969289", "content/media/test/test_metadata.html": "", "content/media/test/test_mozHasAudio.html": "", "content/media/test/test_play_events.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough", diff --git a/testing/mochitest/b2g.json b/testing/mochitest/b2g.json index 60d8b5295515..1b85ccb7c283 100644 --- a/testing/mochitest/b2g.json +++ b/testing/mochitest/b2g.json @@ -32,6 +32,7 @@ "content/media/test/test_info_leak.html": "2 failures", "content/media/test/test_media_selection.html": "timed out", "content/media/test/test_mediarecorder_record_4ch_audiocontext.html": "", + "content/media/test/test_mediarecorder_record_gum_video_timeslice.html": "mimetype check, bug 969289", "content/media/test/test_playback.html": "Test timed out, bug 668973?", "content/media/test/test_playback_rate.html": "", "content/media/test/test_playback_rate_playpause.html": "", From f76df0d352005c6680294764c4506ca26fb4a59d Mon Sep 17 00:00:00 2001 From: Ekanan Ketunuti Date: Mon, 3 Mar 2014 08:57:12 +0700 Subject: [PATCH 44/69] Bug 977047 - Add words related to crypto. r=ehsan --- .../dictionary-sources/upstream-hunspell.diff | 302 +++++++++--------- .../locales/en-US/hunspell/en-US.dic | 9 +- 2 files changed, 165 insertions(+), 146 deletions(-) diff --git a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff index 25294cdcf839..9afb3beb5178 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff +++ b/extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/upstream-hunspell.diff @@ -9186,442 +9186,456 @@ < cider/S --- > cider/MS -17072d22881 +16652a22463 +> ciphertext/S +17072d22882 < cocain/M -17102,17103c22911 +17102,17103c22912 < cocksucker's < cocksucker/S! --- > cocksucker/SM! -17755c23563 +17755c23564 < confer/S --- > confer/SB -17800a23609 +17800a23610 > conformant -18151d23959 +18151d23960 < convenor/S -18206c24014 +18206c24015 < cookie/M --- > cookie/SM -18467a24276 +18467a24277 > could've -19035a24845 +18999a24810 +> cryptologist/MS +19000a24812 +> cryptosystem/S +19035a24848 > cul-de-sac -19246c25056 +19246c25059 < cysteine --- > cysteine/M -19935a25746 +19935a25749 > dequeue/DSG -20196,20197c26007,26008 +20196,20197c26010,26011 < dialog/SM < dialogue/SM --- > dialog/SMGD > dialogue/SMRGD -20481a26293 +20481a26296 > disclose/DSG -20830c26642 +20830c26645 < dogie/M --- > dogie/SM -20895a26708 +20895a26711 > donator/MS -21820a27634 +21820a27637 > elicitor/MS -22071a27886 +22071a27889 > encyclopaedia -22196a28012 +22196a28015 > enqueue/DSG -22556a28373 +22556a28376 > estoppel -22638c28455 +22638c28458 < euthanize --- > euthanize/DSG -22719a28537 +22719a28540 > exabyte/MS -22947a28766 +22947a28769 > experimentalism -23207,23208d29025 +23207,23208d29028 < faecal < faeces/M -23215c29032 +23215c29035 < faggoting's --- > faggot/SMG -23701a29519 +23701a29522 > filesystem/MS -24155c29973 +24155c29976 < fluidized --- > fluidize/DSG -24216a30035 +24216a30038 > foci -24736d30554 +24736d30557 < frier/M -24855,24856c30673,30674 +24855,24856c30676,30677 < fucker/M! < fuckhead/S! --- > fucker/SM! > fuckhead/SM! -24953d30770 +24953d30773 < furore/MS -25125c30942 +25125c30945 < gaolbird/S --- > gaolbirds -25180d30996 +25180d30999 < gasolene/M -25190a31007 +25190a31010 > gastroenterologist/M -25262c31079 +25262c31082 < geezer/M --- > geezer/MS -25327c31144 +25327c31147 < genomic --- > genomic/S -25462a31280 +25462a31283 > gigabit/MS -25464a31283,31285 +25464a31286,31288 > gigajoule/MS > gigapixel/MS > gigawatt/MS -25560d31380 +25560d31383 < glamourize/DSG -25674c31494 +25674c31497 < glycerine's --- > glycerine/M -25905c31725 +25905c31728 < gram/MS --- > gram/KMS -25909d31728 +25909d31731 < gramme/SM -26063c31882,31883 +26063c31885,31886 < greybeard --- > grey/MDRTGSP > greybeard/SM -26066c31886 +26066c31889 < greyness --- > greyness/M -26246,26247d32065 +26246,26247d32068 < guerilla's < guerillas -26432,26436d32249 +26432,26436d32252 < haemoglobin's < haemophilia/M < haemorrhage/DSMG < haemorrhoid/S < haemorrhoids/M -27167c32980 +27167c32983 < hexane --- > hexane/SM -27273a33087 +27273a33090 > hippopotami -27875d33688 +27875d33691 < hyaena/SM -28017c33830 +28017c33833 < iPod/M --- > iPod/MS -28105a33919 +28105a33922 > idolator/SM -28513c34327 +28513c34330 < inbound --- > inbound/s -28650a34465 +28650a34468 > indices -28812d34626 +28812d34629 < inflexion/SM -29216a35031 +29216a35034 > intern/GDL -29266a35082 +29266a35085 > interruptible/U -29272a35089,35092 +29272a35092,35095 > intersex > intersexual/MS > intersexualism > intersexuality -29724c35544 +29724c35547 < jewellery's --- > jewellery/M -29870a35691 +29870a35694 > judgement/MS -30066c35887 +30066c35890 < kiddie/M --- > kiddie/SM -30262,30263c36083 +30262,30263c36086 < kraut's < kraut/S! --- > kraut/MS! -30665a36486 +30665a36489 > lector/MS -31031c36852 +31031c36855 < linguini's --- > linguini/M -31151,31152c36972 +31034c36858 +< linguistically +--- +> linguistical/Y +31151,31152c36975 < liver's < liver/S --- > liver/MS -32230c38050 +32230c38053 < meanie/M --- > meanie/MS -32317,32318c38137 +32317,32318c38140 < megadeath/M < megadeaths --- > megadeath/SM -32320c38139 +32320c38142 < megajoules --- > megajoule/SM -32329c38148 +32329c38151 < megapixel/S --- > megapixel/MS -32708a38528 +32708a38531 > might've -32717a38538 +32717a38541 > migrator/SM -32760a38582 +32760a38585 > millennia -32777d38598 +32777d38601 < millionnaire/M -32934a38756 +32934a38759 > miscommunication/S -32991a38814 +32991a38817 > misjudgement/MS -33784a39608 +33784a39611 > must've -33963c39787 +33963c39790 < native/MS --- > native/MSY -34169,34171c39993,39994 +34169,34171c39996,39997 < neurone/S < neurophysiology < neuroscience --- > neurophysiology/M > neuroscience/MS -34275c40098 +34275c40101 < nightie/M --- > nightie/SM -35104a40928 +35104a40931 > octopi -35219d41042 +35219d41045 < oleomargarin/M -35226a41050 +35226a41053 > oligo -35913c41737 +35913c41740 < oversize/D --- > oversize -36056,36059d41879 +36056,36059d41882 < paederast/S < paediatrician's < paediatricians < paediatrics/M -36291a42112 +36291a42115 > paralyses -36403d42223 +36403d42226 < parrakeet/MS -36449d42268 +36449d42271 < partizan/SM -37093a42913 +37093a42916 > petabyte/MS -37102c42922 +37102c42925 < petitioner/M --- > petitioner/MS -37264a43085 +37264a43088 > phosphorylate/DSGN -37316d43136 +37316d43139 < phrenetic -37796a43617 +37630a43454 +> plaintext +37796a43621 > plugin/MS -37987c43808 +37987c43812 < polypeptide/S --- > polypeptide/MS -38291d44111 +38291d44115 < practise's -38451a44272 +38451a44276 > prejudgement/MS -38805a44627 +38805a44631 > profiler/SM -38835a44658 +38835a44662 > programmatically -38891a44715,44716 +38891a44719,44720 > pronate/DSGN > pronator/MS -38951c44776 +38951c44780 < proprietorship/M --- > proprietorship/MS -39039a44865 +39039a44869 > provender/M -39564a45391 +39095a44926 +> pseudorandom/Y +39564a45396 > quinoa -39873a45701,45702 +39873a45706,45707 > rasterization/M > rasterize/SGDR -40036a45866 +40036a45871 > recency -40140a45971 +40140a45976 > recurse/DGSV -40141a45973 +40141a45978 > recuse/DGS -40208a46041 +40208a46046 > refactor/SMDG -40244d46076 +40244d46081 < reflexion/SM -40659d46490 +40659d46495 < resizing -40829c46660 +40829c46665 < reverie/M --- > reverie/MS -41415a47247 +41415a47252 > sabre/MS -41914c47746 +41914c47751 < schnaps's --- > schnaps/M -41949c47781 +41949c47786 < schrod's --- > schrod/SM -41998a47831 +41998a47836 > scot-free -42883,42885c48716 +42883,42885c48721 < shit's < shit/S! < shite/S! --- > shit/MS! -42887,42888c48718,48719 +42887,42888c48723,48724 < shithead/S! < shitload/! --- > shithead/MS! > shitload/MS! -42891c48722 +42891c48727 < shitty/RT! --- > shitty/TR! -42976a48808 +42976a48813 > should've -43008c48840 +43008c48845 < showtime --- > showtime/MS -43328c49160 +43328c49165 < size/MGBDRS --- > size/AMGBDRS -43724,43726c49556 +43724,43726c49561 < smoulder's < smouldered < smoulders --- > smoulder/GSMD -43766a49597,49598 +43766a49602,49603 > snarkily > snarky/TR -44062c49894 +44062c49899 < sonofabitch --- > sonofabitch/! -44346a50179 +44346a50184 > spelled -44348a50182 +44348a50187 > spelt -44371a50206 +44371a50211 > spick/S! -44383c50218 +44383c50223 < spik/S --- > spik/S! -46106a51942 +46106a51947 > syllabi -46160c51996 +46160c52001 < synch/GMD --- > synch/GMDS -46167d52002 +46167d52007 < synchs -46203,46204c52038,52039 +46203,46204c52043,52044 < sysadmin/S < sysop/S --- > sysadmin/MS > sysop/MS -46752a52588 +46752a52593 > terabit/MS -46753a52590,52591 +46753a52595,52596 > terahertz/M > terapixel/MS -46817a52656 +46817a52661 > testcase/MS -46831a52671 +46831a52676 > testsuite/MS -46925a52766 +46925a52771 > theremin/MS -47455c53296 +47455c53301 < toolbar --- > toolbar/MS -47755a53597 +47755a53602 > transfect/DSMG -47774a53617,53618 +47774a53622,53623 > transgenderism > transgene/MS -47951c53795 +47951c53800 < triage/M --- > triage/MG -48869a54714 +48869a54719 > unlikeable -49211c55056 +49211c55061 < vagina/M --- > vagina/MS -49368,49369c55213 +49368,49369c55218 < velour's < velours's --- > velour/MS -49478a55323 +49478a55328 > vertices -50148a55994 +50148a55999 > weaponize/DSG -50260,50261d56105 +50260,50261d56110 < werwolf/M < werwolves -50728c56572 +50728c56577 < women --- > women/M -50794c56638 +50794c56643 < wop/S! --- > wop/MS! diff --git a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic index 4b4583798529..72938d8ac625 100644 --- a/extensions/spellcheck/locales/en-US/hunspell/en-US.dic +++ b/extensions/spellcheck/locales/en-US/hunspell/en-US.dic @@ -1,4 +1,4 @@ -57460 +57465 0/nm 0th/pt 1/n1 @@ -22722,6 +22722,7 @@ cinnabar/M cinnamon/M cipher's cipher/CGDS +ciphertext/S cir circa circadian @@ -25073,7 +25074,9 @@ cryptographer/MS cryptographic cryptographically cryptography/M +cryptologist/MS cryptology +cryptosystem/S crystal/SM crystalline crystallization/M @@ -37149,7 +37152,7 @@ linguine/M linguini/M linguist/SM linguistic/S -linguistically +linguistical/Y linguistics/M liniment/SM lining/M @@ -43770,6 +43773,7 @@ plainsmen plainsong/M plainspoken plaint/SMV +plaintext plaintiff/SM plaintive/Y plait/MDGS @@ -45245,6 +45249,7 @@ pseudonym/SM pseudonymous pseudopod pseudopodia +pseudorandom/Y pseudoscience/MS pseudy pshaw/MS From 66f56aca38c49329a0374ffe0ad4a47c6e7f8bc9 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Mon, 3 Mar 2014 10:29:08 -0500 Subject: [PATCH 45/69] Bug 977457 - Move _GNU_SOURCE ifdef a little up to account for cxxabi.h from libcxxrt. r=ehsan --- xpcom/base/nsStackWalk.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/xpcom/base/nsStackWalk.cpp b/xpcom/base/nsStackWalk.cpp index bb0e15b5cd9e..76412678dc2b 100644 --- a/xpcom/base/nsStackWalk.cpp +++ b/xpcom/base/nsStackWalk.cpp @@ -23,6 +23,12 @@ struct CriticalAddress { }; static CriticalAddress gCriticalAddress; +// for _Unwind_Backtrace from libcxxrt or libunwind +// cxxabi.h from libcxxrt implicitly includes unwind.h first +#if defined(HAVE__UNWIND_BACKTRACE) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #if defined(HAVE_DLOPEN) || defined(XP_MACOSX) #include #endif @@ -1222,9 +1228,6 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames, #elif defined(HAVE__UNWIND_BACKTRACE) // libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0 -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #include struct unwind_info { From 3e1fbd44bc74e07ebacb6c80cccb61df7d9ea8a3 Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Fri, 28 Feb 2014 15:42:24 -0500 Subject: [PATCH 46/69] Bug 978239 - Synchronize WindowsRealTimeClock to unmess RTCP timestamps. r=jesup --- .../webrtc/system_wrappers/source/clock.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc index 6ae1e97480ed..a6fb280891d3 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/clock.cc @@ -233,12 +233,26 @@ class UnixRealTimeClock : public RealTimeClock { // Keeps the global state for the Windows implementation of RtpRtcpClock. // Note that this is a POD. Only PODs are allowed to have static storage // duration according to the Google Style guide. -static WindowsHelpTimer global_help_timer = {0, 0, {{ 0, 0}, 0}, 0}; +// +// Note that on Windows, GetSystemTimeAsFileTime has poorer (up to 15 ms) +// resolution than the media timers, hence the WindowsHelpTimer context +// object and Synchronize API. +// +// We only sync up once, which means that on Windows, our realtime clock +// wont respond to system time/date changes without a program restart. +// TODO: We could attempt to detect 1+ minute jumps and resync for parity +// with other platforms. + +static WindowsHelpTimer *SyncGlobalHelpTimer() { + static WindowsHelpTimer global_help_timer = {0, 0, {{ 0, 0}, 0}, 0}; + Synchronize(&global_help_timer); + return &global_help_timer; +} #endif Clock* Clock::GetRealTimeClock() { #if defined(_WIN32) - static WindowsRealTimeClock clock(&global_help_timer); + static WindowsRealTimeClock clock(SyncGlobalHelpTimer()); return &clock; #elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) static UnixRealTimeClock clock; From 65e6f8ab2289e03a73272474a5b32acf22c7c3aa Mon Sep 17 00:00:00 2001 From: Randy Lin Date: Mon, 3 Mar 2014 15:34:14 +0800 Subject: [PATCH 47/69] Bug 973235 - Intermittent test_mediarecorder_getencodeddata.html | should get onError first. r=jsmith --- .../test_mediarecorder_getencodeddata.html | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/content/media/test/test_mediarecorder_getencodeddata.html b/content/media/test/test_mediarecorder_getencodeddata.html index 21443d4d1495..e4b646873e02 100644 --- a/content/media/test/test_mediarecorder_getencodeddata.html +++ b/content/media/test/test_mediarecorder_getencodeddata.html @@ -28,21 +28,17 @@ SpecialPowers.pushPrefEnv({"set": [["media.ogg.enabled", false]]}, SimpleTest.finish(); } mediaRecorder.ondataavailable = function(evt) { - if (onErrorFired) { - ondataavailableFired = true; - ok(evt instanceof BlobEvent, - 'Events fired from ondataavailable should be BlobEvent'); - is(evt.type, 'dataavailable', - 'Event type should dataavailable'); - is(evt.data.size, 0, - 'Blob data size received is equal to zero'); - is(evt.data.type, expectedMimeType, - 'Blob data received should have type = ' + expectedMimeType); - is(evt.target.mimeType, expectedMimeType, - 'Mime type in ondataavailable = ' + expectedMimeType); - } else { - ok(false, 'should get onError first'); - } + ondataavailableFired = true; + ok(evt instanceof BlobEvent, + 'Events fired from ondataavailable should be BlobEvent'); + is(evt.type, 'dataavailable', + 'Event type should dataavailable'); + is(evt.data.size, 0, + 'Blob data size received is equal to zero'); + is(evt.data.type, expectedMimeType, + 'Blob data received should have type = ' + expectedMimeType); + is(evt.target.mimeType, expectedMimeType, + 'Mime type in ondataavailable = ' + expectedMimeType); } mediaRecorder.onerror = function(evt) { ok(evt instanceof RecordErrorEvent, From 933c8042aeb8ae5a6652bdaecea3bf613a5d38b3 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Mon, 3 Mar 2014 10:36:52 -0500 Subject: [PATCH 48/69] Bug 843666 - Implement color-buffer-(half-)float for WebGL. r=kamidphish --- content/canvas/src/WebGLContext.h | 3 +- content/canvas/src/WebGLContextExtensions.cpp | 12 ++ content/canvas/src/WebGLContextGL.cpp | 170 ++++++++++++++++-- .../src/WebGLExtensionColorBufferFloat.cpp | 28 +++ .../WebGLExtensionColorBufferHalfFloat.cpp | 28 +++ content/canvas/src/WebGLExtensions.h | 24 +++ content/canvas/src/WebGLFramebuffer.cpp | 29 +++ content/canvas/src/WebGLFramebuffer.h | 1 + content/canvas/src/WebGLRenderbuffer.cpp | 16 +- content/canvas/src/WebGLTexture.cpp | 4 +- content/canvas/src/moz.build | 2 + dom/bindings/Bindings.conf | 10 ++ dom/webidl/WebGLRenderingContext.webidl | 18 ++ gfx/gl/GLContext.cpp | 3 + gfx/gl/GLContext.h | 6 + gfx/gl/GLContextFeatures.cpp | 36 +++- gfx/gl/GfxTexturesReporter.cpp | 17 +- 17 files changed, 378 insertions(+), 29 deletions(-) create mode 100644 content/canvas/src/WebGLExtensionColorBufferFloat.cpp create mode 100644 content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index e6e58bd3ac2b..61ffebfca5b6 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -895,6 +895,7 @@ protected: // ------------------------------------------------------------------------- // WebGL extensions (implemented in WebGLContextExtensions.cpp) enum WebGLExtensionID { + EXT_color_buffer_half_float, EXT_frag_depth, EXT_sRGB, EXT_texture_filter_anisotropic, @@ -905,6 +906,7 @@ protected: OES_texture_half_float, OES_texture_half_float_linear, OES_vertex_array_object, + WEBGL_color_buffer_float, WEBGL_compressed_texture_atc, WEBGL_compressed_texture_pvrtc, WEBGL_compressed_texture_s3tc, @@ -933,7 +935,6 @@ protected: nsTArray mCompressedTextureFormats; - // ------------------------------------------------------------------------- // WebGL 2 specifics (implemented in WebGL2Context.cpp) diff --git a/content/canvas/src/WebGLContextExtensions.cpp b/content/canvas/src/WebGLContextExtensions.cpp index 805a72b6ba15..237280d8a9b5 100644 --- a/content/canvas/src/WebGLContextExtensions.cpp +++ b/content/canvas/src/WebGLContextExtensions.cpp @@ -17,6 +17,7 @@ using namespace mozilla::gl; // must match WebGLContext::WebGLExtensionID static const char *sExtensionNames[] = { + "EXT_color_buffer_half_float", "EXT_frag_depth", "EXT_sRGB", "EXT_texture_filter_anisotropic", @@ -27,6 +28,7 @@ static const char *sExtensionNames[] = { "OES_texture_half_float", "OES_texture_half_float_linear", "OES_vertex_array_object", + "WEBGL_color_buffer_float", "WEBGL_compressed_texture_atc", "WEBGL_compressed_texture_pvrtc", "WEBGL_compressed_texture_s3tc", @@ -108,6 +110,10 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const gl->IsSupported(GLFeature::texture_half_float); case OES_texture_half_float_linear: return gl->IsSupported(GLFeature::texture_half_float_linear); + case WEBGL_color_buffer_float: + return WebGLExtensionColorBufferFloat::IsSupported(this); + case EXT_color_buffer_half_float: + return WebGLExtensionColorBufferHalfFloat::IsSupported(this); case OES_vertex_array_object: return WebGLExtensionVertexArray::IsSupported(this); case EXT_texture_filter_anisotropic: @@ -286,6 +292,12 @@ WebGLContext::EnableExtension(WebGLExtensionID ext) case OES_texture_half_float_linear: obj = new WebGLExtensionTextureHalfFloatLinear(this); break; + case WEBGL_color_buffer_float: + obj = new WebGLExtensionColorBufferFloat(this); + break; + case EXT_color_buffer_half_float: + obj = new WebGLExtensionColorBufferHalfFloat(this); + break; case WEBGL_draw_buffers: obj = new WebGLExtensionDrawBuffers(this); break; diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 354cec2389ba..31ba36ca9a74 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -1394,8 +1394,47 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER)); case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - { return WebGLObjectAsJSValue(cx, fba.Renderbuffer(), rv); + + case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: { + if (!IsExtensionEnabled(EXT_color_buffer_half_float) && + !IsExtensionEnabled(WEBGL_color_buffer_float)) + { + break; + } + + if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { + ErrorInvalidOperation("getFramebufferAttachmentParameter: Cannot get component" + " type of a depth-stencil attachment."); + return JS::NullValue(); + } + + if (!fba.IsComplete()) + return JS::NumberValue(uint32_t(LOCAL_GL_NONE)); + + uint32_t ret = LOCAL_GL_NONE; + switch (fba.Renderbuffer()->InternalFormat()) { + case LOCAL_GL_RGBA4: + case LOCAL_GL_RGB5_A1: + case LOCAL_GL_RGB565: + case LOCAL_GL_SRGB8_ALPHA8: + ret = LOCAL_GL_UNSIGNED_NORMALIZED; + break; + case LOCAL_GL_RGB16F: + case LOCAL_GL_RGBA16F: + case LOCAL_GL_RGB32F: + case LOCAL_GL_RGBA32F: + ret = LOCAL_GL_FLOAT; + break; + case LOCAL_GL_DEPTH_COMPONENT16: + case LOCAL_GL_STENCIL_INDEX8: + ret = LOCAL_GL_UNSIGNED_INT; + break; + default: + MOZ_ASSERT(false, "Unhandled RB component type."); + break; + } + return JS::NumberValue(uint32_t(ret)); } } @@ -1418,20 +1457,58 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, return JS::NumberValue(uint32_t(LOCAL_GL_TEXTURE)); case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - { return WebGLObjectAsJSValue(cx, fba.Texture(), rv); - } case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: return JS::Int32Value(fba.TexImageLevel()); - case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - { + case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: { GLenum face = fba.TexImageTarget(); if (face == LOCAL_GL_TEXTURE_2D) face = 0; return JS::Int32Value(face); } + + case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: { + if (!IsExtensionEnabled(EXT_color_buffer_half_float) && + !IsExtensionEnabled(WEBGL_color_buffer_float)) + { + break; + } + + if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { + ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot component" + " type of depth-stencil attachments."); + return JS::NullValue(); + } + + if (!fba.IsComplete()) + return JS::NumberValue(uint32_t(LOCAL_GL_NONE)); + + uint32_t ret = LOCAL_GL_NONE; + GLenum type = fba.Texture()->ImageInfoAt(fba.TexImageTarget(), + fba.TexImageLevel()).Type(); + switch (type) { + case LOCAL_GL_UNSIGNED_BYTE: + case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: + case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: + case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + ret = LOCAL_GL_UNSIGNED_NORMALIZED; + break; + case LOCAL_GL_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + ret = LOCAL_GL_FLOAT; + break; + case LOCAL_GL_UNSIGNED_SHORT: + case LOCAL_GL_UNSIGNED_INT: + ret = LOCAL_GL_UNSIGNED_INT; + break; + default: + MOZ_ASSERT(false, "Unhandled RB component type."); + break; + } + return JS::NumberValue(uint32_t(ret)); + } } ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: pname", pname); @@ -2218,9 +2295,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLenum type, const Nullable &pixels, ErrorResult& rv) { - if (IsContextLost()) { + if (IsContextLost()) return; - } if (mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerChrome()) { GenerateWarning("readPixels: Not allowed"); @@ -2258,20 +2334,34 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, int requiredDataType = 0; // Check the type param + bool isReadTypeValid = false; + bool isReadTypeFloat = false; switch (type) { case LOCAL_GL_UNSIGNED_BYTE: - bytesPerPixel = 1 * channels; + isReadTypeValid = true; + bytesPerPixel = 1*channels; requiredDataType = js::ArrayBufferView::TYPE_UINT8; break; case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + isReadTypeValid = true; bytesPerPixel = 2; requiredDataType = js::ArrayBufferView::TYPE_UINT16; break; - default: - return ErrorInvalidEnum("readPixels: Bad type"); + case LOCAL_GL_FLOAT: + if (IsExtensionEnabled(WEBGL_color_buffer_float) || + IsExtensionEnabled(EXT_color_buffer_half_float)) + { + isReadTypeValid = true; + isReadTypeFloat = true; + bytesPerPixel = 4*channels; + requiredDataType = js::ArrayBufferView::TYPE_FLOAT32; + } + break; } + if (!isReadTypeValid) + return ErrorInvalidEnum("readPixels: Bad type", type); int dataType = JS_GetArrayBufferViewType(pixels.Value().Obj()); @@ -2301,12 +2391,25 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, return rv.Throw(NS_ERROR_OUT_OF_MEMORY); } + bool isSourceTypeFloat = false; + if (mBoundFramebuffer && + mBoundFramebuffer->ColorAttachmentCount() && + mBoundFramebuffer->ColorAttachment(0).IsDefined()) + { + isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat(); + } + + if (isReadTypeFloat != isSourceTypeFloat) + return ErrorInvalidOperation("readPixels: Invalid type floatness"); + // Check the format and type params to assure they are an acceptable pair (as per spec) switch (format) { case LOCAL_GL_RGBA: { switch (type) { case LOCAL_GL_UNSIGNED_BYTE: break; + case LOCAL_GL_FLOAT: + break; default: return ErrorInvalidOperation("readPixels: Invalid format/type pair"); } @@ -2434,6 +2537,20 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, rowp += 4; } + row += checked_alignedRowSize.value(); + } + } else if (format == LOCAL_GL_RGBA && type == LOCAL_GL_FLOAT) { + float* row = static_cast(data); + + for (GLint j = 0; j < height; ++j) { + float* pAlpha = row + 3; + float* pAlphaEnd = pAlpha + 4*width; + + while (pAlpha != pAlphaEnd) { + *pAlpha = 1.0f; + pAlpha += 4; + } + row += checked_alignedRowSize.value(); } } else { @@ -2489,6 +2606,22 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei break; case LOCAL_GL_SRGB8_ALPHA8_EXT: break; + case LOCAL_GL_RGB16F: + case LOCAL_GL_RGBA16F: { + bool hasExtensions = IsExtensionEnabled(OES_texture_half_float) && + IsExtensionEnabled(EXT_color_buffer_half_float); + if (!hasExtensions) + return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target); + break; + } + case LOCAL_GL_RGB32F: + case LOCAL_GL_RGBA32F: { + bool hasExtensions = IsExtensionEnabled(OES_texture_float) && + IsExtensionEnabled(WEBGL_color_buffer_float); + if (!hasExtensions) + return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target); + break; + } default: return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat); } @@ -3632,8 +3765,12 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target, // convert type for half float if not on GLES2 GLenum realType = type; - if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2()) { - realType = LOCAL_GL_HALF_FLOAT; + if (realType == LOCAL_GL_HALF_FLOAT_OES) { + if (gl->IsSupported(gl::GLFeature::texture_half_float)) { + realType = LOCAL_GL_HALF_FLOAT; + } else { + MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); + } } if (sizeMayChange) { @@ -3888,8 +4025,13 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level, // convert type for half float if not on GLES2 GLenum realType = type; - if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2()) - realType = LOCAL_GL_HALF_FLOAT; + if (realType == LOCAL_GL_HALF_FLOAT_OES) { + if (gl->IsSupported(gl::GLFeature::texture_half_float)) { + realType = LOCAL_GL_HALF_FLOAT; + } else { + MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); + } + } if (actualSrcFormat == dstFormat && srcPremultiplied == mPixelStorePremultiplyAlpha && diff --git a/content/canvas/src/WebGLExtensionColorBufferFloat.cpp b/content/canvas/src/WebGLExtensionColorBufferFloat.cpp new file mode 100644 index 000000000000..717afb3b4342 --- /dev/null +++ b/content/canvas/src/WebGLExtensionColorBufferFloat.cpp @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLContext.h" +#include "WebGLExtensions.h" +#include "mozilla/dom/WebGLRenderingContextBinding.h" + +using namespace mozilla; + +WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(WebGLContext* context) + : WebGLExtensionBase(context) +{ + MOZ_ASSERT(IsSupported(context)); +} + +WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat() +{ +} + +bool +WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* context) +{ + return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_float) && + context->GL()->IsSupported(gl::GLFeature::frag_color_float); +} + +IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferFloat) diff --git a/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp b/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp new file mode 100644 index 000000000000..5a3f29a7d199 --- /dev/null +++ b/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLContext.h" +#include "WebGLExtensions.h" +#include "mozilla/dom/WebGLRenderingContextBinding.h" + +using namespace mozilla; + +WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(WebGLContext* context) + : WebGLExtensionBase(context) +{ + MOZ_ASSERT(IsSupported(context)); +} + +WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat() +{ +} + +bool +WebGLExtensionColorBufferHalfFloat::IsSupported(const WebGLContext* context) +{ + return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_half_float) && + context->GL()->IsSupported(gl::GLFeature::frag_color_float); +} + +IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferHalfFloat) diff --git a/content/canvas/src/WebGLExtensions.h b/content/canvas/src/WebGLExtensions.h index 8665452cb55c..b32e612b4e7f 100644 --- a/content/canvas/src/WebGLExtensions.h +++ b/content/canvas/src/WebGLExtensions.h @@ -205,6 +205,30 @@ public: DECL_WEBGL_EXTENSION_GOOP }; +class WebGLExtensionColorBufferFloat + : public WebGLExtensionBase +{ +public: + WebGLExtensionColorBufferFloat(WebGLContext*); + virtual ~WebGLExtensionColorBufferFloat(); + + static bool IsSupported(const WebGLContext*); + + DECL_WEBGL_EXTENSION_GOOP +}; + +class WebGLExtensionColorBufferHalfFloat + : public WebGLExtensionBase +{ +public: + WebGLExtensionColorBufferHalfFloat(WebGLContext*); + virtual ~WebGLExtensionColorBufferHalfFloat(); + + static bool IsSupported(const WebGLContext*); + + DECL_WEBGL_EXTENSION_GOOP +}; + class WebGLExtensionDrawBuffers : public WebGLExtensionBase { diff --git a/content/canvas/src/WebGLFramebuffer.cpp b/content/canvas/src/WebGLFramebuffer.cpp index 92f0ef7ec200..830b74b5b8c1 100644 --- a/content/canvas/src/WebGLFramebuffer.cpp +++ b/content/canvas/src/WebGLFramebuffer.cpp @@ -60,6 +60,35 @@ WebGLFramebuffer::Attachment::HasAlpha() const return FormatHasAlpha(format); } +bool +WebGLFramebuffer::Attachment::IsReadableFloat() const +{ + if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) { + GLenum type = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).Type(); + switch (type) { + case LOCAL_GL_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + return true; + } + return false; + } + + if (Renderbuffer()) { + GLenum format = Renderbuffer()->InternalFormat(); + switch (format) { + case LOCAL_GL_RGB16F: + case LOCAL_GL_RGBA16F: + case LOCAL_GL_RGB32F: + case LOCAL_GL_RGBA32F: + return true; + } + return false; + } + + MOZ_ASSERT(false, "Should not get here."); + return false; +} + void WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLint level) { diff --git a/content/canvas/src/WebGLFramebuffer.h b/content/canvas/src/WebGLFramebuffer.h index 8634534882d0..72370409def1 100644 --- a/content/canvas/src/WebGLFramebuffer.h +++ b/content/canvas/src/WebGLFramebuffer.h @@ -53,6 +53,7 @@ public: bool IsDeleteRequested() const; bool HasAlpha() const; + bool IsReadableFloat() const; void SetTexImage(WebGLTexture* tex, GLenum target, GLint level); void SetRenderbuffer(WebGLRenderbuffer* rb) { diff --git a/content/canvas/src/WebGLRenderbuffer.cpp b/content/canvas/src/WebGLRenderbuffer.cpp index 81dc4dd1c77f..793ba63ad995 100644 --- a/content/canvas/src/WebGLRenderbuffer.cpp +++ b/content/canvas/src/WebGLRenderbuffer.cpp @@ -95,13 +95,13 @@ WebGLRenderbuffer::MemoryUsage() const { int64_t primarySize = 0; switch (primaryFormat) { case LOCAL_GL_STENCIL_INDEX8: - primarySize = 1 * pixels; + primarySize = 1*pixels; break; case LOCAL_GL_RGBA4: case LOCAL_GL_RGB5_A1: case LOCAL_GL_RGB565: case LOCAL_GL_DEPTH_COMPONENT16: - primarySize = 2 * pixels; + primarySize = 2*pixels; break; case LOCAL_GL_RGB8: case LOCAL_GL_DEPTH_COMPONENT24: @@ -113,6 +113,18 @@ WebGLRenderbuffer::MemoryUsage() const { case LOCAL_GL_DEPTH_COMPONENT32: primarySize = 4*pixels; break; + case LOCAL_GL_RGB16F: + primarySize = 2*3*pixels; + break; + case LOCAL_GL_RGBA16F: + primarySize = 2*4*pixels; + break; + case LOCAL_GL_RGB32F: + primarySize = 4*3*pixels; + break; + case LOCAL_GL_RGBA32F: + primarySize = 4*4*pixels; + break; default: MOZ_ASSERT(false, "Unknown `primaryFormat`."); break; diff --git a/content/canvas/src/WebGLTexture.cpp b/content/canvas/src/WebGLTexture.cpp index 3a969c15ac03..0c1419452885 100644 --- a/content/canvas/src/WebGLTexture.cpp +++ b/content/canvas/src/WebGLTexture.cpp @@ -49,8 +49,8 @@ int64_t WebGLTexture::ImageInfo::MemoryUsage() const { if (mImageDataStatus == WebGLImageDataStatus::NoImageData) return 0; - int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mInternalFormat, mType); - return int64_t(mWidth) * int64_t(mHeight) * texelSizeInBits / 8; + int64_t bitsPerTexel = WebGLContext::GetBitsPerTexel(mInternalFormat, mType); + return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8; } int64_t diff --git a/content/canvas/src/moz.build b/content/canvas/src/moz.build index ec3e2cb6e911..d1446edb9265 100644 --- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -44,6 +44,8 @@ if CONFIG['MOZ_WEBGL']: 'WebGLContextVertices.cpp', 'WebGLElementArrayCache.cpp', 'WebGLExtensionBase.cpp', + 'WebGLExtensionColorBufferFloat.cpp', + 'WebGLExtensionColorBufferHalfFloat.cpp', 'WebGLExtensionCompressedTextureATC.cpp', 'WebGLExtensionCompressedTexturePVRTC.cpp', 'WebGLExtensionCompressedTextureS3TC.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 5d65ffd151f3..6fb0f7224b2b 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1343,6 +1343,16 @@ DOMInterfaces = { 'headerFile': 'WebGLExtensions.h' }, +'WebGLExtensionColorBufferFloat': { + 'nativeType': 'mozilla::WebGLExtensionColorBufferFloat', + 'headerFile': 'WebGLExtensions.h' +}, + +'WebGLExtensionColorBufferHalfFloat': { + 'nativeType': 'mozilla::WebGLExtensionColorBufferHalfFloat', + 'headerFile': 'WebGLExtensions.h' +}, + 'WebGLExtensionDrawBuffers': { 'nativeType': 'mozilla::WebGLExtensionDrawBuffers', 'headerFile': 'WebGLExtensions.h' diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index a377042c14d6..5c834387044e 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -917,6 +917,24 @@ interface WebGLExtensionTextureHalfFloatLinear { }; +[NoInterfaceObject] +interface WebGLExtensionColorBufferFloat +{ + const GLenum RGBA32F_EXT = 0x8814; + const GLenum RGB32F_EXT = 0x8815; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; + const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; +}; + +[NoInterfaceObject] +interface WebGLExtensionColorBufferHalfFloat +{ + const GLenum RGBA16F_EXT = 0x881A; + const GLenum RGB16F_EXT = 0x881B; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; + const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; +}; + [NoInterfaceObject] interface WebGLExtensionVertexArray { const GLenum VERTEX_ARRAY_BINDING_OES = 0x85B5; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index f8997c32ab6d..60cb5b9bf575 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -86,6 +86,9 @@ static const char *sExtensionNames[] = { "GL_OES_texture_half_float", "GL_OES_texture_half_float_linear", "GL_NV_half_float", + "GL_EXT_color_buffer_float", + "GL_EXT_color_buffer_half_float", + "GL_ARB_color_buffer_float", "GL_EXT_unpack_subimage", "GL_OES_standard_derivatives", "GL_EXT_texture_filter_anisotropic", diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index c1c5c59adae5..2afc8606674c 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -90,6 +90,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature) element_index_uint, ES2_compatibility, ES3_compatibility, + frag_color_float, frag_depth, framebuffer_blit, framebuffer_multisample, @@ -102,6 +103,8 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature) occlusion_query2, packed_depth_stencil, query_objects, + renderbuffer_color_float, + renderbuffer_color_half_float, robustness, sRGB, standard_derivatives, @@ -365,6 +368,9 @@ public: OES_texture_half_float, OES_texture_half_float_linear, NV_half_float, + EXT_color_buffer_float, + EXT_color_buffer_half_float, + ARB_color_buffer_float, EXT_unpack_subimage, OES_standard_derivatives, EXT_texture_filter_anisotropic, diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index 4ef469209d9c..fa8f7cfb5daf 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -111,6 +111,18 @@ static const FeatureInfo sFeatureInfoArr[] = { GLContext::Extensions_End } }, + { + // Removes clamping for float color outputs from frag shaders. + "frag_color_float", + 300, // OpenGL version + 300, // OpenGL ES version + { + GLContext::ARB_color_buffer_float, + GLContext::EXT_color_buffer_float, + GLContext::EXT_color_buffer_half_float, + GLContext::Extensions_End + } + }, { "frag_depth", 200, // OpenGL version @@ -252,6 +264,26 @@ static const FeatureInfo sFeatureInfoArr[] = { * (added in OpenGL ES 3.0) */ }, + { + "renderbuffer_float", + 300, // OpenGL version + 300, // OpenGL ES version + { + GLContext::ARB_texture_float, + GLContext::EXT_color_buffer_float, + GLContext::Extensions_End + } + }, + { + "renderbuffer_half_float", + 300, // OpenGL version + 300, // OpenGL ES version + { + GLContext::ARB_texture_float, + GLContext::EXT_color_buffer_half_float, + GLContext::Extensions_End + } + }, { "robustness", 0, // OpenGL version @@ -282,7 +314,7 @@ static const FeatureInfo sFeatureInfoArr[] = { }, { "texture_float", - 310, // OpenGL version + 300, // OpenGL version 300, // OpenGL ES version { GLContext::ARB_texture_float, @@ -302,7 +334,7 @@ static const FeatureInfo sFeatureInfoArr[] = { }, { "texture_half_float", - 310, // OpenGL version + 300, // OpenGL version 300, // OpenGL ES version { GLContext::ARB_half_float_pixel, diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp index 6da12bc3e66b..70440d0d8520 100644 --- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -14,7 +14,8 @@ NS_IMPL_ISUPPORTS1(GfxTexturesReporter, nsIMemoryReporter) int64_t GfxTexturesReporter::sAmount = 0; -static uint32_t GetBitsPerTexel(GLenum format, GLenum type) +static uint32_t +GetBitsPerTexel(GLenum format, GLenum type) { // If there is no defined format or type, we're not taking up any memory if (!format || !type) { @@ -23,16 +24,16 @@ static uint32_t GetBitsPerTexel(GLenum format, GLenum type) if (format == LOCAL_GL_DEPTH_COMPONENT) { if (type == LOCAL_GL_UNSIGNED_SHORT) - return 2; + return 2*8; else if (type == LOCAL_GL_UNSIGNED_INT) - return 4; + return 4*8; } else if (format == LOCAL_GL_DEPTH_STENCIL) { if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) - return 4; + return 4*8; } if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) { - int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; + uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; switch (format) { case LOCAL_GL_ALPHA: case LOCAL_GL_LUMINANCE: @@ -64,7 +65,7 @@ static uint32_t GetBitsPerTexel(GLenum format, GLenum type) type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) { - return 16; + return 2*8; } MOZ_ASSERT(false); @@ -75,8 +76,8 @@ static uint32_t GetBitsPerTexel(GLenum format, GLenum type) GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format, GLenum type, uint16_t tileSize) { - uint32_t bytesPerTexel = GetBitsPerTexel(format, type) / 8; - int64_t bytes = (int64_t)(tileSize * tileSize * bytesPerTexel); + int64_t bitsPerTexel = GetBitsPerTexel(format, type); + int64_t bytes = int64_t(tileSize) * int64_t(tileSize) * bitsPerTexel/8; if (action == MemoryFreed) { sAmount -= bytes; } else { From b9c875a48c7f15631780501aa36d52887f055530 Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Mon, 3 Mar 2014 10:37:08 -0500 Subject: [PATCH 49/69] Bug 975935 - nsDisplaymtdBorder needs to override GetBounds. r=bz --- layout/base/nsDisplayList.cpp | 13 ++- layout/base/nsDisplayList.h | 3 + layout/mathml/nsMathMLmtableFrame.cpp | 110 ++++++++++++++++---------- layout/mathml/nsMathMLmtableFrame.h | 2 + 4 files changed, 81 insertions(+), 47 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index a9f35604af2b..b963f5da4b7a 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2684,13 +2684,18 @@ nsRect nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { *aSnap = true; - const nsStyleBorder *styleBorder = mFrame->StyleBorder(); + return CalculateBounds(*mFrame->StyleBorder()); +} + +nsRect +nsDisplayBorder::CalculateBounds(const nsStyleBorder& aStyleBorder) +{ nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize()); - if (styleBorder->IsBorderImageLoaded()) { - borderBounds.Inflate(mFrame->StyleBorder()->GetImageOutset()); + if (aStyleBorder.IsBorderImageLoaded()) { + borderBounds.Inflate(aStyleBorder.GetImageOutset()); return borderBounds; } else { - nsMargin border = styleBorder->GetComputedBorder(); + nsMargin border = aStyleBorder.GetComputedBorder(); nsRect result; if (border.top > 0) { result = nsRect(borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index d2f31578c8a2..a3687727c1dd 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1919,6 +1919,9 @@ public: virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) MOZ_OVERRIDE; + +protected: + nsRect CalculateBounds(const nsStyleBorder& aStyleBorder); }; /** diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index 429dbe28733b..33fc11f1e86b 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -180,6 +180,55 @@ FindCellProperty(const nsIFrame* aCellFrame, return propertyData; } +static void +ApplyBorderToStyle(const nsMathMLmtdFrame* aFrame, + nsStyleBorder& aStyleBorder) +{ + int32_t rowIndex; + int32_t columnIndex; + aFrame->GetRowIndex(rowIndex); + aFrame->GetColIndex(columnIndex); + + nscoord borderWidth = + aFrame->PresContext()->GetBorderWidthTable()[NS_STYLE_BORDER_WIDTH_THIN]; + + nsTArray* rowLinesList = + FindCellProperty(aFrame, RowLinesProperty()); + + nsTArray* columnLinesList = + FindCellProperty(aFrame, ColumnLinesProperty()); + + // We don't place a row line on top of the first row + if (rowIndex > 0 && rowLinesList) { + // If the row number is greater than the number of provided rowline + // values, we simply repeat the last value. + int32_t listLength = rowLinesList->Length(); + if (rowIndex < listLength) { + aStyleBorder.SetBorderStyle(NS_SIDE_TOP, + rowLinesList->ElementAt(rowIndex - 1)); + } else { + aStyleBorder.SetBorderStyle(NS_SIDE_TOP, + rowLinesList->ElementAt(listLength - 1)); + } + aStyleBorder.SetBorderWidth(NS_SIDE_TOP, borderWidth); + } + + // We don't place a column line on the left of the first column. + if (columnIndex > 0 && columnLinesList) { + // If the column number is greater than the number of provided columline + // values, we simply repeat the last value. + int32_t listLength = columnLinesList->Length(); + if (columnIndex < listLength) { + aStyleBorder.SetBorderStyle(NS_SIDE_LEFT, + columnLinesList->ElementAt(columnIndex - 1)); + } else { + aStyleBorder.SetBorderStyle(NS_SIDE_LEFT, + columnLinesList->ElementAt(listLength - 1)); + } + aStyleBorder.SetBorderWidth(NS_SIDE_LEFT, borderWidth); + } +} + /* * A variant of the nsDisplayBorder contains special code to render a border * around a nsMathMLmtdFrame based on the rowline and columnline properties @@ -192,52 +241,17 @@ public: { } + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE + { + nsStyleBorder styleBorder = *mFrame->StyleBorder(); + ApplyBorderToStyle(static_cast(mFrame), styleBorder); + return CalculateBounds(styleBorder); + } + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE { - int32_t rowIndex; - int32_t columnIndex; - static_cast(mFrame)-> - GetCellIndexes(rowIndex, columnIndex); - nsStyleBorder styleBorder = *mFrame->StyleBorder(); - nscoord borderWidth = - mFrame->PresContext()->GetBorderWidthTable()[NS_STYLE_BORDER_WIDTH_THIN]; - - nsTArray* rowLinesList = - FindCellProperty(mFrame, RowLinesProperty()); - - nsTArray* columnLinesList = - FindCellProperty(mFrame, ColumnLinesProperty()); - - // We don't place a row line on top of the first row - if (rowIndex > 0 && rowLinesList) { - // If the row number is greater than the number of provided rowline - // values, we simply repeat the last value. - int32_t listLength = rowLinesList->Length(); - if (rowIndex < listLength) { - styleBorder.SetBorderStyle(NS_SIDE_TOP, - rowLinesList->ElementAt(rowIndex - 1)); - } else { - styleBorder.SetBorderStyle(NS_SIDE_TOP, - rowLinesList->ElementAt(listLength - 1)); - } - styleBorder.SetBorderWidth(NS_SIDE_TOP, borderWidth); - } - - // We don't place a column line on the left of the first column. - if (columnIndex > 0 && columnLinesList) { - // If the column number is greater than the number of provided columline - // values, we simply repeat the last value. - int32_t listLength = columnLinesList->Length(); - if (columnIndex < listLength) { - styleBorder.SetBorderStyle(NS_SIDE_LEFT, - columnLinesList->ElementAt(columnIndex - 1)); - } else { - styleBorder.SetBorderStyle(NS_SIDE_LEFT, - columnLinesList->ElementAt(listLength - 1)); - } - styleBorder.SetBorderWidth(NS_SIDE_LEFT, borderWidth); - } + ApplyBorderToStyle(static_cast(mFrame), styleBorder); nsPoint offset = ToReferenceFrame(); nsCSSRendering::PaintBorderWithStyleBorder(mFrame->PresContext(), *aCtx, @@ -837,6 +851,16 @@ nsMathMLmtdFrame::ProcessBorders(nsTableFrame* aFrame, nsDisplaymtdBorder(aBuilder, this)); return NS_OK; } + +nsMargin* +nsMathMLmtdFrame::GetBorderWidth(nsMargin& aBorder) const +{ + nsStyleBorder styleBorder = *StyleBorder(); + ApplyBorderToStyle(this, styleBorder); + aBorder = styleBorder.GetComputedBorder(); + return &aBorder; +} + // -------- // implementation of nsMathMLmtdInnerFrame diff --git a/layout/mathml/nsMathMLmtableFrame.h b/layout/mathml/nsMathMLmtableFrame.h index 2f7fc8d89fdc..a5f4a70199f3 100644 --- a/layout/mathml/nsMathMLmtableFrame.h +++ b/layout/mathml/nsMathMLmtableFrame.h @@ -206,6 +206,8 @@ public: return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML)); } + virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const MOZ_OVERRIDE; + protected: nsMathMLmtdFrame(nsStyleContext* aContext) : nsTableCellFrame(aContext) {} virtual ~nsMathMLmtdFrame(); From 228e7a6ebcbdc7d7a20a9f4ab2f4368d224540a8 Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Mon, 3 Mar 2014 10:37:24 -0500 Subject: [PATCH 50/69] Bug 975935 - Import rowlines/columnlines tests from MathJax. r=fredw --- layout/reftests/mathml/columnlines-1-ref.html | 77 +++++++++++++++++++ layout/reftests/mathml/columnlines-1a.html | 77 +++++++++++++++++++ layout/reftests/mathml/columnlines-1b.html | 77 +++++++++++++++++++ layout/reftests/mathml/columnlines-1c.html | 77 +++++++++++++++++++ layout/reftests/mathml/columnlines-2-ref.html | 41 ++++++++++ layout/reftests/mathml/columnlines-2a.html | 41 ++++++++++ layout/reftests/mathml/columnlines-2b.html | 41 ++++++++++ .../reftests/mathml/columnlines-3-1-ref.html | 32 ++++++++ layout/reftests/mathml/columnlines-3-1.html | 48 ++++++++++++ .../reftests/mathml/columnlines-3-2-ref.html | 32 ++++++++ layout/reftests/mathml/columnlines-3-2.html | 48 ++++++++++++ layout/reftests/mathml/reftest.list | 16 +++- layout/reftests/mathml/rowlines-1-ref.html | 77 +++++++++++++++++++ layout/reftests/mathml/rowlines-1a.html | 77 +++++++++++++++++++ layout/reftests/mathml/rowlines-1b.html | 77 +++++++++++++++++++ layout/reftests/mathml/rowlines-1c.html | 77 +++++++++++++++++++ layout/reftests/mathml/rowlines-2-ref.html | 51 ++++++++++++ layout/reftests/mathml/rowlines-2a.html | 51 ++++++++++++ layout/reftests/mathml/rowlines-2b.html | 51 ++++++++++++ layout/reftests/mathml/rowlines-3-1-ref.html | 34 ++++++++ layout/reftests/mathml/rowlines-3-1.html | 53 +++++++++++++ layout/reftests/mathml/rowlines-3-2-ref.html | 34 ++++++++ layout/reftests/mathml/rowlines-3-2.html | 53 +++++++++++++ 23 files changed, 1241 insertions(+), 1 deletion(-) create mode 100644 layout/reftests/mathml/columnlines-1-ref.html create mode 100644 layout/reftests/mathml/columnlines-1a.html create mode 100644 layout/reftests/mathml/columnlines-1b.html create mode 100644 layout/reftests/mathml/columnlines-1c.html create mode 100644 layout/reftests/mathml/columnlines-2-ref.html create mode 100644 layout/reftests/mathml/columnlines-2a.html create mode 100644 layout/reftests/mathml/columnlines-2b.html create mode 100644 layout/reftests/mathml/columnlines-3-1-ref.html create mode 100644 layout/reftests/mathml/columnlines-3-1.html create mode 100644 layout/reftests/mathml/columnlines-3-2-ref.html create mode 100644 layout/reftests/mathml/columnlines-3-2.html create mode 100644 layout/reftests/mathml/rowlines-1-ref.html create mode 100644 layout/reftests/mathml/rowlines-1a.html create mode 100644 layout/reftests/mathml/rowlines-1b.html create mode 100644 layout/reftests/mathml/rowlines-1c.html create mode 100644 layout/reftests/mathml/rowlines-2-ref.html create mode 100644 layout/reftests/mathml/rowlines-2a.html create mode 100644 layout/reftests/mathml/rowlines-2b.html create mode 100644 layout/reftests/mathml/rowlines-3-1-ref.html create mode 100644 layout/reftests/mathml/rowlines-3-1.html create mode 100644 layout/reftests/mathml/rowlines-3-2-ref.html create mode 100644 layout/reftests/mathml/rowlines-3-2.html diff --git a/layout/reftests/mathml/columnlines-1-ref.html b/layout/reftests/mathml/columnlines-1-ref.html new file mode 100644 index 000000000000..e5ea01a7deb2 --- /dev/null +++ b/layout/reftests/mathml/columnlines-1-ref.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-1a.html b/layout/reftests/mathml/columnlines-1a.html new file mode 100644 index 000000000000..3f391c296653 --- /dev/null +++ b/layout/reftests/mathml/columnlines-1a.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-1b.html b/layout/reftests/mathml/columnlines-1b.html new file mode 100644 index 000000000000..9ee1a3e35fee --- /dev/null +++ b/layout/reftests/mathml/columnlines-1b.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-1c.html b/layout/reftests/mathml/columnlines-1c.html new file mode 100644 index 000000000000..d1bd0d7ce37c --- /dev/null +++ b/layout/reftests/mathml/columnlines-1c.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-2-ref.html b/layout/reftests/mathml/columnlines-2-ref.html new file mode 100644 index 000000000000..84c96c5fe3c7 --- /dev/null +++ b/layout/reftests/mathml/columnlines-2-ref.html @@ -0,0 +1,41 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + * + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-2a.html b/layout/reftests/mathml/columnlines-2a.html new file mode 100644 index 000000000000..ea3ed5abe091 --- /dev/null +++ b/layout/reftests/mathml/columnlines-2a.html @@ -0,0 +1,41 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + * + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-2b.html b/layout/reftests/mathml/columnlines-2b.html new file mode 100644 index 000000000000..36182d60ad22 --- /dev/null +++ b/layout/reftests/mathml/columnlines-2b.html @@ -0,0 +1,41 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + * + + + + + + + + diff --git a/layout/reftests/mathml/columnlines-3-1-ref.html b/layout/reftests/mathml/columnlines-3-1-ref.html new file mode 100644 index 000000000000..ce49f5dad450 --- /dev/null +++ b/layout/reftests/mathml/columnlines-3-1-ref.html @@ -0,0 +1,32 @@ + + + + + + mtable frame + + + + + + +
+ + + + + + + + +
+ +
+ +
+ + + diff --git a/layout/reftests/mathml/columnlines-3-1.html b/layout/reftests/mathml/columnlines-3-1.html new file mode 100644 index 000000000000..80c46858e634 --- /dev/null +++ b/layout/reftests/mathml/columnlines-3-1.html @@ -0,0 +1,48 @@ + + + + + + mtable frame + + + + + + + + +
+ + + + + + + + +
+ +
+ + + + + + + + +
+ +
+ +
+ + diff --git a/layout/reftests/mathml/columnlines-3-2-ref.html b/layout/reftests/mathml/columnlines-3-2-ref.html new file mode 100644 index 000000000000..6549ad526332 --- /dev/null +++ b/layout/reftests/mathml/columnlines-3-2-ref.html @@ -0,0 +1,32 @@ + + + + + + mtable frame + + + + + + +
+ + + + + + + + +
+ +
+ +
+ + + diff --git a/layout/reftests/mathml/columnlines-3-2.html b/layout/reftests/mathml/columnlines-3-2.html new file mode 100644 index 000000000000..789013d9f0bb --- /dev/null +++ b/layout/reftests/mathml/columnlines-3-2.html @@ -0,0 +1,48 @@ + + + + + + mtable frame + + + + + + + + +
+ + + + + + + + +
+ +
+ + + + + + + + +
+ +
+ +
+ + diff --git a/layout/reftests/mathml/reftest.list b/layout/reftests/mathml/reftest.list index 7590d05795af..1d932c4753b5 100644 --- a/layout/reftests/mathml/reftest.list +++ b/layout/reftests/mathml/reftest.list @@ -244,4 +244,18 @@ fuzzy-if(OSX,1,100) == menclose-5-circle.html menclose-5-circle-ref.html == mo-accent-dynamic.html mo-accent-dynamic-ref.html == mo-movablelimits-dynamic.html mo-movablelimits-dynamic-ref.html == munderover-accent-dynamic.html munderover-accent-dynamic-ref.html -== munderover-accentunder-dynamic.html munderover-accentunder-dynamic-ref.html \ No newline at end of file +== munderover-accentunder-dynamic.html munderover-accentunder-dynamic-ref.html +== columnlines-1a.html columnlines-1-ref.html +!= columnlines-1b.html columnlines-1-ref.html +!= columnlines-1c.html columnlines-1-ref.html +== columnlines-2a.html columnlines-2-ref.html +== columnlines-2b.html columnlines-2-ref.html +!= columnlines-3-1.html columnlines-3-1-ref.html +== columnlines-3-2.html columnlines-3-2-ref.html +== rowlines-1a.html rowlines-1-ref.html +!= rowlines-1b.html rowlines-1-ref.html +!= rowlines-1c.html rowlines-1-ref.html +== rowlines-2a.html rowlines-2-ref.html +== rowlines-2b.html rowlines-2-ref.html +!= rowlines-3-1.html rowlines-3-1-ref.html +== rowlines-3-2.html rowlines-3-2-ref.html diff --git a/layout/reftests/mathml/rowlines-1-ref.html b/layout/reftests/mathml/rowlines-1-ref.html new file mode 100644 index 000000000000..e5ea01a7deb2 --- /dev/null +++ b/layout/reftests/mathml/rowlines-1-ref.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-1a.html b/layout/reftests/mathml/rowlines-1a.html new file mode 100644 index 000000000000..51073e3d5142 --- /dev/null +++ b/layout/reftests/mathml/rowlines-1a.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-1b.html b/layout/reftests/mathml/rowlines-1b.html new file mode 100644 index 000000000000..860edda59409 --- /dev/null +++ b/layout/reftests/mathml/rowlines-1b.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-1c.html b/layout/reftests/mathml/rowlines-1c.html new file mode 100644 index 000000000000..dd51f155f782 --- /dev/null +++ b/layout/reftests/mathml/rowlines-1c.html @@ -0,0 +1,77 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + + + 5 + + + 6 + + + 7 + + + 8 + + + + + 9 + + + 10 + + + 11 + + + 12 + + + + + 13 + + + 14 + + + 15 + + + 16 + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-2-ref.html b/layout/reftests/mathml/rowlines-2-ref.html new file mode 100644 index 000000000000..f66962bad6a3 --- /dev/null +++ b/layout/reftests/mathml/rowlines-2-ref.html @@ -0,0 +1,51 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + * + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-2a.html b/layout/reftests/mathml/rowlines-2a.html new file mode 100644 index 000000000000..2dfa6cb04a43 --- /dev/null +++ b/layout/reftests/mathml/rowlines-2a.html @@ -0,0 +1,51 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + * + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-2b.html b/layout/reftests/mathml/rowlines-2b.html new file mode 100644 index 000000000000..3489239d142c --- /dev/null +++ b/layout/reftests/mathml/rowlines-2b.html @@ -0,0 +1,51 @@ + + + + + + mtable frame + + + + + + + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + * + + + + + + + + diff --git a/layout/reftests/mathml/rowlines-3-1-ref.html b/layout/reftests/mathml/rowlines-3-1-ref.html new file mode 100644 index 000000000000..9f292f7ce657 --- /dev/null +++ b/layout/reftests/mathml/rowlines-3-1-ref.html @@ -0,0 +1,34 @@ + + + + + + mtable frame + + + + + + +
+ + + + + + + + + + +
+ +
+ +
+ + + diff --git a/layout/reftests/mathml/rowlines-3-1.html b/layout/reftests/mathml/rowlines-3-1.html new file mode 100644 index 000000000000..e40b2b7faf80 --- /dev/null +++ b/layout/reftests/mathml/rowlines-3-1.html @@ -0,0 +1,53 @@ + + + + + + mtable frame + + + + + + + + +
+ + + + + + + + + + +
+ +
+ + + + + + + + + + +
+ +
+ +
+ + + diff --git a/layout/reftests/mathml/rowlines-3-2-ref.html b/layout/reftests/mathml/rowlines-3-2-ref.html new file mode 100644 index 000000000000..01fe8ad0d4ae --- /dev/null +++ b/layout/reftests/mathml/rowlines-3-2-ref.html @@ -0,0 +1,34 @@ + + + + + + mtable frame + + + + + + +
+ + + + + + + + + + +
+ +
+ +
+ + + diff --git a/layout/reftests/mathml/rowlines-3-2.html b/layout/reftests/mathml/rowlines-3-2.html new file mode 100644 index 000000000000..685970faf9e5 --- /dev/null +++ b/layout/reftests/mathml/rowlines-3-2.html @@ -0,0 +1,53 @@ + + + + + + mtable frame + + + + + + + + +
+ + + + + + + + + + +
+ +
+ + + + + + + + + + +
+ +
+ +
+ + + From 88addeaaa1e723bd6e57ffb0d4cd2b142db23f9e Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 3 Mar 2014 11:21:10 -0500 Subject: [PATCH 51/69] Backed out changeset 9024f38e3809 (bug 843666) for bustage. --- content/canvas/src/WebGLContext.h | 3 +- content/canvas/src/WebGLContextExtensions.cpp | 12 -- content/canvas/src/WebGLContextGL.cpp | 170 ++---------------- .../src/WebGLExtensionColorBufferFloat.cpp | 28 --- .../WebGLExtensionColorBufferHalfFloat.cpp | 28 --- content/canvas/src/WebGLExtensions.h | 24 --- content/canvas/src/WebGLFramebuffer.cpp | 29 --- content/canvas/src/WebGLFramebuffer.h | 1 - content/canvas/src/WebGLRenderbuffer.cpp | 16 +- content/canvas/src/WebGLTexture.cpp | 4 +- content/canvas/src/moz.build | 2 - dom/bindings/Bindings.conf | 10 -- dom/webidl/WebGLRenderingContext.webidl | 18 -- gfx/gl/GLContext.cpp | 3 - gfx/gl/GLContext.h | 6 - gfx/gl/GLContextFeatures.cpp | 36 +--- gfx/gl/GfxTexturesReporter.cpp | 17 +- 17 files changed, 29 insertions(+), 378 deletions(-) delete mode 100644 content/canvas/src/WebGLExtensionColorBufferFloat.cpp delete mode 100644 content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 61ffebfca5b6..e6e58bd3ac2b 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -895,7 +895,6 @@ protected: // ------------------------------------------------------------------------- // WebGL extensions (implemented in WebGLContextExtensions.cpp) enum WebGLExtensionID { - EXT_color_buffer_half_float, EXT_frag_depth, EXT_sRGB, EXT_texture_filter_anisotropic, @@ -906,7 +905,6 @@ protected: OES_texture_half_float, OES_texture_half_float_linear, OES_vertex_array_object, - WEBGL_color_buffer_float, WEBGL_compressed_texture_atc, WEBGL_compressed_texture_pvrtc, WEBGL_compressed_texture_s3tc, @@ -935,6 +933,7 @@ protected: nsTArray mCompressedTextureFormats; + // ------------------------------------------------------------------------- // WebGL 2 specifics (implemented in WebGL2Context.cpp) diff --git a/content/canvas/src/WebGLContextExtensions.cpp b/content/canvas/src/WebGLContextExtensions.cpp index 237280d8a9b5..805a72b6ba15 100644 --- a/content/canvas/src/WebGLContextExtensions.cpp +++ b/content/canvas/src/WebGLContextExtensions.cpp @@ -17,7 +17,6 @@ using namespace mozilla::gl; // must match WebGLContext::WebGLExtensionID static const char *sExtensionNames[] = { - "EXT_color_buffer_half_float", "EXT_frag_depth", "EXT_sRGB", "EXT_texture_filter_anisotropic", @@ -28,7 +27,6 @@ static const char *sExtensionNames[] = { "OES_texture_half_float", "OES_texture_half_float_linear", "OES_vertex_array_object", - "WEBGL_color_buffer_float", "WEBGL_compressed_texture_atc", "WEBGL_compressed_texture_pvrtc", "WEBGL_compressed_texture_s3tc", @@ -110,10 +108,6 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const gl->IsSupported(GLFeature::texture_half_float); case OES_texture_half_float_linear: return gl->IsSupported(GLFeature::texture_half_float_linear); - case WEBGL_color_buffer_float: - return WebGLExtensionColorBufferFloat::IsSupported(this); - case EXT_color_buffer_half_float: - return WebGLExtensionColorBufferHalfFloat::IsSupported(this); case OES_vertex_array_object: return WebGLExtensionVertexArray::IsSupported(this); case EXT_texture_filter_anisotropic: @@ -292,12 +286,6 @@ WebGLContext::EnableExtension(WebGLExtensionID ext) case OES_texture_half_float_linear: obj = new WebGLExtensionTextureHalfFloatLinear(this); break; - case WEBGL_color_buffer_float: - obj = new WebGLExtensionColorBufferFloat(this); - break; - case EXT_color_buffer_half_float: - obj = new WebGLExtensionColorBufferHalfFloat(this); - break; case WEBGL_draw_buffers: obj = new WebGLExtensionDrawBuffers(this); break; diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 31ba36ca9a74..354cec2389ba 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -1394,47 +1394,8 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER)); case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + { return WebGLObjectAsJSValue(cx, fba.Renderbuffer(), rv); - - case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: { - if (!IsExtensionEnabled(EXT_color_buffer_half_float) && - !IsExtensionEnabled(WEBGL_color_buffer_float)) - { - break; - } - - if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { - ErrorInvalidOperation("getFramebufferAttachmentParameter: Cannot get component" - " type of a depth-stencil attachment."); - return JS::NullValue(); - } - - if (!fba.IsComplete()) - return JS::NumberValue(uint32_t(LOCAL_GL_NONE)); - - uint32_t ret = LOCAL_GL_NONE; - switch (fba.Renderbuffer()->InternalFormat()) { - case LOCAL_GL_RGBA4: - case LOCAL_GL_RGB5_A1: - case LOCAL_GL_RGB565: - case LOCAL_GL_SRGB8_ALPHA8: - ret = LOCAL_GL_UNSIGNED_NORMALIZED; - break; - case LOCAL_GL_RGB16F: - case LOCAL_GL_RGBA16F: - case LOCAL_GL_RGB32F: - case LOCAL_GL_RGBA32F: - ret = LOCAL_GL_FLOAT; - break; - case LOCAL_GL_DEPTH_COMPONENT16: - case LOCAL_GL_STENCIL_INDEX8: - ret = LOCAL_GL_UNSIGNED_INT; - break; - default: - MOZ_ASSERT(false, "Unhandled RB component type."); - break; - } - return JS::NumberValue(uint32_t(ret)); } } @@ -1457,58 +1418,20 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx, return JS::NumberValue(uint32_t(LOCAL_GL_TEXTURE)); case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + { return WebGLObjectAsJSValue(cx, fba.Texture(), rv); + } case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: return JS::Int32Value(fba.TexImageLevel()); - case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: { + case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + { GLenum face = fba.TexImageTarget(); if (face == LOCAL_GL_TEXTURE_2D) face = 0; return JS::Int32Value(face); } - - case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: { - if (!IsExtensionEnabled(EXT_color_buffer_half_float) && - !IsExtensionEnabled(WEBGL_color_buffer_float)) - { - break; - } - - if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { - ErrorInvalidOperation("getFramebufferAttachmentParameter: cannot component" - " type of depth-stencil attachments."); - return JS::NullValue(); - } - - if (!fba.IsComplete()) - return JS::NumberValue(uint32_t(LOCAL_GL_NONE)); - - uint32_t ret = LOCAL_GL_NONE; - GLenum type = fba.Texture()->ImageInfoAt(fba.TexImageTarget(), - fba.TexImageLevel()).Type(); - switch (type) { - case LOCAL_GL_UNSIGNED_BYTE: - case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: - case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: - case LOCAL_GL_UNSIGNED_SHORT_5_6_5: - ret = LOCAL_GL_UNSIGNED_NORMALIZED; - break; - case LOCAL_GL_FLOAT: - case LOCAL_GL_HALF_FLOAT_OES: - ret = LOCAL_GL_FLOAT; - break; - case LOCAL_GL_UNSIGNED_SHORT: - case LOCAL_GL_UNSIGNED_INT: - ret = LOCAL_GL_UNSIGNED_INT; - break; - default: - MOZ_ASSERT(false, "Unhandled RB component type."); - break; - } - return JS::NumberValue(uint32_t(ret)); - } } ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: pname", pname); @@ -2295,8 +2218,9 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLenum type, const Nullable &pixels, ErrorResult& rv) { - if (IsContextLost()) + if (IsContextLost()) { return; + } if (mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerChrome()) { GenerateWarning("readPixels: Not allowed"); @@ -2334,34 +2258,20 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, int requiredDataType = 0; // Check the type param - bool isReadTypeValid = false; - bool isReadTypeFloat = false; switch (type) { case LOCAL_GL_UNSIGNED_BYTE: - isReadTypeValid = true; - bytesPerPixel = 1*channels; + bytesPerPixel = 1 * channels; requiredDataType = js::ArrayBufferView::TYPE_UINT8; break; case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: case LOCAL_GL_UNSIGNED_SHORT_5_6_5: - isReadTypeValid = true; bytesPerPixel = 2; requiredDataType = js::ArrayBufferView::TYPE_UINT16; break; - case LOCAL_GL_FLOAT: - if (IsExtensionEnabled(WEBGL_color_buffer_float) || - IsExtensionEnabled(EXT_color_buffer_half_float)) - { - isReadTypeValid = true; - isReadTypeFloat = true; - bytesPerPixel = 4*channels; - requiredDataType = js::ArrayBufferView::TYPE_FLOAT32; - } - break; + default: + return ErrorInvalidEnum("readPixels: Bad type"); } - if (!isReadTypeValid) - return ErrorInvalidEnum("readPixels: Bad type", type); int dataType = JS_GetArrayBufferViewType(pixels.Value().Obj()); @@ -2391,25 +2301,12 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, return rv.Throw(NS_ERROR_OUT_OF_MEMORY); } - bool isSourceTypeFloat = false; - if (mBoundFramebuffer && - mBoundFramebuffer->ColorAttachmentCount() && - mBoundFramebuffer->ColorAttachment(0).IsDefined()) - { - isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat(); - } - - if (isReadTypeFloat != isSourceTypeFloat) - return ErrorInvalidOperation("readPixels: Invalid type floatness"); - // Check the format and type params to assure they are an acceptable pair (as per spec) switch (format) { case LOCAL_GL_RGBA: { switch (type) { case LOCAL_GL_UNSIGNED_BYTE: break; - case LOCAL_GL_FLOAT: - break; default: return ErrorInvalidOperation("readPixels: Invalid format/type pair"); } @@ -2537,20 +2434,6 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, rowp += 4; } - row += checked_alignedRowSize.value(); - } - } else if (format == LOCAL_GL_RGBA && type == LOCAL_GL_FLOAT) { - float* row = static_cast(data); - - for (GLint j = 0; j < height; ++j) { - float* pAlpha = row + 3; - float* pAlphaEnd = pAlpha + 4*width; - - while (pAlpha != pAlphaEnd) { - *pAlpha = 1.0f; - pAlpha += 4; - } - row += checked_alignedRowSize.value(); } } else { @@ -2606,22 +2489,6 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei break; case LOCAL_GL_SRGB8_ALPHA8_EXT: break; - case LOCAL_GL_RGB16F: - case LOCAL_GL_RGBA16F: { - bool hasExtensions = IsExtensionEnabled(OES_texture_half_float) && - IsExtensionEnabled(EXT_color_buffer_half_float); - if (!hasExtensions) - return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target); - break; - } - case LOCAL_GL_RGB32F: - case LOCAL_GL_RGBA32F: { - bool hasExtensions = IsExtensionEnabled(OES_texture_float) && - IsExtensionEnabled(WEBGL_color_buffer_float); - if (!hasExtensions) - return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", target); - break; - } default: return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat); } @@ -3765,12 +3632,8 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target, // convert type for half float if not on GLES2 GLenum realType = type; - if (realType == LOCAL_GL_HALF_FLOAT_OES) { - if (gl->IsSupported(gl::GLFeature::texture_half_float)) { - realType = LOCAL_GL_HALF_FLOAT; - } else { - MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); - } + if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2()) { + realType = LOCAL_GL_HALF_FLOAT; } if (sizeMayChange) { @@ -4025,13 +3888,8 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level, // convert type for half float if not on GLES2 GLenum realType = type; - if (realType == LOCAL_GL_HALF_FLOAT_OES) { - if (gl->IsSupported(gl::GLFeature::texture_half_float)) { - realType = LOCAL_GL_HALF_FLOAT; - } else { - MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); - } - } + if (realType == LOCAL_GL_HALF_FLOAT_OES && !gl->IsGLES2()) + realType = LOCAL_GL_HALF_FLOAT; if (actualSrcFormat == dstFormat && srcPremultiplied == mPixelStorePremultiplyAlpha && diff --git a/content/canvas/src/WebGLExtensionColorBufferFloat.cpp b/content/canvas/src/WebGLExtensionColorBufferFloat.cpp deleted file mode 100644 index 717afb3b4342..000000000000 --- a/content/canvas/src/WebGLExtensionColorBufferFloat.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.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 "WebGLContext.h" -#include "WebGLExtensions.h" -#include "mozilla/dom/WebGLRenderingContextBinding.h" - -using namespace mozilla; - -WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(WebGLContext* context) - : WebGLExtensionBase(context) -{ - MOZ_ASSERT(IsSupported(context)); -} - -WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat() -{ -} - -bool -WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* context) -{ - return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_float) && - context->GL()->IsSupported(gl::GLFeature::frag_color_float); -} - -IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferFloat) diff --git a/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp b/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp deleted file mode 100644 index 5a3f29a7d199..000000000000 --- a/content/canvas/src/WebGLExtensionColorBufferHalfFloat.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.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 "WebGLContext.h" -#include "WebGLExtensions.h" -#include "mozilla/dom/WebGLRenderingContextBinding.h" - -using namespace mozilla; - -WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(WebGLContext* context) - : WebGLExtensionBase(context) -{ - MOZ_ASSERT(IsSupported(context)); -} - -WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat() -{ -} - -bool -WebGLExtensionColorBufferHalfFloat::IsSupported(const WebGLContext* context) -{ - return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_half_float) && - context->GL()->IsSupported(gl::GLFeature::frag_color_float); -} - -IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferHalfFloat) diff --git a/content/canvas/src/WebGLExtensions.h b/content/canvas/src/WebGLExtensions.h index b32e612b4e7f..8665452cb55c 100644 --- a/content/canvas/src/WebGLExtensions.h +++ b/content/canvas/src/WebGLExtensions.h @@ -205,30 +205,6 @@ public: DECL_WEBGL_EXTENSION_GOOP }; -class WebGLExtensionColorBufferFloat - : public WebGLExtensionBase -{ -public: - WebGLExtensionColorBufferFloat(WebGLContext*); - virtual ~WebGLExtensionColorBufferFloat(); - - static bool IsSupported(const WebGLContext*); - - DECL_WEBGL_EXTENSION_GOOP -}; - -class WebGLExtensionColorBufferHalfFloat - : public WebGLExtensionBase -{ -public: - WebGLExtensionColorBufferHalfFloat(WebGLContext*); - virtual ~WebGLExtensionColorBufferHalfFloat(); - - static bool IsSupported(const WebGLContext*); - - DECL_WEBGL_EXTENSION_GOOP -}; - class WebGLExtensionDrawBuffers : public WebGLExtensionBase { diff --git a/content/canvas/src/WebGLFramebuffer.cpp b/content/canvas/src/WebGLFramebuffer.cpp index 830b74b5b8c1..92f0ef7ec200 100644 --- a/content/canvas/src/WebGLFramebuffer.cpp +++ b/content/canvas/src/WebGLFramebuffer.cpp @@ -60,35 +60,6 @@ WebGLFramebuffer::Attachment::HasAlpha() const return FormatHasAlpha(format); } -bool -WebGLFramebuffer::Attachment::IsReadableFloat() const -{ - if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) { - GLenum type = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).Type(); - switch (type) { - case LOCAL_GL_FLOAT: - case LOCAL_GL_HALF_FLOAT_OES: - return true; - } - return false; - } - - if (Renderbuffer()) { - GLenum format = Renderbuffer()->InternalFormat(); - switch (format) { - case LOCAL_GL_RGB16F: - case LOCAL_GL_RGBA16F: - case LOCAL_GL_RGB32F: - case LOCAL_GL_RGBA32F: - return true; - } - return false; - } - - MOZ_ASSERT(false, "Should not get here."); - return false; -} - void WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLint level) { diff --git a/content/canvas/src/WebGLFramebuffer.h b/content/canvas/src/WebGLFramebuffer.h index 72370409def1..8634534882d0 100644 --- a/content/canvas/src/WebGLFramebuffer.h +++ b/content/canvas/src/WebGLFramebuffer.h @@ -53,7 +53,6 @@ public: bool IsDeleteRequested() const; bool HasAlpha() const; - bool IsReadableFloat() const; void SetTexImage(WebGLTexture* tex, GLenum target, GLint level); void SetRenderbuffer(WebGLRenderbuffer* rb) { diff --git a/content/canvas/src/WebGLRenderbuffer.cpp b/content/canvas/src/WebGLRenderbuffer.cpp index 793ba63ad995..81dc4dd1c77f 100644 --- a/content/canvas/src/WebGLRenderbuffer.cpp +++ b/content/canvas/src/WebGLRenderbuffer.cpp @@ -95,13 +95,13 @@ WebGLRenderbuffer::MemoryUsage() const { int64_t primarySize = 0; switch (primaryFormat) { case LOCAL_GL_STENCIL_INDEX8: - primarySize = 1*pixels; + primarySize = 1 * pixels; break; case LOCAL_GL_RGBA4: case LOCAL_GL_RGB5_A1: case LOCAL_GL_RGB565: case LOCAL_GL_DEPTH_COMPONENT16: - primarySize = 2*pixels; + primarySize = 2 * pixels; break; case LOCAL_GL_RGB8: case LOCAL_GL_DEPTH_COMPONENT24: @@ -113,18 +113,6 @@ WebGLRenderbuffer::MemoryUsage() const { case LOCAL_GL_DEPTH_COMPONENT32: primarySize = 4*pixels; break; - case LOCAL_GL_RGB16F: - primarySize = 2*3*pixels; - break; - case LOCAL_GL_RGBA16F: - primarySize = 2*4*pixels; - break; - case LOCAL_GL_RGB32F: - primarySize = 4*3*pixels; - break; - case LOCAL_GL_RGBA32F: - primarySize = 4*4*pixels; - break; default: MOZ_ASSERT(false, "Unknown `primaryFormat`."); break; diff --git a/content/canvas/src/WebGLTexture.cpp b/content/canvas/src/WebGLTexture.cpp index 0c1419452885..3a969c15ac03 100644 --- a/content/canvas/src/WebGLTexture.cpp +++ b/content/canvas/src/WebGLTexture.cpp @@ -49,8 +49,8 @@ int64_t WebGLTexture::ImageInfo::MemoryUsage() const { if (mImageDataStatus == WebGLImageDataStatus::NoImageData) return 0; - int64_t bitsPerTexel = WebGLContext::GetBitsPerTexel(mInternalFormat, mType); - return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8; + int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mInternalFormat, mType); + return int64_t(mWidth) * int64_t(mHeight) * texelSizeInBits / 8; } int64_t diff --git a/content/canvas/src/moz.build b/content/canvas/src/moz.build index d1446edb9265..ec3e2cb6e911 100644 --- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -44,8 +44,6 @@ if CONFIG['MOZ_WEBGL']: 'WebGLContextVertices.cpp', 'WebGLElementArrayCache.cpp', 'WebGLExtensionBase.cpp', - 'WebGLExtensionColorBufferFloat.cpp', - 'WebGLExtensionColorBufferHalfFloat.cpp', 'WebGLExtensionCompressedTextureATC.cpp', 'WebGLExtensionCompressedTexturePVRTC.cpp', 'WebGLExtensionCompressedTextureS3TC.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 6fb0f7224b2b..5d65ffd151f3 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1343,16 +1343,6 @@ DOMInterfaces = { 'headerFile': 'WebGLExtensions.h' }, -'WebGLExtensionColorBufferFloat': { - 'nativeType': 'mozilla::WebGLExtensionColorBufferFloat', - 'headerFile': 'WebGLExtensions.h' -}, - -'WebGLExtensionColorBufferHalfFloat': { - 'nativeType': 'mozilla::WebGLExtensionColorBufferHalfFloat', - 'headerFile': 'WebGLExtensions.h' -}, - 'WebGLExtensionDrawBuffers': { 'nativeType': 'mozilla::WebGLExtensionDrawBuffers', 'headerFile': 'WebGLExtensions.h' diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index 5c834387044e..a377042c14d6 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -917,24 +917,6 @@ interface WebGLExtensionTextureHalfFloatLinear { }; -[NoInterfaceObject] -interface WebGLExtensionColorBufferFloat -{ - const GLenum RGBA32F_EXT = 0x8814; - const GLenum RGB32F_EXT = 0x8815; - const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; - const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; -}; - -[NoInterfaceObject] -interface WebGLExtensionColorBufferHalfFloat -{ - const GLenum RGBA16F_EXT = 0x881A; - const GLenum RGB16F_EXT = 0x881B; - const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; - const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; -}; - [NoInterfaceObject] interface WebGLExtensionVertexArray { const GLenum VERTEX_ARRAY_BINDING_OES = 0x85B5; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 60cb5b9bf575..f8997c32ab6d 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -86,9 +86,6 @@ static const char *sExtensionNames[] = { "GL_OES_texture_half_float", "GL_OES_texture_half_float_linear", "GL_NV_half_float", - "GL_EXT_color_buffer_float", - "GL_EXT_color_buffer_half_float", - "GL_ARB_color_buffer_float", "GL_EXT_unpack_subimage", "GL_OES_standard_derivatives", "GL_EXT_texture_filter_anisotropic", diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 2afc8606674c..c1c5c59adae5 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -90,7 +90,6 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature) element_index_uint, ES2_compatibility, ES3_compatibility, - frag_color_float, frag_depth, framebuffer_blit, framebuffer_multisample, @@ -103,8 +102,6 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature) occlusion_query2, packed_depth_stencil, query_objects, - renderbuffer_color_float, - renderbuffer_color_half_float, robustness, sRGB, standard_derivatives, @@ -368,9 +365,6 @@ public: OES_texture_half_float, OES_texture_half_float_linear, NV_half_float, - EXT_color_buffer_float, - EXT_color_buffer_half_float, - ARB_color_buffer_float, EXT_unpack_subimage, OES_standard_derivatives, EXT_texture_filter_anisotropic, diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index fa8f7cfb5daf..4ef469209d9c 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -111,18 +111,6 @@ static const FeatureInfo sFeatureInfoArr[] = { GLContext::Extensions_End } }, - { - // Removes clamping for float color outputs from frag shaders. - "frag_color_float", - 300, // OpenGL version - 300, // OpenGL ES version - { - GLContext::ARB_color_buffer_float, - GLContext::EXT_color_buffer_float, - GLContext::EXT_color_buffer_half_float, - GLContext::Extensions_End - } - }, { "frag_depth", 200, // OpenGL version @@ -264,26 +252,6 @@ static const FeatureInfo sFeatureInfoArr[] = { * (added in OpenGL ES 3.0) */ }, - { - "renderbuffer_float", - 300, // OpenGL version - 300, // OpenGL ES version - { - GLContext::ARB_texture_float, - GLContext::EXT_color_buffer_float, - GLContext::Extensions_End - } - }, - { - "renderbuffer_half_float", - 300, // OpenGL version - 300, // OpenGL ES version - { - GLContext::ARB_texture_float, - GLContext::EXT_color_buffer_half_float, - GLContext::Extensions_End - } - }, { "robustness", 0, // OpenGL version @@ -314,7 +282,7 @@ static const FeatureInfo sFeatureInfoArr[] = { }, { "texture_float", - 300, // OpenGL version + 310, // OpenGL version 300, // OpenGL ES version { GLContext::ARB_texture_float, @@ -334,7 +302,7 @@ static const FeatureInfo sFeatureInfoArr[] = { }, { "texture_half_float", - 300, // OpenGL version + 310, // OpenGL version 300, // OpenGL ES version { GLContext::ARB_half_float_pixel, diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp index 70440d0d8520..6da12bc3e66b 100644 --- a/gfx/gl/GfxTexturesReporter.cpp +++ b/gfx/gl/GfxTexturesReporter.cpp @@ -14,8 +14,7 @@ NS_IMPL_ISUPPORTS1(GfxTexturesReporter, nsIMemoryReporter) int64_t GfxTexturesReporter::sAmount = 0; -static uint32_t -GetBitsPerTexel(GLenum format, GLenum type) +static uint32_t GetBitsPerTexel(GLenum format, GLenum type) { // If there is no defined format or type, we're not taking up any memory if (!format || !type) { @@ -24,16 +23,16 @@ GetBitsPerTexel(GLenum format, GLenum type) if (format == LOCAL_GL_DEPTH_COMPONENT) { if (type == LOCAL_GL_UNSIGNED_SHORT) - return 2*8; + return 2; else if (type == LOCAL_GL_UNSIGNED_INT) - return 4*8; + return 4; } else if (format == LOCAL_GL_DEPTH_STENCIL) { if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT) - return 4*8; + return 4; } if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) { - uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; + int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8; switch (format) { case LOCAL_GL_ALPHA: case LOCAL_GL_LUMINANCE: @@ -65,7 +64,7 @@ GetBitsPerTexel(GLenum format, GLenum type) type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 || type == LOCAL_GL_UNSIGNED_SHORT_5_6_5) { - return 2*8; + return 16; } MOZ_ASSERT(false); @@ -76,8 +75,8 @@ GetBitsPerTexel(GLenum format, GLenum type) GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format, GLenum type, uint16_t tileSize) { - int64_t bitsPerTexel = GetBitsPerTexel(format, type); - int64_t bytes = int64_t(tileSize) * int64_t(tileSize) * bitsPerTexel/8; + uint32_t bytesPerTexel = GetBitsPerTexel(format, type) / 8; + int64_t bytes = (int64_t)(tileSize * tileSize * bytesPerTexel); if (action == MemoryFreed) { sAmount -= bytes; } else { From e81366ccc3ff1f0299c5bee771a65dd6ab4b6fcc Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 08:50:26 -0800 Subject: [PATCH 52/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/05a2237d43c5 Author: Ryan VanderMeulen Desc: Merge pull request #16744 from flodolo/bug977268_ftu Bug 977268 - "Show password" checkbox label on Join hidden network is too narrow for most locales ======== https://hg.mozilla.org/integration/gaia-central/rev/0557528f1538 Author: Francesco Lodolo (:flod) Desc: Bug 977268 - "Show password" label on Join hidden network is too narrow for most locales --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 1928ee92d030..8946046ee1da 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "8b0bebc9fe09fae4e7c33f0eb43eed5cd00b050e", + "revision": "05a2237d43c5ff1080606b933c2bafbe9039d84f", "repo_path": "/integration/gaia-central" } From e0fbf49d77c7f9014ae5673835caa4f0f3667197 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 08:51:30 -0800 Subject: [PATCH 53/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 5b2941158f6e..ad8098f6e168 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@
- + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 1b035d1071bc..78e9a41002d1 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 5b2941158f6e..ad8098f6e168 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index b84c7ec2989d..2db9c17f0907 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 9213f24bbadf..176017e9ec0c 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 0583457c0faf..5e2c5ae5ec5f 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 487a268e85fe..683fed870223 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index d9a54d01b848..318b837dfae6 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 4365dbd2ecdb..1d5eda91c3a8 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From ee769ba5b5ed016cc63b4ef9926b9f376ea23616 Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Mon, 3 Mar 2014 11:53:21 -0500 Subject: [PATCH 54/69] Bug 971943: 5. Add float support to gfxPrefs. apz.max_event_acceleration, apz.fling_friction, apz.fling_stopped_threshold, apz.max_velocity_queue_size, apz.max_velocity_pixels_per_ms preferences moved to gfxPrefs. r=kgupta. --- gfx/layers/ipc/Axis.cpp | 76 +++++++++++++++++------------------------ gfx/thebes/gfxPrefs.cpp | 19 +++++++++-- gfx/thebes/gfxPrefs.h | 15 ++++++-- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/gfx/layers/ipc/Axis.cpp b/gfx/layers/ipc/Axis.cpp index 043b4582ae42..7ebe259f2f0a 100644 --- a/gfx/layers/ipc/Axis.cpp +++ b/gfx/layers/ipc/Axis.cpp @@ -16,75 +16,62 @@ #include "nsMathUtils.h" // for NS_lround #include "nsThreadUtils.h" // for NS_DispatchToMainThread, etc #include "nscore.h" // for NS_IMETHOD +#include "gfxPrefs.h" // for the preferences namespace mozilla { namespace layers { /** + * These are the preferences that control the behavior of APZ + */ + +/** + * "apz.max_event_acceleration" + * * Maximum acceleration that can happen between two frames. Velocity is * throttled if it's above this. This may happen if a time delta is very low, * or we get a touch point very far away from the previous position for some * reason. + * + * The default value is 999.0f, set in gfxPrefs.h */ -static float gMaxEventAcceleration = 999.0f; /** + * "apz.fling_friction" + * * Amount of friction applied during flings. + * + * The default value is 0.002f, set in gfxPrefs.h */ -static float gFlingFriction = 0.002f; /** + * "apz.fling_stopped_threshold" + * * When flinging, if the velocity goes below this number, we just stop the * animation completely. This is to prevent asymptotically approaching 0 * velocity and rerendering unnecessarily. + * + * The default value is 0.01f, set in gfxPrefs.h. */ -static float gFlingStoppedThreshold = 0.01f; /** + * "apz.max_velocity_queue_size" + * * Maximum size of velocity queue. The queue contains last N velocity records. * On touch end we calculate the average velocity in order to compensate * touch/mouse drivers misbehaviour. + * + * The default value is 5, set in gfxPrefs.h */ -static uint32_t gMaxVelocityQueueSize = 5; /** + * "apz.max_velocity_pixels_per_ms" + * * Maximum velocity in pixels per millisecond. Velocity will be capped at this * value if a faster fling occurs. Negative values indicate unlimited velocity. + * + * The default value is -1.0f, set in gfxPrefs.h */ -static float gMaxVelocity = -1.0f; - -static void ReadAxisPrefs() -{ - Preferences::AddFloatVarCache(&gMaxEventAcceleration, "apz.max_event_acceleration", gMaxEventAcceleration); - Preferences::AddFloatVarCache(&gFlingFriction, "apz.fling_friction", gFlingFriction); - Preferences::AddFloatVarCache(&gFlingStoppedThreshold, "apz.fling_stopped_threshold", gFlingStoppedThreshold); - Preferences::AddUintVarCache(&gMaxVelocityQueueSize, "apz.max_velocity_queue_size", gMaxVelocityQueueSize); - Preferences::AddFloatVarCache(&gMaxVelocity, "apz.max_velocity_pixels_per_ms", gMaxVelocity); -} - -class ReadAxisPref MOZ_FINAL : public nsRunnable { -public: - NS_IMETHOD Run() - { - ReadAxisPrefs(); - return NS_OK; - } -}; - -static void InitAxisPrefs() -{ - static bool sInitialized = false; - if (sInitialized) - return; - - sInitialized = true; - if (NS_IsMainThread()) { - ReadAxisPrefs(); - } else { - // We have to dispatch an event to the main thread to read the pref. - NS_DispatchToMainThread(new ReadAxisPref()); - } -} Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) : mPos(0), @@ -92,21 +79,20 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) mAxisLocked(false), mAsyncPanZoomController(aAsyncPanZoomController) { - InitAxisPrefs(); } void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) { float newVelocity = mAxisLocked ? 0 : (mPos - aPos) / aTimeDelta.ToMilliseconds(); - if (gMaxVelocity > 0.0f) { - newVelocity = std::min(newVelocity, gMaxVelocity); + if (gfxPrefs::APZMaxVelocity() > 0.0f) { + newVelocity = std::min(newVelocity, gfxPrefs::APZMaxVelocity()); } mVelocity = newVelocity; mPos = aPos; - // Keep last gMaxVelocityQueueSize or less velocities in the queue. + // Limit queue size pased on pref mVelocityQueue.AppendElement(mVelocity); - if (mVelocityQueue.Length() > gMaxVelocityQueueSize) { + if (mVelocityQueue.Length() > gfxPrefs::APZMaxVelocityQueueSize()) { mVelocityQueue.RemoveElementAt(0); } } @@ -180,14 +166,14 @@ bool Axis::Scrollable() { } bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) { - if (fabsf(mVelocity) <= gFlingStoppedThreshold) { + if (fabsf(mVelocity) <= gfxPrefs::APZFlingStoppedThreshold()) { // If the velocity is very low, just set it to 0 and stop the fling, // otherwise we'll just asymptotically approach 0 and the user won't // actually see any changes. mVelocity = 0.0f; return false; } else { - mVelocity *= pow(1.0f - gFlingFriction, float(aDelta.ToMilliseconds())); + mVelocity *= pow(1.0f - gfxPrefs::APZFlingFriction(), float(aDelta.ToMilliseconds())); } return true; } diff --git a/gfx/thebes/gfxPrefs.cpp b/gfx/thebes/gfxPrefs.cpp index 2d7ad05ded42..a8f2c4527211 100644 --- a/gfx/thebes/gfxPrefs.cpp +++ b/gfx/thebes/gfxPrefs.cpp @@ -59,17 +59,30 @@ void gfxPrefs::PrefAddVarCache(uint32_t* aVariable, Preferences::AddUintVarCache(aVariable, aPref, aDefault); } +void gfxPrefs::PrefAddVarCache(float* aVariable, + const char* aPref, + float aDefault) +{ + Preferences::AddFloatVarCache(aVariable, aPref, aDefault); +} + bool gfxPrefs::PrefGet(const char* aPref, bool aDefault) { - return Preferences::GetBool(aPref,aDefault); + return Preferences::GetBool(aPref, aDefault); } int32_t gfxPrefs::PrefGet(const char* aPref, int32_t aDefault) { - return Preferences::GetInt(aPref,aDefault); + return Preferences::GetInt(aPref, aDefault); } uint32_t gfxPrefs::PrefGet(const char* aPref, uint32_t aDefault) { - return Preferences::GetUint(aPref,aDefault); + return Preferences::GetUint(aPref, aDefault); } + +float gfxPrefs::PrefGet(const char* aPref, float aDefault) +{ + return Preferences::GetFloat(aPref, aDefault); +} + diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 59e174fc539c..936463706cd9 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -56,7 +56,8 @@ public: \ static Type Name() { MOZ_ASSERT(Exists()); return One().mPref##Name.mValue; } \ private: \ static const char* Get##Name##PrefName() { return Pref; } \ -PrefTemplate mPref##Name +static Type Get##Name##PrefDefault() { return Default; } \ +PrefTemplate mPref##Name class gfxPrefs; class gfxPrefs MOZ_FINAL @@ -70,12 +71,12 @@ private: MOZ_END_NESTED_ENUM_CLASS(UpdatePolicy) // Since we cannot use const char*, use a function that returns it. - template + template class PrefTemplate { public: PrefTemplate() - : mValue(Default) + : mValue(Default()) { Register(Update, Pref()); } @@ -102,6 +103,12 @@ private: // We will keep these in an alphabetical order to make it easier to see if // a method accessing a pref already exists. Just add yours in the list. + DECL_GFX_PREF(Once, "apz.fling_friction", APZFlingFriction, float, 0.002f); + DECL_GFX_PREF(Once, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f); + DECL_GFX_PREF(Once, "apz.max_event_acceleration", APZMaxEventAcceleration, float, 999.0f); + DECL_GFX_PREF(Once, "apz.max_velocity_pixels_per_ms", APZMaxVelocity, float, -1.0f); + DECL_GFX_PREF(Once, "apz.max_velocity_queue_size", APZMaxVelocityQueueSize, uint32_t, 5); + #if defined(ANDROID) DECL_GFX_PREF(Once, "gfx.apitrace.enabled", UseApitrace, bool, false); #endif @@ -181,9 +188,11 @@ private: static void PrefAddVarCache(bool*, const char*, bool); static void PrefAddVarCache(int32_t*, const char*, int32_t); static void PrefAddVarCache(uint32_t*, const char*, uint32_t); + static void PrefAddVarCache(float*, const char*, float); static bool PrefGet(const char*, bool); static int32_t PrefGet(const char*, int32_t); static uint32_t PrefGet(const char*, uint32_t); + static float PrefGet(const char*, float); gfxPrefs(); ~gfxPrefs(); From dbe96fbc4dfd56a923d0881d066f7452e52ece7c Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 3 Mar 2014 08:53:42 -0800 Subject: [PATCH 55/69] Bug 975419 - Used a TenuredHeap pointer for SandboxPrivate and BackstagePass. r=mccr8 --- js/xpconnect/public/SandboxPrivate.h | 4 +++- js/xpconnect/src/BackstagePass.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/js/xpconnect/public/SandboxPrivate.h b/js/xpconnect/public/SandboxPrivate.h index 606e918c4d73..88f6623de8b4 100644 --- a/js/xpconnect/public/SandboxPrivate.h +++ b/js/xpconnect/public/SandboxPrivate.h @@ -10,6 +10,8 @@ #include "nsIPrincipal.h" #include "nsWeakReference.h" +#include "js/RootingAPI.h" + // This interface is public only because it is used in jsd. // Once jsd is gone this file should be moved back to xpconnect/src. @@ -43,7 +45,7 @@ public: } private: nsCOMPtr mPrincipal; - JSObject *mGlobalJSObject; + JS::TenuredHeap mGlobalJSObject; }; #endif // __SANDBOXPRIVATE_H__ diff --git a/js/xpconnect/src/BackstagePass.h b/js/xpconnect/src/BackstagePass.h index 87fb7f92c845..692fc2cef9b9 100644 --- a/js/xpconnect/src/BackstagePass.h +++ b/js/xpconnect/src/BackstagePass.h @@ -12,6 +12,8 @@ #include "nsIScriptObjectPrincipal.h" #include "nsIXPCScriptable.h" +#include "js/HeapAPI.h" + class BackstagePass : public nsIGlobalObject, public nsIScriptObjectPrincipal, public nsIXPCScriptable, @@ -48,7 +50,7 @@ public: private: nsCOMPtr mPrincipal; - JSObject *mGlobal; + JS::TenuredHeap mGlobal; }; NS_EXPORT nsresult From 611c847a270e562415dbaad929379ea77b88b130 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 3 Mar 2014 08:53:42 -0800 Subject: [PATCH 56/69] Bug 975419 - Add a JS::TenuredHeap overload to TraceCallbacks. r=mccr8,terrence --- js/public/RootingAPI.h | 2 +- xpcom/base/CycleCollectedJSRuntime.cpp | 8 ++++++++ xpcom/base/nsCycleCollector.cpp | 12 ++++++++++++ xpcom/glue/nsCycleCollectionParticipant.cpp | 6 ++++++ xpcom/glue/nsCycleCollectionParticipant.h | 4 +++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index c782181ee3d2..bc8a438ccd48 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -324,7 +324,7 @@ class TenuredHeap : public js::HeapBase "TenuredHeap must be binary compatible with T."); } explicit TenuredHeap(T p) : bits(0) { setPtr(p); } - explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.ptr); } + explicit TenuredHeap(const TenuredHeap &p) : bits(0) { setPtr(p.getPtr()); } bool operator==(const TenuredHeap &other) { return bits == other.bits; } bool operator!=(const TenuredHeap &other) { return bits != other.bits; } diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 62dd40950335..3e4cf23effcd 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -747,6 +747,9 @@ struct JsGcTracer : public TraceCallbacks virtual void Trace(JS::Heap *p, const char *name, void *closure) const MOZ_OVERRIDE { JS_CallHeapObjectTracer(static_cast(closure), p, name); } + virtual void Trace(JS::TenuredHeap *p, const char *name, void *closure) const MOZ_OVERRIDE { + JS_CallTenuredObjectTracer(static_cast(closure), p, name); + } virtual void Trace(JS::Heap *p, const char *name, void *closure) const MOZ_OVERRIDE { JS_CallHeapStringTracer(static_cast(closure), p, name); } @@ -799,6 +802,11 @@ struct ClearJSHolder : TraceCallbacks *aPtr = nullptr; } + virtual void Trace(JS::TenuredHeap* aPtr, const char*, void*) const MOZ_OVERRIDE + { + *aPtr = nullptr; + } + virtual void Trace(JS::Heap* aPtr, const char*, void*) const MOZ_OVERRIDE { *aPtr = nullptr; diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index ca5fc91abf45..11cd67e20b3f 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -2255,6 +2255,7 @@ public: { MOZ_ASSERT(mValues.IsEmpty()); MOZ_ASSERT(mObjects.IsEmpty()); + MOZ_ASSERT(mTenuredObjects.IsEmpty()); } void Destroy() @@ -2262,6 +2263,7 @@ public: mReferenceToThis = nullptr; mValues.Clear(); mObjects.Clear(); + mTenuredObjects.Clear(); mozilla::DropJSObjects(this); NS_RELEASE_THIS(); } @@ -2272,6 +2274,7 @@ public: JSPurpleBuffer*& mReferenceToThis; SegmentedArray> mValues; SegmentedArray> mObjects; + SegmentedArray> mTenuredObjects; }; NS_IMPL_CYCLE_COLLECTION_CLASS(JSPurpleBuffer) @@ -2299,6 +2302,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(JSPurpleBuffer) NS_TRACE_SEGMENTED_ARRAY(mValues) NS_TRACE_SEGMENTED_ARRAY(mObjects) + NS_TRACE_SEGMENTED_ARRAY(mTenuredObjects) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(JSPurpleBuffer, AddRef) @@ -2384,6 +2388,14 @@ public: } } + virtual void Trace(JS::TenuredHeap* aObject, const char* aName, + void* aClosure) const + { + if (*aObject && xpc_GCThingIsGrayCCThing(*aObject)) { + mCollector->GetJSPurpleBuffer()->mTenuredObjects.AppendElement(*aObject); + } + } + virtual void Trace(JS::Heap* aString, const char* aName, void* aClosure) const { diff --git a/xpcom/glue/nsCycleCollectionParticipant.cpp b/xpcom/glue/nsCycleCollectionParticipant.cpp index a9e977fdadb8..e472667ffdd7 100644 --- a/xpcom/glue/nsCycleCollectionParticipant.cpp +++ b/xpcom/glue/nsCycleCollectionParticipant.cpp @@ -87,6 +87,12 @@ TraceCallbackFunc::Trace(JS::Heap* p, const char* name, void* closure mCallback(*p, name, closure); } +void +TraceCallbackFunc::Trace(JS::TenuredHeap* p, const char* name, void* closure) const +{ + mCallback(*p, name, closure); +} + void TraceCallbackFunc::Trace(JS::Heap* p, const char* name, void* closure) const { diff --git a/xpcom/glue/nsCycleCollectionParticipant.h b/xpcom/glue/nsCycleCollectionParticipant.h index 69bcd131a933..087fe7a717a7 100644 --- a/xpcom/glue/nsCycleCollectionParticipant.h +++ b/xpcom/glue/nsCycleCollectionParticipant.h @@ -7,7 +7,7 @@ #define nsCycleCollectionParticipant_h__ #include "nsCycleCollectionNoteChild.h" -#include "jspubtd.h" +#include "js/RootingAPI.h" #define NS_CYCLECOLLECTIONPARTICIPANT_IID \ { \ @@ -58,6 +58,7 @@ struct TraceCallbacks virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; + virtual void Trace(JS::TenuredHeap* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap* p, const char* name, void* closure) const = 0; @@ -76,6 +77,7 @@ struct TraceCallbackFunc : public TraceCallbacks virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; + virtual void Trace(JS::TenuredHeap* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap* p, const char* name, void* closure) const MOZ_OVERRIDE; From c8041c17a73866f7ea502ed379c4ccd074194ce9 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 3 Mar 2014 08:53:42 -0800 Subject: [PATCH 57/69] Bug 975419 - Trace the Incumbent Global from a CallbackObject (but check it too, just to be safe). r=bz,mccr8 --- dom/bindings/CallbackObject.cpp | 16 +++++++++++++--- dom/bindings/CallbackObject.h | 25 +++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index a5057f9860a2..4884fe93615a 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -35,7 +35,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(CallbackObject) NS_IMPL_CYCLE_COLLECTION_CLASS(CallbackObject) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CallbackObject) - tmp->DropCallback(); + tmp->DropJSObjects(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncumbentGlobal) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject) @@ -44,6 +44,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallback) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mIncumbentJSGlobal) NS_IMPL_CYCLE_COLLECTION_TRACE_END CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, @@ -122,8 +123,17 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, mAutoEntryScript.construct(globalObject, mIsMainThread, cx); mAutoEntryScript.ref().SetWebIDLCallerPrincipal(webIDLCallerPrincipal); - if (aCallback->IncumbentGlobalOrNull()) { - mAutoIncumbentScript.construct(aCallback->IncumbentGlobalOrNull()); + nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull(); + if (incumbent) { + // The callback object traces its incumbent JS global, so in general it + // should be alive here. However, it's possible that we could run afoul + // of the same IPC global weirdness described above, wherein the + // nsIGlobalObject has severed its reference to the JS global. Let's just + // be safe here, so that nobody has to waste a day debugging gaia-ui tests. + if (!incumbent->GetGlobalJSObject()) { + return; + } + mAutoIncumbentScript.construct(incumbent); } // Unmark the callable (by invoking Callback() and not the CallbackPreserveColor() diff --git a/dom/bindings/CallbackObject.h b/dom/bindings/CallbackObject.h index 9465094b453e..2663cc65613f 100644 --- a/dom/bindings/CallbackObject.h +++ b/dom/bindings/CallbackObject.h @@ -57,7 +57,7 @@ public: virtual ~CallbackObject() { - DropCallback(); + DropJSObjects(); } JS::Handle Callback() const @@ -121,28 +121,41 @@ private: inline void Init(JSObject* aCallback, nsIGlobalObject* aIncumbentGlobal) { MOZ_ASSERT(aCallback && !mCallback); - // Set mCallback before we hold, on the off chance that a GC could somehow - // happen in there... (which would be pretty odd, granted). + // Set script objects before we hold, on the off chance that a GC could + // somehow happen in there... (which would be pretty odd, granted). mCallback = aCallback; + if (aIncumbentGlobal) { + mIncumbentGlobal = aIncumbentGlobal; + mIncumbentJSGlobal = aIncumbentGlobal->GetGlobalJSObject(); + } mozilla::HoldJSObjects(this); - - mIncumbentGlobal = aIncumbentGlobal; } CallbackObject(const CallbackObject&) MOZ_DELETE; CallbackObject& operator =(const CallbackObject&) MOZ_DELETE; protected: - void DropCallback() + void DropJSObjects() { + MOZ_ASSERT_IF(mIncumbentJSGlobal, mCallback); if (mCallback) { mCallback = nullptr; + mIncumbentJSGlobal = nullptr; mozilla::DropJSObjects(this); } } JS::Heap mCallback; + // Ideally, we'd just hold a reference to the nsIGlobalObject, since that's + // what we need to pass to AutoIncumbentScript. Unfortunately, that doesn't + // hold the actual JS global alive. So we maintain an additional pointer to + // the JS global itself so that we can trace it. + // + // At some point we should consider trying to make native globals hold their + // scripted global alive, at which point we can get rid of the duplication + // here. nsCOMPtr mIncumbentGlobal; + JS::TenuredHeap mIncumbentJSGlobal; class MOZ_STACK_CLASS CallSetup { From 12e3d71d6d735d31a0795773b2a77b0020cb5b44 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Mon, 3 Mar 2014 16:56:42 +0000 Subject: [PATCH 58/69] Backed out changeset 8ab0a696d2ec (bug 978456) since bug 939562 has now been backed out --- js/src/shell/js.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 9005601ced69..e7d7bd49cd44 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5775,6 +5775,22 @@ SetRuntimeOptions(JSRuntime *rt, const OptionParser &op) rt->setParallelIonCompilationEnabled(parallelCompilation); #endif +#if defined(JS_CODEGEN_X86) && defined(DEBUG) + if (op.getBoolOption("no-fpu")) + JSC::MacroAssembler::SetFloatingPointDisabled(); +#endif + +#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(DEBUG) + if (op.getBoolOption("no-sse3")) { + JSC::MacroAssembler::SetSSE3Disabled(); + PropagateFlagToNestedShells("--no-sse3"); + } + if (op.getBoolOption("no-sse4")) { + JSC::MacroAssembler::SetSSE4Disabled(); + PropagateFlagToNestedShells("--no-sse4"); + } +#endif + #endif // JS_ION #ifdef JS_ARM_SIMULATOR @@ -6032,25 +6048,8 @@ main(int argc, char **argv, char **envp) * allocations as possible. */ OOM_printAllocationCount = op.getBoolOption('O'); - -#if defined(JS_CODEGEN_X86) && defined(JS_ION) - if (op.getBoolOption("no-fpu")) - JSC::MacroAssembler::SetFloatingPointDisabled(); #endif -#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(JS_ION) - if (op.getBoolOption("no-sse3")) { - JSC::MacroAssembler::SetSSE3Disabled(); - PropagateFlagToNestedShells("--no-sse3"); - } - if (op.getBoolOption("no-sse4")) { - JSC::MacroAssembler::SetSSE4Disabled(); - PropagateFlagToNestedShells("--no-sse4"); - } -#endif - -#endif // DEBUG - // Start the engine. if (!JS_Init()) return 1; From fbb61eabea45833a661067ebeb68eb4c3ccc9806 Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Mon, 3 Mar 2014 17:51:42 +0100 Subject: [PATCH 59/69] Bug 968177 - Apply the shared backups code to bookmarks.html export. r=mano --- browser/components/nsBrowserGlue.js | 37 +- browser/components/places/content/places.js | 2 +- .../components/places/BookmarkHTMLUtils.jsm | 449 ++++++++---------- toolkit/components/places/PlacesBackups.jsm | 8 +- toolkit/components/places/PlacesUtils.jsm | 24 + toolkit/components/places/moz.build | 2 +- .../components/places/tests/head_common.js | 1 - toolkit/components/telemetry/Histograms.json | 9 + 8 files changed, 259 insertions(+), 273 deletions(-) diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 33c312bd3c5b..82b2949ec0ce 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -1046,13 +1046,13 @@ BrowserGlue.prototype = { // forced migration (due to a major schema change). // If the database is corrupt or has been newly created we should // import bookmarks. - var dbStatus = PlacesUtils.history.databaseStatus; - var importBookmarks = !aInitialMigrationPerformed && + let dbStatus = PlacesUtils.history.databaseStatus; + let importBookmarks = !aInitialMigrationPerformed && (dbStatus == PlacesUtils.history.DATABASE_STATUS_CREATE || dbStatus == PlacesUtils.history.DATABASE_STATUS_CORRUPT); // Check if user or an extension has required to import bookmarks.html - var importBookmarksHTML = false; + let importBookmarksHTML = false; try { importBookmarksHTML = Services.prefs.getBoolPref("browser.places.importBookmarksHTML"); @@ -1063,7 +1063,7 @@ BrowserGlue.prototype = { Task.spawn(function() { // Check if Safe Mode or the user has required to restore bookmarks from // default profile's bookmarks.html - var restoreDefaultBookmarks = false; + let restoreDefaultBookmarks = false; try { restoreDefaultBookmarks = Services.prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks"); @@ -1091,10 +1091,7 @@ BrowserGlue.prototype = { else { // We have created a new database but we don't have any backup available importBookmarks = true; - var dirService = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties); - var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile); - if (bookmarksHTMLFile.exists()) { + if (yield OS.File.exists(BookmarkHTMLUtils.defaultPath)) { // If bookmarks.html is available in current profile import it... importBookmarksHTML = true; } @@ -1120,36 +1117,30 @@ BrowserGlue.prototype = { // An import operation is about to run. // Don't try to recreate smart bookmarks if autoExportHTML is true or // smart bookmarks are disabled. - var autoExportHTML = false; + let autoExportHTML = false; try { autoExportHTML = Services.prefs.getBoolPref("browser.bookmarks.autoExportHTML"); } catch(ex) {} - var smartBookmarksVersion = 0; + let smartBookmarksVersion = 0; try { smartBookmarksVersion = Services.prefs.getIntPref("browser.places.smartBookmarksVersion"); } catch(ex) {} if (!autoExportHTML && smartBookmarksVersion != -1) Services.prefs.setIntPref("browser.places.smartBookmarksVersion", 0); - // Get bookmarks.html file location - var dirService = Cc["@mozilla.org/file/directory_service;1"]. - getService(Ci.nsIProperties); - - var bookmarksURI = null; + let bookmarksUrl = null; if (restoreDefaultBookmarks) { // User wants to restore bookmarks.html file from default profile folder - bookmarksURI = NetUtil.newURI("resource:///defaults/profile/bookmarks.html"); + bookmarksUrl = "resource:///defaults/profile/bookmarks.html"; } - else { - var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile); - if (bookmarksFile.exists()) - bookmarksURI = NetUtil.newURI(bookmarksFile); + else if (yield OS.File.exists(BookmarkHTMLUtils.defaultPath)) { + bookmarksUrl = OS.Path.toFileURI(BookmarkHTMLUtils.defaultPath); } - if (bookmarksURI) { + if (bookmarksUrl) { // Import from bookmarks.html file. try { - BookmarkHTMLUtils.importFromURL(bookmarksURI.spec, true).then(null, + BookmarkHTMLUtils.importFromURL(bookmarksUrl, true).then(null, function onFailure() { Cu.reportError("Bookmarks.html file could be corrupt."); } @@ -1240,7 +1231,7 @@ BrowserGlue.prototype = { // can safely add a profile-before-change blocker. AsyncShutdown.profileBeforeChange.addBlocker( "Places: bookmarks.html", - () => BookmarkHTMLUtils.exportToFile(Services.dirsvc.get("BMarks", Ci.nsIFile)) + () => BookmarkHTMLUtils.exportToFile(BookmarkHTMLUtils.defaultPath) .then(null, Cu.reportError) ); } diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js index 86fe0e44d4d4..704014fde334 100644 --- a/browser/components/places/content/places.js +++ b/browser/components/places/content/places.js @@ -383,7 +383,7 @@ var PlacesOrganizer = { let fpCallback = function fpCallback_done(aResult) { if (aResult != Ci.nsIFilePicker.returnCancel) { Components.utils.import("resource://gre/modules/BookmarkHTMLUtils.jsm"); - BookmarkHTMLUtils.exportToFile(fp.file) + BookmarkHTMLUtils.exportToFile(fp.file.path) .then(null, Components.utils.reportError); } }; diff --git a/toolkit/components/places/BookmarkHTMLUtils.jsm b/toolkit/components/places/BookmarkHTMLUtils.jsm index 4f0d4adf479e..784c8837328a 100644 --- a/toolkit/components/places/BookmarkHTMLUtils.jsm +++ b/toolkit/components/places/BookmarkHTMLUtils.jsm @@ -62,12 +62,19 @@ const Ci = Components.interfaces; const Cc = Components.classes; const Cu = Components.utils; +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/PlacesUtils.jsm"); +Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js"); + +XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", + "resource://gre/modules/PlacesBackups.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Deprecated", + "resource://gre/modules/Deprecated.jsm"); const Container_Normal = 0; const Container_Toolbar = 1; @@ -82,13 +89,8 @@ const MICROSEC_PER_SEC = 1000000; const EXPORT_INDENT = " "; // four spaces -#ifdef XP_WIN -const EXPORT_NEWLINE = "\r\n"; -#else -const EXPORT_NEWLINE = "\n"; -#endif - -let serialNumber = 0; // for favicons +// Counter used to build fake favicon urls. +let serialNumber = 0; function base64EncodeString(aString) { let stream = Cc["@mozilla.org/io/string-input-stream;1"] @@ -99,6 +101,18 @@ function base64EncodeString(aString) { return encoder.encodeToString(stream, aString.length); } +/** + * Provides HTML escaping for use in HTML attributes and body of the bookmarks + * file, compatible with the old bookmarks system. + */ +function escapeHtmlEntities(aText) { + return (aText || "").replace("&", "&", "g") + .replace("<", "<", "g") + .replace(">", ">", "g") + .replace("\"", """, "g") + .replace("'", "'", "g"); +} + this.BookmarkHTMLUtils = Object.freeze({ /** * Loads the current bookmarks hierarchy from a "bookmarks.html" file. @@ -138,17 +152,47 @@ this.BookmarkHTMLUtils = Object.freeze({ /** * Saves the current bookmarks hierarchy to a "bookmarks.html" file. * - * @param aLocalFile - * nsIFile for the "bookmarks.html" file to be created. + * @param aFilePath + * OS.File path string for the "bookmarks.html" file to be created. * * @return {Promise} - * @resolves When the file has been created. + * @resolves To the exported bookmarks count when the file has been created. * @rejects JavaScript exception. + * @deprecated passing an nsIFile is deprecated */ - exportToFile: function BHU_exportToFile(aLocalFile) { - let exporter = new BookmarkExporter(); - return exporter.exportToFile(aLocalFile); + exportToFile: function BHU_exportToFile(aFilePath) { + if (aFilePath instanceof Ci.nsIFile) { + Deprecated.warning("Passing an nsIFile to BookmarksHTMLUtils.exportToFile " + + "is deprecated. Please use an OS.File path string instead.", + "https://developer.mozilla.org/docs/JavaScript_OS.File"); + aFilePath = aFilePath.path; + } + return Task.spawn(function* () { + let [bookmarks, count] = yield PlacesBackups.getBookmarksTree(); + let startTime = Date.now(); + + // Report the time taken to convert the tree to HTML. + let exporter = new BookmarkExporter(bookmarks); + yield exporter.exportToFile(aFilePath); + + try { + Services.telemetry + .getHistogramById("PLACES_EXPORT_TOHTML_MS") + .add(Date.now() - startTime); + } catch (ex) { + Components.utils.reportError("Unable to report telemetry."); + } + + return count; + }); }, + + get defaultPath() { + try { + return Services.prefs.getCharPref("browser.bookmarks.file"); + } catch (ex) {} + return OS.Path.join(OS.Constants.Path.profileDir, "bookmarks.html") + } }); function Frame(aFrameId) { @@ -877,299 +921,212 @@ BookmarkImporter.prototype = { }; -function BookmarkExporter() { } +function BookmarkExporter(aBookmarksTree) { + // Create a map of the roots. + let rootsMap = new Map(); + for (let child of aBookmarksTree.children) { + if (child.root) + rootsMap.set(child.root, child); + } + + // For backwards compatibility reasons the bookmarks menu is the root, while + // the bookmarks toolbar and unfiled bookmarks will be child items. + this._root = rootsMap.get("bookmarksMenuFolder"); + + for (let key of [ "toolbarFolder", "unfiledBookmarksFolder" ]) { + let root = rootsMap.get(key); + if (root.children && root.children.length > 0) { + if (!this._root.children) + this._root.children = []; + this._root.children.push(root); + } + } +} BookmarkExporter.prototype = { - - /** - * Provides HTML escaping for use in HTML attributes and body of the bookmarks - * file, compatible with the old bookmarks system. - */ - escapeHtml: function escapeHtml(aText) { - return (aText || "").replace("&", "&", "g") - .replace("<", "<", "g") - .replace(">", ">", "g") - .replace("\"", """, "g") - .replace("'", "'", "g"); - }, - - /** - * Provides URL escaping for use in HTML attributes of the bookmarks file, - * compatible with the old bookmarks system. - */ - escapeUrl: function escapeUrl(aText) { - return (aText || "").replace("\"", "%22", "g"); - }, - - exportToFile: function exportToFile(aLocalFile) { - return Task.spawn(this._doExportToFile(aLocalFile)); - }, - - _doExportToFile: function doExportToFile(aLocalFile) { - // Create a file that can be accessed by the current user only. - let safeFileOut = Cc["@mozilla.org/network/safe-file-output-stream;1"] - .createInstance(Ci.nsIFileOutputStream); - safeFileOut.init(aLocalFile, - FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE - | FileUtils.MODE_TRUNCATE, - parseInt("0600", 8), 0); - try { - // We need a buffered output stream for performance. See bug 202477. - let bufferedOut = Cc["@mozilla.org/network/buffered-output-stream;1"] - .createInstance(Ci.nsIBufferedOutputStream); - bufferedOut.init(safeFileOut, 4096); + exportToFile: function exportToFile(aFilePath) { + return Task.spawn(function* () { + // Create a file that can be accessed by the current user only. + let out = FileUtils.openAtomicFileOutputStream(new FileUtils.File(aFilePath)); try { - // Write bookmarks in UTF-8. - this._converterOut = Cc["@mozilla.org/intl/converter-output-stream;1"] - .createInstance(Ci.nsIConverterOutputStream); - this._converterOut.init(bufferedOut, "utf-8", 0, 0); + // We need a buffered output stream for performance. See bug 202477. + let bufferedOut = Cc["@mozilla.org/network/buffered-output-stream;1"] + .createInstance(Ci.nsIBufferedOutputStream); + bufferedOut.init(out, 4096); try { - yield this._doExport(); - - // Flush the buffer and retain the target file on success only. - bufferedOut.QueryInterface(Ci.nsISafeOutputStream).finish(); + // Write bookmarks in UTF-8. + this._converterOut = Cc["@mozilla.org/intl/converter-output-stream;1"] + .createInstance(Ci.nsIConverterOutputStream); + this._converterOut.init(bufferedOut, "utf-8", 0, 0); + try { + this._writeHeader(); + yield this._writeContainer(this._root); + // Retain the target file on success only. + bufferedOut.QueryInterface(Ci.nsISafeOutputStream).finish(); + } finally { + this._converterOut.close(); + this._converterOut = null; + } } finally { - this._converterOut.close(); - this._converterOut = null; + bufferedOut.close(); } } finally { - bufferedOut.close(); + out.close(); } - } finally { - safeFileOut.close(); - } + }.bind(this)); }, _converterOut: null, - _write: function write(aText) { + _write: function (aText) { this._converterOut.writeString(aText || ""); }, - _writeLine: function writeLine(aText) { - this._write(aText + EXPORT_NEWLINE); + _writeAttribute: function (aName, aValue) { + this._write(' ' + aName + '="' + aValue + '"'); }, - _doExport: function doExport() { + _writeLine: function (aText) { + this._write(aText + "\n"); + }, + + _writeHeader: function () { this._writeLine(""); this._writeLine(""); - this._writeLine(""); + this._writeLine(''); this._writeLine("Bookmarks"); + }, - // Write the Bookmarks Menu as the outer container. - let root = PlacesUtils.getFolderContents( - PlacesUtils.bookmarksMenuFolderId).root; - try { - this._writeLine("

" + this.escapeHtml(root.title) + "

"); + _writeContainer: function (aItem, aIndent = "") { + if (aItem == this._root) { + this._writeLine("

" + escapeHtmlEntities(this._root.title) + "

"); this._writeLine(""); - this._writeLine("

"); - yield this._writeContainerContents(root, ""); - } finally { - root.containerOpen = false; + } + else { + this._write(aIndent + "

" + escapeHtmlEntities(aItem.title) + ""); } - // Write the Bookmarks Toolbar as a child item for backwards compatibility. - root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root; - try { - if (root.childCount > 0) { - yield this._writeContainer(root, EXPORT_INDENT); - } - } finally { - root.containerOpen = false; - } + this._writeDescription(aItem, aIndent); - // Write the Unfiled Bookmarks as a child item for backwards compatibility. - root = PlacesUtils.getFolderContents( - PlacesUtils.unfiledBookmarksFolderId).root; - try { - if (root.childCount > 0) { - yield this._writeContainer(root, EXPORT_INDENT); - } - } finally { - root.containerOpen = false; - } - - this._writeLine("

"); - }, - - _writeContainer: function writeContainer(aItem, aIndent) { - this._write(aIndent + "

" + this.escapeHtml(aItem.title) + ""); - yield this._writeDescription(aItem); this._writeLine(aIndent + "

"); - yield this._writeContainerContents(aItem, aIndent); - this._writeLine(aIndent + "

"); + if (aItem.children) + yield this._writeContainerContents(aItem, aIndent); + if (aItem == this._root) + this._writeLine(aIndent + ""); + else + this._writeLine(aIndent + "

"); }, - _writeContainerContents: function writeContainerContents(aItem, aIndent) { + _writeContainerContents: function (aItem, aIndent) { let localIndent = aIndent + EXPORT_INDENT; - for (let i = 0; i < aItem.childCount; ++i) { - let child = aItem.getChild(i); - if (child.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER) { - // Since the livemarks service is asynchronous, use the annotations - // service to get the information for now. - if (PlacesUtils.annotations - .itemHasAnnotation(child.itemId, - PlacesUtils.LMANNO_FEEDURI)) { - yield this._writeLivemark(child, localIndent); - } else { - // This is a normal folder, open it. - PlacesUtils.asContainer(child).containerOpen = true; - try { - yield this._writeContainer(child, localIndent); - } finally { - child.containerOpen = false; - } - } - } else if (child.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) { - yield this._writeSeparator(child, localIndent); - } else { + for (let child of aItem.children) { + if (child.annos && child.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI)) + this._writeLivemark(child, localIndent); + else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) + yield this._writeContainer(child, localIndent); + else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) + this._writeSeparator(child, localIndent); + else yield this._writeItem(child, localIndent); - } } }, - _writeSeparator: function writeSeparator(aItem, aIndent) { + _writeSeparator: function (aItem, aIndent) { this._write(aIndent + ""); }, - _writeLivemark: function writeLivemark(aItem, aIndent) { + _writeLivemark: function (aItem, aIndent) { this._write(aIndent + "

" + this.escapeHtml(aItem.title) + ""); - yield this._writeDescription(aItem); + let feedSpec = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_FEEDURI).value; + this._writeAttribute("FEEDURL", encodeURI(feedSpec)); + let siteSpecAnno = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_SITEURI); + if (siteSpecAnno) + this._writeAttribute("HREF", encodeURI(siteSpecAnno.value)); + this._writeLine(">" + escapeHtmlEntities(aItem.title) + ""); + this._writeDescription(aItem, aIndent); }, - _writeItem: function writeItem(aItem, aIndent) { - let itemUri = null; + _writeItem: function (aItem, aIndent) { + let uri = null; try { - itemUri = NetUtil.newURI(aItem.uri); + uri = NetUtil.newURI(aItem.uri); } catch (ex) { // If the item URI is invalid, skip the item instead of failing later. return; } - this._write(aIndent + "
anno.name == PlacesUtils.POST_DATA_ANNO); + if (postDataAnno) + this._writeAttribute("POST_DATA", escapeHtmlEntities(postDataAnno.value)); - if (PlacesUtils.annotations.itemHasAnnotation(aItem.itemId, - LOAD_IN_SIDEBAR_ANNO)) { - this._write(" WEB_PANEL=\"true\""); - } + if (aItem.annos && aItem.annos.some(anno => anno.name == LOAD_IN_SIDEBAR_ANNO)) + this._writeAttribute("WEB_PANEL", "true"); + if (aItem.charset) + this._writeAttribute("LAST_CHARSET", escapeHtmlEntities(aItem.charset)); + if (aItem.tags) + this._writeAttribute("TAGS", aItem.tags); + this._writeLine(">" + escapeHtmlEntities(aItem.title) + ""); + this._writeDescription(aItem, aIndent); + }, + _writeDateAttributes: function (aItem) { + if (aItem.dateAdded) + this._writeAttribute("ADD_DATE", + Math.floor(aItem.dateAdded / MICROSEC_PER_SEC)); + if (aItem.lastModified) + this._writeAttribute("LAST_MODIFIED", + Math.floor(aItem.lastModified / MICROSEC_PER_SEC)); + }, + + _writeFaviconAttribute: function (aItem) { + if (!aItem.iconuri) + return; + let favicon; try { - let lastCharset = yield PlacesUtils.getCharsetForURI(itemUri); - if (lastCharset) { - this._write(" LAST_CHARSET=\"" + this.escapeHtml(lastCharset) + "\""); - } - } catch(ex) { } - - this._writeLine(">" + this.escapeHtml(aItem.title) + ""); - yield this._writeDescription(aItem); - }, - - _writeDateAttributes: function writeDateAttributes(aItem) { - if (aItem.dateAdded) { - this._write(" ADD_DATE=\"" + - Math.floor(aItem.dateAdded / MICROSEC_PER_SEC) + "\""); - } - if (aItem.lastModified) { - this._write(" LAST_MODIFIED=\"" + - Math.floor(aItem.lastModified / MICROSEC_PER_SEC) + "\""); - } - }, - - _writeFaviconAttribute: function writeFaviconAttribute(aItemUri) { - let [faviconURI, dataLen, data] = yield this._promiseFaviconData(aItemUri); - - if (!faviconURI) { - // Skip in case of errors. + favicon = yield PlacesUtils.promiseFaviconData(aItem.uri); + } catch (ex) { + Components.utils.reportError("Unexpected Error trying to fetch icon data"); return; } - this._write(" ICON_URI=\"" + this.escapeUrl(faviconURI.spec) + "\""); + this._writeAttribute("ICON_URI", encodeURI(favicon.uri.spec)); - if (!faviconURI.schemeIs("chrome") && dataLen > 0) { + if (!favicon.uri.schemeIs("chrome") && favicon.dataLen > 0) { let faviconContents = "data:image/png;base64," + - base64EncodeString(String.fromCharCode.apply(String, data)); - this._write(" ICON=\"" + faviconContents + "\""); - } - }, - - _promiseFaviconData: function(aPageURI) { - var deferred = Promise.defer(); - PlacesUtils.favicons.getFaviconDataForPage(aPageURI, - function (aURI, aDataLen, aData, aMimeType) { - deferred.resolve([aURI, aDataLen, aData, aMimeType]); - }); - return deferred.promise; - }, - - _writeDescription: function writeDescription(aItem) { - if (PlacesUtils.annotations.itemHasAnnotation(aItem.itemId, - DESCRIPTION_ANNO)) { - let description = PlacesUtils.annotations - .getItemAnnotation(aItem.itemId, - DESCRIPTION_ANNO); - // The description is not indented. - this._writeLine("
" + this.escapeHtml(description)); + base64EncodeString(String.fromCharCode.apply(String, favicon.data)); + this._writeAttribute("ICON", faviconContents); } }, + _writeDescription: function (aItem, aIndent) { + let descriptionAnno = aItem.annos && + aItem.annos.find(anno => anno.name == DESCRIPTION_ANNO); + if (descriptionAnno) + this._writeLine(aIndent + "
" + escapeHtmlEntities(descriptionAnno.value)); + } }; diff --git a/toolkit/components/places/PlacesBackups.jsm b/toolkit/components/places/PlacesBackups.jsm index dae3f2f8fac4..afaacfa6ae1c 100644 --- a/toolkit/components/places/PlacesBackups.jsm +++ b/toolkit/components/places/PlacesBackups.jsm @@ -449,6 +449,7 @@ this.PlacesBackups = { * The following properties exist only for a subset of bookmarks: * * annos: array of annotations * * uri: url + * * iconuri: favicon's url * * keyword: associated keyword * * charset: last known charset * * tags: csv string of tags @@ -464,7 +465,8 @@ this.PlacesBackups = { try { rows = yield conn.execute( "SELECT b.id, h.url, IFNULL(b.title, '') AS title, b.parent, " + - "b.position AS [index], b.type, b.dateAdded, b.lastModified, b.guid, " + + "b.position AS [index], b.type, b.dateAdded, b.lastModified, " + + "b.guid, f.url AS iconuri, " + "( SELECT GROUP_CONCAT(t.title, ',') " + "FROM moz_bookmarks b2 " + "JOIN moz_bookmarks t ON t.id = +b2.parent AND t.parent = :tags_folder " + @@ -478,6 +480,7 @@ this.PlacesBackups = { "FROM moz_bookmarks b " + "LEFT JOIN moz_bookmarks p ON p.id = b.parent " + "LEFT JOIN moz_places h ON h.id = b.fk " + + "LEFT JOIN moz_favicons f ON f.id = h.favicon_id " + "WHERE b.id <> :tags_folder AND b.parent <> :tags_folder AND p.parent <> :tags_folder " + "ORDER BY b.parent, b.position", { tags_folder: PlacesUtils.tagsFolderId, @@ -601,6 +604,9 @@ function sqliteRowToBookmarkObject(aRow) { let tags = aRow.getResultByName("tags"); if (tags) bookmark.tags = tags; + let iconuri = aRow.getResultByName("iconuri"); + if (iconuri) + bookmark.iconuri = iconuri; break; case Ci.nsINavBookmarksService.TYPE_FOLDER: bookmark.type = PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER; diff --git a/toolkit/components/places/PlacesUtils.jsm b/toolkit/components/places/PlacesUtils.jsm index fafc98bf2a47..cd0ea0cd5207 100644 --- a/toolkit/components/places/PlacesUtils.jsm +++ b/toolkit/components/places/PlacesUtils.jsm @@ -1776,6 +1776,30 @@ this.PlacesUtils = { }); return deferred.promise; + }, + + /** + * Gets favicon data for a given page url. + * + * @param aPageUrl url of the page to look favicon for. + * @resolves to an object representing a favicon entry, having the following + * properties: { uri, dataLen, data, mimeType } + * @rejects JavaScript exception if the given url has no associated favicon. + */ + promiseFaviconData: function (aPageUrl) { + let deferred = Promise.defer(); + PlacesUtils.favicons.getFaviconDataForPage(NetUtil.newURI(aPageUrl), + function (aURI, aDataLen, aData, aMimeType) { + if (aURI) { + deferred.resolve({ uri: aURI, + dataLen: aDataLen, + data: aData, + mimeType: aMimeType }); + } else { + deferred.reject(); + } + }); + return deferred.promise; } }; diff --git a/toolkit/components/places/moz.build b/toolkit/components/places/moz.build index 088116bec747..a6170dec23a8 100644 --- a/toolkit/components/places/moz.build +++ b/toolkit/components/places/moz.build @@ -60,6 +60,7 @@ if CONFIG['MOZ_PLACES']: ] EXTRA_JS_MODULES = [ + 'BookmarkHTMLUtils.jsm', 'BookmarkJSONUtils.jsm', 'ClusterLib.js', 'ColorAnalyzer_worker.js', @@ -69,7 +70,6 @@ if CONFIG['MOZ_PLACES']: ] EXTRA_PP_JS_MODULES += [ - 'BookmarkHTMLUtils.jsm', 'PlacesUtils.jsm', ] diff --git a/toolkit/components/places/tests/head_common.js b/toolkit/components/places/tests/head_common.js index e4a95f64c030..6083488d60f1 100644 --- a/toolkit/components/places/tests/head_common.js +++ b/toolkit/components/places/tests/head_common.js @@ -7,7 +7,6 @@ const CURRENT_SCHEMA_VERSION = 23; const NS_APP_USER_PROFILE_50_DIR = "ProfD"; const NS_APP_PROFILE_DIR_STARTUP = "ProfDS"; -const NS_APP_BOOKMARKS_50_FILE = "BMarks"; // Shortcuts to transitions type. const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 4d97b112d85f..1a88fb4a2e55 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2836,6 +2836,15 @@ "extended_statistics_ok": true, "description": "PLACES: Time to convert and write the backup" }, + "PLACES_EXPORT_TOHTML_MS": { + "expires_in_version": "never", + "kind": "exponential", + "low": 50, + "high": 2000, + "n_buckets": 10, + "extended_statistics_ok": true, + "description": "PLACES: Time to convert and write bookmarks.html" + }, "FENNEC_FAVICONS_COUNT": { "expires_in_version": "never", "kind": "exponential", From 512c65a96bf2776cad1b20b28883b0e4ca38fbde Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Mon, 3 Mar 2014 17:51:44 +0100 Subject: [PATCH 60/69] Bug 969408 - Remove old Deprecated methods from PlacesUtils. r=mano --- toolkit/components/places/PlacesUtils.jsm | 261 ------------------ .../tests/unit/test_utils_backups_create.js | 2 +- 2 files changed, 1 insertion(+), 262 deletions(-) diff --git a/toolkit/components/places/PlacesUtils.jsm b/toolkit/components/places/PlacesUtils.jsm index cd0ea0cd5207..dde9b524d5ab 100644 --- a/toolkit/components/places/PlacesUtils.jsm +++ b/toolkit/components/places/PlacesUtils.jsm @@ -76,12 +76,6 @@ function QI_node(aNode, aIID) { } return result; } -function asVisit(aNode) { - Deprecated.warning( - "asVisit is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=561450"); - return aNode; -}; function asContainer(aNode) QI_node(aNode, Ci.nsINavHistoryContainerResultNode); function asQuery(aNode) QI_node(aNode, Ci.nsINavHistoryQueryResultNode); @@ -119,7 +113,6 @@ this.PlacesUtils = { TOPIC_BOOKMARKS_RESTORE_SUCCESS: "bookmarks-restore-success", TOPIC_BOOKMARKS_RESTORE_FAILED: "bookmarks-restore-failed", - asVisit: function(aNode) asVisit(aNode), asContainer: function(aNode) asContainer(aNode), asQuery: function(aNode) asQuery(aNode), @@ -188,34 +181,12 @@ this.PlacesUtils = { return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR; }, - /** - * Determines whether or not a ResultNode is a visit item. - * @param aNode - * A result node - * @returns true if the node is a visit item, false otherwise - */ - nodeIsVisit: function PU_nodeIsVisit(aNode) { - Deprecated.warning( - "nodeIsVisit is deprecated ans will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=561450"); - return this.nodeIsURI(aNode) && aNode.parent && - this.nodeIsQuery(aNode.parent) && - asQuery(aNode.parent).queryOptions.resultType == - Ci.nsINavHistoryQueryOptions.RESULTS_AS_VISIT; - }, - /** * Determines whether or not a ResultNode is a URL item. * @param aNode * A result node * @returns true if the node is a URL item, false otherwise */ - get uriTypes() { - Deprecated.warning( - "uriTypes is deprecated ans will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=561450"); - return [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI]; - }, nodeIsURI: function PU_nodeIsURI(aNode) { return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI; }, @@ -1128,155 +1099,6 @@ this.PlacesUtils = { return urls; }, - /** - * Takes a JSON-serialized node and inserts it into the db. - * - * @param aData - * The unwrapped data blob of dropped or pasted data. - * @param aContainer - * The container the data was dropped or pasted into - * @param aIndex - * The index within the container the item was dropped or pasted at - * @returns an array containing of maps of old folder ids to new folder ids, - * and an array of saved search ids that need to be fixed up. - * eg: [[[oldFolder1, newFolder1]], [search1]] - */ - importJSONNode: function PU_importJSONNode(aData, aContainer, aIndex, aGrandParentId) { - Deprecated.warning( - "importJSONNode is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=855842"); - - var folderIdMap = []; - var searchIds = []; - var id = -1; - switch (aData.type) { - case this.TYPE_X_MOZ_PLACE_CONTAINER: - if (aContainer == PlacesUtils.tagsFolderId) { - // node is a tag - if (aData.children) { - aData.children.forEach(function(aChild) { - try { - this.tagging.tagURI(this._uri(aChild.uri), [aData.title]); - } catch (ex) { - // invalid tag child, skip it - } - }, this); - return [folderIdMap, searchIds]; - } - } - else if (aData.livemark && aData.annos) { - // node is a livemark - var feedURI = null; - var siteURI = null; - aData.annos = aData.annos.filter(function(aAnno) { - switch (aAnno.name) { - case this.LMANNO_FEEDURI: - feedURI = this._uri(aAnno.value); - return false; - case this.LMANNO_SITEURI: - siteURI = this._uri(aAnno.value); - return false; - default: - return true; - } - }, this); - - if (feedURI) { - this.livemarks.addLivemark( - { title: aData.title - , feedURI: feedURI - , parentId: aContainer - , index: aIndex - , lastModified: aData.lastModified - , siteURI: siteURI - }, - (function(aStatus, aLivemark) { - if (Components.isSuccessCode(aStatus)) { - let id = aLivemark.id; - if (aData.dateAdded) - this.bookmarks.setItemDateAdded(id, aData.dateAdded); - if (aData.annos && aData.annos.length) - this.setAnnotationsForItem(id, aData.annos); - } - }).bind(this) - ); - } - } - else { - id = this.bookmarks.createFolder(aContainer, aData.title, aIndex); - folderIdMap[aData.id] = id; - // process children - if (aData.children) { - aData.children.forEach(function(aChild, aIndex) { - var [folders, searches] = this.importJSONNode(aChild, id, aIndex, aContainer); - for (var i = 0; i < folders.length; i++) { - if (folders[i]) - folderIdMap[i] = folders[i]; - } - searchIds = searchIds.concat(searches); - }, this); - } - } - break; - case this.TYPE_X_MOZ_PLACE: - id = this.bookmarks.insertBookmark(aContainer, this._uri(aData.uri), - aIndex, aData.title); - if (aData.keyword) - this.bookmarks.setKeywordForBookmark(id, aData.keyword); - if (aData.tags) { - var tags = aData.tags.split(", "); - if (tags.length) - this.tagging.tagURI(this._uri(aData.uri), tags); - } - if (aData.charset) { - this.setCharsetForURI(this._uri(aData.uri), aData.charset); - } - if (aData.uri.substr(0, 6) == "place:") - searchIds.push(id); - if (aData.icon) { - try { - // Create a fake faviconURI to use (FIXME: bug 523932) - let faviconURI = this._uri("fake-favicon-uri:" + aData.uri); - this.favicons.replaceFaviconDataFromDataURL(faviconURI, aData.icon, 0); - this.favicons.setAndFetchFaviconForPage(this._uri(aData.uri), faviconURI, false, - this.favicons.FAVICON_LOAD_NON_PRIVATE); - } catch (ex) { - Components.utils.reportError("Failed to import favicon data:" + ex); - } - } - if (aData.iconUri) { - try { - this.favicons.setAndFetchFaviconForPage(this._uri(aData.uri), - this._uri(aData.iconUri), - false, - this.favicons.FAVICON_LOAD_NON_PRIVATE); - } catch (ex) { - Components.utils.reportError("Failed to import favicon URI:" + ex); - } - } - break; - case this.TYPE_X_MOZ_PLACE_SEPARATOR: - id = this.bookmarks.insertSeparator(aContainer, aIndex); - break; - default: - // Unknown node type - } - - // set generic properties, valid for all nodes - if (id != -1 && - aContainer != PlacesUtils.tagsFolderId && - aGrandParentId != PlacesUtils.tagsFolderId) { - if (aData.dateAdded) - this.bookmarks.setItemDateAdded(id, aData.dateAdded); - if (aData.lastModified) - this.bookmarks.setItemLastModified(id, aData.lastModified); - if (aData.annos && aData.annos.length) - this.setAnnotationsForItem(id, aData.annos); - } - - return [folderIdMap, searchIds]; - }, - /** * Serializes the given node (and all its descendents) as JSON * and writes the serialization to the given output stream. @@ -1491,89 +1313,6 @@ this.PlacesUtils = { } }, - /** - * Serializes the given node (and all its descendents) as JSON - * and writes the serialization to the given output stream. - * - * @param aNode - * An nsINavHistoryResultNode - * @param aStream - * An nsIOutputStream. NOTE: it only uses the write(str, len) - * method of nsIOutputStream. The caller is responsible for - * closing the stream. - * @param aIsUICommand - * Boolean - If true, modifies serialization so that each node self-contained. - * For Example, tags are serialized inline with each bookmark. - * @param aResolveShortcuts - * Converts folder shortcuts into actual folders. - * @param aExcludeItems - * An array of item ids that should not be written to the backup. - */ - serializeNodeAsJSONToOutputStream: - function PU_serializeNodeAsJSONToOutputStream(aNode, aStream, aIsUICommand, - aResolveShortcuts, - aExcludeItems) { - Deprecated.warning( - "serializeNodeAsJSONToOutputStream is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=854761"); - - this._serializeNodeAsJSONToOutputStream(aNode, aStream, aIsUICommand, - aResolveShortcuts, aExcludeItems); - }, - - /** - * Restores bookmarks and tags from a JSON file. - * WARNING: This method *removes* any bookmarks in the collection before - * restoring from the file. - * - * @param aFile - * nsIFile of bookmarks in JSON format to be restored. - */ - restoreBookmarksFromJSONFile: - function PU_restoreBookmarksFromJSONFile(aFile) { - Deprecated.warning( - "restoreBookmarksFromJSONFile is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=854388"); - - BookmarkJSONUtils.importFromFile(aFile, true); - }, - - /** - * Serializes bookmarks using JSON, and writes to the supplied file. - * - * @see backups.saveBookmarksToJSONFile(aFile) - */ - backupBookmarksToFile: function PU_backupBookmarksToFile(aFile) { - Deprecated.warning( - "backupBookmarksToFile is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=852041"); - return PlacesBackups.saveBookmarksToJSONFile(aFile); - }, - - /** - * Creates a dated backup in /bookmarkbackups. - * Stores the bookmarks using JSON. - * - * @see backups.create(aMaxBackups, aForceBackup) - */ - archiveBookmarksFile: - function PU_archiveBookmarksFile(aMaxBackups, aForceBackup) { - Deprecated.warning( - "archiveBookmarksFile is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=857429"); - return PlacesBackups.create(aMaxBackups, aForceBackup); - }, - - /** - * Helper to create and manage backups. - */ - get backups() { - Deprecated.warning( - "PlacesUtils.backups is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=857429"); - return PlacesBackups; - }, - /** * Given a uri returns list of itemIds associated to it. * diff --git a/toolkit/components/places/tests/unit/test_utils_backups_create.js b/toolkit/components/places/tests/unit/test_utils_backups_create.js index 03cc7180fac2..820fcfa24fef 100644 --- a/toolkit/components/places/tests/unit/test_utils_backups_create.js +++ b/toolkit/components/places/tests/unit/test_utils_backups_create.js @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Check for correct functionality of PlacesUtils.archiveBookmarksFile + * Check for correct functionality of bookmarks backups */ const PREFIX = "bookmarks-"; From cbfe2d6c71daae6ac97b4681c432e950acf16ac6 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Mon, 3 Mar 2014 16:54:26 +0000 Subject: [PATCH 61/69] Backed out changeset 508848ad378a (bug 939562) for causing bug 978450 --- dom/base/nsJSEnvironment.cpp | 53 +++ dom/workers/RuntimeService.cpp | 82 ++--- dom/workers/RuntimeService.h | 13 +- dom/workers/WorkerPrivate.cpp | 63 ++-- dom/workers/WorkerPrivate.h | 13 +- dom/workers/Workers.h | 1 - js/jsd/jsd_xpc.cpp | 16 +- js/src/builtin/TestingFunctions.cpp | 10 +- js/src/jit/AsmJS.cpp | 2 +- js/src/jit/BaselineJIT.h | 2 +- js/src/jit/Ion.h | 4 +- js/src/jsapi-tests/testFuncCallback.cpp | 2 +- js/src/jsapi-tests/testProfileStrings.cpp | 6 +- js/src/jsapi.cpp | 68 ++-- js/src/jsapi.h | 135 +++---- js/src/jscompartment.h | 2 +- js/src/jsinfer.cpp | 2 +- js/src/shell/js.cpp | 415 ++++++++++++---------- js/src/vm/Runtime.h | 8 - js/xpconnect/src/XPCComponents.cpp | 49 +-- js/xpconnect/src/XPCJSRuntime.cpp | 46 --- js/xpconnect/src/XPCShellImpl.cpp | 7 +- js/xpconnect/src/nsXPConnect.cpp | 45 ++- modules/libpref/src/init/all.js | 9 +- 24 files changed, 560 insertions(+), 493 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index e600f9130dff..330679921ce5 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -721,8 +721,19 @@ static const char js_werror_option_str[] = JS_OPTIONS_DOT_STR "werror"; static const char js_zeal_option_str[] = JS_OPTIONS_DOT_STR "gczeal"; static const char js_zeal_frequency_str[] = JS_OPTIONS_DOT_STR "gczeal.frequency"; #endif +static const char js_typeinfer_content_str[] = JS_OPTIONS_DOT_STR "typeinference.content"; +static const char js_typeinfer_chrome_str[] = JS_OPTIONS_DOT_STR "typeinference.chrome"; static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log"; static const char js_memnotify_option_str[] = JS_OPTIONS_DOT_STR "mem.notify"; +static const char js_asmjs_content_str[] = JS_OPTIONS_DOT_STR "asmjs"; +static const char js_baselinejit_content_str[] = JS_OPTIONS_DOT_STR "baselinejit.content"; +static const char js_baselinejit_chrome_str[] = JS_OPTIONS_DOT_STR "baselinejit.chrome"; +static const char js_baselinejit_eager_str[] = JS_OPTIONS_DOT_STR "baselinejit.unsafe_eager_compilation"; +static const char js_ion_content_str[] = JS_OPTIONS_DOT_STR "ion.content"; +static const char js_ion_chrome_str[] = JS_OPTIONS_DOT_STR "ion.chrome"; +static const char js_ion_eager_str[] = JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation"; +static const char js_parallel_parsing_str[] = JS_OPTIONS_DOT_STR "parallel_parsing"; +static const char js_ion_parallel_compilation_str[] = JS_OPTIONS_DOT_STR "ion.parallel_compilation"; void nsJSContext::JSOptionChangedCallback(const char *pref, void *data) @@ -745,6 +756,39 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) nsCOMPtr contentWindow(do_QueryInterface(global)); nsCOMPtr chromeWindow(do_QueryInterface(global)); + bool useTypeInference = Preferences::GetBool((chromeWindow || !contentWindow) ? + js_typeinfer_chrome_str : + js_typeinfer_content_str); + bool useBaselineJIT = Preferences::GetBool((chromeWindow || !contentWindow) ? + js_baselinejit_chrome_str : + js_baselinejit_content_str); + bool useBaselineJITEager = Preferences::GetBool(js_baselinejit_eager_str); + bool useIon = Preferences::GetBool((chromeWindow || !contentWindow) ? + js_ion_chrome_str : + js_ion_content_str); + bool useIonEager = Preferences::GetBool(js_ion_eager_str); + bool useAsmJS = Preferences::GetBool(js_asmjs_content_str); + bool parallelParsing = Preferences::GetBool(js_parallel_parsing_str); + bool parallelIonCompilation = Preferences::GetBool(js_ion_parallel_compilation_str); + nsCOMPtr xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID); + if (xr) { + bool safeMode = false; + xr->GetInSafeMode(&safeMode); + if (safeMode) { + useTypeInference = false; + useBaselineJIT = false; + useBaselineJITEager = false; + useIon = false; + useIonEager = false; + useAsmJS = false; + } + } + + JS::ContextOptionsRef(cx).setTypeInference(useTypeInference) + .setBaseline(useBaselineJIT) + .setIon(useIon) + .setAsmJS(useAsmJS); + #ifdef DEBUG // In debug builds, warnings are enabled in chrome context if // javascript.options.strict.debug is true @@ -756,6 +800,15 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data) JS::ContextOptionsRef(cx).setWerror(Preferences::GetBool(js_werror_option_str)); + ::JS_SetParallelParsingEnabled(context->mContext, parallelParsing); + ::JS_SetParallelIonCompilationEnabled(context->mContext, parallelIonCompilation); + + ::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER, + (useBaselineJITEager ? 0 : -1)); + + ::JS_SetGlobalJitCompilerOption(context->mContext, JSJITCOMPILER_ION_USECOUNT_TRIGGER, + (useIonEager ? 0 : -1)); + #ifdef JS_GC_ZEAL int32_t zeal = Preferences::GetInt(js_zeal_option_str, -1); int32_t frequency = Preferences::GetInt(js_zeal_frequency_str, JS_DEFAULT_ZEAL_FREQ); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 697f95ab4ebf..b9e8d079cf7a 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -148,7 +148,7 @@ namespace { const uint32_t kNoIndex = uint32_t(-1); -const JS::ContextOptions kRequiredContextOptions = +const JS::ContextOptions kRequiredJSContextOptions = JS::ContextOptions().setDontReportUncaught(true) .setNoScriptRval(true); @@ -300,7 +300,7 @@ GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName, } void -LoadRuntimeAndContextOptions(const char* aPrefName, void* /* aClosure */) +LoadJSContextOptions(const char* aPrefName, void* /* aClosure */) { AssertIsOnMainThread(); @@ -330,47 +330,51 @@ LoadRuntimeAndContextOptions(const char* aPrefName, void* /* aClosure */) } #endif - // Runtime options. - JS::RuntimeOptions runtimeOptions; - if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) { - runtimeOptions.setAsmJS(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference"))) { - runtimeOptions.setTypeInference(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit"))) { - runtimeOptions.setBaseline(true); - } - if (GetWorkerPref(NS_LITERAL_CSTRING("ion"))) { - runtimeOptions.setIon(true); - } - // Common options. - JS::ContextOptions commonContextOptions = kRequiredContextOptions; + JS::ContextOptions commonOptions = kRequiredJSContextOptions; if (GetWorkerPref(NS_LITERAL_CSTRING("strict"))) { - commonContextOptions.setExtraWarnings(true); + commonOptions.setExtraWarnings(true); } if (GetWorkerPref(NS_LITERAL_CSTRING("werror"))) { - commonContextOptions.setWerror(true); + commonOptions.setWerror(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) { + commonOptions.setAsmJS(true); } // Content options. - JS::ContextOptions contentContextOptions = commonContextOptions; + JS::ContextOptions contentOptions = commonOptions; + if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit.content"))) { + contentOptions.setBaseline(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("ion.content"))) { + contentOptions.setIon(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.content"))) { + contentOptions.setTypeInference(true); + } // Chrome options. - JS::ContextOptions chromeContextOptions = commonContextOptions; + JS::ContextOptions chromeOptions = commonOptions; + if (GetWorkerPref(NS_LITERAL_CSTRING("baselinejit.chrome"))) { + chromeOptions.setBaseline(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("ion.chrome"))) { + chromeOptions.setIon(true); + } + if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.chrome"))) { + chromeOptions.setTypeInference(true); + } #ifdef DEBUG if (GetWorkerPref(NS_LITERAL_CSTRING("strict.debug"))) { - chromeContextOptions.setExtraWarnings(true); + chromeOptions.setExtraWarnings(true); } #endif - RuntimeService::SetDefaultRuntimeAndContextOptions(runtimeOptions, - contentContextOptions, - chromeContextOptions); + RuntimeService::SetDefaultJSContextOptions(contentOptions, chromeOptions); if (rts) { - rts->UpdateAllWorkerRuntimeAndContextOptions(); + rts->UpdateAllWorkerJSContextOptions(); } } @@ -767,8 +771,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime) JSSettings settings; aWorkerPrivate->CopyJSSettings(settings); - JS::RuntimeOptionsRef(aRuntime) = settings.runtimeOptions; - JSSettings::JSGCSettingsArray& gcSettings = settings.gcSettings; // This is the real place where we set the max memory for the runtime. @@ -1612,11 +1614,10 @@ RuntimeService::Init() // Initialize JSSettings. if (!sDefaultJSSettings.gcSettings[0].IsSet()) { - sDefaultJSSettings.runtimeOptions = JS::RuntimeOptions(); - sDefaultJSSettings.chrome.contextOptions = kRequiredContextOptions; + sDefaultJSSettings.chrome.contextOptions = kRequiredJSContextOptions; sDefaultJSSettings.chrome.maxScriptRuntime = -1; sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST); - sDefaultJSSettings.content.contextOptions = kRequiredContextOptions; + sDefaultJSSettings.content.contextOptions = kRequiredJSContextOptions; sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC; #ifdef JS_GC_ZEAL sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ; @@ -1691,13 +1692,13 @@ RuntimeService::Init() PREF_DOM_WINDOW_DUMP_ENABLED, reinterpret_cast(WORKERPREF_DUMP))) || #endif - NS_FAILED(Preferences::RegisterCallback(LoadRuntimeAndContextOptions, + NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions, PREF_JS_OPTIONS_PREFIX, nullptr)) || NS_FAILED(Preferences::RegisterCallbackAndCall( - LoadRuntimeAndContextOptions, - PREF_WORKERS_OPTIONS_PREFIX, - nullptr)) || + LoadJSContextOptions, + PREF_WORKERS_OPTIONS_PREFIX, + nullptr)) || NS_FAILED(Preferences::RegisterCallbackAndCall( JSVersionChanged, PREF_WORKERS_LATEST_JS_VERSION, @@ -1844,10 +1845,10 @@ RuntimeService::Cleanup() if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged, PREF_WORKERS_LATEST_JS_VERSION, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions, + NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions, PREF_JS_OPTIONS_PREFIX, nullptr)) || - NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeAndContextOptions, + NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions, PREF_WORKERS_OPTIONS_PREFIX, nullptr)) || #if DUMP_CONTROLLED_BY_PREF @@ -2229,10 +2230,9 @@ RuntimeService::NoteIdleThread(WorkerThread* aThread) } void -RuntimeService::UpdateAllWorkerRuntimeAndContextOptions() +RuntimeService::UpdateAllWorkerJSContextOptions() { - BROADCAST_ALL_WORKERS(UpdateRuntimeAndContextOptions, - sDefaultJSSettings.runtimeOptions, + BROADCAST_ALL_WORKERS(UpdateJSContextOptions, sDefaultJSSettings.content.contextOptions, sDefaultJSSettings.chrome.contextOptions); } diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h index 9f81fd3fa07b..b209bc90abbe 100644 --- a/dom/workers/RuntimeService.h +++ b/dom/workers/RuntimeService.h @@ -174,19 +174,16 @@ public: } static void - SetDefaultRuntimeAndContextOptions( - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions) + SetDefaultJSContextOptions(const JS::ContextOptions& aContentOptions, + const JS::ContextOptions& aChromeOptions) { AssertIsOnMainThread(); - sDefaultJSSettings.runtimeOptions = aRuntimeOptions; - sDefaultJSSettings.content.contextOptions = aContentCxOptions; - sDefaultJSSettings.chrome.contextOptions = aChromeCxOptions; + sDefaultJSSettings.content.contextOptions = aContentOptions; + sDefaultJSSettings.chrome.contextOptions = aChromeOptions; } void - UpdateAllWorkerRuntimeAndContextOptions(); + UpdateAllWorkerJSContextOptions(); void UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 7f6e6e62dc02..fd9047b71f61 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1515,32 +1515,25 @@ private: } }; -class UpdateRuntimeAndContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable +class UpdateJSContextOptionsRunnable MOZ_FINAL : public WorkerControlRunnable { - JS::RuntimeOptions mRuntimeOptions; - JS::ContextOptions mContentCxOptions; - JS::ContextOptions mChromeCxOptions; + JS::ContextOptions mContentOptions; + JS::ContextOptions mChromeOptions; public: - UpdateRuntimeAndContextOptionsRunnable( - WorkerPrivate* aWorkerPrivate, - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions) + UpdateJSContextOptionsRunnable(WorkerPrivate* aWorkerPrivate, + const JS::ContextOptions& aContentOptions, + const JS::ContextOptions& aChromeOptions) : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount), - mRuntimeOptions(aRuntimeOptions), - mContentCxOptions(aContentCxOptions), - mChromeCxOptions(aChromeCxOptions) + mContentOptions(aContentOptions), mChromeOptions(aChromeOptions) { } private: virtual bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE { - aWorkerPrivate->UpdateRuntimeAndContextOptionsInternal(aCx, - mRuntimeOptions, - mContentCxOptions, - mChromeCxOptions); + aWorkerPrivate->UpdateJSContextOptionsInternal(aCx, mContentOptions, + mChromeOptions); return true; } }; @@ -2842,26 +2835,22 @@ WorkerPrivateParent::GetInnerWindowId() template void -WorkerPrivateParent::UpdateRuntimeAndContextOptions( - JSContext* aCx, - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions) +WorkerPrivateParent::UpdateJSContextOptions( + JSContext* aCx, + const JS::ContextOptions& aContentOptions, + const JS::ContextOptions& aChromeOptions) { AssertIsOnParentThread(); { MutexAutoLock lock(mMutex); - mJSSettings.runtimeOptions = aRuntimeOptions; - mJSSettings.content.contextOptions = aContentCxOptions; - mJSSettings.chrome.contextOptions = aChromeCxOptions; + mJSSettings.content.contextOptions = aContentOptions; + mJSSettings.chrome.contextOptions = aChromeOptions; } - nsRefPtr runnable = - new UpdateRuntimeAndContextOptionsRunnable(ParentAsWorkerPrivate(), - aRuntimeOptions, - aContentCxOptions, - aChromeCxOptions); + nsRefPtr runnable = + new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aContentOptions, + aChromeOptions); if (!runnable->Dispatch(aCx)) { NS_WARNING("Failed to update worker context options!"); JS_ClearPendingException(aCx); @@ -5499,21 +5488,17 @@ WorkerPrivate::RescheduleTimeoutTimer(JSContext* aCx) } void -WorkerPrivate::UpdateRuntimeAndContextOptionsInternal( - JSContext* aCx, - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions) +WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx, + const JS::ContextOptions& aContentOptions, + const JS::ContextOptions& aChromeOptions) { AssertIsOnWorkerThread(); - JS::RuntimeOptionsRef(aCx) = aRuntimeOptions; - JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeCxOptions : aContentCxOptions; + JS::ContextOptionsRef(aCx) = IsChromeWorker() ? aChromeOptions : aContentOptions; for (uint32_t index = 0; index < mChildWorkers.Length(); index++) { - mChildWorkers[index]->UpdateRuntimeAndContextOptions(aCx, aRuntimeOptions, - aContentCxOptions, - aChromeCxOptions); + mChildWorkers[index]->UpdateJSContextOptions(aCx, aContentOptions, + aChromeOptions); } } diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 72189f115a75..ce66719b3ccd 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -389,10 +389,8 @@ public: GetInnerWindowId(); void - UpdateRuntimeAndContextOptions(JSContext* aCx, - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions); + UpdateJSContextOptions(JSContext* aCx, const JS::ContextOptions& aChromeOptions, + const JS::ContextOptions& aContentOptions); void UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue); @@ -908,11 +906,8 @@ public: } void - UpdateRuntimeAndContextOptionsInternal( - JSContext* aCx, - const JS::RuntimeOptions& aRuntimeOptions, - const JS::ContextOptions& aContentCxOptions, - const JS::ContextOptions& aChromeCxOptions); + UpdateJSContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContentOptions, + const JS::ContextOptions& aChromeOptions); void UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue); diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 2a57df013c41..c86c23bccbca 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -107,7 +107,6 @@ struct JSSettings JSContentChromeSettings chrome; JSContentChromeSettings content; JSGCSettingsArray gcSettings; - JS::RuntimeOptions runtimeOptions; #ifdef JS_GC_ZEAL uint8_t gcZeal; diff --git a/js/jsd/jsd_xpc.cpp b/js/jsd/jsd_xpc.cpp index 0f869a7ae134..ca1c299b1b0b 100644 --- a/js/jsd/jsd_xpc.cpp +++ b/js/jsd/jsd_xpc.cpp @@ -1655,7 +1655,11 @@ jsdContext::GetJSContext(JSContext **_rval) #define JSOPTION_DONT_REPORT_UNCAUGHT JS_BIT(8) #define JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT JS_BIT(11) #define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) +#define JSOPTION_BASELINE JS_BIT(14) +#define JSOPTION_TYPE_INFERENCE JS_BIT(16) #define JSOPTION_STRICT_MODE JS_BIT(17) +#define JSOPTION_ION JS_BIT(18) +#define JSOPTION_ASMJS JS_BIT(19) #define JSOPTION_MASK JS_BITMASK(20) NS_IMETHODIMP @@ -1669,7 +1673,11 @@ jsdContext::GetOptions(uint32_t *_rval) | (JS::ContextOptionsRef(mJSCx).dontReportUncaught() ? JSOPTION_DONT_REPORT_UNCAUGHT : 0) | (JS::ContextOptionsRef(mJSCx).noDefaultCompartmentObject() ? JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT : 0) | (JS::ContextOptionsRef(mJSCx).noScriptRval() ? JSOPTION_NO_SCRIPT_RVAL : 0) - | (JS::ContextOptionsRef(mJSCx).strictMode() ? JSOPTION_STRICT_MODE : 0); + | (JS::ContextOptionsRef(mJSCx).strictMode() ? JSOPTION_STRICT_MODE : 0) + | (JS::ContextOptionsRef(mJSCx).baseline() ? JSOPTION_BASELINE : 0) + | (JS::ContextOptionsRef(mJSCx).typeInference() ? JSOPTION_TYPE_INFERENCE : 0) + | (JS::ContextOptionsRef(mJSCx).ion() ? JSOPTION_ION : 0) + | (JS::ContextOptionsRef(mJSCx).asmJS() ? JSOPTION_ASMJS : 0); return NS_OK; } @@ -1690,7 +1698,11 @@ jsdContext::SetOptions(uint32_t options) .setDontReportUncaught(options & JSOPTION_DONT_REPORT_UNCAUGHT) .setNoDefaultCompartmentObject(options & JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT) .setNoScriptRval(options & JSOPTION_NO_SCRIPT_RVAL) - .setStrictMode(options & JSOPTION_STRICT_MODE); + .setStrictMode(options & JSOPTION_STRICT_MODE) + .setBaseline(options & JSOPTION_BASELINE) + .setTypeInference(options & JSOPTION_TYPE_INFERENCE) + .setIon(options & JSOPTION_ION) + .setAsmJS(options & JSOPTION_ASMJS); return NS_OK; } diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 0c07d4fc2cba..6087d77cd276 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1160,7 +1160,7 @@ SetJitCompilerOption(JSContext *cx, unsigned argc, jsval *vp) if (number < 0) number = -1; - JS_SetGlobalJitCompilerOption(cx->runtime(), opt, uint32_t(number)); + JS_SetGlobalJitCompilerOption(cx, opt, uint32_t(number)); args.rval().setUndefined(); return true; @@ -1175,10 +1175,10 @@ GetJitCompilerOptions(JSContext *cx, unsigned argc, jsval *vp) RootedValue value(cx); -#define JIT_COMPILER_MATCH(key, string) \ - opt = JSJITCOMPILER_ ## key; \ - value.setInt32(JS_GetGlobalJitCompilerOption(cx->runtime(), opt)); \ - if (!JS_SetProperty(cx, info, string, value)) \ +#define JIT_COMPILER_MATCH(key, string) \ + opt = JSJITCOMPILER_ ## key; \ + value.setInt32(JS_GetGlobalJitCompilerOption(cx, opt)); \ + if (!JS_SetProperty(cx, info, string, value)) \ return false; JSJitCompilerOption opt = JSJITCOMPILER_NOT_AN_OPTION; diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 3aa1b234ed4f..1942301cce8d 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -6952,7 +6952,7 @@ js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp) cx->signalHandlersInstalled() && cx->gcSystemPageSize() == AsmJSPageSize && !cx->compartment()->debugMode() && - cx->runtime()->options().asmJS(); + cx->compartment()->options().asmJS(cx); args.rval().set(BooleanValue(available)); return true; diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 3edf4715e31d..7bfed2c19196 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -312,7 +312,7 @@ struct BaselineScript inline bool IsBaselineEnabled(JSContext *cx) { - return cx->runtime()->options().baseline(); + return cx->compartment()->options().baseline(cx); } MethodStatus diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index 9a58a81fb92d..bdf0f9bb954e 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -159,8 +159,8 @@ void StopAllOffThreadCompilations(JSCompartment *comp); static inline bool IsIonEnabled(JSContext *cx) { - return cx->runtime()->options().ion() && - cx->runtime()->options().baseline() && + return cx->compartment()->options().ion(cx) && + cx->compartment()->options().baseline(cx) && cx->typeInferenceEnabled(); } diff --git a/js/src/jsapi-tests/testFuncCallback.cpp b/js/src/jsapi-tests/testFuncCallback.cpp index fa70966e5217..4fc83d838c60 100644 --- a/js/src/jsapi-tests/testFuncCallback.cpp +++ b/js/src/jsapi-tests/testFuncCallback.cpp @@ -133,7 +133,7 @@ JSContext *createContext() JSContext *cx = JSAPITest::createContext(); if (!cx) return nullptr; - JS::RuntimeOptionsRef(cx).setBaseline(true) + JS::ContextOptionsRef(cx).setBaseline(true) .setIon(true); return cx; } diff --git a/js/src/jsapi-tests/testProfileStrings.cpp b/js/src/jsapi-tests/testProfileStrings.cpp index 786322573b27..3f51b5ebc798 100644 --- a/js/src/jsapi-tests/testProfileStrings.cpp +++ b/js/src/jsapi-tests/testProfileStrings.cpp @@ -141,7 +141,7 @@ END_TEST(testProfileStrings_isCalledWithInterpreter) BEGIN_TEST(testProfileStrings_isCalledWithJIT) { CHECK(initialize(cx)); - JS::RuntimeOptionsRef(cx).setBaseline(true) + JS::ContextOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function g() { var p = new Prof(); p.test_fn(); }"); @@ -190,7 +190,7 @@ END_TEST(testProfileStrings_isCalledWithJIT) BEGIN_TEST(testProfileStrings_isCalledWhenError) { CHECK(initialize(cx)); - JS::RuntimeOptionsRef(cx).setBaseline(true) + JS::ContextOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function check2() { throw 'a'; }"); @@ -214,7 +214,7 @@ END_TEST(testProfileStrings_isCalledWhenError) BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly) { CHECK(initialize(cx)); - JS::RuntimeOptionsRef(cx).setBaseline(true) + JS::ContextOptionsRef(cx).setBaseline(true) .setIon(true); EXEC("function b(p) { p.test_fn(); }"); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 4fdbff6beaad..c21e6c81c456 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -883,18 +883,6 @@ JS_StringToVersion(const char *string) return JSVERSION_UNKNOWN; } -JS_PUBLIC_API(JS::RuntimeOptions &) -JS::RuntimeOptionsRef(JSRuntime *rt) -{ - return rt->options(); -} - -JS_PUBLIC_API(JS::RuntimeOptions &) -JS::RuntimeOptionsRef(JSContext *cx) -{ - return cx->runtime()->options(); -} - JS_PUBLIC_API(JS::ContextOptions &) JS::ContextOptionsRef(JSContext *cx) { @@ -2466,6 +2454,36 @@ class AutoHoldZone } /* anonymous namespace */ +bool +JS::CompartmentOptions::baseline(JSContext *cx) const +{ + return baselineOverride_.get(cx->options().baseline()); +} + +bool +JS::CompartmentOptions::typeInference(const ExclusiveContext *cx) const +{ + /* Unlike the other options that can be overriden on a per compartment + * basis, the default value for the typeInference option is stored on the + * compartment's type zone, rather than the current JSContext. Type zones + * copy this default value over from the current JSContext when they are + * created. + */ + return typeInferenceOverride_.get(cx->compartment()->zone()->types.inferenceEnabled); +} + +bool +JS::CompartmentOptions::ion(JSContext *cx) const +{ + return ionOverride_.get(cx->options().ion()); +} + +bool +JS::CompartmentOptions::asmJS(JSContext *cx) const +{ + return asmJSOverride_.get(cx->options().asmJS()); +} + bool JS::CompartmentOptions::cloneSingletons(JSContext *cx) const { @@ -4437,7 +4455,7 @@ JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version) strictOption = cx->options().strictMode(); extraWarningsOption = cx->options().extraWarnings(); werrorOption = cx->options().werror(); - asmJSOption = cx->runtime()->options().asmJS(); + asmJSOption = cx->options().asmJS(); } bool @@ -6013,23 +6031,23 @@ JS_ScheduleGC(JSContext *cx, uint32_t count) #endif JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled) +JS_SetParallelParsingEnabled(JSContext *cx, bool enabled) { #ifdef JS_ION - rt->setParallelParsingEnabled(enabled); + cx->runtime()->setParallelParsingEnabled(enabled); #endif } JS_PUBLIC_API(void) -JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled) +JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled) { #ifdef JS_ION - rt->setParallelIonCompilationEnabled(enabled); + cx->runtime()->setParallelIonCompilationEnabled(enabled); #endif } JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value) +JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value) { #ifdef JS_ION @@ -6052,19 +6070,19 @@ JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t v break; case JSJITCOMPILER_ION_ENABLE: if (value == 1) { - JS::RuntimeOptionsRef(rt).setIon(true); + JS::ContextOptionsRef(cx).setIon(true); IonSpew(js::jit::IonSpew_Scripts, "Enable ion"); } else if (value == 0) { - JS::RuntimeOptionsRef(rt).setIon(false); + JS::ContextOptionsRef(cx).setIon(false); IonSpew(js::jit::IonSpew_Scripts, "Disable ion"); } break; case JSJITCOMPILER_BASELINE_ENABLE: if (value == 1) { - JS::RuntimeOptionsRef(rt).setBaseline(true); + JS::ContextOptionsRef(cx).setBaseline(true); IonSpew(js::jit::IonSpew_BaselineScripts, "Enable baseline"); } else if (value == 0) { - JS::RuntimeOptionsRef(rt).setBaseline(false); + JS::ContextOptionsRef(cx).setBaseline(false); IonSpew(js::jit::IonSpew_BaselineScripts, "Disable baseline"); } break; @@ -6075,7 +6093,7 @@ JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t v } JS_PUBLIC_API(int) -JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt) +JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt) { #ifdef JS_ION switch (opt) { @@ -6084,9 +6102,9 @@ JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt) case JSJITCOMPILER_ION_USECOUNT_TRIGGER: return jit::js_JitOptions.forcedDefaultIonUsesBeforeCompile; case JSJITCOMPILER_ION_ENABLE: - return JS::RuntimeOptionsRef(rt).ion(); + return JS::ContextOptionsRef(cx).ion(); case JSJITCOMPILER_BASELINE_ENABLE: - return JS::RuntimeOptionsRef(rt).baseline(); + return JS::ContextOptionsRef(cx).baseline(); default: break; } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 6c7cd095a8dd..b29022f06199 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1438,69 +1438,6 @@ JS_StringToVersion(const char *string); namespace JS { -class JS_PUBLIC_API(RuntimeOptions) { - public: - RuntimeOptions() - : baseline_(false), - typeInference_(false), - ion_(false), - asmJS_(false) - { - } - - bool baseline() const { return baseline_; } - RuntimeOptions &setBaseline(bool flag) { - baseline_ = flag; - return *this; - } - RuntimeOptions &toggleBaseline() { - baseline_ = !baseline_; - return *this; - } - - bool typeInference() const { return typeInference_; } - RuntimeOptions &setTypeInference(bool flag) { - typeInference_ = flag; - return *this; - } - RuntimeOptions &toggleTypeInference() { - typeInference_ = !typeInference_; - return *this; - } - - bool ion() const { return ion_; } - RuntimeOptions &setIon(bool flag) { - ion_ = flag; - return *this; - } - RuntimeOptions &toggleIon() { - ion_ = !ion_; - return *this; - } - - bool asmJS() const { return asmJS_; } - RuntimeOptions &setAsmJS(bool flag) { - asmJS_ = flag; - return *this; - } - RuntimeOptions &toggleAsmJS() { - asmJS_ = !asmJS_; - return *this; - } - - private: - bool baseline_ : 1; - bool typeInference_ : 1; - bool ion_ : 1; - bool asmJS_ : 1; -}; - -JS_PUBLIC_API(RuntimeOptions &) -RuntimeOptionsRef(JSRuntime *rt); - -JS_PUBLIC_API(RuntimeOptions &) -RuntimeOptionsRef(JSContext *cx); - class JS_PUBLIC_API(ContextOptions) { public: ContextOptions() @@ -1512,6 +1449,10 @@ class JS_PUBLIC_API(ContextOptions) { noDefaultCompartmentObject_(false), noScriptRval_(false), strictMode_(false), + baseline_(false), + typeInference_(false), + ion_(false), + asmJS_(false), cloneSingletons_(false) { } @@ -1596,6 +1537,46 @@ class JS_PUBLIC_API(ContextOptions) { return *this; } + bool baseline() const { return baseline_; } + ContextOptions &setBaseline(bool flag) { + baseline_ = flag; + return *this; + } + ContextOptions &toggleBaseline() { + baseline_ = !baseline_; + return *this; + } + + bool typeInference() const { return typeInference_; } + ContextOptions &setTypeInference(bool flag) { + typeInference_ = flag; + return *this; + } + ContextOptions &toggleTypeInference() { + typeInference_ = !typeInference_; + return *this; + } + + bool ion() const { return ion_; } + ContextOptions &setIon(bool flag) { + ion_ = flag; + return *this; + } + ContextOptions &toggleIon() { + ion_ = !ion_; + return *this; + } + + bool asmJS() const { return asmJS_; } + ContextOptions &setAsmJS(bool flag) { + asmJS_ = flag; + return *this; + } + ContextOptions &toggleAsmJS() { + asmJS_ = !asmJS_; + return *this; + } + bool cloneSingletons() const { return cloneSingletons_; } ContextOptions &setCloneSingletons(bool flag) { cloneSingletons_ = flag; @@ -1615,6 +1596,10 @@ class JS_PUBLIC_API(ContextOptions) { bool noDefaultCompartmentObject_ : 1; bool noScriptRval_ : 1; bool strictMode_ : 1; + bool baseline_ : 1; + bool typeInference_ : 1; + bool ion_ : 1; + bool asmJS_ : 1; bool cloneSingletons_ : 1; }; @@ -2661,6 +2646,18 @@ class JS_PUBLIC_API(CompartmentOptions) return *this; } + bool baseline(JSContext *cx) const; + Override &baselineOverride() { return baselineOverride_; } + + bool typeInference(const js::ExclusiveContext *cx) const; + Override &typeInferenceOverride() { return typeInferenceOverride_; } + + bool ion(JSContext *cx) const; + Override &ionOverride() { return ionOverride_; } + + bool asmJS(JSContext *cx) const; + Override &asmJSOverride() { return asmJSOverride_; } + bool cloneSingletons(JSContext *cx) const; Override &cloneSingletonsOverride() { return cloneSingletonsOverride_; } @@ -2683,6 +2680,10 @@ class JS_PUBLIC_API(CompartmentOptions) JSVersion version_; bool invisibleToDebugger_; bool mergeable_; + Override baselineOverride_; + Override typeInferenceOverride_; + Override ionOverride_; + Override asmJSOverride_; Override cloneSingletonsOverride_; union { ZoneSpecifier spec; @@ -4717,10 +4718,10 @@ JS_ScheduleGC(JSContext *cx, uint32_t count); #endif extern JS_PUBLIC_API(void) -JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled); +JS_SetParallelParsingEnabled(JSContext *cx, bool enabled); extern JS_PUBLIC_API(void) -JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled); +JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled); #define JIT_COMPILER_OPTIONS(Register) \ Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \ @@ -4739,9 +4740,9 @@ typedef enum JSJitCompilerOption { } JSJitCompilerOption; extern JS_PUBLIC_API(void) -JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value); +JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value); extern JS_PUBLIC_API(int) -JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt); +JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt); /* * Convert a uint32_t index into a jsid. diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 71ad8e7cc32a..1fe749639967 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -521,7 +521,7 @@ namespace js { inline bool ExclusiveContext::typeInferenceEnabled() const { - return zone()->types.inferenceEnabled; + return compartment_->options().typeInference(this); } inline js::Handle diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index d9698073eadb..43553fd90444 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1862,7 +1862,7 @@ void TypeZone::init(JSContext *cx) { if (!cx || - !cx->runtime()->options().typeInference() || + !cx->options().typeInference() || !cx->runtime()->jitSupportsFloatingPoint) { return; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index e7d7bd49cd44..b632f348a7f0 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -118,7 +118,11 @@ static double gTimeoutInterval = -1.0; static volatile bool gTimedOut = false; static JS::Value gTimeoutFunc; +static bool enableTypeInference = true; static bool enableDisassemblyDumps = false; +static bool enableIon = true; +static bool enableBaseline = true; +static bool enableAsmJS = true; static bool printTiming = false; static const char *jsCacheDir = nullptr; @@ -648,8 +652,7 @@ Options(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); - JS::RuntimeOptions oldRuntimeOptions = JS::RuntimeOptionsRef(cx); - JS::ContextOptions oldContextOptions = JS::ContextOptionsRef(cx); + JS::ContextOptions oldOptions = JS::ContextOptionsRef(cx); for (unsigned i = 0; i < args.length(); i++) { JSString *str = JS::ToString(cx, args[i]); if (!str) @@ -663,7 +666,7 @@ Options(JSContext *cx, unsigned argc, jsval *vp) if (strcmp(opt.ptr(), "strict") == 0) JS::ContextOptionsRef(cx).toggleExtraWarnings(); else if (strcmp(opt.ptr(), "typeinfer") == 0) - JS::RuntimeOptionsRef(cx).toggleTypeInference(); + JS::ContextOptionsRef(cx).toggleTypeInference(); else if (strcmp(opt.ptr(), "werror") == 0) JS::ContextOptionsRef(cx).toggleWerror(); else if (strcmp(opt.ptr(), "strict_mode") == 0) @@ -687,19 +690,19 @@ Options(JSContext *cx, unsigned argc, jsval *vp) char *names = strdup(""); bool found = false; - if (!names && oldContextOptions.extraWarnings()) { + if (!names && oldOptions.extraWarnings()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict"); found = true; } - if (!names && oldRuntimeOptions.typeInference()) { + if (!names && oldOptions.typeInference()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "typeinfer"); found = true; } - if (!names && oldContextOptions.werror()) { + if (!names && oldOptions.werror()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "werror"); found = true; } - if (!names && oldContextOptions.strictMode()) { + if (!names && oldOptions.strictMode()) { names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict_mode"); found = true; } @@ -5482,6 +5485,14 @@ NewContext(JSRuntime *rt) JS_SetContextPrivate(cx, data); JS_SetErrorReporter(cx, my_ErrorReporter); + if (enableTypeInference) + JS::ContextOptionsRef(cx).toggleTypeInference(); + if (enableIon) + JS::ContextOptionsRef(cx).toggleIon(); + if (enableBaseline) + JS::ContextOptionsRef(cx).toggleBaseline(); + if (enableAsmJS) + JS::ContextOptionsRef(cx).toggleAsmJS(); return cx; } @@ -5583,11 +5594,11 @@ BindScriptArgs(JSContext *cx, JSObject *obj_, OptionParser *op) // so we're guarding the function definition with an #ifdef, too, to avoid // build warning for unused function in non-ion-enabled builds: #if defined(JS_ION) -static bool +static int OptionFailure(const char *option, const char *str) { fprintf(stderr, "Unrecognized option for %s: %s\n", option, str); - return false; + return EXIT_FAILURE; } #endif /* JS_ION */ @@ -5596,6 +5607,14 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) { RootedObject obj(cx, obj_); + if (op->getBoolOption('c')) + compileOnly = true; + + if (op->getBoolOption('w')) + reportWarnings = true; + else if (op->getBoolOption('W')) + reportWarnings = false; + if (op->getBoolOption('s')) JS::ContextOptionsRef(cx).toggleExtraWarnings(); @@ -5604,6 +5623,163 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) JS_SetDebugMode(cx, true); } + jsCacheDir = op->getStringOption("js-cache"); + if (jsCacheDir) { + if (op->getBoolOption("js-cache-per-process")) + jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, (unsigned)getpid()); + jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir); + } + + if (op->getBoolOption('b')) + printTiming = true; + + if (op->getBoolOption('D')) { + cx->runtime()->profilingScripts = true; + enableDisassemblyDumps = true; + } + +#ifdef JS_THREADSAFE + int32_t threadCount = op->getIntOption("thread-count"); + if (threadCount >= 0) + SetFakeCPUCount(threadCount); +#endif /* JS_THREADSAFE */ + +#if defined(JS_ION) + if (op->getBoolOption("no-ion")) { + enableIon = false; + JS::ContextOptionsRef(cx).toggleIon(); + } + if (op->getBoolOption("no-asmjs")) { + enableAsmJS = false; + JS::ContextOptionsRef(cx).toggleAsmJS(); + } + + if (op->getBoolOption("no-baseline")) { + enableBaseline = false; + JS::ContextOptionsRef(cx).toggleBaseline(); + } + + if (const char *str = op->getStringOption("ion-gvn")) { + if (strcmp(str, "off") == 0) { + jit::js_JitOptions.disableGvn = true; + } else if (strcmp(str, "pessimistic") == 0) { + jit::js_JitOptions.forceGvnKind = true; + jit::js_JitOptions.forcedGvnKind = jit::GVN_Pessimistic; + } else if (strcmp(str, "optimistic") == 0) { + jit::js_JitOptions.forceGvnKind = true; + jit::js_JitOptions.forcedGvnKind = jit::GVN_Optimistic; + } else { + return OptionFailure("ion-gvn", str); + } + } + + if (const char *str = op->getStringOption("ion-licm")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableLicm = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableLicm = true; + else + return OptionFailure("ion-licm", str); + } + + if (const char *str = op->getStringOption("ion-edgecase-analysis")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableEdgeCaseAnalysis = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableEdgeCaseAnalysis = true; + else + return OptionFailure("ion-edgecase-analysis", str); + } + + if (const char *str = op->getStringOption("ion-range-analysis")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableRangeAnalysis = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableRangeAnalysis = true; + else + return OptionFailure("ion-range-analysis", str); + } + + if (op->getBoolOption("ion-check-range-analysis")) + jit::js_JitOptions.checkRangeAnalysis = true; + + if (const char *str = op->getStringOption("ion-inlining")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.disableInlining = false; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.disableInlining = true; + else + return OptionFailure("ion-inlining", str); + } + + if (const char *str = op->getStringOption("ion-osr")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.osr = true; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.osr = false; + else + return OptionFailure("ion-osr", str); + } + + if (const char *str = op->getStringOption("ion-limit-script-size")) { + if (strcmp(str, "on") == 0) + jit::js_JitOptions.limitScriptSize = true; + else if (strcmp(str, "off") == 0) + jit::js_JitOptions.limitScriptSize = false; + else + return OptionFailure("ion-limit-script-size", str); + } + + int32_t useCount = op->getIntOption("ion-uses-before-compile"); + if (useCount >= 0) + jit::js_JitOptions.setUsesBeforeCompile(useCount); + + useCount = op->getIntOption("baseline-uses-before-compile"); + if (useCount >= 0) + jit::js_JitOptions.baselineUsesBeforeCompile = useCount; + + if (op->getBoolOption("baseline-eager")) + jit::js_JitOptions.baselineUsesBeforeCompile = 0; + + if (const char *str = op->getStringOption("ion-regalloc")) { + if (strcmp(str, "lsra") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_LSRA; + } else if (strcmp(str, "backtracking") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Backtracking; + } else if (strcmp(str, "stupid") == 0) { + jit::js_JitOptions.forceRegisterAllocator = true; + jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Stupid; + } else { + return OptionFailure("ion-regalloc", str); + } + } + + if (op->getBoolOption("ion-eager")) + jit::js_JitOptions.setEagerCompilation(); + + if (op->getBoolOption("ion-compile-try-catch")) + jit::js_JitOptions.compileTryCatch = true; + + bool parallelCompilation = true; + if (const char *str = op->getStringOption("ion-parallel-compile")) { + if (strcmp(str, "off") == 0) + parallelCompilation = false; + else if (strcmp(str, "on") != 0) + return OptionFailure("ion-parallel-compile", str); + } +#ifdef JS_THREADSAFE + cx->runtime()->setParallelIonCompilationEnabled(parallelCompilation); +#endif + +#endif /* JS_ION */ + +#ifdef DEBUG + if (op->getBoolOption("dump-entrained-variables")) + dumpEntrainedVariables = true; +#endif + /* |scriptArgs| gets bound on the global before any code is run. */ if (!BindScriptArgs(cx, obj, op)) return EXIT_FAILURE; @@ -5647,191 +5823,20 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op) return gExitCode ? gExitCode : EXIT_SUCCESS; } -static bool -SetRuntimeOptions(JSRuntime *rt, const OptionParser &op) -{ -#if defined(JS_ION) - bool enableBaseline = !op.getBoolOption("no-baseline"); - bool enableIon = !op.getBoolOption("no-ion"); - bool enableTypeInference = !op.getBoolOption("no-ti"); - bool enableAsmJS = !op.getBoolOption("no-asmjs"); - - JS::RuntimeOptionsRef(rt).setBaseline(enableBaseline) - .setIon(enableIon) - .setTypeInference(enableTypeInference) - .setAsmJS(enableAsmJS); - - if (const char *str = op.getStringOption("ion-gvn")) { - if (strcmp(str, "off") == 0) { - jit::js_JitOptions.disableGvn = true; - } else if (strcmp(str, "pessimistic") == 0) { - jit::js_JitOptions.forceGvnKind = true; - jit::js_JitOptions.forcedGvnKind = jit::GVN_Pessimistic; - } else if (strcmp(str, "optimistic") == 0) { - jit::js_JitOptions.forceGvnKind = true; - jit::js_JitOptions.forcedGvnKind = jit::GVN_Optimistic; - } else { - return OptionFailure("ion-gvn", str); - } - } - - if (const char *str = op.getStringOption("ion-licm")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableLicm = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableLicm = true; - else - return OptionFailure("ion-licm", str); - } - - if (const char *str = op.getStringOption("ion-edgecase-analysis")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableEdgeCaseAnalysis = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableEdgeCaseAnalysis = true; - else - return OptionFailure("ion-edgecase-analysis", str); - } - - if (const char *str = op.getStringOption("ion-range-analysis")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableRangeAnalysis = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableRangeAnalysis = true; - else - return OptionFailure("ion-range-analysis", str); - } - - if (op.getBoolOption("ion-check-range-analysis")) - jit::js_JitOptions.checkRangeAnalysis = true; - - if (const char *str = op.getStringOption("ion-inlining")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.disableInlining = false; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.disableInlining = true; - else - return OptionFailure("ion-inlining", str); - } - - if (const char *str = op.getStringOption("ion-osr")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.osr = true; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.osr = false; - else - return OptionFailure("ion-osr", str); - } - - if (const char *str = op.getStringOption("ion-limit-script-size")) { - if (strcmp(str, "on") == 0) - jit::js_JitOptions.limitScriptSize = true; - else if (strcmp(str, "off") == 0) - jit::js_JitOptions.limitScriptSize = false; - else - return OptionFailure("ion-limit-script-size", str); - } - - int32_t useCount = op.getIntOption("ion-uses-before-compile"); - if (useCount >= 0) - jit::js_JitOptions.setUsesBeforeCompile(useCount); - - useCount = op.getIntOption("baseline-uses-before-compile"); - if (useCount >= 0) - jit::js_JitOptions.baselineUsesBeforeCompile = useCount; - - if (op.getBoolOption("baseline-eager")) - jit::js_JitOptions.baselineUsesBeforeCompile = 0; - - if (const char *str = op.getStringOption("ion-regalloc")) { - if (strcmp(str, "lsra") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_LSRA; - } else if (strcmp(str, "backtracking") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Backtracking; - } else if (strcmp(str, "stupid") == 0) { - jit::js_JitOptions.forceRegisterAllocator = true; - jit::js_JitOptions.forcedRegisterAllocator = jit::RegisterAllocator_Stupid; - } else { - return OptionFailure("ion-regalloc", str); - } - } - - if (op.getBoolOption("ion-eager")) - jit::js_JitOptions.setEagerCompilation(); - - if (op.getBoolOption("ion-compile-try-catch")) - jit::js_JitOptions.compileTryCatch = true; - - bool parallelCompilation = true; - if (const char *str = op.getStringOption("ion-parallel-compile")) { - if (strcmp(str, "off") == 0) - parallelCompilation = false; - else if (strcmp(str, "on") != 0) - return OptionFailure("ion-parallel-compile", str); - } -#ifdef JS_THREADSAFE - rt->setParallelIonCompilationEnabled(parallelCompilation); -#endif - -#if defined(JS_CODEGEN_X86) && defined(DEBUG) - if (op.getBoolOption("no-fpu")) - JSC::MacroAssembler::SetFloatingPointDisabled(); -#endif - -#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(DEBUG) - if (op.getBoolOption("no-sse3")) { - JSC::MacroAssembler::SetSSE3Disabled(); - PropagateFlagToNestedShells("--no-sse3"); - } - if (op.getBoolOption("no-sse4")) { - JSC::MacroAssembler::SetSSE4Disabled(); - PropagateFlagToNestedShells("--no-sse4"); - } -#endif - -#endif // JS_ION - -#ifdef JS_ARM_SIMULATOR - if (op.getBoolOption("arm-sim-icache-checks")) - jit::Simulator::ICacheCheckingEnabled = true; - - int32_t stopAt = op.getIntOption("arm-sim-stop-at"); - if (stopAt >= 0) - jit::Simulator::StopSimAt = stopAt; -#endif - - reportWarnings = op.getBoolOption('w'); - compileOnly = op.getBoolOption('c'); - printTiming = op.getBoolOption('b'); - rt->profilingScripts = enableDisassemblyDumps = op.getBoolOption('D'); - - jsCacheDir = op.getStringOption("js-cache"); - if (jsCacheDir) { - if (op.getBoolOption("js-cache-per-process")) - jsCacheDir = JS_smprintf("%s/%u", jsCacheDir, (unsigned)getpid()); - jsCacheAsmJSPath = JS_smprintf("%s/asmjs.cache", jsCacheDir); - } - -#ifdef JS_THREADSAFE - int32_t threadCount = op.getIntOption("thread-count"); - if (threadCount >= 0) - SetFakeCPUCount(threadCount); -#endif /* JS_THREADSAFE */ - -#ifdef DEBUG - dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables"); -#endif - - return true; -} - static int Shell(JSContext *cx, OptionParser *op, char **envp) { JSAutoRequest ar(cx); + /* + * First check to see if type inference is enabled. These flags + * must be set on the compartment when it is constructed. + */ + if (op->getBoolOption("no-ti")) { + enableTypeInference = false; + JS::ContextOptionsRef(cx).toggleTypeInference(); + } + if (op->getBoolOption("fuzzing-safe")) fuzzingSafe = true; else @@ -6047,7 +6052,33 @@ main(int argc, char **argv, char **envp) * Process OOM options as early as possible so that we can observe as many * allocations as possible. */ - OOM_printAllocationCount = op.getBoolOption('O'); + if (op.getBoolOption('O')) + OOM_printAllocationCount = true; + +#if defined(JS_CODEGEN_X86) && defined(JS_ION) + if (op.getBoolOption("no-fpu")) + JSC::MacroAssembler::SetFloatingPointDisabled(); +#endif + +#if (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)) && defined(JS_ION) + if (op.getBoolOption("no-sse3")) { + JSC::MacroAssembler::SetSSE3Disabled(); + PropagateFlagToNestedShells("--no-sse3"); + } + if (op.getBoolOption("no-sse4")) { + JSC::MacroAssembler::SetSSE4Disabled(); + PropagateFlagToNestedShells("--no-sse4"); + } +#endif +#endif + +#ifdef JS_ARM_SIMULATOR + if (op.getBoolOption("arm-sim-icache-checks")) + jit::Simulator::ICacheCheckingEnabled = true; + + int32_t stopAt = op.getIntOption("arm-sim-stop-at"); + if (stopAt >= 0) + jit::Simulator::StopSimAt = stopAt; #endif // Start the engine. @@ -6058,10 +6089,6 @@ main(int argc, char **argv, char **envp) rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS); if (!rt) return 1; - - if (!SetRuntimeOptions(rt, op)) - return 1; - gTimeoutFunc = NullValue(); if (!JS_AddNamedValueRootRT(rt, &gTimeoutFunc, "gTimeoutFunc")) return 1; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 39fb2226e946..a17e7e6c890c 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1694,7 +1694,6 @@ struct JSRuntime : public JS::shadow::Runtime, void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes *runtime); private: - JS::RuntimeOptions options_; JSUseHelperThreads useHelperThreads_; @@ -1742,13 +1741,6 @@ struct JSRuntime : public JS::shadow::Runtime, return isWorkerRuntime_; } - const JS::RuntimeOptions &options() const { - return options_; - } - JS::RuntimeOptions &options() { - return options_; - } - #ifdef DEBUG public: js::AutoEnterPolicy *enteredPolicy; diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 375ef2f0c465..d4a0368860cf 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3245,41 +3245,26 @@ nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope, return NS_DispatchToMainThread(run); } -#define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ - { \ - *aValue = ContextOptionsRef(cx)._getter(); \ - return NS_OK; \ - } \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ - { \ - ContextOptionsRef(cx)._setter(aValue); \ - return NS_OK; \ +#define GENERATE_JSOPTION_GETTER_SETTER(_attr, _getter, _setter) \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ + { \ + *aValue = ContextOptionsRef(cx)._getter(); \ + return NS_OK; \ + } \ + NS_IMETHODIMP \ + nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ + { \ + ContextOptionsRef(cx)._setter(aValue); \ + return NS_OK; \ } -#define GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(_attr, _getter, _setter) \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \ - { \ - *aValue = RuntimeOptionsRef(cx)._getter(); \ - return NS_OK; \ - } \ - NS_IMETHODIMP \ - nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \ - { \ - RuntimeOptionsRef(cx)._setter(aValue); \ - return NS_OK; \ - } +GENERATE_JSOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings) +GENERATE_JSOPTION_GETTER_SETTER(Werror, werror, setWerror) +GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) +GENERATE_JSOPTION_GETTER_SETTER(Ion, ion, setIon) -GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings) -GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Werror, werror, setWerror) -GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode) -GENERATE_JSRUNTIMEOPTION_GETTER_SETTER(Ion, ion, setIon) - -#undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER -#undef GENERATE_JSRUNTIMEOPTION_GETTER_SETTER +#undef GENERATE_JSOPTION_GETTER_SETTER NS_IMETHODIMP nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx) diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index ed41227c965a..c32b305dee4d 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -46,7 +46,6 @@ #include "nsAboutProtocolUtils.h" #include "GeckoProfiler.h" -#include "nsIXULRuntime.h" #include "nsJSPrincipals.h" #ifdef MOZ_CRASHREPORTER @@ -1499,45 +1498,6 @@ void XPCJSRuntime::SystemIsBeingShutDown() Enumerate(DetachedWrappedNativeProtoShutdownMarker, nullptr); } -#define JS_OPTIONS_DOT_STR "javascript.options." - -static void -ReloadPrefsCallback(const char *pref, void *data) -{ - XPCJSRuntime *runtime = reinterpret_cast(data); - JSRuntime *rt = runtime->Runtime(); - - bool safeMode = false; - nsCOMPtr xr = do_GetService("@mozilla.org/xre/runtime;1"); - if (xr) { - xr->GetInSafeMode(&safeMode); - } - - bool useBaseline = Preferences::GetBool(JS_OPTIONS_DOT_STR "baselinejit") && !safeMode; - bool useTypeInference = Preferences::GetBool(JS_OPTIONS_DOT_STR "typeinference") && !safeMode; - bool useIon = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion") && !safeMode; - bool useAsmJS = Preferences::GetBool(JS_OPTIONS_DOT_STR "asmjs") && !safeMode; - - bool parallelParsing = Preferences::GetBool(JS_OPTIONS_DOT_STR "parallel_parsing"); - bool parallelIonCompilation = Preferences::GetBool(JS_OPTIONS_DOT_STR - "ion.parallel_compilation"); - bool useBaselineEager = Preferences::GetBool(JS_OPTIONS_DOT_STR - "baselinejit.unsafe_eager_compilation"); - bool useIonEager = Preferences::GetBool(JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation"); - - JS::RuntimeOptionsRef(rt).setBaseline(useBaseline) - .setTypeInference(useTypeInference) - .setIon(useIon) - . setAsmJS(useAsmJS); - - JS_SetParallelParsingEnabled(rt, parallelParsing); - JS_SetParallelIonCompilationEnabled(rt, parallelIonCompilation); - JS_SetGlobalJitCompilerOption(rt, JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER, - useBaselineEager ? 0 : -1); - JS_SetGlobalJitCompilerOption(rt, JSJITCOMPILER_ION_USECOUNT_TRIGGER, - useIonEager ? 0 : -1); -} - XPCJSRuntime::~XPCJSRuntime() { // This destructor runs before ~CycleCollectedJSRuntime, which does the @@ -1623,8 +1583,6 @@ XPCJSRuntime::~XPCJSRuntime() MOZ_ASSERT(mScratchStrings[i].empty(), "Short lived string still in use"); } #endif - - Preferences::UnregisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this); } static void @@ -3178,10 +3136,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) if (!JS_GetGlobalDebugHooks(runtime)->debuggerHandler) xpc_InstallJSDebuggerKeywordHandler(runtime); #endif - - // Watch for the JS boolean options. - ReloadPrefsCallback(nullptr, this); - Preferences::RegisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this); } // static diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 95fd1163f1cb..8cb8c842561f 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -1039,11 +1039,11 @@ ProcessArgsForCompartment(JSContext *cx, char **argv, int argc) ContextOptionsRef(cx).toggleExtraWarnings(); break; case 'I': - RuntimeOptionsRef(cx).toggleIon() + ContextOptionsRef(cx).toggleIon() .toggleAsmJS(); break; case 'n': - RuntimeOptionsRef(cx).toggleTypeInference(); + ContextOptionsRef(cx).toggleTypeInference(); break; } } @@ -1487,6 +1487,9 @@ XRE_XPCShellMain(int argc, char **argv, char **envp) return 1; } + // Ion not enabled yet here because of bug 931861. + JS::ContextOptionsRef(cx).setBaseline(true); + argc--; argv++; ProcessArgsForCompartment(cx, argv, argc); diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 1c8903c5ead9..2db0bf586388 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -361,12 +361,56 @@ TraceXPCGlobal(JSTracer *trc, JSObject *obj) mozilla::dom::TraceProtoAndIfaceCache(trc, obj); } +#ifdef DEBUG +#include "mozilla/Preferences.h" +#include "nsIXULRuntime.h" +static void +CheckTypeInference(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal) +{ + // Check that the global class isn't whitelisted. + if (strcmp(clasp->name, "Sandbox") || + strcmp(clasp->name, "nsXBLPrototypeScript compilation scope") || + strcmp(clasp->name, "nsXULPrototypeScript compilation scope")) + return; + + // Check that the pref is on. + if (!mozilla::Preferences::GetBool("javascript.options.typeinference")) + return; + + // Check that we're not chrome. + bool isSystem; + nsIScriptSecurityManager* ssm; + ssm = XPCWrapper::GetSecurityManager(); + if (NS_FAILED(ssm->IsSystemPrincipal(principal, &isSystem)) || !isSystem) + return; + + // Check that safe mode isn't on. + bool safeMode; + nsCOMPtr xr = do_GetService("@mozilla.org/xre/runtime;1"); + if (!xr) { + NS_WARNING("Couldn't get XUL runtime!"); + return; + } + if (NS_FAILED(xr->GetInSafeMode(&safeMode)) || safeMode) + return; + + // Finally, do the damn assert. + MOZ_ASSERT(ContextOptionsRef(cx).typeInference()); +} +#else +#define CheckTypeInference(cx, clasp, principal) {} +#endif + namespace xpc { JSObject* CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, JS::CompartmentOptions& aOptions) { + // Make sure that Type Inference is enabled for everything non-chrome. + // Sandboxes and compilation scopes are exceptions. See bug 744034. + CheckTypeInference(cx, clasp, principal); + MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); MOZ_ASSERT(principal); @@ -376,7 +420,6 @@ CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, if (!global) return nullptr; JSAutoCompartment ac(cx, global); - // The constructor automatically attaches the scope to the compartment private // of |global|. (void) new XPCWrappedNativeScope(cx, global); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 78a1bd0bdc61..d7b2c5a7ae34 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -753,12 +753,15 @@ pref("javascript.options.strict", false); #ifdef DEBUG pref("javascript.options.strict.debug", true); #endif -pref("javascript.options.baselinejit", true); -pref("javascript.options.ion", true); +pref("javascript.options.baselinejit.content", true); +pref("javascript.options.baselinejit.chrome", true); +pref("javascript.options.ion.content", true); +pref("javascript.options.ion.chrome", true); pref("javascript.options.asmjs", true); pref("javascript.options.parallel_parsing", true); pref("javascript.options.ion.parallel_compilation", true); -pref("javascript.options.typeinference", true); +pref("javascript.options.typeinference.content", true); +pref("javascript.options.typeinference.chrome", true); // This preference limits the memory usage of javascript. // If you want to change these values for your device, // please find Bug 417052 comment 17 and Bug 456721 From 04cc0004973bc6fabc951469a1cc2f02621df8b0 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 09:25:24 -0800 Subject: [PATCH 62/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/39ec2452c51c Author: Fernando Jiménez Moreno Desc: Merge pull request #16369 from ferjm/fxa-refresh-auth-2 Bug 968294 - Refresh authentication UI. r=alive ======== https://hg.mozilla.org/integration/gaia-central/rev/beb29ab46bb4 Author: Fernando Jiménez Desc: Bug 968294 - Refresh authentication UI. r=alive --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 8946046ee1da..c570424d9be7 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "05a2237d43c5ff1080606b933c2bafbe9039d84f", + "revision": "39ec2452c51c737b8f2b1b07da53904db02ffb11", "repo_path": "/integration/gaia-central" } From cf9da869b53760dbede3dcefff65af28ab7312f6 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 09:31:12 -0800 Subject: [PATCH 63/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index ad8098f6e168..37910173e908 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 78e9a41002d1..b4cbdd8a6f2c 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index ad8098f6e168..37910173e908 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 2db9c17f0907..cadd3ff92e54 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 176017e9ec0c..7439f621ecdc 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 5e2c5ae5ec5f..c5c0148f77c8 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 683fed870223..b8653f341f0f 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 318b837dfae6..b18cbeef2120 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 1d5eda91c3a8..d7cf92ca8898 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From ecca793f7837c6d61dfe7b2a60964ac4d4c236e7 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 09:50:24 -0800 Subject: [PATCH 64/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/a1c1856c9b08 Author: Kevin Grandon Desc: Merge pull request #16760 from KevinGrandon/bug_978433_disable_failing_test Bug 977337 - Fix intermittent SIM tests ======== https://hg.mozilla.org/integration/gaia-central/rev/6367d9a0b5ac Author: Kevin Grandon Desc: Bug 977337 - Fix intermittent SIM tests r=rik --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index c570424d9be7..bd0c8ad19f94 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "39ec2452c51c737b8f2b1b07da53904db02ffb11", + "revision": "a1c1856c9b0807e992884d891365916c16c0a081", "repo_path": "/integration/gaia-central" } From 026cf446514964df3bbb2c1a4e94a0c84315e578 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 09:56:15 -0800 Subject: [PATCH 65/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 37910173e908..f940689c7afb 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index b4cbdd8a6f2c..bf6dd808c67d 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 37910173e908..f940689c7afb 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index cadd3ff92e54..6bc6211a2026 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 7439f621ecdc..d45c11a2b81e 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index c5c0148f77c8..c586d051449e 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index b8653f341f0f..ce2a2ed4e786 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index b18cbeef2120..74ae20249caa 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index d7cf92ca8898..99908d2bd22b 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From 9fe38e61ae07024845d26aac201ef52cc0a46c55 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 10:30:21 -0800 Subject: [PATCH 66/69] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/c195232a409e Author: Julien Wajsberg Desc: Merge pull request #16738 from julienw/976454-no-provider-error Bug 976454 - [Sora][Message][MMS]The prompt message is wrong when re-ent... ======== https://hg.mozilla.org/integration/gaia-central/rev/95ab69aa24b6 Author: Julien Wajsberg Desc: Bug 976454 - [Sora][Message][MMS]The prompt message is wrong when re-enter message r=schung When invoking an activity, we show the "no provider" message only when we receive this specific error. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index bd0c8ad19f94..b07916358d4b 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "branch": "", "revision": "" }, - "revision": "a1c1856c9b0807e992884d891365916c16c0a081", + "revision": "c195232a409ee2234eca18a63bac2d48c2db0c13", "repo_path": "/integration/gaia-central" } From 1ff91497a699082d95aa1bc84e70d7a4700febe5 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Mon, 3 Mar 2014 10:31:29 -0800 Subject: [PATCH 67/69] Bumping manifests a=b2g-bump --- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/hamachi/sources.xml | 2 +- b2g/config/helix/sources.xml | 2 +- b2g/config/inari/sources.xml | 2 +- b2g/config/leo/sources.xml | 2 +- b2g/config/mako/sources.xml | 2 +- b2g/config/wasabi/sources.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index f940689c7afb..a52bc9465b5f 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index bf6dd808c67d..8f146648de85 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index f940689c7afb..a52bc9465b5f 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 6bc6211a2026..722536482adc 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index d45c11a2b81e..998269e64d8b 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index c586d051449e..ae8d60a0e92a 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index ce2a2ed4e786..d0de426d35ea 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 74ae20249caa..f1db0881435e 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 99908d2bd22b..57a4d9cac6a9 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + From bd01b19f65ee60896e7efb133bbc26a7503cb8c8 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Mon, 3 Mar 2014 14:50:40 -0500 Subject: [PATCH 68/69] Bug 944451 - Land simulator addon into mozilla-central. r=vingtetun, r=gps, r=paul --- b2g/build.mk | 5 + b2g/simulator/build_xpi.py | 145 ++ b2g/simulator/custom-prefs.js | 2 + b2g/simulator/custom-settings.json | 6 + b2g/simulator/icon.png | Bin 0 -> 4762 bytes b2g/simulator/icon64.png | Bin 0 -> 7858 bytes b2g/simulator/lib/main.js | 52 + b2g/simulator/lib/simulator-process.js | 182 ++ b2g/simulator/package-overload.json.in | 7 + b2g/simulator/package.json | 37 + b2g/simulator/packages/subprocess/README.md | 124 ++ .../packages/subprocess/lib/subprocess.js | 1543 +++++++++++++++++ .../subprocess/lib/subprocess_worker_unix.js | 248 +++ .../subprocess/lib/subprocess_worker_win.js | 206 +++ .../packages/subprocess/package.json | 15 + .../subprocess/tests/test-subprocess.js | 144 ++ configure.in | 10 + 17 files changed, 2726 insertions(+) create mode 100644 b2g/simulator/build_xpi.py create mode 100644 b2g/simulator/custom-prefs.js create mode 100644 b2g/simulator/custom-settings.json create mode 100644 b2g/simulator/icon.png create mode 100644 b2g/simulator/icon64.png create mode 100644 b2g/simulator/lib/main.js create mode 100644 b2g/simulator/lib/simulator-process.js create mode 100644 b2g/simulator/package-overload.json.in create mode 100644 b2g/simulator/package.json create mode 100644 b2g/simulator/packages/subprocess/README.md create mode 100644 b2g/simulator/packages/subprocess/lib/subprocess.js create mode 100644 b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js create mode 100644 b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js create mode 100644 b2g/simulator/packages/subprocess/package.json create mode 100644 b2g/simulator/packages/subprocess/tests/test-subprocess.js diff --git a/b2g/build.mk b/b2g/build.mk index 136eefe3a4aa..52a47f3b51b6 100644 --- a/b2g/build.mk +++ b/b2g/build.mk @@ -2,11 +2,16 @@ # License, v. 2.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 $(topsrcdir)/toolkit/mozapps/installer/package-name.mk + installer: @$(MAKE) -C b2g/installer installer package: @$(MAKE) -C b2g/installer +ifdef FXOS_SIMULATOR + $(PYTHON) $(srcdir)/b2g/simulator/build_xpi.py $(MOZ_PKG_PLATFORM) +endif install:: @echo 'B2G can't be installed directly.' diff --git a/b2g/simulator/build_xpi.py b/b2g/simulator/build_xpi.py new file mode 100644 index 000000000000..847b7aaf8f7a --- /dev/null +++ b/b2g/simulator/build_xpi.py @@ -0,0 +1,145 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Generate xpi for the simulator addon by: +# - building a special gaia profile for it, as we need: +# * more languages, and, +# * less apps +# than b2g desktop's one +# - retrieve usefull app version metadata from the build system +# - finally, use addon sdk's cfx tool to build the addon xpi +# that ships: +# * a small firefox addon registering to the app manager +# * b2g desktop runtime +# * gaia profile + +import sys, os, re, subprocess +from mozbuild.preprocessor import Preprocessor +from mozbuild.base import MozbuildObject +from mozbuild.util import ensureParentDir +from zipfile import ZipFile +from distutils.version import LooseVersion + +ftp_root_path = "/pub/mozilla.org/labs/fxos-simulator" +UPDATE_LINK = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/%(xpi_name)s" +UPDATE_URL = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/update.rdf" +XPI_NAME = "fxos-simulator-%(version)s-%(platform)s.xpi" + +class GaiaBuilder(object): + def __init__(self, build, gaia_path): + self.build = build + self.gaia_path = gaia_path + + def clean(self): + self.build._run_make(target="clean", directory=self.gaia_path) + + def profile(self, env): + self.build._run_make(target="profile", directory=self.gaia_path, num_jobs=1, silent=False, append_env=env) + + def override_prefs(self, srcfile): + # Note that each time we call `make profile` in gaia, a fresh new pref file is created + # cat srcfile >> profile/user.js + with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs: + userJs.write(open(srcfile).read()) + +def process_package_overload(src, dst, version, app_buildid): + ensureParentDir(dst) + # First replace numeric version like '1.3' + # Then replace with 'slashed' version like '1_4' + # Finally set the full length addon version like 1.3.20131230 + defines = { + "NUM_VERSION": version, + "SLASH_VERSION": version.replace(".", "_"), + "FULL_VERSION": ("%s.%s" % (version, app_buildid)) + } + pp = Preprocessor(defines=defines) + pp.do_filter("substitution") + with open(dst, "w") as output: + with open(src, "r") as input: + pp.processFile(input=input, output=output) + +def add_dir_to_zip(zip, top, pathInZip, blacklist=()): + zf = ZipFile(zip, "a") + for dirpath, subdirs, files in os.walk(top): + dir_relpath = os.path.relpath(dirpath, top) + if dir_relpath.startswith(blacklist): + continue + zf.write(dirpath, os.path.join(pathInZip, dir_relpath)) + for filename in files: + relpath = os.path.join(dir_relpath, filename) + if relpath in blacklist: + continue + zf.write(os.path.join(dirpath, filename), + os.path.join(pathInZip, relpath)) + zf.close() + +def main(platform): + build = MozbuildObject.from_environment() + topsrcdir = build.topsrcdir + distdir = build.distdir + + srcdir = os.path.join(topsrcdir, "b2g", "simulator") + + app_buildid = open(os.path.join(build.topobjdir, "config", "buildid")).read().strip() + + # The simulator uses a shorter version string, + # it only keeps the major version digits A.B + # whereas MOZ_B2G_VERSION is A.B.C.D + b2g_version = build.config_environment.defines["MOZ_B2G_VERSION"].replace('"', '') + version = ".".join(str(n) for n in LooseVersion(b2g_version).version[0:2]) + + # Build a gaia profile specific to the simulator in order to: + # - disable the FTU + # - set custom prefs to enable devtools debugger server + # - set custom settings to disable lockscreen and screen timeout + # - only ship production apps + gaia_path = build.config_environment.substs["GAIADIR"] + builder = GaiaBuilder(build, gaia_path) + builder.clean() + env = { + "NOFTU": "1", + "GAIA_APP_TARGET": "production", + "SETTINGS_PATH": os.path.join(srcdir, "custom-settings.json") + } + builder.profile(env) + builder.override_prefs(os.path.join(srcdir, "custom-prefs.js")) + + # Substitute version strings in the package manifest overload file + manifest_overload = os.path.join(build.topobjdir, "b2g", "simulator", "package-overload.json") + process_package_overload(os.path.join(srcdir, "package-overload.json.in"), + manifest_overload, + version, + app_buildid) + + # Build the simulator addon xpi + xpi_name = XPI_NAME % {"version": version, "platform": platform} + xpi_path = os.path.join(distdir, xpi_name) + + update_path = "%s/%s" % (version, platform) + update_link = UPDATE_LINK % {"update_path": update_path, "xpi_name": xpi_name} + update_url = UPDATE_URL % {"update_path": update_path} + subprocess.check_call([ + build.virtualenv_manager.python_path, os.path.join(topsrcdir, "addon-sdk", "source", "bin", "cfx"), "xpi", \ + "--pkgdir", srcdir, \ + "--manifest-overload", manifest_overload, \ + "--strip-sdk", \ + "--update-link", update_link, \ + "--update-url", update_url, \ + "--static-args", "{\"label\": \"Firefox OS %s\"}" % version, \ + "--output-file", xpi_path \ + ]) + + # Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi + add_dir_to_zip(xpi_path, os.path.join(distdir, "b2g"), "b2g", ("gaia")) + # Then ship our own gaia profile + add_dir_to_zip(xpi_path, os.path.join(gaia_path, "profile"), "profile") + +if __name__ == '__main__': + if 2 != len(sys.argv): + print("""Usage: + python {0} MOZ_PKG_PLATFORM +""".format(sys.argv[0])) + sys.exit(1) + main(*sys.argv[1:]) + diff --git a/b2g/simulator/custom-prefs.js b/b2g/simulator/custom-prefs.js new file mode 100644 index 000000000000..c3b4cb6fb613 --- /dev/null +++ b/b2g/simulator/custom-prefs.js @@ -0,0 +1,2 @@ +user_pref("devtools.debugger.prompt-connection", false); +user_pref("devtools.debugger.forbid-certified-apps", false); diff --git a/b2g/simulator/custom-settings.json b/b2g/simulator/custom-settings.json new file mode 100644 index 000000000000..ea0264d9a50d --- /dev/null +++ b/b2g/simulator/custom-settings.json @@ -0,0 +1,6 @@ +{ + "debugger.remote-mode": "adb-devtools", + "screen.timeout": 0, + "lockscreen.enabled": false, + "lockscreen.locked": false +} diff --git a/b2g/simulator/icon.png b/b2g/simulator/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c4307fc8418436bb6b2fd3a6afc702c2db28aa77 GIT binary patch literal 4762 zcmV;L5@qd)P)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER000g#Nkl-k(>h5*rk*jGY3h=s;}LS}gf>m4rQ@{NxQSg49;C!L*x`|w zT469C%NXh+KmxsxSiN8S-uvu#7YS3_U>R%bwDq06v%B}+{r_{m?|kR`?_S0*4E%52 zn9m9PUnRiM2HY5%rZ9fv2@qUn*RFczwNMVXJ-8j)w?hMN0_W-*FS4y@)f#GRb(5Ph zOB2r`fo+^&G-w}p-TL|_zG+vrHd|S_YXWJB>@pbC0oCi9*zTfkzLd+cUB2A2Bx^z0 z%HZRvz7Xnm@_xS-e^@CrHggmW7hZrCCe0(TA(h-`7 z7fE_Lz`RA{Iw+up*|&Vn@?~dsFJluP=PC#`o3V^;oJh zST4`WLEy}v+$iFN0^?MlqBmcRB$e>Qg;QrjFXj9Aqp;gXC%VrktBZQ%U3GOP8e`T8 zOgl<#E!ek`uZ!MD!llc+pL5Lr*2F+pX*_zNz`f`}@7(eLZ;csj{! zgTZI{&T+5JBXS;C`8la!`))3fRqieGiy3Z7jCQMx%yHOJXUF0I3oFM!rQv(x27Wqb zpnXz@{gR4RdAi}1*yPazJxNv>eL-?^&xeO1qw`#)ELER!<8($$rf0v47CnCD|*cW_9MHw`9%-lTyG z*EPgDWNcm|>X)u3<9%%-9RVkH4n>vAF1s{ov5m&|ZV#%=tP`khWQ&Gl0+T3k8G3cIE9m_?bdH58YbYq^v35{Jwz3)Yq~=$_Cpu5-w6u^0^-=;~D@QAafosXrIk*U zSK9UAA$cO)AKB-!F#E@%T*xjbBeB+*%jk{-ZbqLvZ1A-$oE%6vl$h$~Y+{+rx^|0< zeSuxDN}7Z4$5}8$Age;a5dEe<$-?7jkQ~>bw8mj{$H1rxw3LjBH5L3d8F9JBwhQYqJQF z!Wxh}!qB1#z%Rlma6)%j({>^!b+DsR7{hcvCet+$%q`DF@ON^dS~zrFiY2eSalUoy zgL9u5A5FBJJ^yZ>BG}`t4YkUw5~ye_=e0nFGoDJiMXR_>QC#1ZG=ig zykvt);1dyA{O}wMjfKT-I*|r-cnnNp9BOI%QTEP_( zfeAp94Ok==fjLwg(Ky=Qz6Q1L666F~Y2kV-`U5|BKM)F~Qr7T9GgW}2;+>s z-FYyZ^jMF&x;lM!2%w(cM+Ju?$Hge{^053CYmw?Q{6U{h@(Zk+Cx4=K4`hUUx(M)P zssRnUJVpdUP}L!Df*(06z6@*rd<>jd;q-Etn;F55uSqD#^F)Utv7cU>5Pxp-_%44j zh&Gy(28A+fO9@ohbN+rwvRVa~#&H3GaeWWSTH`C6FR?xsYuGrz!a`4^5DQ(yWY0+? z2986E4}f=-K=5sbE3X`q&p~~{O(SwxoIim=oYgBAEnrtvEk#mMJ30npFLq7(fB0B6 zq8Bg1(%Ran)z;Q(pOS#N?K0nar!(S`W!7!8IaV>c@?D@B9lhG~}~?^Dmcw zK{XstzxuP*imt8}Qaukrte_}ogC$#KXnDb~v>RzhgGR;f^602qI*1HM7%Z#8OG~T8 zODb{i7pgIG>NI*oA;Y?Sxz^V5CjV#Kw}LF;-P0}q`B$s&x$o$wy`d4zqB4oJw)T1@ zN&9wtd*_bh$4^*}96gEQLDonren!(X2y}o5WP%m#1d^k^K+@q-w8V~}bWRwVWHMHf zfncG+S7a!15_yIBD6v@Zz~%?Q7Zu{)j~!Qsdsnh7BXd7*DFFu1)DM1sb%p7=IJeaE3ghs5K@k0Y5(Dg<0G0hnV< zgJBppEg7EYZW3bBfK3_k6lo@1*yg!ug66x0q+@Q1qQK>H(LKcytX^{u9f#I>p@SV6 z9%H(?JFf2E|MJ!=SFW_)mcSHvGZ5(xc;?KRM=~-po+>FRDL#4fBzErHsSXSba6X@p zF(=kE?Iws1zMEutp1(=t)^pRJ1yeqBjVT}V*usSiv3~t}WM^mV-Q7Lt?CfR-2m3KN zIM96R)T!?^H#h%^@Wnrpz!doOfg?wbEGsH1dO9yJuf~iBO`w@hIy5xIz4X$4G&D4( zQ|vdrX}7h}Db4E#4jg!-yuADc8jPcq8Z@z{swz*iq4c`bcG%Y5f<1fo;*DRPghjN# z?RH_h-`xuOqX?M5&1=o^NQPLqZXMRFSp!iNwab?;a|9ZcCO+ z-+I7pYoMW_;pD1StL`P~#3{Wt0-x5oBuSKR9fNfH7>`)t&jwC4zk)sg_#8Srdf;+9 z)7MO8^F!cG;O2K(mec2#E?tV6ni}Nf9MR|VPib1gi+iKk^R!OB9YMuX9*^(LM|p4%&pr2J{H*a1 z;)xhM9?wmAOp~DKrVG>rPh(>9=FPN34;m8_6Z+MwS2>daMZJ$Q@WR1^2lo?{cEYCK z4*2bAz_d&|dH$Z#($Yu$em|%VG%8@WprDX(IBa<8FB16sA6&(yL9PN8aTOIl4SBK zZO@I4j-Ht=(pzhCrmIo&Hyl}72~G5k{QUec(QYG0!2J0Oh{!xPFRzgKBZwr{=vRoA22iFU9e!mCerEGNu%p>b90cNUucw;78^^KEo3J~+<5Z{ zc`Yr}Hf+)0&*CsS8BaGThr^KuZ#FxMaysg(SFbjr(Wq_~sTpKn$&xHdrg_JrZx8W_fN~^7c}(Ho!n*C{@k4+ zl9nWW^p%yB{q~|oi?-+H=8~*(QBY8zFI-rLtgLK?oF;uO6|6yyLY=gmGc!OW`r6vs zOu0bB)RL^eN+gQSE=s#WE|VT?Y-}uDpcL^WkvMqx@Zo)= z`Du4yKC?$mAIOF@C9AIxiHFH@ou+M?o^N(oS`M5csqAfOX*u$7&FHguLUR)c5y_xF zv6dEL_mlhN5~(4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER000_ENklZZTvi zG~GP90WlB(LljA);*D938FbW`W!B9&cTH9%_s*ImYbMFi%&b{SoNF|}BmogdOi0DJ_%M*w^Tz()XF$pNJ0jFz@ZeDzZ2gU(&PoLFbqnhQGjKQ#c7L=w>| zg&Oh-wKT{9hkQOcQ)Su43^^KWjYrIS)6^B8p>lt~7)qw-K)NTtH`3_#GC5MP%V|5k zanLzk>`8e;OHl4|9Pp>S=j8B~k}Ir%vS z7QAs{Q~iwDQ)1PV>-}17L}3Agk<dT%F9h)}cNt`^wJ2gPDQki}9M^?@A?mAk~-8 zW+WvW@%f6>*5$PC-pxCgE#m@VewkM8k^y)p_|D}Lb+swfJ)#7IhLaL46jyTr>j(bEUY(zb1>3O|tAH=IfR zoP6e%T-F{K?dwakax`m9-e118?tZ6p83vZTS$t?9E*b!j-UxbWSDUn(cFRO@%}H@R zJ}x$amsw)CR8eHZxz4UQcli@-iCLd$brwwXNfTo-8y{qnrbwiD0FW1hgW)Uq&$c*E zmASk5P>HibQMPjB!iF7vzfo=V4MQ$(E!mYpmn-Q!CL>dMGSx4UNbQuo88$VCA# z7WhKCp81kRIYp$q4)@zdD{5KUaMR>jf5ovNU7KG_lWyK=CdSL*#x{3$ON2E?8Iv(g z#AI~!cuflGl3)-q=1rb#08nv=XYwxfjJSOBk)oRjx)e4PdU4aS%Fu9bZP1X`RIEy$ z!z#ma*&fYMrl?oNt%dZe+u6Cy3*u6M_&@;85R#>9SUa`LcJGKzlnmOc5#{AVjq0Px zv8Jp3wv^?*-ox8uN77WYZXy}=Rm^AV6fc%ZtJ9>L<^^a@vqlD3pyL2wRKZ7Q@n5pQ z>1dw#mSKnTDTi1p@75~hPMT=&7uR=7$v$n1-#7Y0+o2PcG9T1kK9Wus3u;q!<<`2{ zPG=`w5(pOofLMKEM`(gVVKSKC4B6ZtS2dO}0>0~%Vc(y#xWTj;5m`ZmL0MxVP(F1i zM=o=urt89V!$Lm=48kE%P?gBWM-O22_l~%s4G!^Qu4qGG9_Z^&ZIN7e(6RHwKEE%M zN~X$zPv-2^OP9LRMT+AE0B}-oz5E9N2jfF3Q^#Scl`7RyYiw@Sm_g$2D1}1Bp-cnxfZVYPaiJ`DUjWX@ z|J@`H5@`WRHyy54Gs#Kln%xkroAj;9u}UKa$&~{>nPNOd;A@>(sp})>$^dX`^^Y`x{zG}6!oop?yS29KBqBAT4hqKp zw4BOff~rCxl`#t|U*wYNQ^=?SAxNgy1fv_~nuL|4ox^3yYC2T~71C@@Ls<3QIaD-& zFqq?1-kaf);*yfd)76trUO%y#2N~oKXpW4Qjyk#G4+lq`?cB}}k>X1#R4!n;73%78 z#!BObrojgQFh+lpX7_HDj~A0#P>K6pE`^clwX#(n7jKMzsjTYP*t}vZnhac!-bip+ zlRGM z6NvIu;aEq_z0P#swomu*=lQ)W^?k(eVB^XU?cXjB!EvD!rc)?1>S4=G^ERK$Yj zu=>TGGO@Hpe53>s$dd*^Ff=p|g$gaXDaPe+kSa{)ewEySDZBgkW-8^r%(iH)`ileI zBiqUqt(S78jAIWL3DsaLssUX@HMl4M28ZHWKz2;m;!zb9KqlT0X&(ReLRp$b$+9au zss{j>DDp!nX(wvR5i(@Lz+fu36Zdq4$wi*=ME$Ao-wK?L_ z8nA#aj0GPIfOz|klLlxYIHCt!%~Z-%%@tmwD|~|4Q1{Iu^Z?`+Y6eUQ8qXvvnWV~a zN|Jy{5p0lA`+T7Qsk%ujFd|?C;YTxsxmNO2Di$E}IS(04!4J!(_Qp81v`*lo1&8|- ziCZuf2Y2q3!#dv+G_ywJMNoyg+fvR$zKJR?^BuMSduk7OfG~_g7e{UG+;TLAJPIgxNPAl;j>-WJ5V%9 z$!CdWlaNb7nS@QYDl~OQ9nH9^nGd9Gt|^Qc3bvgd>{Y9y<|esP`E@*~rMWKeU$=4B zt|mn*CVgPQ6#;+%K>KcaV4zWl@iAptjmoxD!xY{WN;G}7l2Ru)BNjKzpe)CH%(lu> zZYW8X#K>>@C2ej!4IRr=<=U3)s}z47G?Yz|ppuS7{pmg3=}oV0c`JEKq}g6o_dEbt z_Td3Iy9~}=J5KJagRmFkK3U>bHVf1;w^SRfsrnq(!b_www=~QMZ2%LOI{AVmBSm!9Ls}RB!azqcAuLfoo2P%<(@*|+ZZ3r0w%POUloB|f7MKcwuOOyyWQ+jl$dnoHZDp%FN9SZqfRkI4uJ^Y(j z*LW4+vi1V+c7sIYK*T;3CEYLS6y{8+#UyKWJ@LP|qb^{Y-%|CMVwlyETCD*doj62} zhh>0Jp@AJcsW{S4@H12u2*`ePM&(?A3fT;R$&%_vn;D4E__7}cVA zn$nD+^A_a?y7~3jPUMMdKNh4!sgdluW98uEfk><%+3s7#uCBff8@k=q7r3!{(fa`{ zxqd}#hWLsULScvjgoL4ou2uq7UnPZfSuvTOsFhg|J+F>7NKu3uNn#iWD=(KvnOqoP znN&YzP8>w3JPNmHpuq@JV*2&O%os%zaSDfZZ`4pgMT$T#c$sPg67}rbLc_=Q(GAzl zb?42wiW#~>L&JmV!BOkU5vAdmYkQOpUvJ*Zo`3#%XW6o4?q%5#I+F#xGS$_oL8%P6 z*Q;EM)yRrFE*Po*yj4(cwyjD<4b&>WKqJ#4I#a3)5@P79QdlIa$ZANT^l+Ziy(zM# zEd0L(Z{Q;cC}}}IK|kOF6mqi#q=HOgjZqvrP*bhZgg7G|sZ%Kq)6N}#plBq>I~IS+ zjmKiLnBu|1C-(IZW&ZB2o7;ab;@Y}(t1^4`Z2P_UgD)C@F)g@5s66->goeB5?W8Cp zwFcF@0aN^&GPx6Rwk1nVN>FJ85e!x{DJX}V{SvZ((8VGDIl3x*q$(5#%`Y)b)E-kFwE3dqwEL^zI{*ZfuX9;4rl_y6sJ`SVwu3PD-Ee7SpeT3pnw@HrsB9L4N{Zg4du`vQqvt{l-Lp|+N~#&1lU z(o};OrF};-lw~IAbrDhw1f|0*;}AmVeJ1moLV&`(T_SLqGxEly1G1jJ0bI;kn{pxF9z7?$0gymfx(p=64&9)5hPX zXcW1u$U4kV4QVV&KGjdYY9DN~iWSE6Wyu49mh0V7vMMDipnsUsHkCd$emv>0(R2RjHuwgae*4mIXM(-kumB^PFaHFXRzBM>Fs6?YtNlZ+9tjJB#>0ycSyGE)}BesK~1yR!E2;M6o z+l$EmGSVRjVJmv`Lh5^|!Qi(=u*?gZow}LAPQDHeVaOc?0xJf~WwR7ZBxv#Cn{X_m zl@F!p$NyNQ>pDX8m2a37jt}#_dk#sCV~@P~=9|;M_O-9|UN8Ws=pqn9e=C`rHf{RW zq)C&$HZU+CJ@CK-&hLN!dkTd@vfuAVcY9J~$0j{CS?RRb-VNl;-%p+^pL|WCcVA=Y zJOAB7f!7eOvs5ZkeSJNB<$wPfg@Ot65ji^AbCix9O>z^RDZIhxgAYD9f8V}+dp{6> zv*`{X?wvPp-nWCnVEw}nKTNAvuNG>mAb2nEvB`;_X9woJ<^?F7dVVtR-w8@$rvjDE z8|3N7+2<%QPmbf@u&K3mGTn2}=kU8l2M%<5=a$O_`|Y=PD$s!Bx^?Sr01$f-yY-#` z2$hFmC}V;D;0HgLK6mci2XT0G@9gZf(&@AaToQweflpm`&IHfD+Uz`Fy?>x*zo&|o zM+}8R0S2{>uwc~I)<%a9AEtCVBT|I#*|Wzza^#3yTU$%Ly}c{G{q1jmXa4;8BVcav z8~{$IJ1#J>%AE}j4S(6x)Pyma^TZQR(D%OgJ-J*ilj+rAdWZJ(0W?2fFqZ;i=G%sd~XyAZnDZ@-;p&YVfdj~}O0DkZMt5H}YA%cw>|5Vt?| z)KgDjej73D2{1bYhL=v?EARjqGX;-5_So$(GtXRm?X^-io3)|p5`vOX?yqr=Zk0;K zqnxU02v~&|FA}b!#~=THG&(vWssWuWgZz?M@Ls=<(Om>?7zQm_vV?BD@ka0Y(W6Jl z=nnI>la0~+jW^zS3La%GrhX6%N#eBv(%Ct0GXz!i@5f`tj2ZP4CQK+JSUnbtc`FJQ zc)^Q-M5*&`>`UnA6p{O?xBqthL=Qdm;E(9V-~8H}v|z*-aOVs3y}&t}?n2}Q=wc3Y z=FFix?zn@*>K;6J@C>@+r-U>pBmdV!qn;Ka!J`bv-TJ_G_={is;sl`j77&h1 znKFfs8#himJ+B3_g5qL7Pt_zeaSm;IwM;#ST=;UCZoD<%?R{+A_%ck<3fi}Cx5oyt zVyCCYg#<2sionHnqT9oQ5Ij5~H9fi~lSy$7-@A7&2i;k$IwpYF{=}0{{H&|1>lK94 zd*6Ncje?ow3%)S|V>9E`I^S)_|X!5_5L)y z{*oUpZU7u8QFAM!Fa5QT?)-wVJVjdhPmj~j9{(4l#i*wjr>DjHfgsKkKZWoLwu!QK zD>^P=a1gBbeqUdoyKC1jc4|@jQO?$!qWgZN$4DR$$iEle&kFzs*P5G~rz~E)_(iPP zI0&Ex>IiNVXhZ@CF_}`)A_E=SBM*$wUwqxAwwOfG@xP?1#4al34eCF*nA)c;puc}a zq1I_KYH<&(T=`>q>7|#v0LRkeY|k)uh*cNmRZt!}MEBl%FI87pd+IJ;J6qk6|LY%m z=pmu*+fk~AYi_B@ZdrMLx}O&S2%mw{5QVq@p8%p0=rb_Dg&qj%GcmELQ>Ws*W~>0C z{@wx@VAF;d4$!O{ze?7UQE0XHaImkH8STeYVdfP z-rgo|dr@)-UE=p_di}TJhNeT)KW5XP{gs9kkU(4V?g9xQg@$0VUSN+t`Y3JKu)$Mt zvHA-ZETAuZ;R}S%hj%}4j=F>HWmwyF=s1PCZ%0}V-hA`TId~R}KIG#ZD~zBuP%Q`_ z5Xa;`4q^Np^q>PloRbzUlcvzrX%oFYQkR!W+ze7x#oIEoZRTxWWHMPVAVGWa5S2u% zEILX;t@fN88Z3|Q!^6Yxn3*xUL;T(Xa~_AfzkEvF(-)%dAL_5f1RJ2d#@e-O#qPp* z;R=x!_h9mEg03PhV3EaExfBXTsJ(qU)z-#Iu%lG6Pg&Ixg3ox=7FKyo=mZ-?We|;v zcnC&_;Kh4m>MjHqV-0}rPl4{wIu8d9z51DewuOg+|;y zmKLy~4%p!(azjI-S1keo)3eJWcoC!sObDDfMDXGv*dY1|QPYJG;&pe&jveoq8I1V? z)cxl;bsNS@;{5FUnVBp8x5B5TMFRAleb-%g-HpI+5@~__bcG)mX(3h~6ZUdhFhv-l zQ~iXO27>+q1ktJrXDR3oCHLqq${pU@_A@+?0>2a9{c_X&!`>HQ2-F8f7PojC5$Ixc zj(0-~rioxszPz+Rz!JbAbX{I52(1txh;cx1FVDs6=*t~=cW)O7=k!Alo&nu|dCJU; zepq$CVt*}uT3ST$bTZQ7HfY2hSmA2%{?%7s?VwYWMc^X$#m|#FGGz}0)cVuCdj%Ts zYpDBExO4~1%+M{j+>*T<>VCz)FK|}1xCYhYE;LVz5tuB}0&L)*H52)MD$hC2=R-q7 zvhV;nZ;LQ9d-m*kj1$9Sc52cZ~o*bKM_sKcKC^5 zyqCLD>i!?{r7865YIk?HAC_8lJ+%n19_bJO8_LN2enE8{=`Vlz%lQ>6R#fP8n>F*RNkM(aCSdP)kdTi`92fIh^;qU;keofd6Wb|Mmd { + this.shuttingDown = false; + deferred.resolve(exitCode); + }); + if (!this.shuttingDown) { + this.shuttingDown = true; + emit(this, "kill", null); + this.process.kill(); + } + return deferred.promise; + } else { + return Promise.resolve(undefined); + } + }, + + // compute current b2g filename + get b2gFilename() { + return this._executable ? this._executableFilename : "B2G"; + }, + + // compute current b2g file handle + get b2gExecutable() { + if (this._executable) return this._executable; + + let bin = URL.toFilename(BIN_URL); + let executables = { + WINNT: "b2g-bin.exe", + Darwin: "Contents/MacOS/b2g-bin", + Linux: "b2g-bin", + }; + + console.log("bin url: "+bin+"/"+executables[Runtime.OS]); + let path = bin + "/" + executables[Runtime.OS]; + + let executable = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + executable.initWithPath(path); + + if (!executable.exists()) { + // B2G binaries not found + throw Error("b2g-desktop Executable not found."); + } + + this._executable = executable; + this._executableFilename = "b2g-bin"; + + return executable; + }, + + // compute b2g CLI arguments + get b2gArguments() { + let args = []; + + let profile = URL.toFilename(PROFILE_URL); + args.push("-profile", profile); + Cu.reportError(profile); + + // NOTE: push dbgport option on the b2g-desktop commandline + args.push("-dbgport", "" + this.remoteDebuggerPort); + + // Ignore eventual zombie instances of b2g that are left over + args.push("-no-remote"); + + return args; + }, +}); + diff --git a/b2g/simulator/package-overload.json.in b/b2g/simulator/package-overload.json.in new file mode 100644 index 000000000000..b107ba98c3f2 --- /dev/null +++ b/b2g/simulator/package-overload.json.in @@ -0,0 +1,7 @@ +{ + "id": "fxos_@SLASH_VERSION@_simulator@mozilla.org", + "name": "fxos_@SLASH_VERSION@_simulator", + "version": "@FULL_VERSION@", + "fullName": "Firefox OS @NUM_VERSION@ Simulator", + "description": "a Firefox OS @NUM_VERSION@ simulator" +} diff --git a/b2g/simulator/package.json b/b2g/simulator/package.json new file mode 100644 index 000000000000..c2893e4cd4c3 --- /dev/null +++ b/b2g/simulator/package.json @@ -0,0 +1,37 @@ +{ + "id": "fxos_simulator@mozilla.org", + "name": "fxos_simulator", + "version": "1.0.dev", + "fullName": "Firefox OS Simulator", + "label": "Firefox OS", + "description": "a Firefox OS simulator", + "author": "Myk Melez (https://github.com/mykmelez)", + "contributors": [ + "Alexandre Poirot (https://github.com/ochameau)", + "Anant Narayanan (https://github.com/anantn)", + "Brandon Kase (https://github.com/bkase)", + "Breck Yunits (https://github.com/breck7)", + "César Carruitero (https://github.com/ccarruitero)", + "David Gomes (https://github.com/davidgomes)", + "Fabrice Desré (https://github.com/fabricedesre)", + "Fraser Tweedale (https://github.com/frasertweedale)", + "Harald Kirschner (https://github.com/digitarald)", + "Jérémie Patonnier (https://github.com/JeremiePat)", + "J. Ryan Stinnett (https://github.com/jryans)", + "Kan-Ru Chen (陳侃如) (https://github.com/kanru)", + "Louis Stowasser (https://github.com/louisstow)", + "Luca Greco (https://github.com/rpl)", + "Matthew Claypotch (https://github.com/potch)", + "Matthew Riley MacPherson (https://github.com/tofumatt)", + "Nick Desaulniers (https://github.com/nickdesaulniers)", + "Soumen Ganguly (https://github.com/SoumenG)", + "Sudheesh Singanamalla (https://github.com/sudheesh001)", + "Victor Bjelkholm (https://github.com/VictorBjelkholm)" + ], + "permissions": { + "private-browsing": true + }, + "license": "MPL 2.0", + "unpack": true, + "dependencies": ["subprocess"] +} diff --git a/b2g/simulator/packages/subprocess/README.md b/b2g/simulator/packages/subprocess/README.md new file mode 100644 index 000000000000..7f13df6f9f28 --- /dev/null +++ b/b2g/simulator/packages/subprocess/README.md @@ -0,0 +1,124 @@ +

What's that?

+Simply package enigmail hard work on providing IPC feature in mozilla platform. +So we are able to launch child proccesses from javascript, +and in our case, from addon-sdk libraries :) + +

Sample of code:

+ This object allows to start a process, and read/write data to/from it + using stdin/stdout/stderr streams. + Usage example: + + const subprocess = require("subprocess"); + var p = subprocess.call({ + command: '/bin/foo', + arguments: ['-v', 'foo'], + environment: [ "XYZ=abc", "MYVAR=def" ], + charset: 'UTF-8', + workdir: '/home/foo', + //stdin: "some value to write to stdin\nfoobar", + stdin: function(stdin) { + stdin.write("some value to write to stdin\nfoobar"); + stdin.close(); + }, + stdout: function(data) { + dump("got data on stdout:" + data + "\n"); + }, + stderr: function(data) { + dump("got data on stderr:" + data + "\n"); + }, + done: function(result) { + dump("process terminated with " + result.exitCode + "\n"); + }, + mergeStderr: false + }); + p.wait(); // wait for the subprocess to terminate + // this will block the main thread, + // only do if you can wait that long + + + Description of parameters: + -------------------------- + Apart from , all arguments are optional. + + command: either a |nsIFile| object pointing to an executable file or a + String containing the platform-dependent path to an executable + file. + + arguments: optional string array containing the arguments to the command. + + environment: optional string array containing environment variables to pass + to the command. The array elements must have the form + "VAR=data". Please note that if environment is defined, it + replaces any existing environment variables for the subprocess. + + charset: Output is decoded with given charset and a string is returned. + If charset is undefined, "UTF-8" is used as default. + To get binary data, set this to null and the returned string + is not decoded in any way. + + workdir: optional; String containing the platform-dependent path to a + directory to become the current working directory of the subprocess. + + stdin: optional input data for the process to be passed on standard + input. stdin can either be a string or a function. + A |string| gets written to stdin and stdin gets closed; + A |function| gets passed an object with write and close function. + Please note that the write() function will return almost immediately; + data is always written asynchronously on a separate thread. + + stdout: an optional function that can receive output data from the + process. The stdout-function is called asynchronously; it can be + called mutliple times during the execution of a process. + At a minimum at each occurance of \n or \r. + Please note that null-characters might need to be escaped + with something like 'data.replace(/\0/g, "\\0");'. + + stderr: an optional function that can receive stderr data from the + process. The stderr-function is called asynchronously; it can be + called mutliple times during the execution of a process. Please + note that null-characters might need to be escaped with + something like 'data.replace(/\0/g, "\\0");'. + (on windows it only gets called once right now) + + done: optional function that is called when the process has terminated. + The exit code from the process available via result.exitCode. If + stdout is not defined, then the output from stdout is available + via result.stdout. stderr data is in result.stderr + + mergeStderr: optional boolean value. If true, stderr is merged with stdout; + no data will be provided to stderr. + + + Description of object returned by subprocess.call(...) + ------------------------------------------------------ + The object returned by subprocess.call offers a few methods that can be + executed: + + wait(): waits for the subprocess to terminate. It is not required to use + wait; done will be called in any case when the subprocess terminated. + + kill(hardKill): kill the subprocess. Any open pipes will be closed and + done will be called. + hardKill [ignored on Windows]: + - false: signal the process terminate (SIGTERM) + - true: kill the process (SIGKILL) + + + Other methods in subprocess + --------------------------- + + registerDebugHandler(functionRef): register a handler that is called to get + debugging information + registerLogHandler(functionRef): register a handler that is called to get error + messages + + example: + subprocess.registerLogHandler( function(s) { dump(s); } ); + + +

Credits:

+All enigmail team working on IPC component. + The Initial Developer of this code is Jan Gerber. + Portions created by Jan Gerber , + Patrick Brunschwig (author of almost all code) , + Ramalingam Saravanan (from enigmail team) diff --git a/b2g/simulator/packages/subprocess/lib/subprocess.js b/b2g/simulator/packages/subprocess/lib/subprocess.js new file mode 100644 index 000000000000..0f88a860bd81 --- /dev/null +++ b/b2g/simulator/packages/subprocess/lib/subprocess.js @@ -0,0 +1,1543 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +'use strict'; + +const { Cc, Ci, Cu, ChromeWorker } = require("chrome"); + +Cu.import("resource://gre/modules/ctypes.jsm"); + +const NS_LOCAL_FILE = "@mozilla.org/file/local;1"; + +const Runtime = require("sdk/system/runtime"); +const Environment = require("sdk/system/environment").env; +const DEFAULT_ENVIRONMENT = []; +if (Runtime.OS == "Linux" && "DISPLAY" in Environment) { + DEFAULT_ENVIRONMENT.push("DISPLAY=" + Environment.DISPLAY); +} + +/* +Fake require statements to ensure worker scripts are packaged: +require("subprocess_worker_win.js"); +require("subprocess_worker_unix.js"); +*/ +const URL_PREFIX = module.uri.replace(/subprocess\.js/, ""); +const WORKER_URL_WIN = URL_PREFIX + "subprocess_worker_win.js"; +const WORKER_URL_UNIX = URL_PREFIX + "subprocess_worker_unix.js"; + +//Windows API definitions +if (ctypes.size_t.size == 8) { + var WinABI = ctypes.default_abi; +} else { + var WinABI = ctypes.winapi_abi; +} +const WORD = ctypes.uint16_t; +const DWORD = ctypes.uint32_t; +const LPDWORD = DWORD.ptr; + +const UINT = ctypes.unsigned_int; +const BOOL = ctypes.bool; +const HANDLE = ctypes.size_t; +const HWND = HANDLE; +const HMODULE = HANDLE; +const WPARAM = ctypes.size_t; +const LPARAM = ctypes.size_t; +const LRESULT = ctypes.size_t; +const ULONG_PTR = ctypes.uintptr_t; +const PVOID = ctypes.voidptr_t; +const LPVOID = PVOID; +const LPCTSTR = ctypes.jschar.ptr; +const LPCWSTR = ctypes.jschar.ptr; +const LPTSTR = ctypes.jschar.ptr; +const LPSTR = ctypes.char.ptr; +const LPCSTR = ctypes.char.ptr; +const LPBYTE = ctypes.char.ptr; + +const CREATE_NEW_CONSOLE = 0x00000010; +const CREATE_NO_WINDOW = 0x08000000; +const CREATE_UNICODE_ENVIRONMENT = 0x00000400; +const STARTF_USESHOWWINDOW = 0x00000001; +const STARTF_USESTDHANDLES = 0x00000100; +const SW_HIDE = 0; +const DUPLICATE_SAME_ACCESS = 0x00000002; +const STILL_ACTIVE = 259; +const INFINITE = DWORD(0xFFFFFFFF); +const WAIT_TIMEOUT = 0x00000102; + +/* +typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; +*/ +const SECURITY_ATTRIBUTES = new ctypes.StructType("SECURITY_ATTRIBUTES", [ + {"nLength": DWORD}, + {"lpSecurityDescriptor": LPVOID}, + {"bInheritHandle": BOOL}, +]); + +/* +typedef struct _STARTUPINFO { + DWORD cb; + LPTSTR lpReserved; + LPTSTR lpDesktop; + LPTSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} STARTUPINFO, *LPSTARTUPINFO; +*/ +const STARTUPINFO = new ctypes.StructType("STARTUPINFO", [ + {"cb": DWORD}, + {"lpReserved": LPTSTR}, + {"lpDesktop": LPTSTR}, + {"lpTitle": LPTSTR}, + {"dwX": DWORD}, + {"dwY": DWORD}, + {"dwXSize": DWORD}, + {"dwYSize": DWORD}, + {"dwXCountChars": DWORD}, + {"dwYCountChars": DWORD}, + {"dwFillAttribute": DWORD}, + {"dwFlags": DWORD}, + {"wShowWindow": WORD}, + {"cbReserved2": WORD}, + {"lpReserved2": LPBYTE}, + {"hStdInput": HANDLE}, + {"hStdOutput": HANDLE}, + {"hStdError": HANDLE}, +]); + +/* +typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; +} PROCESS_INFORMATION, *LPPROCESS_INFORMATION; +*/ +const PROCESS_INFORMATION = new ctypes.StructType("PROCESS_INFORMATION", [ + {"hProcess": HANDLE}, + {"hThread": HANDLE}, + {"dwProcessId": DWORD}, + {"dwThreadId": DWORD}, +]); + +/* +typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + }; + PVOID Pointer; + }; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; +*/ +const OVERLAPPED = new ctypes.StructType("OVERLAPPED"); + +//UNIX definitions +const pid_t = ctypes.int32_t; +const WNOHANG = 1; +const F_GETFD = 1; +const F_SETFL = 4; + +const LIBNAME = 0; +const O_NONBLOCK = 1; +const RLIM_T = 2; +const RLIMIT_NOFILE = 3; + +function getPlatformValue(valueType) { + + if (! gXulRuntime) + gXulRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); + + const platformDefaults = { + // Windows API: + 'winnt': [ 'kernel32.dll' ], + + // Unix API: + // library name O_NONBLOCK RLIM_T RLIMIT_NOFILE + 'darwin': [ 'libc.dylib', 0x04 , ctypes.uint64_t , 8 ], + 'linux': [ 'libc.so.6', 2024 , ctypes.unsigned_long, 7 ], + 'freebsd': [ 'libc.so.7', 0x04 , ctypes.int64_t , 8 ], + 'openbsd': [ 'libc.so.61.0', 0x04 , ctypes.int64_t , 8 ], + 'sunos': [ 'libc.so', 0x80 , ctypes.unsigned_long, 5 ] + } + + return platformDefaults[gXulRuntime.OS.toLowerCase()][valueType]; +} + + +var gDebugFunc = null, + gLogFunc = null, + gXulRuntime = null; + +function LogError(s) { + if (gLogFunc) + gLogFunc(s); + else + dump(s); +} + +function debugLog(s) { + if (gDebugFunc) + gDebugFunc(s); +} + +function setTimeout(callback, timeout) { + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback(callback, timeout, Ci.nsITimer.TYPE_ONE_SHOT); +}; + +function getBytes(data) { + var string = ''; + data.forEach(function(x) { string += String.fromCharCode(x < 0 ? x + 256 : x) }); + return string; +} + +function readString(data, length, charset) { + var string = '', bytes = []; + for(var i = 0;i < length; i++) { + if(data[i] == 0 && charset !== null) // stop on NULL character for non-binary data + break + bytes.push(data[i]); + } + if (!bytes || bytes.length == 0) + return string; + if(charset === null) { + return bytes; + } + return convertBytes(bytes, charset); +} + +function convertBytes(bytes, charset) { + var string = ''; + charset = charset || 'UTF-8'; + var unicodeConv = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .getService(Ci.nsIScriptableUnicodeConverter); + try { + unicodeConv.charset = charset; + string = unicodeConv.convertFromByteArray(bytes, bytes.length); + } catch (ex) { + LogError("String conversion failed: "+ex.toString()+"\n") + string = ''; + } + string += unicodeConv.Finish(); + return string; +} + + +// temporary solution for removal of nsILocalFile +function getLocalFileApi() { + if ("nsILocalFile" in Ci) { + return Ci.nsILocalFile; + } + else + return Ci.nsIFile; +} + +function getCommandStr(command) { + let commandStr = null; + if (typeof(command) == "string") { + let file = Cc[NS_LOCAL_FILE].createInstance(getLocalFileApi()); + file.initWithPath(command); + if (! (file.isExecutable() && file.isFile())) + throw("File '"+command+"' is not an executable file"); + commandStr = command; + } + else { + if (! (command.isExecutable() && command.isFile())) + throw("File '"+command.path+"' is not an executable file"); + commandStr = command.path; + } + + return commandStr; +} + +function getWorkDir(workdir) { + let workdirStr = null; + if (typeof(workdir) == "string") { + let file = Cc[NS_LOCAL_FILE].createInstance(getLocalFileApi()); + file.initWithPath(workdir); + if (! (file.isDirectory())) + throw("Directory '"+workdir+"' does not exist"); + workdirStr = workdir; + } + else if (workdir) { + if (! workdir.isDirectory()) + throw("Directory '"+workdir.path+"' does not exist"); + workdirStr = workdir.path; + } + return workdirStr; +} + + +var subprocess = { + call: function(options) { + options.mergeStderr = options.mergeStderr || false; + options.workdir = options.workdir || null; + options.environment = options.environment || DEFAULT_ENVIRONMENT; + if (options.arguments) { + var args = options.arguments; + options.arguments = []; + args.forEach(function(argument) { + options.arguments.push(argument); + }); + } else { + options.arguments = []; + } + + options.libc = getPlatformValue(LIBNAME); + + if (gXulRuntime.OS.substring(0, 3) == "WIN") { + return subprocess_win32(options); + } else { + return subprocess_unix(options); + } + + }, + registerDebugHandler: function(func) { + gDebugFunc = func; + }, + registerLogHandler: function(func) { + gLogFunc = func; + } +}; + + + +function subprocess_win32(options) { + var kernel32dll = ctypes.open(options.libc), + hChildProcess, + active = true, + done = false, + exitCode = -1, + child = {}, + stdinWorker = null, + stdoutWorker = null, + stderrWorker = null, + pendingWriteCount = 0, + readers = options.mergeStderr ? 1 : 2, + stdinOpenState = 2, + error = '', + output = ''; + + // stdin pipe states + const OPEN = 2; + const CLOSEABLE = 1; + const CLOSED = 0; + + //api declarations + /* + BOOL WINAPI CloseHandle( + __in HANDLE hObject + ); + */ + var CloseHandle = kernel32dll.declare("CloseHandle", + WinABI, + BOOL, + HANDLE + ); + + /* + BOOL WINAPI CreateProcess( + __in_opt LPCTSTR lpApplicationName, + __inout_opt LPTSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, + __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, + __in_opt LPVOID lpEnvironment, + __in_opt LPCTSTR lpCurrentDirectory, + __in LPSTARTUPINFO lpStartupInfo, + __out LPPROCESS_INFORMATION lpProcessInformation + ); + */ + var CreateProcessW = kernel32dll.declare("CreateProcessW", + WinABI, + BOOL, + LPCTSTR, + LPTSTR, + SECURITY_ATTRIBUTES.ptr, + SECURITY_ATTRIBUTES.ptr, + BOOL, + DWORD, + LPVOID, + LPCTSTR, + STARTUPINFO.ptr, + PROCESS_INFORMATION.ptr + ); + +// /* +// BOOL WINAPI ReadFile( +// __in HANDLE hFile, +// __out LPVOID ReadFileBuffer, +// __in DWORD nNumberOfBytesToRead, +// __out_opt LPDWORD lpNumberOfBytesRead, +// __inout_opt LPOVERLAPPED lpOverlapped +// ); +// */ +// var ReadFileBufferSize = 1024, +// ReadFileBuffer = ctypes.char.array(ReadFileBufferSize), +// ReadFile = kernel32dll.declare("ReadFile", +// WinABI, +// BOOL, +// HANDLE, +// ReadFileBuffer, +// DWORD, +// LPDWORD, +// OVERLAPPED.ptr +// ); +// +// /* +// BOOL WINAPI PeekNamedPipe( +// __in HANDLE hNamedPipe, +// __out_opt LPVOID lpBuffer, +// __in DWORD nBufferSize, +// __out_opt LPDWORD lpBytesRead, +// __out_opt LPDWORD lpTotalBytesAvail, +// __out_opt LPDWORD lpBytesLeftThisMessage +// ); +// */ +// var PeekNamedPipe = kernel32dll.declare("PeekNamedPipe", +// WinABI, +// BOOL, +// HANDLE, +// ReadFileBuffer, +// DWORD, +// LPDWORD, +// LPDWORD, +// LPDWORD +// ); +// +// /* +// BOOL WINAPI WriteFile( +// __in HANDLE hFile, +// __in LPCVOID lpBuffer, +// __in DWORD nNumberOfBytesToWrite, +// __out_opt LPDWORD lpNumberOfBytesWritten, +// __inout_opt LPOVERLAPPED lpOverlapped +// ); +// */ +// var WriteFile = kernel32dll.declare("WriteFile", +// WinABI, +// BOOL, +// HANDLE, +// ctypes.char.ptr, +// DWORD, +// LPDWORD, +// OVERLAPPED.ptr +// ); + + /* + BOOL WINAPI CreatePipe( + __out PHANDLE hReadPipe, + __out PHANDLE hWritePipe, + __in_opt LPSECURITY_ATTRIBUTES lpPipeAttributes, + __in DWORD nSize + ); + */ + var CreatePipe = kernel32dll.declare("CreatePipe", + WinABI, + BOOL, + HANDLE.ptr, + HANDLE.ptr, + SECURITY_ATTRIBUTES.ptr, + DWORD + ); + + /* + HANDLE WINAPI GetCurrentProcess(void); + */ + var GetCurrentProcess = kernel32dll.declare("GetCurrentProcess", + WinABI, + HANDLE + ); + + /* + DWORD WINAPI GetLastError(void); + */ + var GetLastError = kernel32dll.declare("GetLastError", + WinABI, + DWORD + ); + + /* + BOOL WINAPI DuplicateHandle( + __in HANDLE hSourceProcessHandle, + __in HANDLE hSourceHandle, + __in HANDLE hTargetProcessHandle, + __out LPHANDLE lpTargetHandle, + __in DWORD dwDesiredAccess, + __in BOOL bInheritHandle, + __in DWORD dwOptions + ); + */ + var DuplicateHandle = kernel32dll.declare("DuplicateHandle", + WinABI, + BOOL, + HANDLE, + HANDLE, + HANDLE, + HANDLE.ptr, + DWORD, + BOOL, + DWORD + ); + + + /* + BOOL WINAPI GetExitCodeProcess( + __in HANDLE hProcess, + __out LPDWORD lpExitCode + ); + */ + var GetExitCodeProcess = kernel32dll.declare("GetExitCodeProcess", + WinABI, + BOOL, + HANDLE, + LPDWORD + ); + + /* + DWORD WINAPI WaitForSingleObject( + __in HANDLE hHandle, + __in DWORD dwMilliseconds + ); + */ + var WaitForSingleObject = kernel32dll.declare("WaitForSingleObject", + WinABI, + DWORD, + HANDLE, + DWORD + ); + + /* + BOOL WINAPI TerminateProcess( + __in HANDLE hProcess, + __in UINT uExitCode + ); + */ + var TerminateProcess = kernel32dll.declare("TerminateProcess", + WinABI, + BOOL, + HANDLE, + UINT + ); + + //functions + function popen(command, workdir, args, environment, child) { + //escape arguments + args.unshift(command); + for (var i = 0; i < args.length; i++) { + if (typeof args[i] != "string") { args[i] = args[i].toString(); } + /* quote arguments with spaces */ + if (args[i].match(/\s/)) { + args[i] = "\"" + args[i] + "\""; + } + /* If backslash is followed by a quote, double it */ + args[i] = args[i].replace(/\\\"/g, "\\\\\""); + } + command = args.join(' '); + + environment = environment || []; + if(environment.length) { + //An environment block consists of + //a null-terminated block of null-terminated strings. + //Using CREATE_UNICODE_ENVIRONMENT so needs to be jschar + environment = ctypes.jschar.array()(environment.join('\0') + '\0'); + } else { + environment = null; + } + + var hOutputReadTmp = new HANDLE(), + hOutputRead = new HANDLE(), + hOutputWrite = new HANDLE(); + + var hErrorRead = new HANDLE(), + hErrorReadTmp = new HANDLE(), + hErrorWrite = new HANDLE(); + + var hInputRead = new HANDLE(), + hInputWriteTmp = new HANDLE(), + hInputWrite = new HANDLE(); + + // Set up the security attributes struct. + var sa = new SECURITY_ATTRIBUTES(); + sa.nLength = SECURITY_ATTRIBUTES.size; + sa.lpSecurityDescriptor = null; + sa.bInheritHandle = true; + + // Create output pipe. + + if(!CreatePipe(hOutputReadTmp.address(), hOutputWrite.address(), sa.address(), 0)) + LogError('CreatePipe hOutputReadTmp failed'); + + if(options.mergeStderr) { + // Create a duplicate of the output write handle for the std error + // write handle. This is necessary in case the child application + // closes one of its std output handles. + if (!DuplicateHandle(GetCurrentProcess(), hOutputWrite, + GetCurrentProcess(), hErrorWrite.address(), 0, + true, DUPLICATE_SAME_ACCESS)) + LogError("DuplicateHandle hOutputWrite failed"); + } else { + // Create error pipe. + if(!CreatePipe(hErrorReadTmp.address(), hErrorWrite.address(), sa.address(), 0)) + LogError('CreatePipe hErrorReadTmp failed'); + } + + // Create input pipe. + if (!CreatePipe(hInputRead.address(),hInputWriteTmp.address(),sa.address(), 0)) + LogError("CreatePipe hInputRead failed"); + + // Create new output/error read handle and the input write handles. Set + // the Properties to FALSE. Otherwise, the child inherits the + // properties and, as a result, non-closeable handles to the pipes + // are created. + if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, + GetCurrentProcess(), + hOutputRead.address(), // Address of new handle. + 0, false, // Make it uninheritable. + DUPLICATE_SAME_ACCESS)) + LogError("DupliateHandle hOutputReadTmp failed"); + + if(!options.mergeStderr) { + if (!DuplicateHandle(GetCurrentProcess(), hErrorReadTmp, + GetCurrentProcess(), + hErrorRead.address(), // Address of new handle. + 0, false, // Make it uninheritable. + DUPLICATE_SAME_ACCESS)) + LogError("DupliateHandle hErrorReadTmp failed"); + } + if (!DuplicateHandle(GetCurrentProcess(), hInputWriteTmp, + GetCurrentProcess(), + hInputWrite.address(), // Address of new handle. + 0, false, // Make it uninheritable. + DUPLICATE_SAME_ACCESS)) + LogError("DupliateHandle hInputWriteTmp failed"); + + // Close inheritable copies of the handles. + if (!CloseHandle(hOutputReadTmp)) LogError("CloseHandle hOutputReadTmp failed"); + if(!options.mergeStderr) + if (!CloseHandle(hErrorReadTmp)) LogError("CloseHandle hErrorReadTmp failed"); + if (!CloseHandle(hInputWriteTmp)) LogError("CloseHandle failed"); + + var pi = new PROCESS_INFORMATION(); + var si = new STARTUPINFO(); + + si.cb = STARTUPINFO.size; + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = hInputRead; + si.hStdOutput = hOutputWrite; + si.hStdError = hErrorWrite; + + // Launch the process + if(!CreateProcessW(null, // executable name + command, // command buffer + null, // process security attribute + null, // thread security attribute + true, // inherits system handles + CREATE_UNICODE_ENVIRONMENT|CREATE_NO_WINDOW, // process flags + environment, // envrionment block + workdir, // set as current directory + si.address(), // (in) startup information + pi.address() // (out) process information + )) + throw("Fatal - Could not launch subprocess '"+command+"'"); + + // Close any unnecessary handles. + if (!CloseHandle(pi.hThread)) + LogError("CloseHandle pi.hThread failed"); + + // Close pipe handles (do not continue to modify the parent). + // You need to make sure that no handles to the write end of the + // output pipe are maintained in this process or else the pipe will + // not close when the child process exits and the ReadFile will hang. + if (!CloseHandle(hInputRead)) LogError("CloseHandle hInputRead failed"); + if (!CloseHandle(hOutputWrite)) LogError("CloseHandle hOutputWrite failed"); + if (!CloseHandle(hErrorWrite)) LogError("CloseHandle hErrorWrite failed"); + + //return values + child.stdin = hInputWrite; + child.stdout = hOutputRead; + child.stderr = options.mergeStderr ? undefined : hErrorRead; + child.process = pi.hProcess; + return pi.hProcess; + } + + /* + * createStdinWriter () + * + * Create a ChromeWorker object for writing data to the subprocess' stdin + * pipe. The ChromeWorker object lives on a separate thread; this avoids + * internal deadlocks. + */ + function createStdinWriter() { + debugLog("Creating new stdin worker\n"); + stdinWorker = new ChromeWorker(WORKER_URL_WIN); + stdinWorker.onmessage = function(event) { + switch(event.data) { + case "WriteOK": + pendingWriteCount--; + debugLog("got OK from stdinWorker - remaining count: "+pendingWriteCount+"\n"); + break; + case "ClosedOK": + stdinOpenState = CLOSED; + debugLog("Stdin pipe closed\n"); + break; + default: + debugLog("got msg from stdinWorker: "+event.data+"\n"); + } + } + stdinWorker.onerror = function(error) { + pendingWriteCount--; + LogError("got error from stdinWorker: "+error.message+"\n"); + } + + stdinWorker.postMessage({msg: "init", libc: options.libc}); + } + + /* + * writeStdin() + * @data: String containing the data to write + * + * Write data to the subprocess' stdin (equals to sending a request to the + * ChromeWorker object to write the data). + */ + function writeStdin(data) { + ++pendingWriteCount; + debugLog("sending "+data.length+" bytes to stdinWorker\n"); + var pipePtr = parseInt(ctypes.cast(child.stdin.address(), ctypes.uintptr_t).value); + + stdinWorker.postMessage({ + msg: 'write', + pipe: pipePtr, + data: data + }); + } + + /* + * closeStdinHandle() + * + * Close the stdin pipe, either directly or by requesting the ChromeWorker to + * close the pipe. The ChromeWorker will only close the pipe after the last write + * request process is done. + */ + + function closeStdinHandle() { + debugLog("trying to close stdin\n"); + if (stdinOpenState != OPEN) return; + stdinOpenState = CLOSEABLE; + + if (stdinWorker) { + debugLog("sending close stdin to worker\n"); + var pipePtr = parseInt(ctypes.cast(child.stdin.address(), ctypes.uintptr_t).value); + stdinWorker.postMessage({ + msg: 'close', + pipe: pipePtr + }); + } + else { + stdinOpenState = CLOSED; + debugLog("Closing Stdin\n"); + CloseHandle(child.stdin) || LogError("CloseHandle hInputWrite failed"); + } + } + + + /* + * createReader(pipe, name) + * + * @pipe: handle to the pipe + * @name: String containing the pipe name (stdout or stderr) + * + * Create a ChromeWorker object for reading data asynchronously from + * the pipe (i.e. on a separate thread), and passing the result back to + * the caller. + */ + function createReader(pipe, name, callbackFunc) { + var worker = new ChromeWorker(WORKER_URL_WIN); + worker.onmessage = function(event) { + switch(event.data.msg) { + case "data": + debugLog("got "+event.data.count+" bytes from "+name+"\n"); + var data = ''; + if (options.charset === null) { + data = getBytes(event.data.data); + } + else { + try { + data = convertBytes(event.data.data, options.charset); + } + catch(ex) { + console.warn("error decoding output: " + ex); + data = getBytes(event.data.data); + } + } + + callbackFunc(data); + break; + case "done": + debugLog("Pipe "+name+" closed\n"); + --readers; + if (readers == 0) cleanup(); + break; + default: + debugLog("Got msg from "+name+": "+event.data.data+"\n"); + } + } + + worker.onerror = function(errorMsg) { + LogError("Got error from "+name+": "+errorMsg.message); + } + + var pipePtr = parseInt(ctypes.cast(pipe.address(), ctypes.uintptr_t).value); + + worker.postMessage({ + msg: 'read', + pipe: pipePtr, + libc: options.libc, + charset: options.charset === null ? "null" : options.charset, + name: name + }); + + return worker; + } + + /* + * readPipes() + * + * Open the pipes for reading from stdout and stderr + */ + function readPipes() { + + stdoutWorker = createReader(child.stdout, "stdout", function (data) { + if(options.stdout) { + setTimeout(function() { + options.stdout(data); + }, 0); + } else { + output += data; + } + }); + + + if (!options.mergeStderr) stderrWorker = createReader(child.stderr, "stderr", function (data) { + if(options.stderr) { + setTimeout(function() { + options.stderr(data); + }, 0); + } else { + error += data; + } + }); + } + + /* + * cleanup() + * + * close stdin if needed, get the exit code from the subprocess and invoke + * the caller's done() function. + * + * Note: because stdout() and stderr() are called using setTimeout, we need to + * do the same here in order to guarantee the message sequence. + */ + function cleanup() { + debugLog("Cleanup called\n"); + if(active) { + active = false; + + closeStdinHandle(); // should only be required in case of errors + + var exit = new DWORD(); + GetExitCodeProcess(child.process, exit.address()); + exitCode = exit.value; + + if (stdinWorker) + stdinWorker.postMessage({msg: 'stop'}) + + setTimeout(function _done() { + if (options.done) { + try { + options.done({ + exitCode: exitCode, + stdout: output, + stderr: error, + }); + } + catch (ex) { + // prevent from blocking if options.done() throws an error + done = true; + throw ex; + } + } + done = true; + }, 0); + kernel32dll.close(); + } + } + + var cmdStr = getCommandStr(options.command); + var workDir = getWorkDir(options.workdir); + + //main + hChildProcess = popen(cmdStr, workDir, options.arguments, options.environment, child); + + readPipes(); + + if (options.stdin) { + createStdinWriter(); + + if(typeof(options.stdin) == 'function') { + try { + options.stdin({ + write: function(data) { + writeStdin(data); + }, + close: function() { + closeStdinHandle(); + } + }); + } + catch (ex) { + // prevent from failing if options.stdin() throws an exception + closeStdinHandle(); + throw ex; + } + } else { + writeStdin(options.stdin); + closeStdinHandle(); + } + } + else + closeStdinHandle(); + + return { + kill: function(hardKill) { + // hardKill is currently ignored on Windows + var r = !!TerminateProcess(child.process, 255); + cleanup(-1); + return r; + }, + wait: function() { + // wait for async operations to complete + var thread = Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager).currentThread; + while (!done) thread.processNextEvent(true); + + return exitCode; + } + } +} + + +function subprocess_unix(options) { + // stdin pipe states + const OPEN = 2; + const CLOSEABLE = 1; + const CLOSED = 0; + + var libc = ctypes.open(options.libc), + active = true, + done = false, + exitCode = -1, + workerExitCode = 0, + child = {}, + pid = -1, + stdinWorker = null, + stdoutWorker = null, + stderrWorker = null, + pendingWriteCount = 0, + readers = options.mergeStderr ? 1 : 2, + stdinOpenState = OPEN, + error = '', + output = ''; + + //api declarations + + //pid_t fork(void); + var fork = libc.declare("fork", + ctypes.default_abi, + pid_t + ); + + //NULL terminated array of strings, argv[0] will be command >> + 2 + var argv = ctypes.char.ptr.array(options.arguments.length + 2); + var envp = ctypes.char.ptr.array(options.environment.length + 1); + + // posix_spawn_file_actions_t is a complex struct that may be different on + // each platform. We do not care about its attributes, we don't need to + // get access to them, but we do need to allocate the right amount + // of memory for it. + // Bug 936297 - Use OS.File internals to fetch + // sizeof(posix_spawn_file_actions_t) + var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); + var sizeof_file_actions_t = OS.Constants.libc.OSFILE_SIZEOF_DIRENT; + var posix_spawn_file_actions_t = ctypes.uint8_t.array(sizeof_file_actions_t); + + //int posix_spawn(pid_t *restrict pid, const char *restrict path, + // const posix_spawn_file_actions_t *file_actions, + // const posix_spawnattr_t *restrict attrp, + // char *const argv[restrict], char *const envp[restrict]); + var posix_spawn = libc.declare("posix_spawn", + ctypes.default_abi, + ctypes.int, + pid_t.ptr, + ctypes.char.ptr, + posix_spawn_file_actions_t.ptr, + ctypes.voidptr_t, + argv, + envp + ); + + //int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions); + var posix_spawn_file_actions_init = libc.declare("posix_spawn_file_actions_init", + ctypes.default_abi, + ctypes.int, + posix_spawn_file_actions_t.ptr + ); + + //int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions); + var posix_spawn_file_actions_destroy = libc.declare("posix_spawn_file_actions_destroy", + ctypes.default_abi, + ctypes.int, + posix_spawn_file_actions_t.ptr + ); + + // int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t * + // file_actions, int fildes, int newfildes); + var posix_spawn_file_actions_adddup2 = libc.declare("posix_spawn_file_actions_adddup2", + ctypes.default_abi, + ctypes.int, + posix_spawn_file_actions_t.ptr, + ctypes.int, + ctypes.int + ); + + // int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t * + // file_actions, int fildes); + var posix_spawn_file_actions_addclose = libc.declare("posix_spawn_file_actions_addclose", + ctypes.default_abi, + ctypes.int, + posix_spawn_file_actions_t.ptr, + ctypes.int + ); + + //int pipe(int pipefd[2]); + var pipefd = ctypes.int.array(2); + var pipe = libc.declare("pipe", + ctypes.default_abi, + ctypes.int, + pipefd + ); + + //int close(int fd); + var close = libc.declare("close", + ctypes.default_abi, + ctypes.int, + ctypes.int + ); + + //pid_t waitpid(pid_t pid, int *status, int options); + var waitpid = libc.declare("waitpid", + ctypes.default_abi, + pid_t, + pid_t, + ctypes.int.ptr, + ctypes.int + ); + + //int kill(pid_t pid, int sig); + var kill = libc.declare("kill", + ctypes.default_abi, + ctypes.int, + pid_t, + ctypes.int + ); + + //int read(int fd, void *buf, size_t count); + var bufferSize = 1024; + var buffer = ctypes.char.array(bufferSize); + var read = libc.declare("read", + ctypes.default_abi, + ctypes.int, + ctypes.int, + buffer, + ctypes.int + ); + + //ssize_t write(int fd, const void *buf, size_t count); + var write = libc.declare("write", + ctypes.default_abi, + ctypes.int, + ctypes.int, + ctypes.char.ptr, + ctypes.int + ); + + //int chdir(const char *path); + var chdir = libc.declare("chdir", + ctypes.default_abi, + ctypes.int, + ctypes.char.ptr + ); + + //int fcntl(int fd, int cmd, ... /* arg */ ); + var fcntl = libc.declare("fcntl", + ctypes.default_abi, + ctypes.int, + ctypes.int, + ctypes.int, + ctypes.int + ); + + function popen(command, workdir, args, environment, child) { + var _in, + _out, + _err, + pid, + rc; + _in = new pipefd(); + _out = new pipefd(); + if(!options.mergeStderr) + _err = new pipefd(); + + var _args = argv(); + args.unshift(command); + for(var i=0;i= 0) { + posix_spawn_file_actions_addclose(action.address(), i); + } + } + } + + /* + * createStdinWriter () + * + * Create a ChromeWorker object for writing data to the subprocess' stdin + * pipe. The ChromeWorker object lives on a separate thread; this avoids + * internal deadlocks. + */ + function createStdinWriter() { + debugLog("Creating new stdin worker\n"); + stdinWorker = new ChromeWorker(WORKER_URL_UNIX); + stdinWorker.onmessage = function(event) { + switch (event.data.msg) { + case "info": + switch(event.data.data) { + case "WriteOK": + pendingWriteCount--; + debugLog("got OK from stdinWorker - remaining count: "+pendingWriteCount+"\n"); + break; + case "ClosedOK": + stdinOpenState = CLOSED; + debugLog("Stdin pipe closed\n"); + break; + default: + debugLog("got msg from stdinWorker: "+event.data.data+"\n"); + } + break; + case "debug": + debugLog("stdinWorker: "+event.data.data+"\n"); + break; + case "error": + LogError("got error from stdinWorker: "+event.data.data+"\n"); + pendingWriteCount = 0; + stdinOpenState = CLOSED; + } + } + stdinWorker.onerror = function(error) { + pendingWriteCount = 0; + closeStdinHandle(); + LogError("got error from stdinWorker: "+error.message+"\n"); + } + stdinWorker.postMessage({msg: "init", libc: options.libc}); + } + + /* + * writeStdin() + * @data: String containing the data to write + * + * Write data to the subprocess' stdin (equals to sending a request to the + * ChromeWorker object to write the data). + */ + function writeStdin(data) { + if (stdinOpenState == CLOSED) return; // do not write to closed pipes + + ++pendingWriteCount; + debugLog("sending "+data.length+" bytes to stdinWorker\n"); + var pipe = parseInt(child.stdin); + + stdinWorker.postMessage({ + msg: 'write', + pipe: pipe, + data: data + }); + } + + + /* + * closeStdinHandle() + * + * Close the stdin pipe, either directly or by requesting the ChromeWorker to + * close the pipe. The ChromeWorker will only close the pipe after the last write + * request process is done. + */ + + function closeStdinHandle() { + debugLog("trying to close stdin\n"); + if (stdinOpenState != OPEN) return; + stdinOpenState = CLOSEABLE; + + if (stdinWorker) { + debugLog("sending close stdin to worker\n"); + var pipePtr = parseInt(child.stdin); + + stdinWorker.postMessage({ + msg: 'close', + pipe: pipePtr + }); + } + else { + stdinOpenState = CLOSED; + debugLog("Closing Stdin\n"); + close(child.stdin) && LogError("CloseHandle stdin failed"); + } + } + + + /* + * createReader(pipe, name) + * + * @pipe: handle to the pipe + * @name: String containing the pipe name (stdout or stderr) + * @callbackFunc: function to be called with the read data + * + * Create a ChromeWorker object for reading data asynchronously from + * the pipe (i.e. on a separate thread), and passing the result back to + * the caller. + * + */ + function createReader(pipe, name, callbackFunc) { + var worker = new ChromeWorker(WORKER_URL_UNIX); + worker.onmessage = function(event) { + switch(event.data.msg) { + case "data": + debugLog("got "+event.data.count+" bytes from "+name+"\n"); + var data = ''; + if (options.charset === null) { + data = getBytes(event.data.data); + } + else { + try { + data = convertBytes(event.data.data, options.charset); + } + catch(ex) { + console.warn("error decoding output: " + ex); + data = getBytes(event.data.data); + } + } + + callbackFunc(data); + break; + case "done": + debugLog("Pipe "+name+" closed\n"); + if (event.data.data != 0) workerExitCode = event.data.data; + --readers; + if (readers == 0) cleanup(); + break; + default: + debugLog("Got msg from "+name+": "+event.data.data+"\n"); + } + } + worker.onerror = function(error) { + LogError("Got error from "+name+": "+error.message); + } + + worker.postMessage({ + msg: 'read', + pipe: pipe, + pid: pid, + libc: options.libc, + charset: options.charset === null ? "null" : options.charset, + name: name + }); + + return worker; + } + + /* + * readPipes() + * + * Open the pipes for reading from stdout and stderr + */ + function readPipes() { + + stdoutWorker = createReader(child.stdout, "stdout", function (data) { + if(options.stdout) { + setTimeout(function() { + options.stdout(data); + }, 0); + } else { + output += data; + } + }); + + if (!options.mergeStderr) stderrWorker = createReader(child.stderr, "stderr", function (data) { + if(options.stderr) { + setTimeout(function() { + options.stderr(data); + }, 0); + } else { + error += data; + } + }); + } + + function cleanup() { + debugLog("Cleanup called\n"); + if(active) { + active = false; + + closeStdinHandle(); // should only be required in case of errors + + var result, status = ctypes.int(); + result = waitpid(child.pid, status.address(), 0); + if (result > 0) + exitCode = status.value + else + if (workerExitCode >= 0) + exitCode = workerExitCode + else + exitCode = status.value; + + if (stdinWorker) + stdinWorker.postMessage({msg: 'stop'}) + + setTimeout(function _done() { + if (options.done) { + try { + options.done({ + exitCode: exitCode, + stdout: output, + stderr: error, + }); + } + catch(ex) { + // prevent from blocking if options.done() throws an error + done = true; + throw ex; + } + + } + done = true; + }, 0); + + libc.close(); + } + } + + //main + + var cmdStr = getCommandStr(options.command); + var workDir = getWorkDir(options.workdir); + + child = {}; + pid = popen(cmdStr, workDir, options.arguments, options.environment, child); + + debugLog("subprocess started; got PID "+pid+"\n"); + + readPipes(); + + if (options.stdin) { + createStdinWriter(); + if(typeof(options.stdin) == 'function') { + try { + options.stdin({ + write: function(data) { + writeStdin(data); + }, + close: function() { + closeStdinHandle(); + } + }); + } + catch(ex) { + // prevent from failing if options.stdin() throws an exception + closeStdinHandle(); + throw ex; + } + } else { + writeStdin(options.stdin); + closeStdinHandle(); + } + } + + return { + wait: function() { + // wait for async operations to complete + var thread = Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager).currentThread; + while (! done) thread.processNextEvent(true) + return exitCode; + }, + kill: function(hardKill) { + var rv = kill(pid, (hardKill ? 9: 15)); + cleanup(-1); + return rv; + } + } +} + + +module.exports = subprocess; diff --git a/b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js b/b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js new file mode 100644 index 000000000000..a502959a5f2c --- /dev/null +++ b/b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js @@ -0,0 +1,248 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * ChromeWorker Object subprocess.jsm on Unix-like systems (Linux, Mac OS X, ...) + * to process stdin/stdout/stderr on separate threads. + * + */ + +// Being a ChromeWorker object, implicitly uses the following: +// Components.utils.import("resource://gre/modules/ctypes.jsm"); + +'use strict'; + +const BufferSize = 1024; + +var libc = null; +var libcFunc = {}; + + +/* + struct pollfd { + int fd; // file descriptor + short events; // events to look for + short revents; // events returned + }; +*/ + +var pollfd = new ctypes.StructType("pollfd", + [ {'fd': ctypes.int}, + {'events': ctypes.short}, + {'revents': ctypes.short} + ]); + +var WriteBuffer = ctypes.uint8_t.array(BufferSize); +var ReadBuffer = ctypes.char.array(BufferSize); + + +const POLLIN = 0x0001; +const POLLOUT = 0x0004; + +const POLLERR = 0x0008; // some poll error occurred +const POLLHUP = 0x0010; // file descriptor was "hung up" +const POLLNVAL = 0x0020; // requested events "invalid" + +const WNOHANG = 0x01; + +const pid_t = ctypes.int32_t; + +const INDEFINITE = -1; +const NOWAIT = 0; +const WAITTIME = 200 // wait time for poll() in ms + +function initLibc(libName) { + postMessage({msg: "debug", data: "initialising library with "+ libName}); + + libc = ctypes.open(libName); + + libcFunc.pollFds = pollfd.array(1); + + // int poll(struct pollfd fds[], nfds_t nfds, int timeout); + libcFunc.poll = libc.declare("poll", + ctypes.default_abi, + ctypes.int, + libcFunc.pollFds, + ctypes.unsigned_int, + ctypes.int); + + //ssize_t write(int fd, const void *buf, size_t count); + // NOTE: buf is declared as array of unsigned int8 instead of char to avoid + // implicit charset conversion + libcFunc.write = libc.declare("write", + ctypes.default_abi, + ctypes.int, + ctypes.int, + WriteBuffer, + ctypes.int); + + //int read(int fd, void *buf, size_t count); + libcFunc.read = libc.declare("read", + ctypes.default_abi, + ctypes.int, + ctypes.int, + ReadBuffer, + ctypes.int); + + //int pipe(int pipefd[2]); + libcFunc.pipefd = ctypes.int.array(2); + + //int close(int fd); + libcFunc.close = libc.declare("close", + ctypes.default_abi, + ctypes.int, + ctypes.int); + + //pid_t waitpid(pid_t pid, int *status, int options); + libcFunc.waitpid = libc.declare("waitpid", + ctypes.default_abi, + pid_t, + pid_t, + ctypes.int.ptr, + ctypes.int); +} + +function closePipe(pipe) { + libcFunc.close(pipe); +} + +function writePipe(pipe, data) { + + postMessage({msg: "debug", data: "trying to write to "+pipe}); + + let numChunks = Math.floor(data.length / BufferSize); + let pData = new WriteBuffer(); + + for (var chunk = 0; chunk <= numChunks; chunk ++) { + let numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize; + for (var i=0; i < numBytes; i++) { + pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256; + } + + let bytesWritten = libcFunc.write(pipe, pData, numBytes); + if (bytesWritten != numBytes) { + closePipe(); + libc.close(); + postMessage({ msg: "error", data: "error: wrote "+bytesWritten+" instead of "+numBytes+" bytes"}); + close(); + } + } + postMessage({msg: "info", data: "wrote "+data.length+" bytes of data"}); +} + + +function readString(data, length, charset) { + var string = '', bytes = []; + for(var i = 0;i < length; i++) { + if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data + break; + + bytes.push(data[i]); + } + + return bytes; +} + +function readPipe(pipe, charset, pid) { + var p = new libcFunc.pollFds; + p[0].fd = pipe; + p[0].events = POLLIN | POLLERR | POLLHUP; + p[0].revents = 0; + var pollTimeout = WAITTIME; + var exitCode = -1; + var readCount = 0; + var result, status = ctypes.int(); + result = 0; + + + const i=0; + while (true) { + if (result == 0) { + result = libcFunc.waitpid(pid, status.address(), WNOHANG); + if (result > 0) { + pollTimeout = NOWAIT; + exitCode = parseInt(status.value); + postMessage({msg: "debug", data: "waitpid signaled subprocess stop, exitcode="+status.value }); + } + } + var r = libcFunc.poll(p, 1, pollTimeout); + if (r > 0) { + if (p[i].revents & POLLIN) { + postMessage({msg: "debug", data: "reading next chunk"}); + readCount = readPolledFd(p[i].fd, charset); + if (readCount == 0) break; + } + + if (p[i].revents & POLLHUP) { + postMessage({msg: "debug", data: "poll returned HUP"}); + break; + } + else if (p[i].revents & POLLERR) { + postMessage({msg: "error", data: "poll returned error"}); + break; + } + else if (p[i].revents != POLLIN) { + postMessage({msg: "error", data: "poll returned "+p[i]}); + break; + } + } + else + if (pollTimeout == 0 || r < 0) break; + } + + // continue reading until the buffer is empty + while (readCount > 0) { + readCount = readPolledFd(pipe, charset); + } + + libcFunc.close(pipe); + postMessage({msg: "done", data: exitCode }); + libc.close(); + close(); +} + +function readPolledFd(pipe, charset) { + var line = new ReadBuffer(); + var r = libcFunc.read(pipe, line, BufferSize); + + if (r > 0) { + var c = readString(line, r, charset); + postMessage({msg: "data", data: c, count: c.length}); + } + return r; +} + +onmessage = function (event) { + switch (event.data.msg) { + case "init": + initLibc(event.data.libc); + break; + case "read": + initLibc(event.data.libc); + readPipe(event.data.pipe, event.data.charset, event.data.pid); + break; + case "write": + // data contents: + // msg: 'write' + // data: the data (string) to write + // pipe: ptr to pipe + writePipe(event.data.pipe, event.data.data); + postMessage({msg: "info", data: "WriteOK"}); + break; + case "close": + postMessage({msg: "debug", data: "closing stdin\n"}); + + closePipe(event.data.pipe); + postMessage({msg: "info", data: "ClosedOK"}); + break; + case "stop": + libc.close(); // do not use libc after this point + close(); + break; + default: + throw("error: Unknown command"+event.data.msg+"\n"); + } + return; +}; diff --git a/b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js b/b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js new file mode 100644 index 000000000000..69c3d8714bdb --- /dev/null +++ b/b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js @@ -0,0 +1,206 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * ChromeWorker Object subprocess.jsm on Windows to process stdin/stdout/stderr + * on separate threads. + * + */ + +// Being a ChromeWorker object, implicitly uses the following: +// Components.utils.import("resource://gre/modules/ctypes.jsm"); + +'use strict'; + +const BufferSize = 1024; + +const BOOL = ctypes.bool; +const HANDLE = ctypes.size_t; +const DWORD = ctypes.uint32_t; +const LPDWORD = DWORD.ptr; +const PVOID = ctypes.voidptr_t; +const LPVOID = PVOID; + +/* +typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + }; + PVOID Pointer; + }; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; +*/ +const OVERLAPPED = new ctypes.StructType("OVERLAPPED"); + +var ReadFileBuffer = ctypes.char.array(BufferSize); +var WriteFileBuffer = ctypes.uint8_t.array(BufferSize); + +var kernel32dll = null; +var libFunc = {}; + +function initLib(libName) { + if (ctypes.size_t.size == 8) { + var WinABI = ctypes.default_abi; + } else { + var WinABI = ctypes.winapi_abi; + } + + kernel32dll = ctypes.open(libName); + + /* + BOOL WINAPI WriteFile( + __in HANDLE hFile, + __in LPCVOID lpBuffer, + __in DWORD nNumberOfBytesToWrite, + __out_opt LPDWORD lpNumberOfBytesWritten, + __inout_opt LPOVERLAPPED lpOverlapped + ); + + NOTE: lpBuffer is declared as array of unsigned int8 instead of char to avoid + implicit charset conversion + */ + libFunc.WriteFile = kernel32dll.declare("WriteFile", + WinABI, + BOOL, + HANDLE, + WriteFileBuffer, + DWORD, + LPDWORD, + OVERLAPPED.ptr + ); + + /* + BOOL WINAPI ReadFile( + __in HANDLE hFile, + __out LPVOID ReadFileBuffer, + __in DWORD nNumberOfBytesToRead, + __out_opt LPDWORD lpNumberOfBytesRead, + __inout_opt LPOVERLAPPED lpOverlapped + ); + */ + libFunc.ReadFile = kernel32dll.declare("ReadFile", + WinABI, + BOOL, + HANDLE, + ReadFileBuffer, + DWORD, + LPDWORD, + OVERLAPPED.ptr + ); + + /* + BOOL WINAPI CloseHandle( + __in HANDLE hObject + ); + */ + libFunc.CloseHandle = kernel32dll.declare("CloseHandle", + WinABI, + BOOL, + HANDLE + ); +} + + +function writePipe(pipe, data) { + var bytesWritten = DWORD(0); + + var pData = new WriteFileBuffer(); + + var numChunks = Math.floor(data.length / BufferSize); + for (var chunk = 0; chunk <= numChunks; chunk ++) { + var numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize; + for (var i=0; i < numBytes; i++) { + pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256; + } + + var r = libFunc.WriteFile(pipe, pData, numBytes, bytesWritten.address(), null); + if (bytesWritten.value != numBytes) + throw("error: wrote "+bytesWritten.value+" instead of "+numBytes+" bytes"); + } + postMessage("wrote "+data.length+" bytes of data"); +} + +function readString(data, length, charset) { + var string = '', bytes = []; + for(var i = 0;i < length; i++) { + if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data + break; + + bytes.push(data[i]); + } + + return bytes; +} + +function readPipe(pipe, charset) { + while (true) { + var bytesRead = DWORD(0); + var line = new ReadFileBuffer(); + var r = libFunc.ReadFile(pipe, line, BufferSize, bytesRead.address(), null); + + if (!r) { + // stop if we get an error (such as EOF reached) + postMessage({msg: "info", data: "ReadFile failed"}); + break; + } + + if (bytesRead.value > 0) { + var c = readString(line, bytesRead.value, charset); + postMessage({msg: "data", data: c, count: c.length}); + } + else { + break; + } + } + libFunc.CloseHandle(pipe); + postMessage({msg: "done"}); + kernel32dll.close(); + close(); +} + +onmessage = function (event) { + let pipePtr; + switch (event.data.msg) { + case "init": + initLib(event.data.libc); + break; + case "write": + // data contents: + // msg: 'write' + // data: the data (string) to write + // pipe: ptr to pipe + pipePtr = HANDLE.ptr(event.data.pipe); + writePipe(pipePtr.contents, event.data.data); + postMessage("WriteOK"); + break; + case "read": + initLib(event.data.libc); + pipePtr = HANDLE.ptr(event.data.pipe); + readPipe(pipePtr.contents, event.data.charset); + break; + case "close": + pipePtr = HANDLE.ptr(event.data.pipe); + postMessage("closing stdin\n"); + + if (libFunc.CloseHandle(pipePtr.contents)) { + postMessage("ClosedOK"); + } + else + postMessage("Could not close stdin handle"); + break; + case "stop": + kernel32dll.close(); + close(); + break; + default: + throw("error: Unknown command"+event.data.msg+"\n"); + } + return; +}; diff --git a/b2g/simulator/packages/subprocess/package.json b/b2g/simulator/packages/subprocess/package.json new file mode 100644 index 000000000000..f828476cefa9 --- /dev/null +++ b/b2g/simulator/packages/subprocess/package.json @@ -0,0 +1,15 @@ +{ + "name": "subprocess", + "license": "MPL 1.1/GPL 2.0/LGPL 2.1", + "author": "Alexandre Poirot", + "contributors": [ + "Jan Gerber (original creator) ", + "Patrick Brunschwig (author of almost all code) ", + "Ramalingam Saravanan (from enigmail team) " + ], + "version": "0.1.1", + "dependencies": [ + "api-utils" + ], + "description": "Addon-sdk package for subprocess xpcom components from enigmail. Allow to run process, manipulate stdin/out and kill it." +} diff --git a/b2g/simulator/packages/subprocess/tests/test-subprocess.js b/b2g/simulator/packages/subprocess/tests/test-subprocess.js new file mode 100644 index 000000000000..5130dd3c9b64 --- /dev/null +++ b/b2g/simulator/packages/subprocess/tests/test-subprocess.js @@ -0,0 +1,144 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +const { Cc, Ci } = require("chrome"); +const subprocess = require("subprocess"); +const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); + +// For now, only test on windows +if (env.get('OS') && env.get('OS').match(/Windows/)) { + +exports.testWindows = function (test) { + test.waitUntilDone(); + let envTestValue = "OK"; + let gotStdout = false; + + var p = subprocess.call({ + // Retrieve windows cmd.exe path from env + command: env.get('ComSpec'), + // In order to execute a simple "echo" function + arguments: ['/C', 'echo %ENV_TEST%'], // ' & type CON' should display stdin, but doesn't work + // Printing an environnement variable set here by the parent process + environment: ['ENV_TEST='+envTestValue], + + stdin: function(stdin) { + // Win32 command line is not really made for stdin + // So it doesn't seems to work as it's hard to retrieve stdin + stdin.write("stdin"); + stdin.close(); + }, + stdout: function(data) { + test.assert(!gotStdout,"don't get stdout twice"); + test.assertEqual(data,envTestValue+"\r\n","stdout contains the environment variable"); + gotStdout = true; + }, + stderr: function(data) { + test.fail("shouldn't get stderr"); + }, + done: function() { + test.assert(gotStdout, "got stdout before finished"); + test.done(); + }, + mergeStderr: false + }); + +} + +exports.testWindowsStderr = function (test) { + test.waitUntilDone(); + let gotStderr = false; + + var p = subprocess.call({ + command: env.get('ComSpec'), + arguments: ['/C', 'nonexistent'], + + stdout: function(data) { + test.fail("shouldn't get stdout"); + }, + stderr: function(data) { + test.assert(!gotStderr,"don't get stderr twice"); + test.assertEqual( + data, + "'nonexistent' is not recognized as an internal or external command,\r\n" + + "operable program or batch file.\r\n", + "stderr contains the error message" + ); + gotStderr = true; + }, + done: function() { + test.assert(gotStderr, "got stderr before finished"); + test.done(); + }, + mergeStderr: false + }); + +} + +} + +if (env.get('USER') && env.get('SHELL')) { + +exports.testUnix = function (test) { + test.waitUntilDone(); + let envTestValue = "OK"; + let gotStdout = false; + + var p = subprocess.call({ + command: '/bin/sh', + // Print stdin and our env variable + //arguments: ['-c', 'echo $@ $ENV_TEST'], + environment: ['ENV_TEST='+envTestValue], + + stdin: function(stdin) { + stdin.write("echo $ENV_TEST"); + stdin.close(); + }, + stdout: function(data) { + test.assert(!gotStdout,"don't get stdout twice"); + test.assertEqual(data,envTestValue+"\n","stdout contains the environment variable"); + gotStdout = true; + }, + stderr: function(data) { + test.fail("shouldn't get stderr"); + }, + done: function() { + test.assert(gotStdout, "got stdout before finished"); + test.done(); + }, + mergeStderr: false + }); +} + +exports.testUnixStderr = function (test) { + test.waitUntilDone(); + let gotStderr = false; + + var p = subprocess.call({ + // Hope that we don't have to give absolute path on linux ... + command: '/bin/sh', + arguments: ['nonexistent'], + + stdout: function(data) { + test.fail("shouldn't get stdout"); + }, + stderr: function(data) { + test.assert(!gotStderr,"don't get stderr twice"); + // There is two variant of error message + if (data == "/bin/sh: 0: Can't open nonexistent\n") + test.pass("stderr containes the expected error message"); + else + test.assertEqual(data, "/bin/sh: nonexistent: No such file or directory\n", + "stderr contains the error message"); + gotStderr = true; + }, + done: function() { + test.assert(gotStderr, "got stderr before finished"); + test.done(); + }, + mergeStderr: false + }); +} + +} diff --git a/configure.in b/configure.in index 526cc0752411..141cb5aeabd7 100644 --- a/configure.in +++ b/configure.in @@ -164,11 +164,20 @@ if test -z "$PERL" -o "$PERL" = ":"; then AC_MSG_ERROR([perl not found in \$PATH]) fi +if test -n "$GAIADIR" -a ! -d "$GAIADIR" ; then + AC_MSG_ERROR([GAIADIR '$GAIADIR' isn't a valid directory]) +fi + AC_SUBST(GAIADIR) if test -n "$GAIADIR" ; then AC_DEFINE(PACKAGE_GAIA) fi +if test -n "$FXOS_SIMULATOR" -a -z "$GAIADIR" ; then + AC_MSG_ERROR([FXOS_SIMULATOR=1 requires GAIADIR to be defined]) +fi +AC_SUBST(FXOS_SIMULATOR) + MOZ_ARG_WITH_STRING(gonk, [ --with-gonk=DIR location of gonk dir], @@ -4160,6 +4169,7 @@ AC_SUBST(MOZ_BUILD_APP) AC_SUBST(MOZ_PHOENIX) AC_SUBST(MOZ_XULRUNNER) AC_SUBST(MOZ_B2G) +AC_SUBST(MOZ_B2G_VERSION) AC_DEFINE_UNQUOTED(MOZ_BUILD_APP,$MOZ_BUILD_APP) From af268e6aabdbc601010bb1d83e34e8786685af91 Mon Sep 17 00:00:00 2001 From: Jan Keromnes Date: Mon, 3 Mar 2014 14:50:56 -0500 Subject: [PATCH 69/69] Bug 978058 - Make Firefox OS' devtools track frames instead of app manifests. r=vingtetun --- b2g/chrome/content/devtools.js | 201 +++++++++++++++++---------------- b2g/chrome/content/shell.js | 16 +-- 2 files changed, 109 insertions(+), 108 deletions(-) diff --git a/b2g/chrome/content/devtools.js b/b2g/chrome/content/devtools.js index c3b669dd6908..921eecf724b8 100644 --- a/b2g/chrome/content/devtools.js +++ b/b2g/chrome/content/devtools.js @@ -35,8 +35,8 @@ XPCOMUtils.defineLazyGetter(this, 'MemoryFront', function() { */ let developerHUD = { - _apps: new Map(), - _urls: new Map(), + _targets: new Map(), + _frames: new Map(), _client: null, _webappsActor: null, _watchers: [], @@ -72,19 +72,16 @@ let developerHUD = { } } - Services.obs.addObserver(this, 'remote-browser-pending', false); + Services.obs.addObserver(this, 'remote-browser-shown', false); Services.obs.addObserver(this, 'inprocess-browser-shown', false); Services.obs.addObserver(this, 'message-manager-disconnect', false); let systemapp = document.querySelector('#systemapp'); - let manifestURL = systemapp.getAttribute("mozapp"); - this.trackApp(manifestURL); + this.trackFrame(systemapp); - let frames = - systemapp.contentWindow.document.querySelectorAll('iframe[mozapp]'); + let frames = systemapp.contentWindow.document.querySelectorAll('iframe[mozapp]'); for (let frame of frames) { - let manifestURL = frame.getAttribute("mozapp"); - this.trackApp(manifestURL); + this.trackFrame(frame); } }); }); @@ -94,11 +91,11 @@ let developerHUD = { if (!this._client) return; - for (let manifest of this._apps.keys()) { - this.untrackApp(manifest); + for (let frame of this._targets.keys()) { + this.untrackFrame(frame); } - Services.obs.removeObserver(this, 'remote-browser-pending'); + Services.obs.removeObserver(this, 'remote-browser-shown'); Services.obs.removeObserver(this, 'inprocess-browser-shown'); Services.obs.removeObserver(this, 'message-manager-disconnect'); @@ -108,43 +105,43 @@ let developerHUD = { /** * This method will ask all registered watchers to track and update metrics - * on an app. + * on an app frame. */ - trackApp: function dwp_trackApp(manifestURL) { - if (this._apps.has(manifestURL)) + trackFrame: function dwp_trackFrame(frame) { + if (this._targets.has(frame)) return; // FIXME(Bug 962577) Factor getAppActor out of webappsActor. this._client.request({ to: this._webappsActor, type: 'getAppActor', - manifestURL: manifestURL + manifestURL: frame.appManifestURL }, (res) => { if (res.error) { return; } - let app = new App(manifestURL, res.actor); - this._apps.set(manifestURL, app); + let target = new Target(frame, res.actor); + this._targets.set(frame, target); for (let w of this._watchers) { - w.trackApp(app); + w.trackTarget(target); } }); }, - untrackApp: function dwp_untrackApp(manifestURL) { - let app = this._apps.get(manifestURL); - if (app) { + untrackFrame: function dwp_untrackFrame(frame) { + let target = this._targets.get(frame); + if (target) { for (let w of this._watchers) { - w.untrackApp(app); + w.untrackTarget(target); } // Delete the metrics and call display() to clean up the front-end. - delete app.metrics; - app.display(); + delete target.metrics; + target.display(); - this._apps.delete(manifestURL); + this._target.delete(frame); } }, @@ -152,12 +149,12 @@ let developerHUD = { if (!this._client) return; - let manifestURL; + let frame; switch(topic) { // listen for frame creation in OOP (device) as well as in parent process (b2g desktop) - case 'remote-browser-pending': + case 'remote-browser-shown': case 'inprocess-browser-shown': let frameLoader = subject; // get a ref to the app