This commit is contained in:
Wes Kocher 2015-01-21 14:14:21 -08:00
Родитель 52b08e3604 c0d4e14e92
Коммит b0e827c8f4
99 изменённых файлов: 1145 добавлений и 909 удалений

Просмотреть файл

@ -22,5 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1100184 - Lots of file moves from the /netwerk flattening and zero faith
in the build system to properly handle them.
Bug 1115998 - (DOMString or sequence<DOMString>) needs binding flush (Bug 1103153)

Просмотреть файл

@ -12,7 +12,7 @@
namespace mozilla {
namespace a11y {
MOZ_BEGIN_ENUM_CLASS(RelationType)
enum class RelationType {
/**
* This object is labelled by a target object.
@ -131,7 +131,7 @@ MOZ_BEGIN_ENUM_CLASS(RelationType)
LAST = CONTAINING_APPLICATION
MOZ_END_ENUM_CLASS(RelationType)
};
} // namespace a11y
} // namespace mozilla

Просмотреть файл

@ -84,6 +84,14 @@ function test() {
}
});
window.messageManager.addMessageListener("Test:ActivateEvent", function(message) {
ok(message.data.ok, "Test:ActivateEvent");
});
window.messageManager.addMessageListener("Test:DeactivateEvent", function(message) {
ok(message.data.ok, "Test:DeactivateEvent");
});
browser1.addEventListener("load", check, true);
browser2.addEventListener("load", check, true);
browser1.contentWindow.location = testPage;
@ -132,6 +140,25 @@ function childFunction()
sendAsyncMessage("Test:FocusReceived", { });
}, false);
var windowGotActivate = false;
var windowGotDeactivate = false;
addEventListener("activate", function() {
sendAsyncMessage("Test:ActivateEvent", { ok: !windowGotActivate });
windowGotActivate = false;
});
addEventListener("deactivate", function() {
sendAsyncMessage("Test:DeactivateEvent", { ok: !windowGotDeactivate });
windowGotDeactivate = false;
});
content.addEventListener("activate", function() {
windowGotActivate = true;;
});
content.addEventListener("deactivate", function() {
windowGotDeactivate = true;
});
content.setInterval(function () {
if (!expectingResponse) {
return;

Просмотреть файл

@ -31,6 +31,7 @@ skip-if = e10s # Bug 1053965 "cw.ensureSnippetsMapThen is not a function", also
[browser_addons.js]
[browser_blocklist.js]
[browser_share.js]
skip-if = true # bug 1115131
[browser_social_activation.js]
skip-if = e10s # Bug 933103 synthesizeMouseAtCenter not e10s friendly
[browser_social_chatwindow.js]

Просмотреть файл

@ -3620,7 +3620,8 @@ nsresult
nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget,
const nsAString& aEventName,
bool aCanBubble, bool aCancelable,
bool aTrusted, bool *aDefaultAction)
bool aTrusted, bool *aDefaultAction,
bool aOnlyChromeDispatch)
{
nsCOMPtr<nsIDOMEvent> event;
nsCOMPtr<EventTarget> target;
@ -3628,6 +3629,7 @@ nsContentUtils::DispatchEvent(nsIDocument* aDoc, nsISupports* aTarget,
aCancelable, aTrusted, getter_AddRefs(event),
getter_AddRefs(target));
NS_ENSURE_SUCCESS(rv, rv);
event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = aOnlyChromeDispatch;
bool dummy;
return target->DispatchEvent(event, aDefaultAction ? aDefaultAction : &dummy);
@ -3664,6 +3666,17 @@ nsContentUtils::DispatchChromeEvent(nsIDocument *aDoc,
return rv;
}
nsresult
nsContentUtils::DispatchEventOnlyToChrome(nsIDocument* aDoc,
nsISupports* aTarget,
const nsAString& aEventName,
bool aCanBubble, bool aCancelable,
bool* aDefaultAction)
{
return DispatchEvent(aDoc, aTarget, aEventName, aCanBubble, aCancelable,
true, aDefaultAction, true);
}
/* static */
Element*
nsContentUtils::MatchElementId(nsIContent *aContent, const nsIAtom* aId)

Просмотреть файл

@ -987,7 +987,10 @@ public:
/**
* This method creates and dispatches a trusted event to the chrome
* event handler.
* event handler (the parent object of the DOM Window in the event target
* chain). Note, chrome event handler is used even if aTarget is a chrome
* object. Use DispatchEventOnlyToChrome if the normal event dispatching is
* wanted in case aTarget is a chrome object.
* Works only with events which can be created by calling
* nsIDOMDocument::CreateEvent() with parameter "Events".
* @param aDocument The document which will be used to create the event,
@ -1007,6 +1010,32 @@ public:
bool aCancelable,
bool *aDefaultAction = nullptr);
/**
* This method creates and dispatches a trusted event.
* If aTarget is not a chrome object, the nearest chrome object in the
* propagation path will be used as the start of the event target chain.
* This method is different than DispatchChromeEvent, which always dispatches
* events to chrome event handler. DispatchEventOnlyToChrome works like
* DispatchTrustedEvent in the case aTarget is a chrome object.
* Works only with events which can be created by calling
* nsIDOMDocument::CreateEvent() with parameter "Events".
* @param aDoc The document which will be used to create the event.
* @param aTarget The target of the event, should be QIable to
* nsIDOMEventTarget.
* @param aEventName The name of the event.
* @param aCanBubble Whether the event can bubble.
* @param aCancelable Is the event cancelable.
* @param aDefaultAction Set to true if default action should be taken,
* see nsIDOMEventTarget::DispatchEvent.
*/
static nsresult DispatchEventOnlyToChrome(nsIDocument* aDoc,
nsISupports* aTarget,
const nsAString& aEventName,
bool aCanBubble,
bool aCancelable,
bool *aDefaultAction = nullptr);
/**
* Determines if an event attribute name (such as onclick) is valid for
* a given element type. Types are from the EventNameType enumeration
@ -1252,7 +1281,7 @@ public:
* @param aDiscoverMode Set to eRecurseIntoChildren to descend recursively
* into children.
*/
enum TextContentDiscoverMode MOZ_ENUM_TYPE(uint8_t) {
enum TextContentDiscoverMode : uint8_t {
eRecurseIntoChildren, eDontRecurseIntoChildren
};
@ -2046,7 +2075,7 @@ public:
*/
static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
enum AutocompleteAttrState MOZ_ENUM_TYPE(uint8_t)
enum AutocompleteAttrState : uint8_t
{
eAutocompleteAttrState_Unknown = 1,
eAutocompleteAttrState_Invalid,
@ -2253,7 +2282,8 @@ private:
bool aCanBubble,
bool aCancelable,
bool aTrusted,
bool *aDefaultAction = nullptr);
bool *aDefaultAction = nullptr,
bool aOnlyChromeDispatch = false);
static void InitializeModifierStrings();

Просмотреть файл

@ -1145,11 +1145,12 @@ nsFocusManager::ActivateOrDeactivate(nsPIDOMWindow* aWindow, bool aActive)
aWindow->ActivateOrDeactivate(aActive);
// Send the activate event.
nsContentUtils::DispatchTrustedEvent(aWindow->GetExtantDoc(),
aWindow,
aActive ? NS_LITERAL_STRING("activate") :
NS_LITERAL_STRING("deactivate"),
true, true, nullptr);
nsContentUtils::DispatchEventOnlyToChrome(aWindow->GetExtantDoc(),
aWindow,
aActive ?
NS_LITERAL_STRING("activate") :
NS_LITERAL_STRING("deactivate"),
true, true, nullptr);
// Look for any remote child frames, iterate over them and send the activation notification.
nsContentUtils::CallOnAllRemoteChildren(aWindow, ActivateOrDeactivateChild,

Просмотреть файл

@ -461,7 +461,7 @@ GetWrapperCache(const SmartPtr<T>& aObject)
return GetWrapperCache(aObject.get());
}
struct ParentObject {
struct MOZ_STACK_CLASS ParentObject {
template<class T>
ParentObject(T* aObject) :
mObject(aObject),
@ -482,7 +482,9 @@ struct ParentObject {
mUseXBLScope(false)
{}
nsISupports* const mObject;
// We don't want to make this an nsCOMPtr because of performance reasons, but
// it's safe because ParentObject is a stack class.
nsISupports* const MOZ_NON_OWNING_REF mObject;
nsWrapperCache* const mWrapperCache;
bool mUseXBLScope;
};

Просмотреть файл

@ -187,7 +187,7 @@ public:
MOZ_ASSERT(mActor);
}
NS_IMETHODIMP Run()
NS_IMETHODIMP Run() MOZ_OVERRIDE
{
MOZ_ASSERT(mActor);
if (mActor->IsActorDestroyed()) {
@ -221,7 +221,7 @@ public:
return NS_OK;
}
NS_IMETHODIMP Cancel()
NS_IMETHODIMP Cancel() MOZ_OVERRIDE
{
mActor = nullptr;
return NS_OK;
@ -247,13 +247,13 @@ public:
MOZ_ASSERT(mBC);
}
NS_IMETHODIMP Run()
NS_IMETHODIMP Run() MOZ_OVERRIDE
{
mBC->Shutdown();
return NS_OK;
}
NS_IMETHODIMP Cancel()
NS_IMETHODIMP Cancel() MOZ_OVERRIDE
{
mBC = nullptr;
return NS_OK;
@ -278,7 +278,7 @@ public:
MOZ_ASSERT(mActor);
}
NS_IMETHODIMP Run()
NS_IMETHODIMP Run() MOZ_OVERRIDE
{
MOZ_ASSERT(mActor);
if (!mActor->IsActorDestroyed()) {
@ -287,7 +287,7 @@ public:
return NS_OK;
}
NS_IMETHODIMP Cancel()
NS_IMETHODIMP Cancel() MOZ_OVERRIDE
{
mActor = nullptr;
return NS_OK;

Просмотреть файл

@ -42,7 +42,7 @@ private:
~BroadcastChannelChild();
void ActorDestroy(ActorDestroyReason aWhy);
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
// This raw pointer is actually the parent object.
// It's set to null when the parent object is deleted.

Просмотреть файл

@ -37,7 +37,6 @@ StaticRefPtr<CameraPreferences> CameraPreferences::sObserver;
NS_IMPL_ISUPPORTS(CameraPreferences, nsIObserver);
#endif
#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
/* static */
nsresult
CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal)
@ -49,7 +48,6 @@ CameraPreferences::UpdatePref(const char* aPref, nsresult& aVal)
}
return rv;
}
#endif
/* static */
nsresult
@ -156,7 +154,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure)
nsresult rv;
switch (p.mValueType) {
case kPrefValueIsNsResult:
#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
{
nsresult& v = *p.mValue.mAsNsResult;
rv = UpdatePref(aPref, v);
@ -165,7 +162,6 @@ CameraPreferences::PreferenceChanged(const char* aPref, void* aClosure)
}
}
break;
#endif
case kPrefValueIsUint32:
{
@ -331,7 +327,6 @@ CameraPreferences::GetPref(const char* aPref, nsACString& aVal)
return true;
}
#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
/* static */
bool
CameraPreferences::GetPref(const char* aPref, nsresult& aVal)
@ -359,7 +354,6 @@ CameraPreferences::GetPref(const char* aPref, nsresult& aVal)
aVal = v;
return true;
}
#endif
/* static */
bool

Просмотреть файл

@ -12,13 +12,6 @@
#include "mozilla/StaticPtr.h"
#endif
#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) || defined(MOZ_HAVE_CXX11_ENUM_TYPE)
// Older compilers that don't support strongly-typed enums
// just typedef uint32_t to nsresult, which results in conflicting
// overloaded members in CameraPreferences.
#define CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
#endif
namespace mozilla {
template<class T> class StaticAutoPtr;
@ -38,9 +31,7 @@ public:
static void Shutdown();
static bool GetPref(const char* aPref, nsACString& aVal);
#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
static bool GetPref(const char* aPref, nsresult& aVal);
#endif
static bool GetPref(const char* aPref, uint32_t& aVal);
static bool GetPref(const char* aPref, bool& aVal);
@ -49,9 +40,7 @@ protected:
static uint32_t PrefToIndex(const char* aPref);
static void PreferenceChanged(const char* aPref, void* aClosure);
#ifdef CAMERAPREFERENCES_HAVE_SEPARATE_UINT32_AND_NSRESULT
static nsresult UpdatePref(const char* aPref, nsresult& aVar);
#endif
static nsresult UpdatePref(const char* aPref, uint32_t& aVar);
static nsresult UpdatePref(const char* aPref, nsACString& aVar);
static nsresult UpdatePref(const char* aPref, bool& aVar);

Просмотреть файл

@ -162,7 +162,7 @@ public:
nsString mTypeString; // for non-main-threads
uint16_t mEventType;
enum ListenerType MOZ_ENUM_TYPE(uint8_t)
enum ListenerType : uint8_t
{
eNativeListener = 0,
eJSEventListener,

Просмотреть файл

@ -429,7 +429,7 @@ protected:
/**
* Computes the default action for the aEvent with the prefs.
*/
enum Action MOZ_ENUM_TYPE(uint8_t)
enum Action : uint8_t
{
ACTION_NONE = 0,
ACTION_SCROLL,

Просмотреть файл

@ -323,13 +323,24 @@ RTCPeerConnection.prototype = {
init: function(win) { this._win = win; },
__init: function(rtcConfig) {
this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
if (!rtcConfig.iceServers ||
!Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) {
rtcConfig.iceServers =
JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers"));
}
this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
// Normalize iceServers input
rtcConfig.iceServers.forEach(server => {
if (typeof server.urls === "string") {
server.urls = [server.urls];
} else if (!server.urls && server.url) {
// TODO: Remove support for legacy iceServer.url eventually (Bug 1116766)
server.urls = [server.url];
this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0);
}
});
this._mustValidateRTCConfiguration(rtcConfig,
"RTCPeerConnection constructor passed invalid RTCConfiguration");
if (_globalPCList._networkdown || !this._win.navigator.onLine) {
@ -432,10 +443,11 @@ RTCPeerConnection.prototype = {
},
/**
* An RTCConfiguration looks like this:
* An RTCConfiguration may look like this:
*
* { "iceServers": [ { url:"stun:stun.example.org" },
* { url:"turn:turn.example.org",
* { "iceServers": [ { urls: "stun:stun.example.org", },
* { url: "stun:stun.example.org", }, // deprecated version
* { urls: ["turn:turn1.x.org", "turn:turn2.x.org"],
* username:"jib", credential:"mypass"} ] }
*
* WebIDL normalizes structure for us, so we test well-formed stun/turn urls,
@ -456,27 +468,29 @@ RTCPeerConnection.prototype = {
};
rtcConfig.iceServers.forEach(server => {
if (!server.url) {
throw new this._win.DOMException(msg + " - missing url", "InvalidAccessError");
if (!server.urls) {
throw new this._win.DOMException(msg + " - missing urls", "InvalidAccessError");
}
let url = nicerNewURI(server.url);
if (url.scheme in { turn:1, turns:1 }) {
if (!server.username) {
throw new this._win.DOMException(msg + " - missing username: " + server.url,
"InvalidAccessError");
server.urls.forEach(urlStr => {
let url = nicerNewURI(urlStr);
if (url.scheme in { turn:1, turns:1 }) {
if (!server.username) {
throw new this._win.DOMException(msg + " - missing username: " + urlStr,
"InvalidAccessError");
}
if (!server.credential) {
throw new this._win.DOMException(msg + " - missing credential: " + urlStr,
"InvalidAccessError");
}
}
if (!server.credential) {
throw new this._win.DOMException(msg + " - missing credential: " + server.url,
"InvalidAccessError");
else if (!(url.scheme in { stun:1, stuns:1 })) {
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
"SyntaxError");
}
}
else if (!(url.scheme in { stun:1, stuns:1 })) {
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
"SyntaxError");
}
if (url.scheme in { stuns:1, turns:1 }) {
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
}
if (url.scheme in { stuns:1, turns:1 }) {
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
}
});
});
},

Просмотреть файл

@ -14,78 +14,66 @@
title: "RTCConfiguration valid/invalid permutations"
});
makePC = function (config, expect_success) {
var exception = null;
var pc = null;
try {
pc = new mozRTCPeerConnection(config);
} catch (e) {
exception = e;
}
if (pc !== null) {
pc.close();
}
pc = null
if (expect_success) {
ok(!exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") succeeds");
} else {
ok(exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") throws");
}
makePC = (config, expected_error) => {
var exception;
try {
new mozRTCPeerConnection(config).close();
} catch (e) {
exception = e;
}
is((exception? exception.name : "success"), expected_error || "success",
"mozRTCPeerConnection(" + JSON.stringify(config) + ")");
}
// This is a test of the iceServers parsing code + readable errors
runNetworkTest(function () {
var pcs = null;
var exception = null;
var config;
try {
pcs = new mozRTCPeerConnection();
new mozRTCPeerConnection().close();
} catch (e) {
exception = e;
}
ok(!exception, "mozRTCPeerConnection() succeeds");
if (pcs !== null) {
pcs.close();
}
pcs = null;
exception = null;
makePC(1, false);
makePC();
makePC({}, true);
makePC(1, "TypeError");
makePC({ iceServers: [] }, true);
makePC({});
makePC({ iceServers: [{ url:"" }] }, false);
makePC({ iceServers: [] });
makePC({ iceServers: [{ urls:"" }] }, "SyntaxError");
makePC({ iceServers: [
{ url:"stun:127.0.0.1" },
{ url:"stuns:localhost", foo:"" },
{ url:"turn:[::1]:3478", username:"p", credential:"p" },
{ url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }
]}, true);
{ urls:"stun:127.0.0.1" },
{ urls:"stun:localhost", foo:"" },
{ urls: ["stun:127.0.0.1", "stun:localhost"] },
{ urls:"stuns:localhost", foo:"" },
{ urls:"turn:[::1]:3478", username:"p", credential:"p" },
{ urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" },
{ urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" },
{ urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" },
{ url:"stun:localhost", foo:"" },
{ url:"turn:localhost", username:"p", credential:"p" }
]});
makePC({ iceServers: [{ url:"turns:localhost:3478", username:"p" }] }, false);
makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError");
makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false);
makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError");
makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError");
makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError");
try {
pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] });
new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close();
} catch (e) {
ok(e.message.indexOf("http") > 0,
"mozRTCPeerConnection() constructor has readable exceptions");
ok(e.message.indexOf("http") > 0,
"mozRTCPeerConnection() constructor has readable exceptions");
}
if (pcs !== null) {
pcs.close();
}
pcs = null;
networkTestFinished();
});

Просмотреть файл

@ -23,7 +23,7 @@ namespace dom {
// This is an internal helper class and should not be used outside of this header.
struct AudioTimelineEvent {
enum Type MOZ_ENUM_TYPE(uint32_t) {
enum Type : uint32_t {
SetValue,
LinearRamp,
ExponentialRamp,

Просмотреть файл

@ -48,18 +48,33 @@ NetworkStatsDB.prototype = {
return this.newTxn(txn_type, store_name, callback, successCb, errorCb);
},
/**
* The onupgradeneeded handler of the IDBOpenDBRequest.
* This function is called in IndexedDBHelper open() method.
*
* @param {IDBTransaction} aTransaction
* {IDBDatabase} aDb
* {64-bit integer} aOldVersion The version number on local storage.
* {64-bit integer} aNewVersion The version number to be upgraded to.
*
* @note Be careful with the database upgrade pattern.
* Because IndexedDB operations are performed asynchronously, we must
* apply a recursive approach instead of an iterative approach while
* upgrading versions.
*/
upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
if (DEBUG) {
debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!");
}
let db = aDb;
let objectStore;
for (let currVersion = aOldVersion; currVersion < aNewVersion; currVersion++) {
if (currVersion == 0) {
/**
* Create the initial database schema.
*/
// An array of upgrade functions for each version.
let upgradeSteps = [
function upgrade0to1() {
if (DEBUG) debug("Upgrade 0 to 1: Create object stores and indexes.");
// Create the initial database schema.
objectStore = db.createObjectStore(DEPRECATED_STORE_NAME, { keyPath: ["connectionType", "timestamp"] });
objectStore.createIndex("connectionType", "connectionType", { unique: false });
objectStore.createIndex("timestamp", "timestamp", { unique: false });
@ -67,10 +82,18 @@ NetworkStatsDB.prototype = {
objectStore.createIndex("txBytes", "txBytes", { unique: false });
objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false });
objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false });
if (DEBUG) {
debug("Created object stores and indexes");
}
} else if (currVersion == 2) {
upgradeNextVersion();
},
function upgrade1to2() {
if (DEBUG) debug("Upgrade 1 to 2: Do nothing.");
upgradeNextVersion();
},
function upgrade2to3() {
if (DEBUG) debug("Upgrade 2 to 3: Add keyPath appId to object store.");
// In order to support per-app traffic data storage, the original
// objectStore needs to be replaced by a new objectStore with new
// key path ("appId") and new index ("appId").
@ -99,11 +122,13 @@ NetworkStatsDB.prototype = {
objectStore.createIndex("rxTotalBytes", "rxTotalBytes", { unique: false });
objectStore.createIndex("txTotalBytes", "txTotalBytes", { unique: false });
if (DEBUG) {
debug("Created object stores and indexes for version 3");
}
} else if (currVersion == 3) {
// Delete redundent indexes (leave "network" only).
upgradeNextVersion();
},
function upgrade3to4() {
if (DEBUG) debug("Upgrade 3 to 4: Delete redundant indexes.");
// Delete redundant indexes (leave "network" only).
objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME);
if (objectStore.indexNames.contains("appId")) {
objectStore.deleteIndex("appId");
@ -127,10 +152,12 @@ NetworkStatsDB.prototype = {
objectStore.deleteIndex("txTotalBytes");
}
if (DEBUG) {
debug("Deleted redundent indexes for version 4");
}
} else if (currVersion == 4) {
upgradeNextVersion();
},
function upgrade4to5() {
if (DEBUG) debug("Upgrade 4 to 5: Create object store for alarms.");
// In order to manage alarms, it is necessary to use a global counter
// (totalBytes) that will increase regardless of the system reboot.
objectStore = aTransaction.objectStore(DEPRECATED_STORE_NAME);
@ -143,6 +170,8 @@ NetworkStatsDB.prototype = {
objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor){
// upgrade4to5 completed now.
upgradeNextVersion();
return;
}
@ -188,11 +217,11 @@ NetworkStatsDB.prototype = {
objectStore = db.createObjectStore(ALARMS_STORE_NAME, { keyPath: "id", autoIncrement: true });
objectStore.createIndex("alarm", ['networkId','threshold'], { unique: false });
objectStore.createIndex("manifestURL", "manifestURL", { unique: false });
},
function upgrade5to6() {
if (DEBUG) debug("Upgrade 5 to 6: Add keyPath serviceType to object store.");
if (DEBUG) {
debug("Created alarms store for version 5");
}
} else if (currVersion == 5) {
// In contrast to "per-app" traffic data, "system-only" traffic data
// refers to data which can not be identified by any applications.
// To further support "system-only" data storage, the data can be
@ -209,6 +238,8 @@ NetworkStatsDB.prototype = {
let cursor = event.target.result;
if (!cursor) {
db.deleteObjectStore(DEPRECATED_STORE_NAME);
// upgrade5to6 completed now.
upgradeNextVersion();
return;
}
@ -217,11 +248,11 @@ NetworkStatsDB.prototype = {
newObjectStore.put(newStats);
cursor.continue();
};
},
function upgrade6to7() {
if (DEBUG) debug("Upgrade 6 to 7: Replace alarm threshold by relativeThreshold.");
if (DEBUG) {
debug("Added new key 'serviceType' for version 6");
}
} else if (currVersion == 6) {
// Replace threshold attribute of alarm index by relativeThreshold in alarms DB.
// Now alarms are indexed by relativeThreshold, which is the threshold relative
// to current system stats.
@ -239,6 +270,7 @@ NetworkStatsDB.prototype = {
alarmsStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
upgrade6to7_updateTotalBytes();
return;
}
@ -250,75 +282,132 @@ NetworkStatsDB.prototype = {
cursor.continue();
}
// Previous versions save accumulative totalBytes, increasing althought the system
// reboots or resets stats. But is necessary to reset the total counters when reset
// through 'clearInterfaceStats'.
let statsStore = aTransaction.objectStore(STATS_STORE_NAME);
let networks = [];
// Find networks stored in the database.
statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
networks.push(cursor.key);
cursor.continue();
return;
}
function upgrade6to7_updateTotalBytes() {
if (DEBUG) debug("Upgrade 6 to 7: Update TotalBytes.");
// Previous versions save accumulative totalBytes, increasing although the system
// reboots or resets stats. But is necessary to reset the total counters when reset
// through 'clearInterfaceStats'.
let statsStore = aTransaction.objectStore(STATS_STORE_NAME);
let networks = [];
networks.forEach(function(network) {
let lowerFilter = [0, "", network, 0];
let upperFilter = [0, "", network, ""];
let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false);
// Find networks stored in the database.
statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) {
let cursor = event.target.result;
// Find number of samples for a given network.
statsStore.count(range).onsuccess = function(event) {
// If there are more samples than the max allowed, there is no way to know
// when does reset take place.
if (event.target.result >= VALUES_MAX_LENGTH) {
return;
}
// Store each network into an array.
if (cursor) {
networks.push(cursor.key);
cursor.continue();
return;
}
let last = null;
// Reset detected if the first sample totalCounters are different than bytes
// counters. If so, the total counters should be recalculated.
statsStore.openCursor(range).onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
// Start to deal with each network.
let pending = networks.length;
if (pending === 0) {
// Found no records of network. upgrade6to7 completed now.
upgradeNextVersion();
return;
}
networks.forEach(function(network) {
let lowerFilter = [0, "", network, 0];
let upperFilter = [0, "", network, ""];
let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false);
// Find number of samples for a given network.
statsStore.count(range).onsuccess = function(event) {
let recordCount = event.target.result;
// If there are more samples than the max allowed, there is no way to know
// when does reset take place.
if (recordCount === 0 || recordCount >= VALUES_MAX_LENGTH) {
pending--;
if (pending === 0) {
upgradeNextVersion();
}
return;
}
if (!last) {
if (cursor.value.rxTotalBytes == cursor.value.rxBytes &&
cursor.value.txTotalBytes == cursor.value.txBytes) {
let last = null;
// Reset detected if the first sample totalCounters are different than bytes
// counters. If so, the total counters should be recalculated.
statsStore.openCursor(range).onsuccess = function(event) {
let cursor = event.target.result;
if (!cursor) {
pending--;
if (pending === 0) {
upgradeNextVersion();
}
return;
}
if (!last) {
if (cursor.value.rxTotalBytes == cursor.value.rxBytes &&
cursor.value.txTotalBytes == cursor.value.txBytes) {
pending--;
if (pending === 0) {
upgradeNextVersion();
}
return;
}
cursor.value.rxTotalBytes = cursor.value.rxBytes;
cursor.value.txTotalBytes = cursor.value.txBytes;
cursor.update(cursor.value);
last = cursor.value;
cursor.continue();
return;
}
cursor.value.rxTotalBytes = cursor.value.rxBytes;
cursor.value.txTotalBytes = cursor.value.txBytes;
// Recalculate the total counter for last / current sample
cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes;
cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes;
cursor.update(cursor.value);
last = cursor.value;
cursor.continue();
return;
}
// Recalculate the total counter for last / current sample
cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes;
cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes;
cursor.update(cursor.value);
last = cursor.value;
cursor.continue();
}
}
}, this);
};
} else if (currVersion == 7) {
}, this); // end of networks.forEach()
}; // end of statsStore.index("network").openKeyCursor().onsuccess callback
} // end of function upgrade6to7_updateTotalBytes
},
function upgrade7to8() {
if (DEBUG) debug("Upgrade 7 to 8: Create index serviceType.");
// Create index for 'ServiceType' in order to make it retrievable.
let statsStore = aTransaction.objectStore(STATS_STORE_NAME);
statsStore.createIndex("serviceType", "serviceType", { unique: false });
},
];
if (DEBUG) {
debug("Create index of 'serviceType' for version 8");
}
let index = aOldVersion;
let outer = this;
function upgradeNextVersion() {
if (index == aNewVersion) {
debug("Upgrade finished.");
return;
}
try {
var i = index++;
if (DEBUG) debug("Upgrade step: " + i + "\n");
upgradeSteps[i].call(outer);
} catch (ex) {
dump("Caught exception " + ex);
throw ex;
return;
}
}
if (aNewVersion > upgradeSteps.length) {
debug("No migration steps for the new version!");
aTransaction.abort();
return;
}
upgradeNextVersion();
},
importData: function importData(aStats) {

Просмотреть файл

@ -1557,6 +1557,10 @@ nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain,
nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
if (!tag->IsEnabled()) {
return NS_ERROR_NOT_AVAILABLE;
}
// We only ensure support for clearing Flash site data for now.
// We will also attempt to clear data for any plugin that happens
// to be loaded already.

Просмотреть файл

@ -90,8 +90,7 @@ SVGCircleElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
if (r <= 0.f) {
// Rendering of the element is disabled
aBounds->MoveTo(x, y);
aBounds->SetEmpty();
*aBounds = Rect(aTransform * Point(x, y), Size());
return true;
}

Просмотреть файл

@ -101,8 +101,7 @@ SVGEllipseElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
if (rx <= 0.f || ry <= 0.f) {
// Rendering of the element is disabled
aBounds->MoveTo(x, y);
aBounds->SetEmpty();
*aBounds = Rect(aTransform * Point(x, y), Size());
return true;
}

Просмотреть файл

@ -226,6 +226,23 @@ SVGImageElement::IsAttributeMapped(const nsIAtom* name) const
/* For the purposes of the update/invalidation logic pretend to
be a rectangle. */
bool
SVGImageElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform)
{
Rect rect;
GetAnimatedLengthValues(&rect.x, &rect.y, &rect.width,
&rect.height, nullptr);
if (rect.IsEmpty()) {
// Rendering of the element disabled
rect.SetEmpty(); // Make sure width/height are zero and not negative
}
*aBounds = aTransform.TransformBounds(rect);
return true;
}
TemporaryRef<Path>
SVGImageElement::BuildPath(PathBuilder* aBuilder)
{

Просмотреть файл

@ -53,6 +53,8 @@ public:
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
// nsSVGPathGeometryElement methods:
virtual bool GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
const Matrix& aTransform) MOZ_OVERRIDE;
virtual TemporaryRef<Path> BuildPath(PathBuilder* aBuilder) MOZ_OVERRIDE;
// nsSVGSVGElement methods:

Просмотреть файл

@ -17,7 +17,7 @@
namespace mozilla {
// Alignment Types
enum SVGAlign MOZ_ENUM_TYPE(uint8_t) {
enum SVGAlign : uint8_t {
SVG_PRESERVEASPECTRATIO_UNKNOWN = 0,
SVG_PRESERVEASPECTRATIO_NONE = 1,
SVG_PRESERVEASPECTRATIO_XMINYMIN = 2,
@ -37,7 +37,7 @@ const uint16_t SVG_ALIGN_MIN_VALID = SVG_PRESERVEASPECTRATIO_NONE;
const uint16_t SVG_ALIGN_MAX_VALID = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
// Meet-or-slice Types
enum SVGMeetOrSlice MOZ_ENUM_TYPE(uint8_t) {
enum SVGMeetOrSlice : uint8_t {
SVG_MEETORSLICE_UNKNOWN = 0,
SVG_MEETORSLICE_MEET = 1,
SVG_MEETORSLICE_SLICE = 2

Просмотреть файл

@ -122,7 +122,8 @@ SVGRectElement::GetGeometryBounds(Rect* aBounds, Float aStrokeWidth,
if (rect.IsEmpty()) {
// Rendering of the element disabled
rect.SetEmpty(); // Make sure width/height are zero and not negative
*aBounds = rect; // We still want the x/y position from 'rect'
// We still want the x/y position from 'rect'
*aBounds = aTransform.TransformBounds(rect);
return true;
}

Просмотреть файл

@ -1247,5 +1247,33 @@ SVGSVGElement::ClearTransformProperty()
return UnsetProperty(nsGkAtoms::transform);
}
int32_t
SVGSVGElement::GetIntrinsicWidth()
{
if (mLengthAttributes[ATTR_WIDTH].IsPercentage()) {
return -1;
}
// Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue
// that uses the passed argument as the context, but that's fine since we
// know the length isn't a percentage so the context won't be used (and we
// need to pass the element to be able to resolve em/ex units).
float width = mLengthAttributes[ATTR_WIDTH].GetAnimValue(this);
return nsSVGUtils::ClampToInt(width);
}
int32_t
SVGSVGElement::GetIntrinsicHeight()
{
if (mLengthAttributes[ATTR_HEIGHT].IsPercentage()) {
return -1;
}
// Passing |this| as a SVGSVGElement* invokes the variant of GetAnimValue
// that uses the passed argument as the context, but that's fine since we
// know the length isn't a percentage so the context won't be used (and we
// need to pass the element to be able to resolve em/ex units).
float height = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(this);
return nsSVGUtils::ClampToInt(height);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -147,6 +147,15 @@ public:
// public helpers:
/**
* Returns -1 if the width/height is a percentage, else returns the user unit
* length clamped to fit in a int32_t.
* XXX see bug 1112533 comment 3 - we should fix drawImage so that we can
* change these methods to make zero the error flag for percentages.
*/
int32_t GetIntrinsicWidth();
int32_t GetIntrinsicHeight();
/**
* Returns true if this element has a base/anim value for its "viewBox"
* attribute that defines a viewBox rectangle with finite values, or

Просмотреть файл

@ -8,7 +8,8 @@
*/
dictionary RTCIceServer {
DOMString url;
(DOMString or sequence<DOMString>) urls;
DOMString url; //deprecated
DOMString? credential = null;
DOMString? username = null;
};

Просмотреть файл

@ -125,8 +125,11 @@ SVGTurbulenceRenderer<Type,Stitch,f32x4_t,i32x4_t,u8x16_t>::InitFromSeed(int32_t
float gradient[4][sBSize][2];
for (int32_t k = 0; k < 4; k++) {
for (int32_t i = 0; i < sBSize; i++) {
float a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize;
float b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize;
float a, b;
do {
a = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize;
b = float((rand.Next() % (sBSize + sBSize)) - sBSize) / sBSize;
} while (a == 0 && b == 0);
float s = sqrt(a * a + b * b);
gradient[k][i][0] = a / s;
gradient[k][i][1] = b / s;

Просмотреть файл

@ -1050,6 +1050,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
return;
}
nsIntSize oldSize = mSize;
UpdateRenderTarget();
// Failed to create a render target or the view.
@ -1069,7 +1070,13 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
nsIntRect intRect = nsIntRect(nsIntPoint(0, 0), mSize);
// Sometimes the invalid region is larger than we want to draw.
nsIntRegion invalidRegionSafe;
invalidRegionSafe.And(aInvalidRegion, intRect);
if (mSize != oldSize) {
invalidRegionSafe = intRect;
} else {
invalidRegionSafe.And(aInvalidRegion, intRect);
}
nsIntRect invalidRect = invalidRegionSafe.GetBounds();
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
mInvalidRegion = invalidRegionSafe;

Просмотреть файл

@ -239,7 +239,7 @@ private:
DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000);
DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520);
DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time", ImageMemDecodeBytesAtATime, uint32_t, 200000);
DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, false);
DECL_GFX_PREF(Live, "image.mem.decodeondraw", ImageMemDecodeOnDraw, bool, true);
DECL_GFX_PREF(Live, "image.mem.discardable", ImageMemDiscardable, bool, false);
DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1);
DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb", ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024);

Просмотреть файл

@ -68,45 +68,6 @@ SVGDocumentWrapper::DestroyViewer()
}
}
bool
SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension,
int32_t& aResult)
{
SVGSVGElement* rootElem = GetRootSVGElem();
NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type");
// Get the width or height SVG object
nsRefPtr<SVGAnimatedLength> domAnimLength;
if (aDimension == eWidth) {
domAnimLength = rootElem->Width();
} else {
NS_ABORT_IF_FALSE(aDimension == eHeight, "invalid dimension");
domAnimLength = rootElem->Height();
}
NS_ENSURE_TRUE(domAnimLength, false);
// Get the animated value from the object
nsRefPtr<DOMSVGLength> domLength = domAnimLength->AnimVal();
NS_ENSURE_TRUE(domLength, false);
// Check if it's a percent value (and fail if so)
uint16_t unitType;
nsresult rv = domLength->GetUnitType(&unitType);
NS_ENSURE_SUCCESS(rv, false);
if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
return false;
}
// Non-percent value - woot! Grab it & return it.
float floatLength;
rv = domLength->GetValue(&floatLength);
NS_ENSURE_SUCCESS(rv, false);
aResult = nsSVGUtils::ClampToInt(floatLength);
return true;
}
nsIFrame*
SVGDocumentWrapper::GetRootLayoutFrame()
{

Просмотреть файл

@ -52,21 +52,6 @@ public:
eHeight
};
/**
* Looks up the value of the wrapped SVG document's |width| or |height|
* attribute in CSS pixels, and returns it by reference. If the document has
* a percent value for the queried attribute, then this method fails
* (returns false).
*
* @param aDimension Indicates whether the width or height is desired.
* @param[out] aResult If this method succeeds, then this outparam will be
populated with the width or height in CSS pixels.
* @return false to indicate failure, if the queried attribute has a
* percent value. Otherwise, true.
*
*/
bool GetWidthOrHeight(Dimension aDimension, int32_t& aResult);
/**
* Returns the wrapped document, or nullptr on failure. (No AddRef.)
*/

Просмотреть файл

@ -472,17 +472,14 @@ NS_IMETHODIMP
VectorImage::GetWidth(int32_t* aWidth)
{
if (mError || !mIsFullyLoaded) {
*aWidth = 0;
return NS_ERROR_FAILURE;
*aWidth = -1;
} else {
SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem();
MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished "
"loading without errors");
*aWidth = rootElem->GetIntrinsicWidth();
}
if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth,
*aWidth)) {
*aWidth = 0;
return NS_ERROR_FAILURE;
}
return NS_OK;
return *aWidth >= 0 ? NS_OK : NS_ERROR_FAILURE;
}
//******************************************************************************
@ -541,17 +538,14 @@ NS_IMETHODIMP
VectorImage::GetHeight(int32_t* aHeight)
{
if (mError || !mIsFullyLoaded) {
*aHeight = 0;
return NS_ERROR_FAILURE;
*aHeight = -1;
} else {
SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem();
MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished "
"loading without errors");
*aHeight = rootElem->GetIntrinsicHeight();
}
if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight,
*aHeight)) {
*aHeight = 0;
return NS_ERROR_FAILURE;
}
return NS_OK;
return *aHeight >= 0 ? NS_OK : NS_ERROR_FAILURE;
}
//******************************************************************************
@ -663,17 +657,20 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
if (aWhichFrame > FRAME_MAX_VALUE)
return nullptr;
if (mError)
if (mError || !mIsFullyLoaded)
return nullptr;
// Look up height & width
// ----------------------
nsIntSize imageIntSize;
if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth,
imageIntSize.width) ||
!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight,
imageIntSize.height)) {
// We'll get here if our SVG doc has a percent-valued width or height.
SVGSVGElement* svgElem = mSVGDocumentWrapper->GetRootSVGElem();
MOZ_ASSERT(svgElem, "Should have a root SVG elem, since we finished "
"loading without errors");
nsIntSize imageIntSize(svgElem->GetIntrinsicWidth(),
svgElem->GetIntrinsicHeight());
if (imageIntSize.IsEmpty()) {
// We'll get here if our SVG doc has a percent-valued or negative width or
// height.
return nullptr;
}

Просмотреть файл

@ -9,9 +9,8 @@ SOURCES += [
]
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
LOCAL_INCLUDES += [
'../icu/source/common',
'../icu/source/i18n',
'../locale',
'../lwbrk',
'../strres',

Просмотреть файл

@ -11,10 +11,9 @@ UNIFIED_SOURCES += [
]
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
LOCAL_INCLUDES += [
'..',
'../../icu/source/common',
'../../icu/source/i18n',
]
FAIL_ON_WARNINGS = True

Просмотреть файл

@ -3052,18 +3052,6 @@ MOZ_ARG_WITH_STRING(wrap-malloc,
[ --with-wrap-malloc=DIR Location of malloc wrapper library],
WRAP_LDFLAGS="${WRAP_LDFLAGS} $withval")
dnl ========================================================
dnl = Use compacting GC
dnl ========================================================
dnl Compact the heap by moving GC things when doing a shrinking colletion.
MOZ_ARG_ENABLE_BOOL(gccompacting,
[ --enable-gccompacting Compact the heap by moving GC things],
JSGC_COMPACTING=1,
JSGC_COMPACTING= )
if test -n "$JSGC_COMPACTING"; then
AC_DEFINE(JSGC_COMPACTING)
fi
dnl ========================================================
dnl = Use a smaller chunk size for GC chunks
dnl ========================================================

Просмотреть файл

@ -3257,6 +3257,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS
MOZ_ASSERT(element->pn_kid->isKind(PNK_NAME));
target = element->pn_kid;
}
if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
if (target->isKind(PNK_NAME)) {
if (!EmitName(cx, bce, prologOp, target))
return false;
@ -3276,6 +3278,8 @@ EmitDestructuringDeclsWithEmitter(ExclusiveContext *cx, BytecodeEmitter *bce, JS
ParseNode *target = member->isKind(PNK_MUTATEPROTO) ? member->pn_kid : member->pn_right;
if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
if (target->isKind(PNK_NAME)) {
if (!EmitName(cx, bce, prologOp, target))
return false;
@ -3341,7 +3345,7 @@ EmitDestructuringOpsHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode
* lhs expression. (Same post-condition as EmitDestructuringOpsHelper)
*/
static bool
EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption emitOption)
EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *target, VarEmitOption emitOption)
{
MOZ_ASSERT(emitOption != DefineVars);
@ -3349,10 +3353,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
// destructuring initialiser-form, call ourselves to handle it, then pop
// the matched value. Otherwise emit an lvalue bytecode sequence followed
// by an assignment op.
if (pn->isKind(PNK_SPREAD))
pn = pn->pn_kid;
if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) {
if (!EmitDestructuringOpsHelper(cx, bce, pn, emitOption))
if (target->isKind(PNK_SPREAD))
target = target->pn_kid;
else if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
if (target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT)) {
if (!EmitDestructuringOpsHelper(cx, bce, target, emitOption))
return false;
if (emitOption == InitializeVars) {
// Per its post-condition, EmitDestructuringOpsHelper has left the
@ -3363,15 +3369,15 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
} else if (emitOption == PushInitialValues) {
// The lhs is a simple name so the to-be-destructured value is
// its initial value and there is nothing to do.
MOZ_ASSERT(pn->getOp() == JSOP_SETLOCAL || pn->getOp() == JSOP_INITLEXICAL);
MOZ_ASSERT(pn->pn_dflags & PND_BOUND);
MOZ_ASSERT(target->getOp() == JSOP_SETLOCAL || target->getOp() == JSOP_INITLEXICAL);
MOZ_ASSERT(target->pn_dflags & PND_BOUND);
} else {
switch (pn->getKind()) {
switch (target->getKind()) {
case PNK_NAME:
if (!BindNameToSlot(cx, bce, pn))
if (!BindNameToSlot(cx, bce, target))
return false;
switch (pn->getOp()) {
switch (target->getOp()) {
case JSOP_SETNAME:
case JSOP_STRICTSETNAME:
case JSOP_SETGNAME:
@ -3388,11 +3394,11 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
// but the operands are on the stack in the wrong order for
// JSOP_SETPROP, so we have to add a JSOP_SWAP.
jsatomid atomIndex;
if (!bce->makeAtomIndex(pn->pn_atom, &atomIndex))
if (!bce->makeAtomIndex(target->pn_atom, &atomIndex))
return false;
if (!pn->isOp(JSOP_SETCONST)) {
bool global = pn->isOp(JSOP_SETGNAME) || pn->isOp(JSOP_STRICTSETGNAME);
if (!target->isOp(JSOP_SETCONST)) {
bool global = target->isOp(JSOP_SETGNAME) || target->isOp(JSOP_STRICTSETGNAME);
JSOp bindOp = global ? JSOP_BINDGNAME : JSOP_BINDNAME;
if (!EmitIndex32(cx, bindOp, atomIndex, bce))
return false;
@ -3400,7 +3406,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
return false;
}
if (!EmitIndexOp(cx, pn->getOp(), atomIndex, bce))
if (!EmitIndexOp(cx, target->getOp(), atomIndex, bce))
return false;
break;
}
@ -3408,7 +3414,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
case JSOP_SETLOCAL:
case JSOP_SETARG:
case JSOP_INITLEXICAL:
if (!EmitVarOp(cx, pn, pn->getOp(), bce))
if (!EmitVarOp(cx, target, target->getOp(), bce))
return false;
break;
@ -3427,12 +3433,12 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
// In `[a.x] = [b]`, per spec, `b` is evaluated before `a`. Then we
// need a property set -- but the operands are on the stack in the
// wrong order for JSOP_SETPROP, so we have to add a JSOP_SWAP.
if (!EmitTree(cx, bce, pn->pn_expr))
if (!EmitTree(cx, bce, target->pn_expr))
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
JSOp setOp = bce->sc->strict ? JSOP_STRICTSETPROP : JSOP_SETPROP;
if (!EmitAtomOp(cx, pn, setOp, bce))
if (!EmitAtomOp(cx, target, setOp, bce))
return false;
break;
}
@ -3443,14 +3449,14 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
// `[a[x]] = [b]`, is handled much the same way. The JSOP_SWAP
// is emitted by EmitElemOperands.
JSOp setOp = bce->sc->strict ? JSOP_STRICTSETELEM : JSOP_SETELEM;
if (!EmitElemOp(cx, pn, setOp, bce))
if (!EmitElemOp(cx, target, setOp, bce))
return false;
break;
}
case PNK_CALL:
MOZ_ASSERT(pn->pn_xflags & PNX_SETCALL);
if (!EmitTree(cx, bce, pn))
MOZ_ASSERT(target->pn_xflags & PNX_SETCALL);
if (!EmitTree(cx, bce, target))
return false;
// Pop the call return value. Below, we pop the RHS too, balancing
@ -3500,6 +3506,33 @@ EmitIteratorNext(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn=nullp
return true;
}
/**
* EmitDefault will check if the value on top of the stack is "undefined".
* If so, it will replace that value on the stack with the value defined by |defaultExpr|.
*/
static bool
EmitDefault(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *defaultExpr)
{
if (Emit1(cx, bce, JSOP_DUP) < 0) // VALUE VALUE
return false;
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) // VALUE VALUE UNDEFINED
return false;
if (Emit1(cx, bce, JSOP_STRICTEQ) < 0) // VALUE EQL?
return false;
// Emit source note to enable ion compilation.
if (NewSrcNote(cx, bce, SRC_IF) < 0)
return false;
ptrdiff_t jump = EmitJump(cx, bce, JSOP_IFEQ, 0); // VALUE
if (jump < 0)
return false;
if (Emit1(cx, bce, JSOP_POP) < 0) // .
return false;
if (!EmitTree(cx, bce, defaultExpr)) // DEFAULTVALUE
return false;
SetJumpOffsetAt(bce, jump);
return true;
}
static bool
EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pattern,
VarEmitOption emitOption)
@ -3526,7 +3559,14 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
* current property name "label" on the left of a colon in the object
* initializer.
*/
if (member->isKind(PNK_SPREAD)) {
ParseNode *pndefault = nullptr;
ParseNode *elem = member;
if (elem->isKind(PNK_ASSIGN)) {
pndefault = elem->pn_right;
elem = elem->pn_left;
}
if (elem->isKind(PNK_SPREAD)) {
/* Create a new array with the rest of the iterator */
ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3); // ... OBJ? ITER ARRAY
if (off < 0)
@ -3581,8 +3621,11 @@ EmitDestructuringOpsArrayHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Pars
return false;
}
if (pndefault && !EmitDefault(cx, bce, pndefault))
return false;
// Destructure into the pattern the element contains.
ParseNode *subpattern = member;
ParseNode *subpattern = elem;
if (subpattern->isKind(PNK_ELISION)) {
// The value destructuring into an elision just gets ignored.
if (Emit1(cx, bce, JSOP_POP) < 0) // ... OBJ? ITER
@ -3684,6 +3727,12 @@ EmitDestructuringOpsObjectHelper(ExclusiveContext *cx, BytecodeEmitter *bce, Par
if (needsGetElem && !EmitElemOpBase(cx, bce, JSOP_GETELEM)) // ... OBJ PROP
return false;
if (subpattern->isKind(PNK_ASSIGN)) {
if (!EmitDefault(cx, bce, subpattern->pn_right))
return false;
subpattern = subpattern->pn_left;
}
// Destructure PROP per this member's subpattern.
int32_t depthBefore = bce->stackDepth;
if (!EmitDestructuringLHS(cx, bce, subpattern, emitOption))

Просмотреть файл

@ -3385,6 +3385,8 @@ Parser<FullParseHandler>::checkDestructuringObject(BindData<FullParseHandler> *d
MOZ_ASSERT(member->isKind(PNK_COLON) || member->isKind(PNK_SHORTHAND));
expr = member->pn_right;
}
if (expr->isKind(PNK_ASSIGN))
expr = expr->pn_left;
bool ok;
if (expr->isKind(PNK_ARRAY) || expr->isKind(PNK_OBJECT)) {
@ -3429,6 +3431,8 @@ Parser<FullParseHandler>::checkDestructuringArray(BindData<FullParseHandler> *da
report(ParseError, false, target, JSMSG_BAD_DESTRUCT_TARGET);
return false;
}
} else if (target->isKind(PNK_ASSIGN)) {
target = target->pn_left;
}
bool ok;

Просмотреть файл

@ -143,7 +143,6 @@ void
CheckHashTablesAfterMovingGC(JSRuntime *rt);
#endif
#ifdef JSGC_COMPACTING
struct MovingTracer : JSTracer {
explicit MovingTracer(JSRuntime *rt) : JSTracer(rt, Visit, TraceWeakMapKeysValues) {}
@ -152,7 +151,6 @@ struct MovingTracer : JSTracer {
return trc->callback == Visit;
}
};
#endif
} /* namespace gc */
} /* namespace js */

Просмотреть файл

@ -34,11 +34,8 @@ struct FinalizePhase;
class MarkingValidator;
struct AutoPrepareForTracing;
class AutoTraceSession;
#ifdef JSGC_COMPACTING
struct ArenasToUpdate;
struct MovingTracer;
#endif
class ChunkPool
{
@ -297,11 +294,7 @@ class GCRuntime
bool isHeapMajorCollecting() { return heapState == js::MajorCollecting; }
bool isHeapMinorCollecting() { return heapState == js::MinorCollecting; }
bool isHeapCollecting() { return isHeapMajorCollecting() || isHeapMinorCollecting(); }
#ifdef JSGC_COMPACTING
bool isHeapCompacting() { return isHeapMajorCollecting() && state() == COMPACT; }
#else
bool isHeapCompacting() { return false; }
#endif
bool triggerGC(JS::gcreason::Reason reason);
void maybeAllocTriggerZoneGC(Zone *zone, const AutoLockGC &lock);
@ -437,11 +430,9 @@ class GCRuntime
void disableGenerationalGC();
void enableGenerationalGC();
#ifdef JSGC_COMPACTING
void disableCompactingGC();
void enableCompactingGC();
bool isCompactingGCEnabled();
#endif
void setGrayRootsTracer(JSTraceDataOp traceOp, void *data);
bool addBlackRootsTracer(JSTraceDataOp traceOp, void *data);
@ -604,19 +595,17 @@ class GCRuntime
void assertBackgroundSweepingFinished();
bool shouldCompact();
bool compactPhase(bool lastGC);
#ifdef JSGC_COMPACTING
void sweepTypesAfterCompacting(Zone *zone);
void sweepZoneAfterCompacting(Zone *zone);
ArenaHeader *relocateArenas();
void updateAllCellPointersParallel(ArenasToUpdate &source);
void updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source);
void updateAllCellPointersParallel(MovingTracer *trc);
void updateAllCellPointersSerial(MovingTracer *trc);
void updatePointersToRelocatedCells();
void releaseRelocatedArenas(ArenaHeader *relocatedList);
void releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, const AutoLockGC& lock);
#ifdef DEBUG
void protectRelocatedArenas(ArenaHeader *relocatedList);
void unprotectRelocatedArenas(ArenaHeader *relocatedList);
#endif
#endif
void finishCollection();
@ -811,13 +800,11 @@ class GCRuntime
*/
unsigned generationalDisabled;
#ifdef JSGC_COMPACTING
/*
* Some code cannot tolerate compacting GC so it can be disabled with this
* counter.
*/
unsigned compactingDisabled;
#endif
/*
* This is true if we are in the middle of a brain transplant (e.g.,
@ -918,9 +905,7 @@ class GCRuntime
size_t noGCOrAllocationCheck;
#ifdef JSGC_COMPACTING
ArenaHeader* relocatedArenasToRelease;
#endif
#endif

Просмотреть файл

@ -642,10 +642,8 @@ struct ArenaHeader
void unmarkAll();
#ifdef JSGC_COMPACTING
size_t countUsedCells();
size_t countFreeCells();
#endif
};
static_assert(ArenaZoneOffset == offsetof(ArenaHeader, zone),
"The hardcoded API zone offset must match the actual offset.");

Просмотреть файл

@ -161,18 +161,14 @@ CheckMarkedThing(JSTracer *trc, T **thingp)
T *thing = *thingp;
MOZ_ASSERT(*thingp);
#ifdef JSGC_COMPACTING
thing = MaybeForwarded(thing);
#endif
/* This function uses data that's not available in the nursery. */
if (IsInsideNursery(thing))
return;
#ifdef JSGC_COMPACTING
MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc) && !Nursery::IsMinorCollectionTracer(trc),
!IsForwarded(*thingp));
#endif
/*
* Permanent atoms are not associated with this runtime, but will be ignored
@ -184,13 +180,8 @@ CheckMarkedThing(JSTracer *trc, T **thingp)
Zone *zone = thing->zoneFromAnyThread();
JSRuntime *rt = trc->runtime();
#ifdef JSGC_COMPACTING
MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessZone(zone));
MOZ_ASSERT_IF(!MovingTracer::IsMovingTracer(trc), CurrentThreadCanAccessRuntime(rt));
#else
MOZ_ASSERT(CurrentThreadCanAccessZone(zone));
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
#endif
MOZ_ASSERT(zone->runtimeFromAnyThread() == trc->runtime());
MOZ_ASSERT(trc->hasTracingDetails());
@ -437,10 +428,8 @@ IsMarkedFromAnyThread(T **thingp)
Zone *zone = (*thingp)->asTenured().zoneFromAnyThread();
if (!zone->isCollectingFromAnyThread() || zone->isGCFinished())
return true;
#ifdef JSGC_COMPACTING
if (zone->isGCCompacting() && IsForwarded(*thingp))
*thingp = Forwarded(*thingp);
#endif
return (*thingp)->asTenured().isMarked();
}
@ -481,12 +470,10 @@ IsAboutToBeFinalizedFromAnyThread(T **thingp)
return false;
return !thing->asTenured().isMarked();
}
#ifdef JSGC_COMPACTING
else if (zone->isGCCompacting() && IsForwarded(thing)) {
*thingp = Forwarded(thing);
return false;
}
#endif
return false;
}
@ -504,11 +491,10 @@ UpdateIfRelocated(JSRuntime *rt, T **thingp)
return *thingp;
}
#ifdef JSGC_COMPACTING
Zone *zone = (*thingp)->zone();
if (zone->isGCCompacting() && IsForwarded(*thingp))
*thingp = Forwarded(*thingp);
#endif
return *thingp;
}
@ -1815,10 +1801,8 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
// Global objects all have the same trace hook. That hook is safe without barriers
// if the global has no custom trace hook of its own, or has been moved to a different
// compartment, and so can't have one.
MOZ_ASSERT_IF(runtime()->gc.isIncrementalGCEnabled() &&
!(clasp->trace == JS_GlobalObjectTraceHook &&
(!obj->compartment()->options().getTrace() ||
!obj->isOwnGlobal())),
MOZ_ASSERT_IF(!(clasp->trace == JS_GlobalObjectTraceHook &&
(!obj->compartment()->options().getTrace() || !obj->isOwnGlobal())),
clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS);
if (clasp->trace == InlineTypedObject::obj_trace)
goto scan_typed_obj;

Просмотреть файл

@ -0,0 +1,166 @@
load(libdir + 'asserts.js');
load(libdir + 'eqArrayHelper.js');
var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]';
var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}';
var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}';
function testAll(fn) {
assertEqArray(fn(arrayPattern, []), [1, 2, 3, 4, 5, 6]);
assertEqArray(fn(arrayPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]);
assertEqArray(fn(arrayPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]);
assertEqArray(fn(arrayPattern, [0, false]), [0, false, 3, 4, 5, 6]);
assertEqArray(fn(objectPattern, []), [1, 2, 3, 4, 5, 6]);
assertEqArray(fn(objectPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]);
assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]);
assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]);
assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]);
assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]);
assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]);
assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}, d: {d: 5, e: 6}}), [1, 3, 4, 5, 6, 6]);
}
function testVar(pattern, input) {
return new Function('input',
'var ' + pattern + ' = input;' +
'return [a, b, c, d, e, f];'
)(input);
}
testAll(testVar);
function testLet(pattern, input) {
return new Function('input',
'let ' + pattern + ' = input;' +
'return [a, b, c, d, e, f];'
)(input);
}
testAll(testLet);
function testConst(pattern, input) {
return new Function('input',
'const ' + pattern + ' = input;' +
'return [a, b, c, d, e, f];'
)(input);
}
testAll(testConst);
function testGlobal(pattern, input) {
return new Function('input',
'(' + pattern + ') = input;' +
'return [a, b, c, d, e, f];'
)(input);
}
testAll(testGlobal);
function testClosure(pattern, input) {
return new Function('input',
'var rest; (function () {' +
'(' + pattern + ') = input;' +
'})();' +
'return [a, b, c, d, e, f];'
)(input);
}
testAll(testClosure);
function testArgument(pattern, input) {
return new Function('input',
'return (function (' + pattern + ') {' +
'return [a, b, c, d, e, f]; })(input);'
)(input);
}
testAll(testArgument);
function testArgumentFunction(pattern, input) {
return new Function(pattern,
'return [a, b, c, d, e, f];'
)(input);
}
// XXX: ES6 requires the `Function` constructor to accept arbitrary
// `BindingElement`s as formal parameters. See Bug 1037939.
// Once fixed, please update the assertions below.
assertThrowsInstanceOf(() => testAll(testArgumentFunction), SyntaxError);
function testThrow(pattern, input) {
return new Function('input',
'try { throw input }' +
'catch(' + pattern + ') {' +
'return [a, b, c, d, e, f]; }'
)(input);
}
testAll(testThrow);
// XXX: Support for let blocks and expressions will be removed in bug 1023609.
// However, they test a special code path in destructuring assignment so having
// these tests here for now seems like a good idea.
function testLetBlock(pattern, input) {
return new Function('input',
'let (' + pattern + ' = input)' +
'{ return [a, b, c, d, e, f]; }'
)(input);
}
testAll(testLetBlock);
function testLetExpression(pattern, input) {
return new Function('input',
'return (let (' + pattern + ' = input) [a, b, c, d, e, f]);'
)(input);
}
testAll(testLetExpression);
// test global const
const [ca = 1, cb = 2] = [];
assertEq(ca, 1);
assertEq(cb, 2);
const {a: {a: cc = 3} = {a: undefined}} = {};
assertEq(cc, 3);
// test that the assignment happens in source order
var a = undefined, b = undefined, c = undefined;
({a: a = 1, c: c = 2, b: b = 3}) = {
get a() {
assertEq(a, undefined);
assertEq(c, undefined);
assertEq(b, undefined);
return undefined;
},
get b() {
assertEq(a, 1);
assertEq(c, 2);
assertEq(b, undefined);
return 4;
},
get c() {
assertEq(a, 1);
assertEq(c, undefined);
assertEq(b, undefined);
return undefined;
}
};
assertEq(b, 4);
assertThrowsInstanceOf(() => { var {a: {a} = null} = {}; }, TypeError);
assertThrowsInstanceOf(() => { var [[a] = 2] = []; }, TypeError);
// destructuring assignment might have duplicate variable names.
var [a = 1, a = 2] = [3];
assertEq(a, 2);
// assignment to properties of default params
[a = {y: 2}, a.x = 1] = [];
assertEq(typeof a, 'object');
assertEq(a.x, 1);
assertEq(a.y, 2);
// defaults are evaluated even if there is no binding
var evaled = false;
({a: {} = (evaled = true, null)}) = {};
assertEq(evaled, true);
evaled = false;
assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError);
assertEq(evaled, true);
assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError);

Просмотреть файл

@ -0,0 +1,9 @@
if (!this.hasOwnProperty("SIMD"))
quit();
var float64x2 = SIMD.float64x2;
function test() {
var a = float64x2(1, 2);
}
test();
test();

Просмотреть файл

@ -2530,9 +2530,8 @@ IonBuilder::inlineConstructSimdObject(CallInfo &callInfo, SimdTypeDescr *descr)
case SimdTypeDescr::TYPE_FLOAT32:
simdType = MIRType_Float32x4;
break;
default:
MOZ_CRASH("Unknown SIMD kind when generating MSimdBox instruction.");
return InliningStatus_NotInlined;
case SimdTypeDescr::TYPE_FLOAT64:
return InliningStatus_NotInlined; // :TODO: NYI (Bug 1124205)
}
// We do not inline SIMD constructors if the number of arguments does not

Просмотреть файл

@ -31,9 +31,6 @@
/* Define to 1 if SpiderMonkey should use small chunks. */
#undef JS_GC_SMALL_CHUNK_SIZE
/* Define to 1 if SpiderMonkey should use Compacting GC. */
#undef JSGC_COMPACTING
/* Define to 1 if the <endian.h> header is present and
useable. See jscpucfg.h. */
#undef JS_HAVE_ENDIAN_H

Просмотреть файл

@ -21,7 +21,7 @@ int BarkWhenTracedClass::finalizeCount;
int BarkWhenTracedClass::traceCount;
const JSClass BarkWhenTracedClass::class_ = {
"BarkWhenTracedClass", 0,
"BarkWhenTracedClass", JSCLASS_IMPLEMENTS_BARRIERS,
nullptr,
nullptr,
nullptr,

Просмотреть файл

@ -66,10 +66,6 @@ checkSize(JS::HandleObject map, uint32_t expected)
}
END_TEST(testWeakMap_basicOperations)
// TODO: this test stores object pointers in a private slot which is not marked
// and so doesn't work with compacting GC.
#ifndef JSGC_COMPACTING
BEGIN_TEST(testWeakMap_keyDelegates)
{
JS_SetGCParameter(rt, JSGC_MODE, JSGC_MODE_INCREMENTAL);
@ -253,5 +249,3 @@ checkSize(JS::HandleObject map, uint32_t expected)
return true;
}
END_TEST(testWeakMap_keyDelegates)
#endif

Просмотреть файл

@ -649,8 +649,6 @@ JSCompartment::sweepCrossCompartmentWrappers()
}
}
#ifdef JSGC_COMPACTING
void JSCompartment::fixupAfterMovingGC()
{
fixupGlobal();
@ -667,8 +665,6 @@ JSCompartment::fixupGlobal()
global_.set(MaybeForwarded(global));
}
#endif // JSGC_COMPACTING
void
JSCompartment::purge()
{

Просмотреть файл

@ -398,12 +398,10 @@ struct JSCompartment
void purge();
void clearTables();
#ifdef JSGC_COMPACTING
void fixupInitialShapeTable();
void fixupNewTypeObjectTable(js::types::NewTypeObjectTable &table);
void fixupAfterMovingGC();
void fixupGlobal();
#endif
bool hasObjectMetadataCallback() const { return objectMetadataCallback; }
void setObjectMetadataCallback(js::ObjectMetadataCallback callback);

Просмотреть файл

@ -1112,9 +1112,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
sliceBudget(SliceBudget::Unlimited),
incrementalAllowed(true),
generationalDisabled(0),
#ifdef JSGC_COMPACTING
compactingDisabled(0),
#endif
manipulatingDeadZones(false),
objectsMarkedInDeadZones(0),
poked(false),
@ -1134,9 +1132,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
#ifdef DEBUG
inUnsafeRegion(0),
noGCOrAllocationCheck(0),
#ifdef JSGC_COMPACTING
relocatedArenasToRelease(nullptr),
#endif
#endif
lock(nullptr),
lockOwner(nullptr),
@ -1930,15 +1926,9 @@ ArenaLists::allocateFromArenaInner(JS::Zone *zone, ArenaHeader *aheader, AllocKi
bool
GCRuntime::shouldCompact()
{
#ifdef JSGC_COMPACTING
return invocationKind == GC_SHRINK && isCompactingGCEnabled();
#else
return false;
#endif
}
#ifdef JSGC_COMPACTING
void
GCRuntime::disableCompactingGC()
{
@ -2373,13 +2363,19 @@ namespace gc {
struct ArenasToUpdate
{
explicit ArenasToUpdate(JSRuntime *rt);
enum KindsToUpdate {
FOREGROUND = 1,
BACKGROUND = 2,
ALL = FOREGROUND | BACKGROUND
};
ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds);
bool done() { return initialized && arena == nullptr; }
ArenaHeader* next();
ArenaHeader *getArenasToUpdate(AutoLockHelperThreadState& lock, unsigned max);
private:
bool initialized;
KindsToUpdate kinds;
GCZonesIter zone; // Current zone to process, unless zone.done()
unsigned kind; // Current alloc kind to process
ArenaHeader *arena; // Next arena to process
@ -2390,16 +2386,25 @@ struct ArenasToUpdate
bool ArenasToUpdate::shouldProcessKind(unsigned kind)
{
MOZ_ASSERT(kind < FINALIZE_LIMIT);
return
kind != FINALIZE_FAT_INLINE_STRING &&
kind != FINALIZE_STRING &&
kind != FINALIZE_EXTERNAL_STRING &&
kind != FINALIZE_SYMBOL;
if (kind == FINALIZE_FAT_INLINE_STRING ||
kind == FINALIZE_STRING ||
kind == FINALIZE_EXTERNAL_STRING ||
kind == FINALIZE_SYMBOL)
{
return false;
}
if (kind > FINALIZE_OBJECT_LAST || js::gc::IsBackgroundFinalized(AllocKind(kind)))
return (kinds & BACKGROUND) != 0;
else
return (kinds & FOREGROUND) != 0;
}
ArenasToUpdate::ArenasToUpdate(JSRuntime *rt)
: initialized(false), zone(rt, SkipAtoms)
{}
ArenasToUpdate::ArenasToUpdate(JSRuntime *rt, KindsToUpdate kinds)
: initialized(false), kinds(kinds), zone(rt, SkipAtoms)
{
MOZ_ASSERT(kinds && !(kinds & ~ALL));
}
ArenaHeader *
ArenasToUpdate::next()
@ -2526,20 +2531,23 @@ UpdateCellPointersTask::run()
} // namespace js
void
GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source)
GCRuntime::updateAllCellPointersParallel(MovingTracer *trc)
{
AutoDisableProxyCheck noProxyCheck(rt); // These checks assert when run in parallel.
const size_t minTasks = 2;
const size_t maxTasks = 8;
unsigned taskCount = Min(Max(HelperThreadState().cpuCount / 2, minTasks),
maxTasks);
maxTasks) + 1;
UpdateCellPointersTask updateTasks[maxTasks];
ArenasToUpdate fgArenas(rt, ArenasToUpdate::FOREGROUND);
ArenasToUpdate bgArenas(rt, ArenasToUpdate::BACKGROUND);
AutoLockHelperThreadState lock;
unsigned i;
for (i = 0; i < taskCount && !source.done(); ++i) {
updateTasks[i].init(rt, &source, lock);
for (i = 0; i < taskCount && !bgArenas.done(); ++i) {
ArenasToUpdate *source = i == 0 ? &fgArenas : &bgArenas;
updateTasks[i].init(rt, source, lock);
startTask(updateTasks[i], gcstats::PHASE_COMPACT_UPDATE_CELLS);
}
unsigned tasksStarted = i;
@ -2549,9 +2557,10 @@ GCRuntime::updateAllCellPointersParallel(ArenasToUpdate &source)
}
void
GCRuntime::updateAllCellPointersSerial(MovingTracer *trc, ArenasToUpdate &source)
GCRuntime::updateAllCellPointersSerial(MovingTracer *trc)
{
while (ArenaHeader *arena = source.next())
ArenasToUpdate allArenas(rt, ArenasToUpdate::ALL);
while (ArenaHeader *arena = allArenas.next())
UpdateCellPointers(trc, arena);
}
@ -2580,11 +2589,10 @@ GCRuntime::updatePointersToRelocatedCells()
// Iterate through all cells that can contain JSObject pointers to update
// them. Since updating each cell is independent we try to parallelize this
// as much as possible.
ArenasToUpdate source(rt);
if (CanUseExtraThreads())
updateAllCellPointersParallel(source);
updateAllCellPointersParallel(&trc);
else
updateAllCellPointersSerial(&trc, source);
updateAllCellPointersSerial(&trc);
// Mark roots to update them.
{
@ -2697,12 +2705,10 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(ArenaHeader *relocatedList, co
}
}
#endif // JSGC_COMPACTING
void
GCRuntime::releaseHeldRelocatedArenas()
{
#if defined(JSGC_COMPACTING) && defined(DEBUG)
#ifdef DEBUG
// In debug mode we don't release relocated arenas straight away. Instead
// we protect them and hold onto them until the next GC sweep phase to catch
// any pointers to them that didn't get forwarded.
@ -5462,9 +5468,6 @@ GCRuntime::endSweepPhase(bool lastGC)
bool
GCRuntime::compactPhase(bool lastGC)
{
#ifndef JSGC_COMPACTING
MOZ_CRASH();
#else
gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT);
if (isIncremental) {
@ -5529,8 +5532,6 @@ GCRuntime::compactPhase(bool lastGC)
}
}
#endif
#endif // JSGC_COMPACTING
return true;
}
@ -5690,7 +5691,6 @@ GCRuntime::resetIncrementalGC(const char *reason)
break;
}
#ifdef JSGC_COMPACTING
case COMPACT: {
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD);
@ -5706,7 +5706,6 @@ GCRuntime::resetIncrementalGC(const char *reason)
invocationKind = oldInvocationKind;
break;
}
#endif
default:
MOZ_CRASH("Invalid incremental GC state");
@ -6394,7 +6393,7 @@ GCRuntime::onOutOfMallocMemory(const AutoLockGC &lock)
{
// Release any relocated arenas we may be holding on to, without releasing
// the GC lock.
#if defined(JSGC_COMPACTING) && defined(DEBUG)
#ifdef DEBUG
unprotectRelocatedArenas(relocatedArenasToRelease);
releaseRelocatedArenasWithoutUnlocking(relocatedArenasToRelease, lock);
relocatedArenasToRelease = nullptr;
@ -7115,19 +7114,13 @@ JS::IsIncrementalGCEnabled(JSRuntime *rt)
JS_PUBLIC_API(void)
JS::DisableCompactingGC(JSRuntime *rt)
{
#ifdef JSGC_COMPACTING
rt->gc.disableCompactingGC();
#endif
}
JS_PUBLIC_API(bool)
JS::IsCompactingGCEnabled(JSRuntime *rt)
{
#ifdef JSGC_COMPACTING
return rt->gc.isCompactingGCEnabled();
#else
return false;
#endif
}
JS_PUBLIC_API(bool)

Просмотреть файл

@ -454,11 +454,9 @@ class ArenaList {
return *this;
}
#ifdef JSGC_COMPACTING
ArenaHeader *removeRemainingArenas(ArenaHeader **arenap, const AutoLockGC &lock);
ArenaHeader *pickArenasToRelocate(JSRuntime *runtime);
ArenaHeader *relocateArenas(ArenaHeader *toRelocate, ArenaHeader *relocated);
#endif
};
/*
@ -785,9 +783,7 @@ class ArenaLists
MOZ_ASSERT(freeLists[kind].isEmpty());
}
#ifdef JSGC_COMPACTING
ArenaHeader *relocateArenas(ArenaHeader *relocatedList);
#endif
void queueForegroundObjectsForSweep(FreeOp *fop);
void queueForegroundThingsForSweep(FreeOp *fop);
@ -1270,9 +1266,7 @@ inline void
CheckGCThingAfterMovingGC(T *t)
{
MOZ_ASSERT_IF(t, !IsInsideNursery(t));
#ifdef JSGC_COMPACTING
MOZ_ASSERT_IF(t, !IsForwarded(t));
#endif
}
inline void
@ -1429,16 +1423,11 @@ struct AutoDisableProxyCheck
struct AutoDisableCompactingGC
{
#ifdef JSGC_COMPACTING
explicit AutoDisableCompactingGC(JSRuntime *rt);
~AutoDisableCompactingGC();
private:
gc::GCRuntime &gc;
#else
explicit AutoDisableCompactingGC(JSRuntime *rt) {}
~AutoDisableCompactingGC() {}
#endif
};
void

Просмотреть файл

@ -4891,8 +4891,6 @@ JSCompartment::sweepNewTypeObjectTable(NewTypeObjectTable &table)
}
}
#ifdef JSGC_COMPACTING
void
JSCompartment::fixupNewTypeObjectTable(NewTypeObjectTable &table)
{
@ -4966,8 +4964,6 @@ TypeObject::fixupAfterMovingGC()
}
}
#endif // JSGC_COMPACTING
#ifdef JSGC_HASH_TABLE_CHECKS
void

Просмотреть файл

@ -293,7 +293,7 @@ public:
};
/* Flags and other state stored in TypeSet::flags */
enum MOZ_ENUM_TYPE(uint32_t) {
enum : uint32_t {
TYPE_FLAG_UNDEFINED = 0x1,
TYPE_FLAG_NULL = 0x2,
TYPE_FLAG_BOOLEAN = 0x4,
@ -352,7 +352,7 @@ enum MOZ_ENUM_TYPE(uint32_t) {
typedef uint32_t TypeFlags;
/* Flags and other state stored in TypeObject::flags */
enum MOZ_ENUM_TYPE(uint32_t) {
enum : uint32_t {
/* Whether this type object is associated with some allocation site. */
OBJECT_FLAG_FROM_ALLOCATION_SITE = 0x1,
@ -925,10 +925,7 @@ class TypeNewScript
void trace(JSTracer *trc);
void sweep();
#ifdef JSGC_COMPACTING
void fixupAfterMovingGC();
#endif
void registerNewObject(PlainObject *res);
void unregisterNewObject(PlainObject *res);
@ -1241,9 +1238,7 @@ struct TypeObject : public gc::TenuredCell
flags_ |= generation << OBJECT_FLAG_GENERATION_SHIFT;
}
#ifdef JSGC_COMPACTING
void fixupAfterMovingGC();
#endif
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;

Просмотреть файл

@ -1232,32 +1232,10 @@ NewObject(ExclusiveContext *cx, types::TypeObject *type_, JSObject *parent, gc::
obj = nobj;
}
/*
* This will cancel an already-running incremental GC from doing any more
* slices, and it will prevent any future incremental GCs.
*/
bool globalWithoutCustomTrace = clasp->trace == JS_GlobalObjectTraceHook &&
!cx->compartment()->options().getTrace();
if (clasp->trace &&
!globalWithoutCustomTrace &&
!(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS))
{
if (!cx->shouldBeJSContext())
return nullptr;
JSRuntime *rt = cx->asJSContext()->runtime();
rt->gc.disallowIncrementalGC();
#ifdef DEBUG
if (rt->gc.gcMode() == JSGC_MODE_INCREMENTAL) {
fprintf(stderr,
"The class %s has a trace hook but does not declare the\n"
"JSCLASS_IMPLEMENTS_BARRIERS flag. Please ensure that it correctly\n"
"implements write barriers and then set the flag.\n",
clasp->name);
MOZ_CRASH();
}
#endif
}
if (clasp->trace && !globalWithoutCustomTrace)
MOZ_RELEASE_ASSERT(clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS);
probes::CreateObject(cx, obj);
return obj;
@ -2928,13 +2906,18 @@ js::NonProxyLookupOwnProperty(JSContext *cx, LookupGenericOp lookup,
MaybeRooted<JSObject*, allowGC>::template downcastHandle<NativeObject>(obj);
bool done;
if (!LookupOwnPropertyInline<allowGC>(cx, nobj, id, objp, propp, &done))
if (!LookupOwnPropertyInline<allowGC>(cx, nobj, id, propp, &done))
return false;
if (!done) {
objp.set(nullptr);
propp.set(nullptr);
return true;
}
if (propp)
objp.set(obj);
else
objp.set(nullptr);
}
if (!propp)

Просмотреть файл

@ -235,8 +235,6 @@ Shape::finalize(FreeOp *fop)
fop->delete_(kids.toHash());
}
#ifdef JSGC_COMPACTING
void
Shape::fixupDictionaryShapeAfterMovingGC()
{
@ -322,8 +320,6 @@ Shape::fixupAfterMovingGC()
fixupShapeTreeAfterMovingGC();
}
#endif // JSGC_COMPACTING
void
ShapeGetterSetterRef::mark(JSTracer *trc)
{

Просмотреть файл

@ -20,8 +20,7 @@
#include "js/TypeDecls.h"
#if (defined(JS_GC_ZEAL)) || \
(defined(JSGC_COMPACTING) && defined(DEBUG))
#if (defined(JS_GC_ZEAL)) || defined(DEBUG)
# define JSGC_HASH_TABLE_CHECKS
#endif

Просмотреть файл

@ -357,6 +357,12 @@ ShellInterruptCallback(JSContext *cx)
if (!gServiceInterrupt)
return true;
// Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to
// true to distinguish watchdog or user triggered interrupts.
// Do this first to prevent other interrupts that may occur while the
// user-supplied callback is executing from re-entering the handler.
gServiceInterrupt = false;
bool result;
RootedValue interruptFunc(cx, *gInterruptFunc);
if (!interruptFunc.isNull()) {
@ -379,10 +385,6 @@ ShellInterruptCallback(JSContext *cx)
if (!result && gExitCode == 0)
gExitCode = EXITCODE_TIMEOUT;
// Reset gServiceInterrupt. CancelExecution or InterruptIf will set it to
// true to distinguish watchdog or user triggered interrupts.
gServiceInterrupt = false;
return result;
}

Просмотреть файл

@ -112,6 +112,11 @@ function compOfBlock(left, right) Pattern({ type: "ComprehensionBlock", left: le
function arrPatt(elts) Pattern({ type: "ArrayPattern", elements: elts })
function objPatt(elts) Pattern({ type: "ObjectPattern", properties: elts })
function assignElem(target, defaultExpr = null, targetIdent = typeof target == 'string' ? ident(target) : target) defaultExpr ? aExpr('=', targetIdent, defaultExpr) : targetIdent
function assignProp(property, target, defaultExpr = null, shorthand = !target, targetProp = target || ident(property)) Pattern({
type: "Property", key: ident(property), shorthand,
value: defaultExpr ? aExpr('=', targetProp, defaultExpr) : targetProp })
function localSrc(src) "(function(){ " + src + " })"
function localPatt(patt) program([exprStmt(funExpr(null, [], blockStmt([patt])))])
function blockSrc(src) "(function(){ { " + src + " } })"
@ -235,7 +240,7 @@ assertDecl("function f(a,b,c) { function b() { } }",
funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
assertDecl("function f(a,[x,y]) { function a() { } }",
funDecl(ident("f"),
[ident("a"), arrPatt([ident("x"), ident("y")])],
[ident("a"), arrPatt([assignElem("x"), assignElem("y")])],
blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
// Bug 632027: array holes should reflect as null
@ -269,7 +274,7 @@ assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident(
assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([])));
assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([])));
assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([])));
assertExpr("([a, b]) => {}", arrowExpr([arrPatt([ident("a"), ident("b")])], blockStmt([])));
assertExpr("([a, b]) => {}", arrowExpr([arrPatt([assignElem("a"), assignElem("b")])], blockStmt([])));
assertExpr("(++x)", updExpr("++", ident("x"), true));
assertExpr("(x++)", updExpr("++", ident("x"), false));
assertExpr("(+x)", unExpr("+", ident("x")));
@ -566,9 +571,9 @@ assertStmt("function f() { var x = 42; var x = 43; }",
varDecl([{ id: ident("x"), init: lit(43) }])])));
assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y"), shorthand: false }]),
assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]),
init: ident("foo") }]));
assertDecl("var {x} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("x"), shorthand: true }]),
assertDecl("var {x} = foo;", varDecl([{ id: objPatt([assignProp("x")]),
init: ident("foo") }]));
// Bug 632030: redeclarations between var and funargs, var and function
@ -581,16 +586,16 @@ assertProg("f.p = 1; var f; f.p; function f(){}",
funDecl(ident("f"), [], blockStmt([]))]);
// global let is var
assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
assertGlobalDecl("let {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]),
init: ident("foo") }]));
// function-global let is let
assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]),
init: ident("foo") }]));
// block-local let is let
assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]),
init: ident("foo") }]));
assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([{ key: ident("x"), value: ident("y") }]),
assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([assignProp("x", ident("y"))]),
init: ident("foo") }]));
@ -670,16 +675,23 @@ function testParamPatternCombinations(makePattSrc, makePattPatt) {
}
testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"),
function(n) (objPatt([{ key: ident("a" + n), value: ident("x" + n) },
{ key: ident("b" + n), value: ident("y" + n) },
{ key: ident("c" + n), value: ident("z" + n) }])));
function(n) (objPatt([assignProp("a" + n, ident("x" + n)),
assignProp("b" + n, ident("y" + n)),
assignProp("c" + n, ident("z" + n))])));
testParamPatternCombinations(function(n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10}"),
function(n) (objPatt([assignProp("a" + n, ident("x" + n), lit(10)),
assignProp("b" + n, ident("y" + n), lit(10)),
assignProp("c" + n, ident("z" + n), lit(10))])));
testParamPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "]"),
function(n) (arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)])));
function(n) (arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)])));
testParamPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "]"),
function(n) (arrPatt([ident("a" + n), spread(ident("b" + n))])));
function(n) (arrPatt([assignElem("a" + n), spread(ident("b" + n))])));
testParamPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10]"),
function(n) (arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))])));
// destructuring variable declarations
@ -712,19 +724,28 @@ function testVarPatternCombinations(makePattSrc, makePattPatt) {
}
testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"),
function (n) ({ id: objPatt([{ key: ident("a" + n), value: ident("x" + n) },
{ key: ident("b" + n), value: ident("y" + n) },
{ key: ident("c" + n), value: ident("z" + n) }]),
function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n)),
assignProp("b" + n, ident("y" + n)),
assignProp("c" + n, ident("z" + n))]),
init: lit(0) }));
testVarPatternCombinations(function (n) ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10} = 0"),
function (n) ({ id: objPatt([assignProp("a" + n, ident("x" + n), lit(10)),
assignProp("b" + n, ident("y" + n), lit(10)),
assignProp("c" + n, ident("z" + n), lit(10))]),
init: lit(0) }));
testVarPatternCombinations(function(n) ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"),
function(n) ({ id: arrPatt([ident("x" + n), ident("y" + n), ident("z" + n)]),
function(n) ({ id: arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]),
init: lit(0) }));
testVarPatternCombinations(function(n) ("[a" + n + ", ..." + "b" + n + "] = 0"),
function(n) ({ id: arrPatt([ident("a" + n), spread(ident("b" + n))]),
function(n) ({ id: arrPatt([assignElem("a" + n), spread(ident("b" + n))]),
init: lit(0) }));
testVarPatternCombinations(function(n) ("[a" + n + ", " + "b" + n + " = 10] = 0"),
function(n) ({ id: arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]),
init: lit(0) }));
// destructuring assignment
function testAssignmentCombinations(makePattSrc, makePattPatt) {
@ -746,18 +767,18 @@ function testAssignmentCombinations(makePattSrc, makePattPatt) {
testAssignmentCombinations(function (n) ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"),
function (n) (aExpr("=",
objPatt([{ key: ident("a" + n), value: ident("x" + n) },
{ key: ident("b" + n), value: ident("y" + n) },
{ key: ident("c" + n), value: ident("z" + n) }]),
objPatt([assignProp("a" + n, ident("x" + n)),
assignProp("b" + n, ident("y" + n)),
assignProp("c" + n, ident("z" + n))]),
lit(0))));
// destructuring in for-in and for-each-in loop heads
var axbycz = objPatt([{ key: ident("a"), value: ident("x") },
{ key: ident("b"), value: ident("y") },
{ key: ident("c"), value: ident("z") }]);
var xyz = arrPatt([ident("x"), ident("y"), ident("z")]);
var axbycz = objPatt([assignProp("a", ident("x")),
assignProp("b", ident("y")),
assignProp("c", ident("z"))]);
var xyz = arrPatt([assignElem("x"), assignElem("y"), assignElem("z")]);
assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));
assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt));

