зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c a=merge
This commit is contained in:
Коммит
b0e827c8f4
3
CLOBBER
3
CLOBBER
|
@ -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',
|
||||
|
|
Загрузка…
Ссылка в новой задаче