Просмотреть файл

@ -400,38 +400,30 @@ NewNativeObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSOb
/*
* Call obj's resolve hook.
*
* cx, id, and flags are the parameters initially passed to the ongoing lookup;
* objp and propp are its out parameters. obj is an object along the prototype
* chain from where the lookup started.
* cx and id are the parameters initially passed to the ongoing lookup;
* propp and recursedp are its out parameters.
*
* There are four possible outcomes:
*
* - On failure, report an error or exception and return false.
*
* - If we are already resolving a property of *curobjp, set *recursedp = true,
* - If we are already resolving a property of obj, set *recursedp = true,
* and return true.
*
* - If the resolve hook finds or defines the sought property, set *objp and
* *propp appropriately, set *recursedp = false, and return true.
* - If the resolve hook finds or defines the sought property, set propp
* appropriately, set *recursedp = false, and return true.
*
* - Otherwise no property was resolved. Set *propp = nullptr and
* - Otherwise no property was resolved. Set propp to nullptr and
* *recursedp = false and return true.
*/
static MOZ_ALWAYS_INLINE bool
CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleObject objp,
MutableHandleShape propp, bool *recursedp)
CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleShape propp,
bool *recursedp)
{
/*
* Avoid recursion on (obj, id) already being resolved on cx.
*
* Once we have successfully added an entry for (obj, key) to
* cx->resolvingTable, control must go through cleanup: before
* returning. But note that JS_DHASH_ADD may find an existing
* entry, in which case we bail to suppress runaway recursion.
*/
// Avoid recursion on (obj, id) already being resolved on cx.
AutoResolving resolving(cx, obj, id);
if (resolving.alreadyStarted()) {
/* Already resolving id in obj -- suppress recursion. */
// Already resolving id in obj, suppress recursion.
*recursedp = true;
return true;
}
@ -444,18 +436,14 @@ CallResolveOp(JSContext *cx, HandleNativeObject obj, HandleId id, MutableHandleO
if (!resolved)
return true;
objp.set(obj);
if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) {
MarkDenseOrTypedArrayElementFound<CanGC>(propp);
return true;
}
if (Shape *shape = obj->lookup(cx, id))
propp.set(shape);
else
objp.set(nullptr);
MOZ_ASSERT(!IsAnyTypedArray(obj));
propp.set(obj->lookup(cx, id));
return true;
}
@ -464,13 +452,11 @@ static MOZ_ALWAYS_INLINE bool
LookupOwnPropertyInline(ExclusiveContext *cx,
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
typename MaybeRooted<jsid, allowGC>::HandleType id,
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp,
bool *donep)
{
// Check for a native dense element.
if (JSID_IS_INT(id) && obj->containsDenseElement(JSID_TO_INT(id))) {
objp.set(obj);
MarkDenseOrTypedArrayElementFound<allowGC>(propp);
*donep = true;
return true;
@ -483,10 +469,8 @@ LookupOwnPropertyInline(ExclusiveContext *cx,
uint64_t index;
if (IsTypedArrayIndex(id, &index)) {
if (index < AnyTypedArrayLength(obj)) {
objp.set(obj);
MarkDenseOrTypedArrayElementFound<allowGC>(propp);
} else {
objp.set(nullptr);
propp.set(nullptr);
}
*donep = true;
@ -496,7 +480,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx,
// Check for a native property.
if (Shape *shape = obj->lookup(cx, id)) {
objp.set(obj);
propp.set(shape);
*donep = true;
return true;
@ -512,7 +495,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx,
if (!CallResolveOp(cx->asJSContext(),
MaybeRooted<NativeObject*, allowGC>::toHandle(obj),
MaybeRooted<jsid, allowGC>::toHandle(id),
MaybeRooted<JSObject*, allowGC>::toMutableHandle(objp),
MaybeRooted<Shape*, allowGC>::toMutableHandle(propp),
&recursed))
{
@ -520,7 +502,6 @@ LookupOwnPropertyInline(ExclusiveContext *cx,
}
if (recursed) {
objp.set(nullptr);
propp.set(nullptr);
*donep = true;
return true;
@ -532,6 +513,7 @@ LookupOwnPropertyInline(ExclusiveContext *cx,
}
}
propp.set(nullptr);
*donep = false;
return true;
}
@ -584,10 +566,15 @@ LookupPropertyInline(ExclusiveContext *cx,
while (true) {
bool done;
if (!LookupOwnPropertyInline<allowGC>(cx, current, id, objp, propp, &done))
if (!LookupOwnPropertyInline<allowGC>(cx, current, id, propp, &done))
return false;
if (done)
if (done) {
if (propp)
objp.set(current);
else
objp.set(nullptr);
return true;
}
typename MaybeRooted<JSObject*, allowGC>::RootType proto(cx, current->getProto());

Просмотреть файл

@ -1458,14 +1458,8 @@ static bool
NativeLookupOwnProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
MutableHandle<Shape*> shapep)
{
RootedObject pobj(cx);
bool done;
if (!LookupOwnPropertyInline<CanGC>(cx, obj, id, &pobj, shapep, &done))
return false;
if (!done || pobj != obj)
shapep.set(nullptr);
return true;
return LookupOwnPropertyInline<CanGC>(cx, obj, id, shapep, &done);
}
template <AllowGC allowGC>
@ -2072,13 +2066,9 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv
for (;;) {
// Steps 2-3. ('done' is a SpiderMonkey-specific thing, used below.)
bool done;
RootedObject ancestor(cx);
if (!LookupOwnPropertyInline<CanGC>(cx, pobj, id, &ancestor, &shape, &done))
if (!LookupOwnPropertyInline<CanGC>(cx, pobj, id, &shape, &done))
return false;
if (!done || ancestor != pobj)
shape = nullptr;
if (shape) {
// Steps 5-6.
return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, strict);

Просмотреть файл

@ -224,14 +224,12 @@ GetShapeAttributes(JSObject *obj, Shape *shape)
return shape->attributes();
}
#ifdef JSGC_COMPACTING
inline void
BaseShape::fixupAfterMovingGC()
{
if (hasTable())
table().fixupAfterMovingGC();
}
#endif
} /* namespace js */

Просмотреть файл

@ -256,7 +256,6 @@ ShapeTable::search(jsid id, bool adding)
MOZ_CRASH("Shape::search failed to find an expected entry.");
}
#ifdef JSGC_COMPACTING
void
ShapeTable::fixupAfterMovingGC()
{
@ -268,7 +267,6 @@ ShapeTable::fixupAfterMovingGC()
entry.setPreservingCollision(Forwarded(shape));
}
}
#endif
bool
ShapeTable::change(int log2Delta, ExclusiveContext *cx)
@ -1693,7 +1691,6 @@ JSCompartment::sweepInitialShapeTable()
}
}
#ifdef JSGC_COMPACTING
void
JSCompartment::fixupInitialShapeTable()
{
@ -1732,7 +1729,6 @@ JSCompartment::fixupInitialShapeTable()
}
}
}
#endif // JSGC_COMPACTING
void
AutoRooterGetterSetter::Inner::trace(JSTracer *trc)

Просмотреть файл

@ -227,10 +227,8 @@ class ShapeTable {
bool change(int log2Delta, ExclusiveContext *cx);
Entry &search(jsid id, bool adding);
#ifdef JSGC_COMPACTING
/* Update entries whose shapes have been moved */
void fixupAfterMovingGC();
#endif
private:
Entry &getEntry(uint32_t i) const {
@ -530,9 +528,7 @@ class BaseShape : public gc::TenuredCell
gc::MarkObject(trc, &metadata, "metadata");
}
#ifdef JSGC_COMPACTING
void fixupAfterMovingGC();
#endif
private:
static void staticAsserts() {
@ -1061,9 +1057,7 @@ class Shape : public gc::TenuredCell
inline Shape *search(ExclusiveContext *cx, jsid id);
inline Shape *searchLinear(jsid id);
#ifdef JSGC_COMPACTING
void fixupAfterMovingGC();
#endif
/* For JIT usage */
static inline size_t offsetOfBase() { return offsetof(Shape, base_); }
@ -1071,10 +1065,8 @@ class Shape : public gc::TenuredCell
static inline uint32_t fixedSlotsMask() { return FIXED_SLOTS_MASK; }
private:
#ifdef JSGC_COMPACTING
void fixupDictionaryShapeAfterMovingGC();
void fixupShapeTreeAfterMovingGC();
#endif
static void staticAsserts() {
JS_STATIC_ASSERT(offsetof(Shape, base_) == offsetof(js::shadow::Shape, base));

Просмотреть файл

@ -65,7 +65,7 @@ using JS::CanonicalizeNaN;
// a stable ID, it need not be at the end of the list and should not be used for
// sizing data structures.
enum StructuredDataType MOZ_ENUM_TYPE(uint32_t) {
enum StructuredDataType : uint32_t {
/* Structured data types provided by the engine */
SCTAG_FLOAT_MAX = 0xFFF00000,
SCTAG_NULL = 0xFFFF0000,

Просмотреть файл

@ -1065,9 +1065,12 @@ public:
static void
TraceWrappedNativesInAllScopes(JSTracer* trc, XPCJSRuntime* rt);
void TraceInside(JSTracer *trc) {
void TraceSelf(JSTracer *trc) {
MOZ_ASSERT(mGlobalJSObject);
mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
}
void TraceInside(JSTracer *trc) {
if (mContentXBLScope)
mContentXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
for (size_t i = 0; i < mAddonScopes.Length(); i++)
@ -1847,7 +1850,7 @@ public:
mScriptableInfo->Mark();
}
GetScope()->TraceInside(trc);
GetScope()->TraceSelf(trc);
}
void TraceJS(JSTracer *trc) {
@ -2162,7 +2165,7 @@ public:
if (HasProto())
GetProto()->TraceSelf(trc);
else
GetScope()->TraceInside(trc);
GetScope()->TraceSelf(trc);
if (mFlatJSObject && JS_IsGlobalObject(mFlatJSObject))
{
xpc::TraceXPCGlobal(trc, mFlatJSObject);

Просмотреть файл

@ -2343,11 +2343,14 @@ ContainerState::PopPaintedLayerData()
EventRegions regions;
regions.mHitRegion = ScaleRegionToOutsidePixels(data->mHitRegion);
// Points whose hit-region status we're not sure about need to be dispatched
// to the content thread.
// to the content thread. If a point is in both maybeHitRegion and hitRegion
// then it's not a "maybe" any more, and doesn't go into the dispatch-to-
// content region.
nsIntRegion maybeHitRegion = ScaleRegionToOutsidePixels(data->mMaybeHitRegion);
regions.mDispatchToContentHitRegion.Sub(maybeHitRegion, regions.mHitRegion);
regions.mDispatchToContentHitRegion.Or(regions.mDispatchToContentHitRegion,
ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion));
regions.mDispatchToContentHitRegion.OrWith(
ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion));
regions.mHitRegion.OrWith(maybeHitRegion);
nsIntPoint translation = -GetTranslationForPaintedLayer(data->mLayer);
regions.mHitRegion.MoveBy(translation);

Просмотреть файл

@ -56,8 +56,4 @@ LOCAL_INCLUDES += [
if CONFIG['ENABLE_INTL_API']:
# nsNumberControlFrame.cpp requires ICUUtils.h which in turn requires
# i18n/unum.h
LOCAL_INCLUDES += [
'../../intl/icu/source/common',
'../../intl/icu/source/i18n',
]
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']

Просмотреть файл

@ -1469,7 +1469,7 @@ void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
static_cast<nsComboboxControlFrame*>(mFrame)
->PaintFocus(*aCtx, ToReferenceFrame());
->PaintFocus(*aCtx->GetDrawTarget(), ToReferenceFrame());
}
void
@ -1511,7 +1511,7 @@ nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplaySelectionOverlay(aBuilder, aLists.Content());
}
void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext,
void nsComboboxControlFrame::PaintFocus(DrawTarget& aDrawTarget,
nsPoint aPt)
{
/* Do we need to do anything? */
@ -1519,13 +1519,12 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext,
if (eventStates.HasState(NS_EVENT_STATE_DISABLED) || sFocused != this)
return;
gfxContext* gfx = aRenderingContext.ThebesContext();
int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
gfx->Save();
nsRect clipRect = mDisplayFrame->GetRect() + aPt;
gfx->Clip(NSRectToSnappedRect(clipRect,
PresContext()->AppUnitsPerDevPixel(),
*aRenderingContext.GetDrawTarget()));
aDrawTarget.PushClipRect(NSRectToSnappedRect(clipRect,
appUnitsPerDevPixel,
aDrawTarget));
// REVIEW: Why does the old code paint mDisplayFrame again? We've
// already painted it in the children above. So clipping it here won't do
@ -1540,12 +1539,10 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext,
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
clipRect.width -= onePixel;
clipRect.height -= onePixel;
Rect r =
ToRect(nsLayoutUtils::RectToGfxRect(clipRect, PresContext()->AppUnitsPerDevPixel()));
StrokeSnappedEdgesOfRect(r, *aRenderingContext.GetDrawTarget(),
color, strokeOptions);
Rect r = ToRect(nsLayoutUtils::RectToGfxRect(clipRect, appUnitsPerDevPixel));
StrokeSnappedEdgesOfRect(r, aDrawTarget, color, strokeOptions);
gfx->Restore();
aDrawTarget.PopClip();
}
//---------------------------------------------------------

Просмотреть файл

@ -37,6 +37,12 @@ class nsComboboxDisplayFrame;
class nsIDOMEventListener;
class nsIScrollableFrame;
namespace mozilla {
namespace gfx {
class DrawTarget;
}
}
class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame,
public nsIFormControlFrame,
public nsIComboboxControlFrame,
@ -45,6 +51,8 @@ class nsComboboxControlFrame MOZ_FINAL : public nsBlockFrame,
public nsIRollupListener,
public nsIStatefulFrame
{
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
friend nsContainerFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext,
@ -84,7 +92,7 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt);
void PaintFocus(DrawTarget& aDrawTarget, nsPoint aPt);
// XXXbz this is only needed to prevent the quirk percent height stuff from
// leaking out of the combobox. We may be able to get rid of this as more

Просмотреть файл

@ -2916,8 +2916,9 @@ void
SVGTextDrawPathCallbacks::HandleTextGeometry()
{
if (IsClipPathChild()) {
gfx->SetColor(gfxRGBA(1.0f, 1.0f, 1.0f, 1.0f));
gfx->Fill();
RefPtr<Path> path = gfx->GetPath();
ColorPattern white(Color(1.f, 1.f, 1.f, 1.f)); // for masking, so no ToDeviceColor
gfx->GetDrawTarget()->Fill(path, white);
} else {
// Normal painting.
gfxContextMatrixAutoSaveRestore saveMatrix(gfx);
@ -2984,11 +2985,15 @@ SVGTextDrawPathCallbacks::FillGeometry()
GeneralPattern fillPattern;
MakeFillPattern(&fillPattern);
if (fillPattern.GetPattern()) {
gfx->SetFillRule(
nsSVGUtils::ToFillRule(
IsClipPathChild() ?
mFrame->StyleSVG()->mClipRule : mFrame->StyleSVG()->mFillRule));
gfx->Fill(fillPattern);
RefPtr<Path> path = gfx->GetPath();
FillRule fillRule = nsSVGUtils::ToFillRule(IsClipPathChild() ?
mFrame->StyleSVG()->mClipRule :
mFrame->StyleSVG()->mFillRule);
if (fillRule != path->GetFillRule()) {
RefPtr<PathBuilder> builder = path->CopyToBuilder(fillRule);
path = builder->Finish();
}
gfx->GetDrawTarget()->Fill(path, fillPattern);
}
}

Просмотреть файл

@ -468,20 +468,32 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc,
IceConfiguration *aDst)
{
#ifdef MOZILLA_INTERNAL_API
if (!aSrc.mIceServers.WasPassed()) {
return NS_OK;
if (aSrc.mIceServers.WasPassed()) {
for (size_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) {
nsresult rv = AddIceServer(aSrc.mIceServers.Value()[i], aDst);
NS_ENSURE_SUCCESS(rv, rv);
}
}
for (uint32_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) {
const RTCIceServer& server = aSrc.mIceServers.Value()[i];
NS_ENSURE_TRUE(server.mUrl.WasPassed(), NS_ERROR_UNEXPECTED);
#endif
return NS_OK;
}
nsresult
PeerConnectionImpl::AddIceServer(const RTCIceServer &aServer,
IceConfiguration *aDst)
{
#ifdef MOZILLA_INTERNAL_API
NS_ENSURE_STATE(aServer.mUrls.WasPassed());
NS_ENSURE_STATE(aServer.mUrls.Value().IsStringSequence());
auto &urls = aServer.mUrls.Value().GetAsStringSequence();
for (size_t i = 0; i < urls.Length(); i++) {
// Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than
// nsStandardURL. To parse STUN/TURN URI's to spec
// http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3
// http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3
// we parse out the query-string, and use ParseAuthority() on the rest
nsRefPtr<nsIURI> url;
nsresult rv = NS_NewURI(getter_AddRefs(url), server.mUrl.Value());
nsresult rv = NS_NewURI(getter_AddRefs(url), urls[i]);
NS_ENSURE_SUCCESS(rv, rv);
bool isStun = false, isStuns = false, isTurn = false, isTurns = false;
url->SchemeIs("stun", &isStun);
@ -542,8 +554,8 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc,
port = (isStuns || isTurns)? 5349 : 3478;
if (isTurn || isTurns) {
NS_ConvertUTF16toUTF8 credential(server.mCredential);
NS_ConvertUTF16toUTF8 username(server.mUsername);
NS_ConvertUTF16toUTF8 credential(aServer.mCredential);
NS_ConvertUTF16toUTF8 username(aServer.mUsername);
// Bug 1039655 - TURN TCP is not e10s ready
if ((transport == kNrIceTransportTcp) &&

Просмотреть файл

@ -78,6 +78,7 @@ class DOMMediaStream;
namespace dom {
struct RTCConfiguration;
struct RTCIceServer;
struct RTCOfferOptions;
#ifdef USE_FAKE_MEDIA_STREAMS
typedef Fake_MediaStreamTrack MediaStreamTrack;
@ -118,6 +119,7 @@ namespace mozilla {
using mozilla::dom::PeerConnectionObserver;
using mozilla::dom::RTCConfiguration;
using mozilla::dom::RTCIceServer;
using mozilla::dom::RTCOfferOptions;
using mozilla::DOMMediaStream;
using mozilla::NrIceCtx;
@ -259,6 +261,8 @@ public:
static PeerConnectionImpl* CreatePeerConnection();
static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc,
IceConfiguration *aDst);
static nsresult AddIceServer(const RTCIceServer& aServer,
IceConfiguration* aDst);
already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo,

Просмотреть файл

@ -14,31 +14,6 @@
#if defined(__cplusplus)
/**
* MOZ_ENUM_TYPE specifies the underlying numeric type for an enum. It's
* specified by placing MOZ_ENUM_TYPE(type) immediately after the enum name in
* its declaration, and before the opening curly brace, like
*
* enum MyEnum MOZ_ENUM_TYPE(uint16_t)
* {
* A,
* B = 7,
* C
* };
*
* In supporting compilers, the macro will expand to ": uint16_t". The
* compiler will allocate exactly two bytes for MyEnum and will require all
* enumerators to have values between 0 and 65535. (Thus specifying "B =
* 100000" instead of "B = 7" would fail to compile.) In old compilers the
* macro expands to the empty string, and the underlying type is generally
* undefined.
*/
#ifdef MOZ_HAVE_CXX11_ENUM_TYPE
# define MOZ_ENUM_TYPE(type) : type
#else
# define MOZ_ENUM_TYPE(type) /* no support */
#endif
/**
* MOZ_BEGIN_ENUM_CLASS and MOZ_END_ENUM_CLASS provide access to the
* strongly-typed enumeration feature of C++11 ("enum class"). If supported
@ -155,7 +130,7 @@
class Name \
{ \
public: \
enum Enum MOZ_ENUM_TYPE(type) \
enum Enum : type \
{
# define MOZ_END_NESTED_ENUM_CLASS(Name) \
}; \

Просмотреть файл

@ -26,18 +26,15 @@
# define __has_extension __has_feature /* compatibility, for older versions of clang */
# endif
# if __has_extension(cxx_strong_enums)
# define MOZ_HAVE_CXX11_ENUM_TYPE
# define MOZ_HAVE_CXX11_STRONG_ENUMS
# endif
#elif defined(__GNUC__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if MOZ_GCC_VERSION_AT_LEAST(4, 6, 3)
# define MOZ_HAVE_CXX11_ENUM_TYPE
# define MOZ_HAVE_CXX11_STRONG_ENUMS
# endif
# endif
#elif defined(_MSC_VER)
# define MOZ_HAVE_CXX11_ENUM_TYPE
# define MOZ_HAVE_CXX11_STRONG_ENUMS
#endif

Просмотреть файл

@ -563,7 +563,7 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true);
pref("media.fragmented-mp4.android-media-codec.preferred", true);
// optimize images memory usage
pref("image.mem.decodeondraw", false);
pref("image.mem.decodeondraw", true);
#ifdef NIGHTLY_BUILD
// Shumway component (SWF player) is disabled by default. Also see bug 904346.

Просмотреть файл

@ -7,7 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
const CONFIG = { iceServers: [{ "url": "stun:stun.services.mozilla.com" }] };
const CONFIG = { iceServers: [{ "urls": ["stun:stun.services.mozilla.com"] }] };
let log = Cu.import("resource://gre/modules/AndroidLog.jsm",
{}).AndroidLog.d.bind(null, "TabMirror");

Просмотреть файл

@ -360,7 +360,7 @@ pref("media.peerconnection.video.start_bitrate", 300);
pref("media.peerconnection.video.max_bitrate", 2000);
#endif
pref("media.navigator.permission.disabled", false);
pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]");
pref("media.peerconnection.default_iceservers", "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]");
pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
pref("media.peerconnection.use_document_iceservers", true);
// Do not enable identity before ensuring that the UX cannot be spoofed
@ -3789,7 +3789,7 @@ pref("image.mem.discardable", true);
// Prevents images from automatically being decoded on load, instead allowing
// them to be decoded on demand when they are drawn.
pref("image.mem.decodeondraw", false);
pref("image.mem.decodeondraw", true);
// Allows image locking of decoded image data in content processes.
pref("image.mem.allow_locking_in_content_processes", true);

Просмотреть файл

@ -2183,8 +2183,10 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
nsCOMPtr<nsIURI> uri;
mRedirects[i]->GetURI(getter_AddRefs(uri));
nsCString spec;
uri->GetSpec(spec);
LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect %s "
if (uri) {
uri->GetSpec(spec);
}
LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect \'%s\' "
"[this=%p]", spec.get(), this));
#endif
httpInternal->AddRedirect(mRedirects[i]);

Просмотреть файл

@ -1,5 +1,6 @@
[DEFAULT]
skip-if = buildapp == 'b2g' || e10s
skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # Android: Bug 1111137 & 1078267
support-files =
method.sjs
partial_content.sjs
@ -10,7 +11,6 @@ support-files =
[test_partially_cached_content.html]
[test_uri_scheme.html]
[test_user_agent_overrides.html]
skip-if = toolkit == 'android' # Bug 1111137
[test_user_agent_updates.html]
[test_user_agent_updates_reset.html]
[test_xhr_method_case.html]

Просмотреть файл

@ -263,8 +263,10 @@ fail-if = os == "android"
# spdy and http2 unit tests require us to have node available to run the spdy and http2 server
[test_spdy.js]
run-if = hasNode
run-sequentially = node server exceptions dont replay well
[test_http2.js]
run-if = hasNode
run-sequentially = node server exceptions dont replay well
[test_speculative_connect.js]
[test_standardurl.js]
[test_standardurl_port.js]

Просмотреть файл

@ -0,0 +1,105 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
config = {
"suite_definitions": {
"mochitest": {
"run_filename": "runtestsremote.py",
"testsdir": "mochitest",
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
"--quiet", "--log-raw=%(raw_log_file)s",
"--total-chunks=16",
"--run-only-tests=android23.json",
],
},
"mochitest-gl": {
"run_filename": "runtestsremote.py",
"testsdir": "mochitest",
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
"--quiet", "--log-raw=%(raw_log_file)s",
"--total-chunks=2",
"--test-manifest=gl.json",
],
},
"robocop": {
"run_filename": "runtestsremote.py",
"testsdir": "mochitest",
"options": ["--autorun", "--close-when-done", "--dm_trans=adb",
"--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s",
"--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s",
"--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s",
"--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s",
"--quiet", "--log-raw=%(raw_log_file)s",
"--total-chunks=4",
"--robocop-path=../..",
"--robocop-ids=fennec_ids.txt",
"--robocop=robocop.ini",
],
},
"reftest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [ "--app=%(app)s", "--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--total-chunks=16",
"tests/layout/reftests/reftest.list",
],
},
"crashtest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [ "--app=%(app)s", "--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"--total-chunks=2",
"tests/testing/crashtest/crashtests.list",
],
},
"jsreftest": {
"run_filename": "remotereftest.py",
"testsdir": "reftest",
"options": [ "--app=%(app)s", "--ignore-window-size",
"--dm_trans=adb",
"--bootstrap",
"--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s",
"--utility-path=%(utility_path)s", "--http-port=%(http_port)s",
"--ssl-port=%(ssl_port)s", "--httpd-path", "%(modules_dir)s",
"--symbols-path=%(symbols_path)s",
"../jsreftest/tests/jstests.list",
"--total-chunks=6",
"--extra-profile-file=jsreftest/tests/user.js",
],
},
"xpcshell": {
"run_filename": "remotexpcshelltests.py",
"testsdir": "xpcshell",
"options": [
"--dm_trans=adb",
"--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s",
"--apk=%(installer_path)s", "--no-logfiles",
"--symbols-path=%(symbols_path)s",
"--manifest=tests/xpcshell.ini",
"--log-raw=%(raw_log_file)s",
"--total-chunks=3",
],
},
}, # end suite_definitions
}

Просмотреть файл

@ -5,7 +5,7 @@
},
"global": {
"talos_repo": "https://hg.mozilla.org/build/talos",
"talos_revision": "ebc4327b8cb8"
"talos_revision": "39c9c9b33cfc"
},
"extra_options": {
"android": [ "--apkPath=%(apk_path)s" ]
@ -39,7 +39,8 @@
"tests": ["tpaint"]
},
"other-snow-e10s": {
"tests": ["tpaint"]
"tests": ["tpaint"],
"talos_options": ["--e10s"]
},
"other_nol64": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"]
@ -80,7 +81,8 @@
"tests": ["glterrain"]
},
"g1-snow-e10s": {
"tests": ["glterrain"]
"tests": ["glterrain"],
"talos_options": ["--e10s"]
},
"svgr": {
"tests": ["tsvgx", "tsvgr_opacity", "tart", "tscrollx", "cart"]
@ -93,7 +95,8 @@
"tests": ["tsvgx", "tscrollx"]
},
"svgr-snow-e10s": {
"tests": ["tsvgx", "tscrollx"]
"tests": ["tsvgx", "tscrollx"],
"talos_options": ["--e10s"]
},
"tp5o": {
"tests": ["tp5o"],

Просмотреть файл

@ -186,8 +186,16 @@ class FirefoxBrowser(Browser):
# TODO: Maybe only set this if certutil won't launch?
env = os.environ.copy()
certutil_dir = os.path.dirname(self.binary)
env["LD_LIBRARY_PATH"] = certutil_dir
env["PATH"] = os.path.pathsep.join([certutil_dir, env["PATH"]])
if mozinfo.isMac:
env_var = "DYLD_LIBRARY_PATH"
elif mozinfo.isUnix:
env_var = "LD_LIBRARY_PATH"
else:
env_var = "PATH"
env[env_var] = (os.path.pathsep.join([certutil_dir, env[env_var]])
if env_var in env else certutil_dir)
def certutil(*args):
cmd = [self.certutil_binary] + list(args)

Просмотреть файл

@ -28,5 +28,6 @@ skip-if = toolkit == 'android' #TIMED_OUT
[test_videocontrols_audio.html]
[test_videocontrols_audio_direction.html]
[test_videocontrols_standalone.html]
skip-if = android_version == '10' # bug 1075573
[test_videocontrols_video_direction.html]
[test_bug898940.html]

Просмотреть файл

@ -76,7 +76,7 @@ public:
nsresult GetStatus(uint16_t *aStatus);
private:
enum LoadStatus MOZ_ENUM_TYPE(uint16_t) {
enum LoadStatus : uint16_t {
UNINITIALIZED = 0U,
REQUESTED = 1U,
RECEIVING = 2U,

Просмотреть файл

@ -32,7 +32,7 @@ namespace mozilla {
typedef uint8_t EventClassIDType;
enum EventClassID MOZ_ENUM_TYPE(EventClassIDType)
enum EventClassID : EventClassIDType
{
// The event class name will be:
// eBasicEventClass for WidgetEvent
@ -77,7 +77,7 @@ enum CodeNameIndex
#define NS_DEFINE_COMMAND(aName, aCommandStr) , Command##aName
typedef int8_t CommandInt;
enum Command MOZ_ENUM_TYPE(CommandInt)
enum Command : CommandInt
{
CommandDoNothing

Просмотреть файл

@ -30,7 +30,8 @@
#include "mozilla/StaticPtr.h"
#include "cutils/properties.h"
#include "gfx2DGlue.h"
#include "nsWindow.h"
#include "gfxPlatform.h"
#include "VsyncSource.h"
#if ANDROID_VERSION >= 17
#include "libdisplay/FramebufferSurface.h"
@ -227,7 +228,8 @@ HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp)
LOGE("Non-uniform vsync interval: %lld\n", vsyncInterval);
}
mLastVsyncTime = aVsyncTimestamp;
nsWindow::NotifyVsync(vsyncTime);
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().NotifyVsync(vsyncTime);
}
// Called on the "invalidator" thread (run from HAL).

Просмотреть файл

@ -215,21 +215,6 @@ nsWindow::DoDraw(void)
}
}
/* static */ void
nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp)
{
if (!gFocusedWindow) {
return;
}
CompositorVsyncDispatcher* vsyncDispatcher = gFocusedWindow->GetCompositorVsyncDispatcher();
// During bootup, there is a delay between when the nsWindow is created
// and when the Compositor is created, but vsync is already turned on
if (vsyncDispatcher) {
vsyncDispatcher->NotifyVsync(aVsyncTimestamp);
}
}
/*static*/ nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
{

Просмотреть файл

@ -50,7 +50,6 @@ public:
nsWindow();
virtual ~nsWindow();
static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
static void DoDraw(void);
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent);
static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);

Просмотреть файл

@ -225,7 +225,7 @@ struct nsIMEUpdatePreference {
typedef uint8_t Notifications;
enum MOZ_ENUM_TYPE(Notifications)
enum : Notifications
{
NOTIFY_NOTHING = 0,
NOTIFY_SELECTION_CHANGE = 1 << 0,
@ -519,7 +519,7 @@ struct SizeConstraints {
// Update values in GeckoEditable.java if you make changes here.
// XXX Negative values are used in Android...
typedef int8_t IMEMessageType;
enum IMEMessage MOZ_ENUM_TYPE(IMEMessageType)
enum IMEMessage : IMEMessageType
{
// An editable content is getting focus
NOTIFY_IME_OF_FOCUS = 1,

Просмотреть файл

@ -480,7 +480,7 @@ protected:
struct PendingAction MOZ_FINAL
{
enum ActionType MOZ_ENUM_TYPE(uint8_t)
enum ActionType : uint8_t
{
COMPOSITION_START,
COMPOSITION_UPDATE,
@ -635,7 +635,7 @@ protected:
nsTextStore::Selection& mSelection;
// The minimum offset of modified part of the text.
enum MOZ_ENUM_TYPE(uint32_t)
enum : uint32_t
{
NOT_MODIFIED = UINT32_MAX
};

Просмотреть файл

@ -136,7 +136,7 @@
* #define's for compatibility with old code.
*/
#include "ErrorListCxxDefines.h"
#elif defined(MOZ_HAVE_CXX11_ENUM_TYPE)
#elif defined(__cplusplus)
typedef enum tag_nsresult : uint32_t
{
#undef ERROR
@ -144,21 +144,6 @@
#include "ErrorList.h"
#undef ERROR
} nsresult;
#elif defined(__cplusplus)
/*
* We're C++ in an old compiler lacking enum classes *and* typed enums (likely
* gcc < 4.5.1 as clang/MSVC have long supported one or both), or compiler
* support is unknown. Yet nsresult must have unsigned 32-bit representation.
* So just make it a typedef, and implement the constants with global consts.
*/
typedef uint32_t nsresult;
const nsresult
#undef ERROR
#define ERROR(key, val) key = val
#include "ErrorList.h"
#undef ERROR
;
#else
/*
* C doesn't have any way to fix the type underlying an enum, and enum

Просмотреть файл

@ -3,8 +3,9 @@
* License, v. 2.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 "TestHarness.h"
#include <algorithm>
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsIThread.h"
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
@ -13,76 +14,11 @@
#include "nsCRT.h"
#include "nsIPipe.h" // new implementation
#include "mozilla/Monitor.h"
#include "mozilla/ReentrantMonitor.h"
#include "gtest/gtest.h"
using namespace mozilla;
/** NS_NewPipe2 reimplemented, because it's not exported by XPCOM */
nsresult TP_NewPipe2(nsIAsyncInputStream** input,
nsIAsyncOutputStream** output,
bool nonBlockingInput,
bool nonBlockingOutput,
uint32_t segmentSize,
uint32_t segmentCount,
nsIMemory* segmentAlloc)
{
nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
if (!pipe)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = pipe->Init(nonBlockingInput,
nonBlockingOutput,
segmentSize,
segmentCount,
segmentAlloc);
if (NS_FAILED(rv))
return rv;
pipe->GetInputStream(input);
pipe->GetOutputStream(output);
return NS_OK;
}
/** NS_NewPipe reimplemented, because it's not exported by XPCOM */
#define TP_DEFAULT_SEGMENT_SIZE 4096
nsresult TP_NewPipe(nsIInputStream **pipeIn,
nsIOutputStream **pipeOut,
uint32_t segmentSize = 0,
uint32_t maxSize = 0,
bool nonBlockingInput = false,
bool nonBlockingOutput = false,
nsIMemory *segmentAlloc = nullptr);
nsresult TP_NewPipe(nsIInputStream **pipeIn,
nsIOutputStream **pipeOut,
uint32_t segmentSize,
uint32_t maxSize,
bool nonBlockingInput,
bool nonBlockingOutput,
nsIMemory *segmentAlloc)
{
if (segmentSize == 0)
segmentSize = TP_DEFAULT_SEGMENT_SIZE;
// Handle maxSize of UINT32_MAX as a special case
uint32_t segmentCount;
if (maxSize == UINT32_MAX)
segmentCount = UINT32_MAX;
else
segmentCount = maxSize / segmentSize;
nsIAsyncInputStream *in;
nsIAsyncOutputStream *out;
nsresult rv = TP_NewPipe2(&in, &out, nonBlockingInput, nonBlockingOutput,
segmentSize, segmentCount, segmentAlloc);
if (NS_FAILED(rv)) return rv;
*pipeIn = in;
*pipeOut = out;
return NS_OK;
}
#define KEY 0xa7
#define ITERATIONS 33333
char kTestPattern[] = "My hovercraft is full of eels.\n";
@ -104,11 +40,11 @@ WriteAll(nsIOutputStream *os, const char *buf, uint32_t bufLen, uint32_t *lenWri
return NS_OK;
}
class nsReceiver : public nsIRunnable {
class nsReceiver MOZ_FINAL : public nsIRunnable {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD Run() {
NS_IMETHOD Run() MOZ_OVERRIDE {
nsresult rv;
char buf[101];
uint32_t count;
@ -136,11 +72,14 @@ public:
return rv;
}
nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) {
explicit nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) {
}
uint32_t GetBytesRead() { return mCount; }
private:
~nsReceiver() {}
protected:
nsCOMPtr<nsIInputStream> mIn;
uint32_t mCount;
@ -151,7 +90,7 @@ NS_IMPL_ISUPPORTS(nsReceiver, nsIRunnable)
nsresult
TestPipe(nsIInputStream* in, nsIOutputStream* out)
{
nsCOMPtr<nsReceiver> receiver = new nsReceiver(in);
nsRefPtr<nsReceiver> receiver = new nsReceiver(in);
if (!receiver)
return NS_ERROR_OUT_OF_MEMORY;
@ -188,18 +127,18 @@ TestPipe(nsIInputStream* in, nsIOutputStream* out)
printf("wrote %d bytes, time = %dms\n", total,
PR_IntervalToMilliseconds(end - start));
NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything");
EXPECT_EQ(receiver->GetBytesRead(), total);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
class nsShortReader : public nsIRunnable {
class nsShortReader MOZ_FINAL : public nsIRunnable {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD Run() {
NS_IMETHOD Run() MOZ_OVERRIDE {
nsresult rv;
char buf[101];
uint32_t count;
@ -230,24 +169,24 @@ public:
return rv;
}
nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) {
mMon = new Monitor("nsShortReader");
explicit nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) {
mMon = new ReentrantMonitor("nsShortReader");
}
void Received(uint32_t count) {
MonitorAutoEnter mon(*mMon);
ReentrantMonitorAutoEnter mon(*mMon);
mReceived += count;
mon.Notify();
}
uint32_t WaitForReceipt(const uint32_t aWriteCount) {
MonitorAutoEnter mon(*mMon);
ReentrantMonitorAutoEnter mon(*mMon);
uint32_t result = mReceived;
while (result < aWriteCount) {
mon.Wait();
NS_ASSERTION(mReceived > result, "failed to receive");
EXPECT_TRUE(mReceived > result);
result = mReceived;
}
@ -255,10 +194,13 @@ public:
return result;
}
private:
~nsShortReader() {}
protected:
nsCOMPtr<nsIInputStream> mIn;
uint32_t mReceived;
Monitor* mMon;
ReentrantMonitor* mMon;
};
NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable)
@ -266,7 +208,7 @@ NS_IMPL_ISUPPORTS(nsShortReader, nsIRunnable)
nsresult
TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
{
nsCOMPtr<nsShortReader> receiver = new nsShortReader(in);
nsRefPtr<nsShortReader> receiver = new nsShortReader(in);
if (!receiver)
return NS_ERROR_OUT_OF_MEMORY;
@ -282,10 +224,10 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
char* buf = PR_smprintf("%d %s", i, kTestPattern);
uint32_t len = strlen(buf);
len = len * rand() / RAND_MAX;
len = XPCOM_MAX(1, len);
len = std::min(1u, len);
rv = WriteAll(out, buf, len, &writeCount);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(writeCount == len, "didn't write enough");
EXPECT_EQ(writeCount, len);
total += writeCount;
if (gTrace)
@ -297,9 +239,9 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
#ifdef DEBUG
const uint32_t received =
#endif
receiver->WaitForReceipt(writeCount);
NS_ASSERTION(received == writeCount, "received wrong amount");
EXPECT_EQ(received, writeCount);
#endif
}
rv = out->Close();
if (NS_FAILED(rv)) return rv;
@ -313,12 +255,12 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
////////////////////////////////////////////////////////////////////////////////
class nsPump : public nsIRunnable
class nsPump MOZ_FINAL : public nsIRunnable
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD Run() {
NS_IMETHOD Run() MOZ_OVERRIDE {
nsresult rv;
uint32_t count;
while (true) {
@ -346,6 +288,9 @@ public:
: mIn(in), mOut(out), mCount(0) {
}
private:
~nsPump() {}
protected:
nsCOMPtr<nsIInputStream> mIn;
nsCOMPtr<nsIOutputStream> mOut;
@ -354,35 +299,36 @@ protected:
NS_IMPL_ISUPPORTS(nsPump, nsIRunnable)
nsresult
TestChainedPipes()
TEST(Pipes, ChainedPipes)
{
nsresult rv;
printf("TestChainedPipes\n");
if (gTrace) {
printf("TestChainedPipes\n");
}
nsCOMPtr<nsIInputStream> in1;
nsCOMPtr<nsIOutputStream> out1;
rv = TP_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999);
if (NS_FAILED(rv)) return rv;
rv = NS_NewPipe(getter_AddRefs(in1), getter_AddRefs(out1), 20, 1999);
if (NS_FAILED(rv)) return;
nsCOMPtr<nsIInputStream> in2;
nsCOMPtr<nsIOutputStream> out2;
rv = TP_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401);
if (NS_FAILED(rv)) return rv;
rv = NS_NewPipe(getter_AddRefs(in2), getter_AddRefs(out2), 200, 401);
if (NS_FAILED(rv)) return;
nsCOMPtr<nsPump> pump = new nsPump(in1, out2);
if (pump == nullptr) return NS_ERROR_OUT_OF_MEMORY;
nsRefPtr<nsPump> pump = new nsPump(in1, out2);
if (pump == nullptr) return;
nsCOMPtr<nsIThread> thread;
rv = NS_NewThread(getter_AddRefs(thread), pump);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return;
nsCOMPtr<nsReceiver> receiver = new nsReceiver(in2);
if (receiver == nullptr) return NS_ERROR_OUT_OF_MEMORY;
nsRefPtr<nsReceiver> receiver = new nsReceiver(in2);
if (receiver == nullptr) return;
nsCOMPtr<nsIThread> receiverThread;
rv = NS_NewThread(getter_AddRefs(receiverThread), receiver);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return;
uint32_t total = 0;
for (uint32_t i = 0; i < ITERATIONS; i++) {
@ -390,10 +336,10 @@ TestChainedPipes()
char* buf = PR_smprintf("%d %s", i, kTestPattern);
uint32_t len = strlen(buf);
len = len * rand() / RAND_MAX;
len = XPCOM_MAX(1, len);
len = std::max(1u, len);
rv = WriteAll(out1, buf, len, &writeCount);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(writeCount == len, "didn't write enough");
if (NS_FAILED(rv)) return;
EXPECT_EQ(writeCount, len);
total += writeCount;
if (gTrace)
@ -401,14 +347,14 @@ TestChainedPipes()
PR_smprintf_free(buf);
}
printf("wrote total of %d bytes\n", total);
if (gTrace) {
printf("wrote total of %d bytes\n", total);
}
rv = out1->Close();
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) return;
thread->Shutdown();
receiverThread->Shutdown();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
@ -420,50 +366,26 @@ RunTests(uint32_t segSize, uint32_t segCount)
nsCOMPtr<nsIInputStream> in;
nsCOMPtr<nsIOutputStream> out;
uint32_t bufSize = segSize * segCount;
printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize);
printf("Testing long writes...\n");
rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
if (gTrace) {
printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize);
printf("Testing long writes...\n");
}
rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = TestPipe(in, out);
NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
EXPECT_TRUE(NS_SUCCEEDED(rv));
printf("Testing short writes...\n");
rv = TP_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
NS_ASSERTION(NS_SUCCEEDED(rv), "TP_NewPipe failed");
if (gTrace) {
printf("Testing short writes...\n");
}
rv = NS_NewPipe(getter_AddRefs(in), getter_AddRefs(out), segSize, bufSize);
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = TestShortWrites(in, out);
NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
EXPECT_TRUE(NS_SUCCEEDED(rv));
}
////////////////////////////////////////////////////////////////////////////////
#if 0
extern void
TestSegmentedBuffer();
#endif
int
main(int argc, char* argv[])
TEST(Pipes, Main)
{
nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr;
rv = NS_InitXPCOM2(getter_AddRefs(servMgr), nullptr, nullptr);
if (NS_FAILED(rv)) return rv;
if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0)
gTrace = true;
rv = TestChainedPipes();
NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed");
RunTests(16, 1);
RunTests(4096, 16);
servMgr = 0;
rv = NS_ShutdownXPCOM(nullptr);
NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
return 0;
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -7,6 +7,7 @@
#include "nsTPriorityQueue.h"
#include <stdio.h>
#include <stdlib.h>
#include "gtest/gtest.h"
template<class T, class Compare>
void
@ -16,32 +17,13 @@ CheckPopSequence(const nsTPriorityQueue<T, Compare>& aQueue,
nsTPriorityQueue<T, Compare> copy(aQueue);
for (uint32_t i = 0; i < aSequenceLength; i++) {
if (copy.IsEmpty()) {
printf("Number of elements in the queue is too short by %d.\n",
aSequenceLength - i);
exit(-1);
}
EXPECT_FALSE(copy.IsEmpty());
T pop = copy.Pop();
if (pop != aExpectedSequence[i]) {
printf("Unexpected value in pop sequence at position %d\n", i);
printf(" Sequence:");
for (size_t j = 0; j < aSequenceLength; j++) {
printf(" %d", aExpectedSequence[j]);
if (j == i) {
printf("**");
}
}
printf("\n ** Got %d instead\n", pop);
exit(-1);
}
EXPECT_EQ(pop, aExpectedSequence[i]);
}
if (!copy.IsEmpty()) {
printf("Number of elements in the queue is too long by %d.\n",
copy.Length());
exit(-1);
}
EXPECT_TRUE(copy.IsEmpty());
}
template<class A>
@ -52,11 +34,11 @@ public:
}
};
int main()
TEST(PriorityQueue, Main)
{
nsTPriorityQueue<int> queue;
NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not initially empty");
EXPECT_TRUE(queue.IsEmpty());
queue.Push(8);
queue.Push(6);
@ -64,9 +46,9 @@ int main()
queue.Push(2);
queue.Push(10);
queue.Push(6);
NS_ABORT_IF_FALSE(queue.Top() == 2, "Unexpected queue top");
NS_ABORT_IF_FALSE(queue.Length() == 6, "Unexpected queue length");
NS_ABORT_IF_FALSE(!queue.IsEmpty(), "Queue empty when populated");
EXPECT_EQ(queue.Top(), 2);
EXPECT_EQ(queue.Length(), 6u);
EXPECT_FALSE(queue.IsEmpty());
int expected[] = { 2, 4, 6, 6, 8, 10 };
CheckPopSequence(queue, expected, sizeof(expected) / sizeof(expected[0]));
@ -77,7 +59,7 @@ int main()
CheckPopSequence(queue2, expected, sizeof(expected) / sizeof(expected[0]));
queue.Clear();
NS_ABORT_IF_FALSE(queue.IsEmpty(), "Queue not emptied by Clear");
EXPECT_TRUE(queue.IsEmpty());
// try same sequence with a max heap
nsTPriorityQueue<int, MaxCompare<int> > max_queue;
@ -87,10 +69,8 @@ int main()
max_queue.Push(2);
max_queue.Push(10);
max_queue.Push(6);
NS_ABORT_IF_FALSE(max_queue.Top() == 10, "Unexpected queue top for max heap");
EXPECT_EQ(max_queue.Top(), 10);
int expected_max[] = { 10, 8, 6, 6, 4, 2 };
CheckPopSequence(max_queue, expected_max,
sizeof(expected_max) / sizeof(expected_max[0]));
return 0;
}

Просмотреть файл

@ -7,8 +7,9 @@
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
#include "gtest/gtest.h"
int main()
TEST(TestStorageStreams, Main)
{
char kData[4096];
memset(kData, 0, sizeof(kData));
@ -17,94 +18,75 @@ int main()
nsCOMPtr<nsIStorageStream> stor;
rv = NS_NewStorageStream(4096, UINT32_MAX, getter_AddRefs(stor));
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
nsCOMPtr<nsIOutputStream> out;
rv = stor->GetOutputStream(0, getter_AddRefs(out));
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
uint32_t n;
rv = out->Write(kData, sizeof(kData), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Write(kData, sizeof(kData), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Close();
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
out = nullptr;
nsCOMPtr<nsIInputStream> in;
rv = stor->NewInputStream(0, getter_AddRefs(in));
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
char buf[4096];
// consume contents of input stream
do {
rv = in->Read(buf, sizeof(buf), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
} while (n != 0);
rv = in->Close();
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
in = nullptr;
// now, write 3 more full 4k segments + 11 bytes, starting at 8192
// total written equals 20491 bytes
rv = stor->GetOutputStream(8192, getter_AddRefs(out));
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Write(kData, sizeof(kData), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Write(kData, sizeof(kData), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Write(kData, sizeof(kData), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Write(kData, 11, &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
rv = out->Close();
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
out = nullptr;
// now, read all
rv = stor->NewInputStream(0, getter_AddRefs(in));
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
// consume contents of input stream
do {
rv = in->Read(buf, sizeof(buf), &n);
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
} while (n != 0);
rv = in->Close();
if (NS_FAILED(rv))
return -1;
EXPECT_TRUE(NS_SUCCEEDED(rv));
in = nullptr;
return 0;
}

Просмотреть файл

@ -8,7 +8,10 @@ UNIFIED_SOURCES += [
'TestCRT.cpp',
'TestEncoding.cpp',
'TestExpirationTracker.cpp',
'TestPipes.cpp',
'TestPriorityQueue.cpp',
'TestSnappyStreams.cpp',
'TestStorageStream.cpp',
'TestStrings.cpp',
]

Просмотреть файл

@ -80,9 +80,6 @@ if CONFIG['MOZ_MEMORY']:
# XXX Make these tests work in libxul builds.
#CPP_UNIT_TESTS += [
# 'TestPipes',
# 'TestPriorityQueue',
# 'TestStorageStream',
# 'TestSynchronization',
# 'TestTArray',
# 'TestThreadPool',