Merge inbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-05-20 18:16:22 -07:00
Родитель aae36aaed4 5369765244
Коммит 98d8b5b1e9
90 изменённых файлов: 1651 добавлений и 908 удалений

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

@ -5,7 +5,6 @@ no_sccache=1
ac_add_options --enable-valgrind
ac_add_options --disable-jemalloc
ac_add_options --enable-optimize="-g -O -freorder-blocks"
ac_add_options --disable-install-strip
# Include the override mozconfig again (even though the above includes it)

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

@ -5,7 +5,6 @@ no_sccache=1
ac_add_options --enable-valgrind
ac_add_options --disable-jemalloc
ac_add_options --enable-optimize="-g -O -freorder-blocks"
ac_add_options --disable-install-strip
# Include the override mozconfig again (even though the above includes it)

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

@ -201,6 +201,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaDevices)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagesManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageStores)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager)
@ -307,6 +308,7 @@ Navigator::Invalidate()
#endif
mCameraManager = nullptr;
mMediaDevices = nullptr;
if (mMessagesManager) {
mMessagesManager = nullptr;

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<body>
<script>
// This should not leak.
var a = navigator;
navigator.mediaDevices._ = null;
</script>
</body>

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

@ -202,3 +202,4 @@ load xhr_empty_datauri.html
load xhr_html_nullresponse.html
load structured_clone_container_throws.html
load 1154598.xhtml
load 1157995.html

174
dom/cache/DBSchema.cpp поставляемый
Просмотреть файл

@ -181,7 +181,7 @@ static void AppendListParamsToQuery(nsACString& aQuery,
static nsresult BindListParamsToQuery(mozIStorageStatement* aState,
const nsTArray<EntryId>& aEntryIdList,
uint32_t aPos, int32_t aLen);
static nsresult BindId(mozIStorageStatement* aState, uint32_t aPos,
static nsresult BindId(mozIStorageStatement* aState, const nsACString& aName,
const nsID* aId);
static nsresult ExtractId(mozIStorageStatement* aState, uint32_t aPos,
nsID* aIdOut);
@ -412,11 +412,11 @@ DeleteCacheId(mozIStorageConnection* aConn, CacheId aCacheId,
// Delete the remainder of the cache using cascade semantics.
nsCOMPtr<mozIStorageStatement> state;
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM caches WHERE id=?1;"
"DELETE FROM caches WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -438,11 +438,11 @@ IsCacheOrphaned(mozIStorageConnection* aConn, CacheId aCacheId,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT COUNT(*) FROM storage WHERE cache_id=?1;"
"SELECT COUNT(*) FROM storage WHERE cache_id=:cache_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -646,11 +646,11 @@ StorageMatch(mozIStorageConnection* aConn,
nsCOMPtr<mozIStorageStatement> state;
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT cache_id FROM storage WHERE namespace=?1 ORDER BY rowid;"
"SELECT cache_id FROM storage WHERE namespace=:namespace ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsAutoTArray<CacheId, 32> cacheIdList;
@ -693,14 +693,15 @@ StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
// Use IS for matching the key since an EmptryString() key maps to NULL.
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT cache_id FROM storage WHERE namespace=?1 AND key IS ?2 ORDER BY rowid;"
"SELECT cache_id FROM storage WHERE namespace=:namespace AND key IS :key "
"ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -727,17 +728,18 @@ StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"INSERT INTO storage (namespace, key, cache_id) VALUES(?1, ?2, ?3);"
"INSERT INTO storage (namespace, key, cache_id) "
"VALUES (:namespace, :key, :cache_id);"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(2, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -756,14 +758,14 @@ StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
// Use IS for matching the key since an EmptryString() key maps to NULL.
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM storage WHERE namespace=?1 AND key IS ?2;"
"DELETE FROM storage WHERE namespace=:namespace AND key IS :key;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -781,11 +783,11 @@ StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT key FROM storage WHERE namespace=?1 ORDER BY rowid;"
"SELECT key FROM storage WHERE namespace=:namespace ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -811,11 +813,11 @@ QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id FROM entries WHERE cache_id=?1 ORDER BY id;"
"SELECT id FROM entries WHERE cache_id=:cache_id ORDER BY id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -851,7 +853,7 @@ QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
"FROM entries "
"LEFT OUTER JOIN response_headers ON entries.id=response_headers.entry_id "
"AND response_headers.name='vary' "
"WHERE entries.cache_id=?1 "
"WHERE entries.cache_id=:cache_id "
"AND entries."
);
@ -864,16 +866,16 @@ QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
query.AppendLiteral("request_url");
}
query.AppendLiteral("=?2 GROUP BY entries.id ORDER BY entries.id;");
query.AppendLiteral("=:url GROUP BY entries.id ORDER BY entries.id;");
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(query, getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(1, urlToMatch);
rv = state->BindStringByName(NS_LITERAL_CSTRING("url"), urlToMatch);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -919,11 +921,11 @@ MatchByVaryHeader(mozIStorageConnection* aConn,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT value FROM response_headers "
"WHERE name='vary' AND entry_id=?1;"
"WHERE name='vary' AND entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsAutoTArray<nsCString, 8> varyValues;
@ -943,11 +945,11 @@ MatchByVaryHeader(mozIStorageConnection* aConn,
state->Reset();
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT name, value FROM request_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsRefPtr<InternalHeaders> cachedHeaders =
@ -1138,71 +1140,101 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"response_body_id, "
"response_security_info, "
"cache_id "
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19)"
") VALUES ("
":request_method, "
":request_url, "
":request_url_no_query, "
":request_referrer, "
":request_headers_guard, "
":request_mode, "
":request_credentials, "
":request_contentpolicytype, "
":request_context, "
":request_cache, "
":request_body_id, "
":response_type, "
":response_url, "
":response_status, "
":response_status_text, "
":response_headers_guard, "
":response_body_id, "
":response_security_info, "
":cache_id "
");"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(0, aRequest.method());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("request_method"),
aRequest.method());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(1, aRequest.url());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_url"),
aRequest.url());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(2, aRequest.urlWithoutQuery());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_url_no_query"),
aRequest.urlWithoutQuery());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(3, aRequest.referrer());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_referrer"),
aRequest.referrer());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(4,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_headers_guard"),
static_cast<int32_t>(aRequest.headersGuard()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(5, static_cast<int32_t>(aRequest.mode()));
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_mode"),
static_cast<int32_t>(aRequest.mode()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(6,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_credentials"),
static_cast<int32_t>(aRequest.credentials()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(7,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_contentpolicytype"),
static_cast<int32_t>(aRequest.contentPolicyType()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(8,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_context"),
static_cast<int32_t>(aRequest.context()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(9,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_cache"),
static_cast<int32_t>(aRequest.requestCache()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = BindId(state, 10, aRequestBodyId);
rv = BindId(state, NS_LITERAL_CSTRING("request_body_id"), aRequestBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(11, static_cast<int32_t>(aResponse.type()));
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_type"),
static_cast<int32_t>(aResponse.type()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(12, aResponse.url());
rv = state->BindStringByName(NS_LITERAL_CSTRING("response_url"),
aResponse.url());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(13, aResponse.status());
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_status"),
aResponse.status());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(14, aResponse.statusText());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("response_status_text"),
aResponse.statusText());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(15,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_headers_guard"),
static_cast<int32_t>(aResponse.headersGuard()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = BindId(state, 16, aResponseBodyId);
rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringAsBlobParameter(17, aResponse.securityInfo());
rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("response_security_info"),
aResponse.securityInfo());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(18, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1226,19 +1258,21 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"name, "
"value, "
"entry_id "
") VALUES (?1, ?2, ?3)"
") VALUES (:name, :value, :entry_id)"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
const nsTArray<HeadersEntry>& requestHeaders = aRequest.headers();
for (uint32_t i = 0; i < requestHeaders.Length(); ++i) {
rv = state->BindUTF8StringParameter(0, requestHeaders[i].name());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("name"),
requestHeaders[i].name());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(1, requestHeaders[i].value());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("value"),
requestHeaders[i].value());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(2, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1250,19 +1284,21 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"name, "
"value, "
"entry_id "
") VALUES (?1, ?2, ?3)"
") VALUES (:name, :value, :entry_id)"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
const nsTArray<HeadersEntry>& responseHeaders = aResponse.headers();
for (uint32_t i = 0; i < responseHeaders.Length(); ++i) {
rv = state->BindUTF8StringParameter(0, responseHeaders[i].name());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("name"),
responseHeaders[i].name());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(1, responseHeaders[i].value());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("value"),
responseHeaders[i].value());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(2, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1291,11 +1327,11 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
"response_body_id, "
"response_security_info "
"FROM entries "
"WHERE id=?1;"
"WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -1342,11 +1378,11 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
"name, "
"value "
"FROM response_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
@ -1387,11 +1423,11 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"request_cache, "
"request_body_id "
"FROM entries "
"WHERE id=?1;"
"WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -1460,11 +1496,11 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"name, "
"value "
"FROM request_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
@ -1506,28 +1542,28 @@ BindListParamsToQuery(mozIStorageStatement* aState,
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT((aPos + aLen) <= aEntryIdList.Length());
for (int32_t i = aPos; i < aLen; ++i) {
nsresult rv = aState->BindInt32Parameter(i, aEntryIdList[i]);
nsresult rv = aState->BindInt32ByIndex(i, aEntryIdList[i]);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
BindId(mozIStorageStatement* aState, uint32_t aPos, const nsID* aId)
BindId(mozIStorageStatement* aState, const nsACString& aName, const nsID* aId)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aState);
nsresult rv;
if (!aId) {
rv = aState->BindNullParameter(aPos);
rv = aState->BindNullByName(aName);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
return rv;
}
char idBuf[NSID_LENGTH];
aId->ToProvidedString(idBuf);
rv = aState->BindUTF8StringParameter(aPos, nsAutoCString(idBuf));
rv = aState->BindUTF8StringByName(aName, nsAutoCString(idBuf));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
return rv;

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

@ -465,15 +465,7 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
return NS_OK;
}
// Kick off the geo device, if it isn't already running
nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
nsresult rv = gs->StartDevice(GetPrincipal());
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
bool canUseCache = false;
CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
@ -497,6 +489,15 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
// getCurrentPosition requests serviced by the cache
// will now be owned by the RequestSendLocationEvent
Update(lastPosition.position);
} else {
// Kick off the geo device, if it isn't already running
nsresult rv = gs->StartDevice(GetPrincipal());
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
}
if (mIsWatchPositionRequest || !canUseCache) {
@ -957,7 +958,9 @@ nsGeolocationService::Observe(nsISupports* aSubject,
NS_IMETHODIMP
nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
{
if (aSomewhere) {
SetCachedPosition(aSomewhere);
}
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
mGeolocators[i]->Update(aSomewhere);

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

@ -193,7 +193,9 @@ let FormAssistant = {
addEventListener("focus", this, true, false);
addEventListener("blur", this, true, false);
addEventListener("resize", this, true, false);
addEventListener("submit", this, true, false);
// We should not blur the fucus if the submit event is cancelled,
// therefore we are binding our event listener in the bubbling phase here.
addEventListener("submit", this, false, false);
addEventListener("pagehide", this, true, false);
addEventListener("beforeunload", this, true, false);
addEventListener("input", this, true, false);
@ -399,7 +401,7 @@ let FormAssistant = {
}
// fall through
case "submit":
if (this.focusedElement) {
if (this.focusedElement && !evt.defaultPrevented) {
this.focusedElement.blur();
}
break;

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

@ -64,56 +64,6 @@ SetUpSandboxEnvironment()
return;
}
}
#if defined(NIGHTLY_BUILD)
static void
CleanUpOldSandboxEnvironment()
{
// Temporary code to clean up the old low integrity temp directories.
// The removal of this is tracked by bug 1165818.
nsCOMPtr<nsIFile> lowIntegrityMozilla;
nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOCAL_APPDATA_LOW_DIR,
getter_AddRefs(lowIntegrityMozilla));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
rv = lowIntegrityMozilla->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsISimpleEnumerator> iter;
rv = lowIntegrityMozilla->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool more;
nsCOMPtr<nsISupports> elem;
while (NS_SUCCEEDED(iter->HasMoreElements(&more)) && more) {
rv = iter->GetNext(getter_AddRefs(elem));
if (NS_FAILED(rv)) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(elem);
if (!file) {
continue;
}
nsAutoString leafName;
rv = file->GetLeafName(leafName);
if (NS_FAILED(rv)) {
continue;
}
if (leafName.Find(NS_LITERAL_STRING("MozTemp-{")) == 0) {
file->Remove(/* aRecursive */ true);
}
}
}
#endif
#endif
void
@ -138,12 +88,11 @@ ContentProcess::Init()
return true;
}
// Note: CleanUp() never gets called in non-debug builds because we exit early
// in ContentChild::ActorDestroy().
void
ContentProcess::CleanUp()
{
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) && defined(NIGHTLY_BUILD)
CleanUpOldSandboxEnvironment();
#endif
mXREEmbed.Stop();
}

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

@ -14,9 +14,9 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s || toolkit == 'androi
[test_cpow_cookies.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_NuwaProcessCreation.html]
skip-if = toolkit != 'gonk'
skip-if = true # bug 1166923
[test_NuwaProcessDeadlock.html]
skip-if = toolkit != 'gonk'
skip-if = true # bug 1166923
[test_child_docshell.html]
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
[test_CrashService_crash.html]

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

@ -0,0 +1,185 @@
/* 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/. */
/*
* ManifestImageObjectProcessor
* Implementation of Image Object processing algorithms from:
* http://www.w3.org/2008/webapps/manifest/#image-object-and-its-members
*
* This is intended to be used in conjunction with ManifestProcessor.jsm
*
* Creates an object to process Image Objects as defined by the
* W3C specification. This is used to process things like the
* icon member and the splash_screen member.
*
* Usage:
*
* .process(aManifest, aBaseURL, aMemberName, console);
*
*/
/*exported EXPORTED_SYMBOLS */
/*globals extractValue, Components*/
'use strict';
this.EXPORTED_SYMBOLS = ['ManifestImageObjectProcessor']; // jshint ignore:line
const imports = {};
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
scriptLoader.loadSubScript(
'resource://gre/modules/manifestValueExtractor.js',
this); // jshint ignore:line
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.importGlobalProperties(['URL']);
imports.netutil = Cc['@mozilla.org/network/util;1']
.getService(Ci.nsINetUtil);
imports.DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
.getService(Ci.inIDOMUtils);
function ManifestImageObjectProcessor() {}
// Static getters
Object.defineProperties(ManifestImageObjectProcessor, {
'decimals': {
get: function() {
return /^\d+$/;
}
},
'anyRegEx': {
get: function() {
return new RegExp('any', 'i');
}
}
});
ManifestImageObjectProcessor.process = function(
aManifest, aBaseURL, aMemberName, console
) {
const spec = {
objectName: 'manifest',
object: aManifest,
property: aMemberName,
expectedType: 'array',
trim: false
};
const images = [];
const value = extractValue(spec, console);
if (Array.isArray(value)) {
// Filter out images whose "src" is not useful.
value.filter(item => !!processSrcMember(item, aBaseURL))
.map(toImageObject)
.forEach(image => images.push(image));
}
return images;
function toImageObject(aImageSpec) {
return {
'src': processSrcMember(aImageSpec, aBaseURL),
'type': processTypeMember(aImageSpec),
'sizes': processSizesMember(aImageSpec),
'density': processDensityMember(aImageSpec),
'background_color': processBackgroundColorMember(aImageSpec)
};
}
function processTypeMember(aImage) {
const charset = {};
const hadCharset = {};
const spec = {
objectName: 'image',
object: aImage,
property: 'type',
expectedType: 'string',
trim: true
};
let value = extractValue(spec, console);
if (value) {
value = imports.netutil.parseContentType(value, charset, hadCharset);
}
return value || undefined;
}
function processDensityMember(aImage) {
const value = parseFloat(aImage.density);
const validNum = Number.isNaN(value) || value === +Infinity || value <=
0;
return (validNum) ? 1.0 : value;
}
function processSrcMember(aImage, aBaseURL) {
const spec = {
objectName: 'image',
object: aImage,
property: 'src',
expectedType: 'string',
trim: false
};
const value = extractValue(spec, console);
let url;
if (value && value.length) {
try {
url = new URL(value, aBaseURL).href;
} catch (e) {}
}
return url;
}
function processSizesMember(aImage) {
const sizes = new Set();
const spec = {
objectName: 'image',
object: aImage,
property: 'sizes',
expectedType: 'string',
trim: true
};
const value = extractValue(spec, console);
if (value) {
// Split on whitespace and filter out invalid values.
value.split(/\s+/)
.filter(isValidSizeValue)
.forEach(size => sizes.add(size));
}
return sizes;
// Implementation of HTML's link@size attribute checker.
function isValidSizeValue(aSize) {
const size = aSize.toLowerCase();
if (ManifestImageObjectProcessor.anyRegEx.test(aSize)) {
return true;
}
if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
return false;
}
// Split left of x for width, after x for height.
const widthAndHeight = size.split('x');
const w = widthAndHeight.shift();
const h = widthAndHeight.join('x');
const validStarts = !w.startsWith('0') && !h.startsWith('0');
const validDecimals = ManifestImageObjectProcessor.decimals.test(w + h);
return (validStarts && validDecimals);
}
}
function processBackgroundColorMember(aImage) {
const spec = {
objectName: 'image',
object: aImage,
property: 'background_color',
expectedType: 'string',
trim: true
};
const value = extractValue(spec, console);
let color;
if (imports.DOMUtils.isValidCSSColor(value)) {
color = value;
} else {
const msg = `background_color: ${value} is not a valid CSS color.`;
console.warn(msg);
}
return color;
}
};
this.ManifestImageObjectProcessor = ManifestImageObjectProcessor; // jshint ignore:line

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

@ -12,54 +12,38 @@
*
* .process({jsonText,manifestURL,docURL});
*
* Depends on ManifestImageObjectProcessor to process things like
* icons and splash_screens.
*
* TODO: The constructor should accept the UA's supported orientations.
* TODO: The constructor should accept the UA's supported display modes.
* TODO: hook up developer tools to console. (1086997).
*/
/*exported EXPORTED_SYMBOLS */
/*JSLint options in comment below: */
/*globals Components, XPCOMUtils*/
/*globals Components, XPCOMUtils, extractValue*/
'use strict';
this.EXPORTED_SYMBOLS = ['ManifestProcessor'];
this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line
const imports = {};
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
//Add extractValue() helper to this context.
scriptLoader.loadSubScript(
'resource://gre/modules/manifestValueExtractor.js',
this); // jshint ignore:line
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.importGlobalProperties(['URL']);
XPCOMUtils.defineLazyModuleGetter(imports, 'Services',
'resource://gre/modules/Services.jsm');
imports.netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil);
// Helper function extracts values from manifest members
// and reports conformance violations.
function extractValue({
objectName,
object,
property,
expectedType,
trim
}, console) {
const value = object[property];
const isArray = Array.isArray(value);
// We need to special-case "array", as it's not a JS primitive.
const type = (isArray) ? 'array' : typeof value;
if (type !== expectedType) {
if (type !== 'undefined') {
let msg = `Expected the ${objectName}'s ${property} `;
msg += `member to a be a ${expectedType}.`;
console.log(msg);
}
return undefined;
}
// Trim string and returned undefined if the empty string.
const shouldTrim = expectedType === 'string' && value && trim;
if (shouldTrim) {
return value.trim() || undefined;
}
return value;
}
XPCOMUtils.defineLazyModuleGetter(imports, 'ManifestImageObjectProcessor',
'resource://gre/modules/ManifestImageObjectProcessor.jsm');
imports.netutil = Cc['@mozilla.org/network/util;1']
.getService(Ci.nsINetUtil);
const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
'browser'
]);
@ -93,13 +77,12 @@ Object.defineProperties(ManifestProcessor, {
});
ManifestProcessor.prototype = {
// process method: processes json text into a clean manifest
// process method: processes JSON text into a clean manifest
// that conforms with the W3C specification. Takes an object
// expecting the following dictionary items:
// * jsonText: the JSON string to be processd.
// * manifestURL: the URL of the manifest, to resolve URLs.
// * docURL: the URL of the owner doc, for security checks.
// * aJsonText: the JSON string to be processed.
// * aManifestURL: the URL of the manifest, to resolve URLs.
// * aDocURL: the URL of the owner doc, for security checks.
process({
jsonText: aJsonText,
manifestURL: aManifestURL,
@ -120,15 +103,20 @@ ManifestProcessor.prototype = {
rawManifest = {};
}
const processedManifest = {
start_url: processStartURLMember(rawManifest, manifestURL, docURL),
display: processDisplayMember(rawManifest),
orientation: processOrientationMember(rawManifest),
name: processNameMember(rawManifest),
icons: IconsProcessor.process(rawManifest, manifestURL, console),
short_name: processShortNameMember(rawManifest),
'start_url': processStartURLMember(rawManifest, manifestURL, docURL),
'display': processDisplayMember(rawManifest),
'orientation': processOrientationMember(rawManifest),
'name': processNameMember(rawManifest),
'icons': imports.ManifestImageObjectProcessor.process(
rawManifest, manifestURL, 'icons', console
),
'splash_screens': imports.ManifestImageObjectProcessor.process(
rawManifest, manifestURL, 'splash_screens', console
),
'short_name': processShortNameMember(rawManifest),
};
processedManifest.scope = processScopeMember(rawManifest, manifestURL,
docURL, new URL(processedManifest.start_url));
docURL, new URL(processedManifest['start_url'])); // jshint ignore:line
return processedManifest;
@ -251,126 +239,4 @@ ManifestProcessor.prototype = {
}
}
};
this.ManifestProcessor = ManifestProcessor;
function IconsProcessor() {}
// Static getters
Object.defineProperties(IconsProcessor, {
'onlyDecimals': {
get: function() {
return /^\d+$/;
}
},
'anyRegEx': {
get: function() {
return new RegExp('any', 'i');
}
}
});
IconsProcessor.process = function(aManifest, aBaseURL, console) {
const spec = {
objectName: 'manifest',
object: aManifest,
property: 'icons',
expectedType: 'array',
trim: false
};
const icons = [];
const value = extractValue(spec, console);
if (Array.isArray(value)) {
// Filter out icons whose "src" is not useful.
value.filter(item => !!processSrcMember(item, aBaseURL))
.map(toIconObject)
.forEach(icon => icons.push(icon));
}
return icons;
function toIconObject(aIconData) {
return {
src: processSrcMember(aIconData, aBaseURL),
type: processTypeMember(aIconData),
sizes: processSizesMember(aIconData),
density: processDensityMember(aIconData)
};
}
function processTypeMember(aIcon) {
const charset = {};
const hadCharset = {};
const spec = {
objectName: 'icon',
object: aIcon,
property: 'type',
expectedType: 'string',
trim: true
};
let value = extractValue(spec, console);
if (value) {
value = imports.netutil.parseContentType(value, charset, hadCharset);
}
return value || undefined;
}
function processDensityMember(aIcon) {
const value = parseFloat(aIcon.density);
const validNum = Number.isNaN(value) || value === +Infinity || value <=
0;
return (validNum) ? 1.0 : value;
}
function processSrcMember(aIcon, aBaseURL) {
const spec = {
objectName: 'icon',
object: aIcon,
property: 'src',
expectedType: 'string',
trim: false
};
const value = extractValue(spec, console);
let url;
if (value && value.length) {
try {
url = new URL(value, aBaseURL).href;
} catch (e) {}
}
return url;
}
function processSizesMember(aIcon) {
const sizes = new Set(),
spec = {
objectName: 'icon',
object: aIcon,
property: 'sizes',
expectedType: 'string',
trim: true
},
value = extractValue(spec, console);
if (value) {
// Split on whitespace and filter out invalid values.
value.split(/\s+/)
.filter(isValidSizeValue)
.forEach(size => sizes.add(size));
}
return sizes;
// Implementation of HTML's link@size attribute checker.
function isValidSizeValue(aSize) {
const size = aSize.toLowerCase();
if (IconsProcessor.anyRegEx.test(aSize)) {
return true;
}
if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
return false;
}
// Split left of x for width, after x for height.
const widthAndHeight = size.split('x');
const w = widthAndHeight.shift();
const h = widthAndHeight.join('x');
const validStarts = !w.startsWith('0') && !h.startsWith('0');
const validDecimals = IconsProcessor.onlyDecimals.test(w + h);
return (validStarts && validDecimals);
}
}
};
this.ManifestProcessor = ManifestProcessor; // jshint ignore:line

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

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Helper function extracts values from manifest members
* and reports conformance violations.
*/
function extractValue({
objectName,
object,
property,
expectedType,
trim
}, console) {
const value = object[property];
const isArray = Array.isArray(value);
// We need to special-case "array", as it's not a JS primitive.
const type = (isArray) ? 'array' : typeof value;
if (type !== expectedType) {
if (type !== 'undefined') {
let msg = `Expected the ${objectName}'s ${property} `;
msg += `member to be a ${expectedType}.`;
console.log(msg);
}
return undefined;
}
// Trim string and returned undefined if the empty string.
const shouldTrim = expectedType === 'string' && value && trim;
if (shouldTrim) {
return value.trim() || undefined;
}
return value;
}

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

@ -5,8 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'ManifestImageObjectProcessor.jsm',
'ManifestObtainer.jsm',
'ManifestProcessor.jsm',
'manifestValueExtractor.js'
]
MOCHITEST_MANIFESTS += ['test/mochitest.ini']

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

@ -4,10 +4,11 @@ support-files =
resource.sjs
manifestLoader.html
[test_IconsProcessor_density.html]
[test_IconsProcessor_sizes.html]
[test_IconsProcessor_src.html]
[test_IconsProcessor_type.html]
[test_ImageObjectProcessor_background_color.html]
[test_ImageObjectProcessor_density.html]
[test_ImageObjectProcessor_sizes.html]
[test_ImageObjectProcessor_src.html]
[test_ImageObjectProcessor_type.html]
[test_ManifestProcessor_display.html]
[test_ManifestProcessor_icons.html]
[test_ManifestProcessor_JSON.html]
@ -15,3 +16,4 @@ support-files =
[test_ManifestProcessor_orientation.html]
[test_ManifestProcessor_start_url.html]
[test_ManifestProcessor_scope.html]
[test_ManifestProcessor_splash_screens.html]

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

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1162808
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1162808</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script src="common.js"></script>
<script type="application/javascript">
/**
* Image object's type member
* https://w3c.github.io/manifest/#type-member
*
* Checks that invalid and valid colors are processed correctly.
**/
/*globals data, processor, is*/
'use strict';
var testIcon = {
icons: [{
src: 'test',
'background_color': undefined
}]
};
// Test invalid colors.
var invalidColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}'
];
invalidColors.forEach((invalidColor) => {
var expected = `Treat invalid color (${invalidColor}) as undefined.`;
testIcon.icons[0].background_color = invalidColor;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
is(result.icons[0].background_color, undefined, expected);
});
// Test valid colors.
var validColors = [
'maroon',
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(300,0,0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)'
];
validColors.forEach((color) => {
var expected = `Treat valid CSS color (${color}) as valid input.`;
testIcon.icons[0].background_color = color;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
is(result.icons[0].background_color, color, expected);
});
</script>
</head>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1162808">Mozilla Bug 1162808</a>

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

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's density member
* Image object density member
* https://w3c.github.io/manifest/#density-member
**/
'use strict';

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

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's sizes property
* Image object's sizes member
* https://w3c.github.io/manifest/#sizes-member
**/
'use strict';

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

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's src member
* Image object's src member
* https://w3c.github.io/manifest/#src-member
**/
'use strict';

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

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's type property
* Image object's type property
* https://w3c.github.io/manifest/#type-member
**/

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

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1162808
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1162808</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* Manifest splash_screens member
* http://www.w3.org/TR/appmanifest/#splash_screens-member
**/
'use strict';
typeTests.forEach((type) => {
var expected = `Expect non-array splash_screens to be empty: ${typeof type}.`;
data.jsonText = JSON.stringify({
splash_screens: type
});
var result = processor.process(data);
is(result.splash_screens.length, 0, expected);
});
</script>
</head>

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

@ -47,9 +47,10 @@ MediaStreamPlayback.prototype = {
startMedia : function(isResume) {
var canPlayThroughFired = false;
// If we're initially running this media, check that the time is zero
// If we're playing this media element for the first time,
// check that the time is zero.
if (!isResume) {
is(this.mediaStream.currentTime, 0,
is(this.mediaElement.currentTime, 0,
"Before starting the media element, currentTime = 0");
}

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

@ -14,13 +14,13 @@ skip-if = toolkit == "gonk"
[test_tcpsocket_enabled_with_perm.html]
skip-if = toolkit == "gonk" || e10s
[test_networkstats_alarms.html]
skip-if = true # Bug 958689
skip-if = toolkit != "gonk"
[test_networkstats_basics.html]
skip-if = true # Bug 958689, bug 858005
skip-if = toolkit != "gonk"
[test_networkstats_disabled.html]
skip-if = toolkit != "gonk"
[test_networkstats_enabled_no_perm.html]
skip-if = true # Bug 958689
skip-if = toolkit != "gonk"
[test_networkstats_enabled_perm.html]
skip-if = toolkit != "gonk"
[test_udpsocket.html]

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

@ -149,7 +149,6 @@ var steps = [
},
function () {
ok(true, "all done!\n");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
return;
}
@ -170,9 +169,10 @@ function next() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
@ -185,6 +185,7 @@ SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
test();
});
});
</script>

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

@ -301,7 +301,6 @@ var steps = [
},
function () {
ok(true, "all done!\n");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
return;
}
@ -322,9 +321,10 @@ function next() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
@ -337,6 +337,7 @@ SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
test();
});
});
</script>

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

@ -15,10 +15,12 @@
// Test to ensure NetworkStats is enabled but mozNetworkStats.getAvailableNetworks
// does not work in content because mozNetworkStats is null when no permission.
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [['dom.mozNetworkStats.enabled', true]]}, runTest);
function runTest() {
SpecialPowers.removePermission("networkstats-manage", document);
SpecialPowers.pushPrefEnv({"set": [['dom.mozNetworkStats.enabled', true]]},
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 0, 'context': window.document }], runTest);
});
function runTest() {
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");

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

@ -16,10 +16,12 @@
SimpleTest.waitForExplicitFinish();
// Test to ensure NetworkStats is not accessible when it is disabled
SpecialPowers.addPermission("networkstats-manage", true, document);
// Test to ensure NetworkStats is not accessible when it is disabled.
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function(){
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
@ -31,8 +33,8 @@ SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
});
});
</script>

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

@ -35,4 +35,5 @@ FINAL_LIBRARY = 'xul'
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']

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

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT]
[browser_monitorUncaught.js]

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

@ -4,6 +4,8 @@
"use strict";
const { utils: Cu } = Components;
Cu.import("resource://gre/modules/Timer.jsm", this);
add_task(function* test_globals() {
@ -18,7 +20,7 @@ add_task(function* test_promiseID() {
let promise = [p1, p2, p3];
let identifiers = promise.map(PromiseDebugging.getPromiseID);
info("Identifiers: " + JSON.stringify(identifiers));
do_print("Identifiers: " + JSON.stringify(identifiers));
let idSet = new Set(identifiers);
Assert.equal(idSet.size, identifiers.length,
"PromiseDebugging.getPromiseID returns a distinct id per promise");
@ -42,7 +44,7 @@ add_task(function* test_observe_uncaught() {
};
CallbackResults.prototype = {
observe: function(promise) {
info(this.name + " observing Promise " + names.get(promise));
do_print(this.name + " observing Promise " + names.get(promise));
Assert.equal(PromiseDebugging.getState(promise).state, "rejected",
this.name + " observed a rejected Promise");
if (!this.expected.has(promise)) {
@ -62,8 +64,8 @@ add_task(function* test_observe_uncaught() {
if (this.expected.size == 0) {
this.resolve();
} else {
info(this.name + " is still waiting for " + this.expected.size + " observations:");
info(JSON.stringify([names.get(x) for (x of this.expected.values())]));
do_print(this.name + " is still waiting for " + this.expected.size + " observations:");
do_print(JSON.stringify([names.get(x) for (x of this.expected.values())]));
}
},
};
@ -117,7 +119,7 @@ add_task(function* test_observe_uncaught() {
// Reject a promise now, consume it later.
let p = Promise.reject("Reject now, consume later");
setTimeout(() => p.then(null, () => {
info("Consumed promise");
do_print("Consumed promise");
}), 200);
yield {
promise: p,
@ -190,7 +192,7 @@ add_task(function* test_observe_uncaught() {
let samples = [];
for (let s of makeSamples()) {
samples.push(s);
info("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
do_print("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
}
PromiseDebugging.addUncaughtRejectionObserver(observer);
@ -205,17 +207,17 @@ add_task(function* test_observe_uncaught() {
}
}
info("Test setup, waiting for callbacks.");
do_print("Test setup, waiting for callbacks.");
yield onLeftUncaught.blocker;
info("All calls to onLeftUncaught are complete.");
do_print("All calls to onLeftUncaught are complete.");
if (onConsumed.expected.size != 0) {
info("onConsumed is still waiting for the following Promise:");
info(JSON.stringify([names.get(x) for (x of onConsumed.expected.values())]));
do_print("onConsumed is still waiting for the following Promise:");
do_print(JSON.stringify([names.get(x) for (x of onConsumed.expected.values())]));
yield onConsumed.blocker;
}
info("All calls to onConsumed are complete.");
do_print("All calls to onConsumed are complete.");
let removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
Assert.ok(removed, "removeUncaughtRejectionObserver succeeded");
removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
@ -246,21 +248,23 @@ add_task(function* test_uninstall_observer() {
},
};
info("Adding an observer.");
do_print("Adding an observer.");
let deactivate = new Observer();
Promise.reject("I am an uncaught rejection.");
yield deactivate.blocker;
Assert.ok(true, "The observer has observed an uncaught Promise.");
deactivate.active = false;
info("Removing the observer, it should not observe any further uncaught Promise.");
do_print("Removing the observer, it should not observe any further uncaught Promise.");
info("Rejecting a Promise and waiting a little to give a chance to observers.");
do_print("Rejecting a Promise and waiting a little to give a chance to observers.");
let wait = new Observer();
Promise.reject("I am another uncaught rejection.");
yield wait.blocker;
yield new Promise(resolve => setTimeout(resolve, 100));
// Normally, `deactivate` should not be notified of the uncaught rejection.
wait.active = false;
});
function run_test() {
run_next_test();
}

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

@ -0,0 +1,5 @@
[DEFAULT]
head =
tail =
[test_monitor_uncaught.js]

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

@ -53,9 +53,6 @@ NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistrationBase, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationBase)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationBase,
DOMEventTargetHelper, mCCDummy);
ServiceWorkerRegistrationBase::ServiceWorkerRegistrationBase(nsPIDOMWindow* aWindow,
const nsAString& aScope)
: DOMEventTargetHelper(aWindow)

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

@ -66,8 +66,6 @@ class ServiceWorkerRegistrationBase : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationBase,
DOMEventTargetHelper)
IMPL_EVENT_HANDLER(updatefound)
@ -91,8 +89,6 @@ protected:
{ }
const nsString mScope;
private:
nsCOMPtr<nsISupports> mCCDummy;
};
class ServiceWorkerRegistrationMainThread final : public ServiceWorkerRegistrationBase,

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

@ -969,7 +969,8 @@ GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
GLenum destTarget,
bool internalFBs)
{
MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
// On the Android 4.3 emulator, IsFramebuffer may return false incorrectly.
MOZ_ASSERT_IF(mGL->Renderer() != GLRenderer::AndroidEmulator, !srcFB || mGL->fIsFramebuffer(srcFB));
MOZ_ASSERT(mGL->fIsTexture(destTex));
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {

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

@ -417,7 +417,7 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
// Draw a translation delay warning overlay
int width;
int border;
if ((now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
if (!mWarnTime.IsNull() && (now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
EffectChain effects;
// Black blorder

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

@ -14,6 +14,10 @@
#include "gfx2DGlue.h"
#include "SharedSurfaceGralloc.h"
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <ui/Fence.h>
#endif
namespace mozilla {
namespace layers {

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

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "GfxDriverInfo.h"
#include "nsVersionComparator.h"
using namespace mozilla::widget;
TEST(GfxWidgets, Split) {
char aStr[8], bStr[8], cStr[8], dStr[8];
ASSERT_TRUE(SplitDriverVersion("33.4.3.22", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 33 && atoi(bStr) == 4 && atoi(cStr) == 3 && atoi(dStr) == 22);
ASSERT_TRUE(SplitDriverVersion("28.74.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 28 && atoi(bStr) == 74 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("132.0.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 132 && atoi(bStr) == 0 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("2.3.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 2 && atoi(bStr) == 3 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("25.4.0.8", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
}
TEST(GfxWidgets, Versioning) {
ASSERT_TRUE(mozilla::Version("0") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("39.0.5b7") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("18.0.5b7") < mozilla::Version("18.2"));
ASSERT_TRUE(mozilla::Version("30.0.5b7") < mozilla::Version("41.0b9"));
ASSERT_TRUE(mozilla::Version("100") > mozilla::Version("43.0a1"));
ASSERT_FALSE(mozilla::Version("42.0") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0.5") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.1") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("42.0b7") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("") == mozilla::Version("0"));
// Note these two; one would expect for 42.0b1 and 42b1 to compare the
// same, but they do not. If this ever changes, we want to know, so
// leave the test here to fail.
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0b2"));
ASSERT_FALSE(mozilla::Version("42.0a1") < mozilla::Version("42b2"));
}

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

@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
'TestColorNames.cpp',
'TestCompositor.cpp',
'TestGfxPrefs.cpp',
'TestGfxWidgets.cpp',
'TestLayers.cpp',
'TestRegion.cpp',
'TestSkipChars.cpp',

78
image/ImageCacheKey.cpp Normal file
Просмотреть файл

@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageCacheKey.h"
#include "mozilla/Move.h"
#include "File.h"
#include "ImageURL.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsString.h"
namespace mozilla {
using namespace dom;
namespace image {
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
: mURI(new ImageURL(aURI))
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
mHash = ComputeHash(mURI);
}
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
: mURI(aURI)
{
MOZ_ASSERT(mURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
mHash = ComputeHash(mURI);
}
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
: mURI(aOther.mURI)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
: mURI(Move(aOther.mURI))
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
bool
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
{
return *mURI == *aOther.mURI;
}
const char*
ImageCacheKey::Spec() const
{
return mURI->Spec();
}
/* static */ uint32_t
ImageCacheKey::ComputeHash(ImageURL* aURI)
{
// Since we frequently call Hash() several times in a row on the same
// ImageCacheKey, as an optimization we compute our hash once and store it.
nsAutoCString spec;
aURI->GetSpec(spec);
return HashString(spec);
}
} // namespace image
} // namespace mozilla

55
image/ImageCacheKey.h Normal file
Просмотреть файл

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* ImageCacheKey is the key type for the image cache (see imgLoader.h).
*/
#ifndef mozilla_image_src_ImageCacheKey_h
#define mozilla_image_src_ImageCacheKey_h
class nsIURI;
namespace mozilla {
namespace image {
class ImageURL;
/**
* An ImageLib cache entry key.
*
* We key the cache on the initial URI (before any redirects), with some
* canonicalization applied. See ComputeHash() for the details.
*/
class ImageCacheKey final
{
public:
explicit ImageCacheKey(nsIURI* aURI);
explicit ImageCacheKey(ImageURL* aURI);
ImageCacheKey(const ImageCacheKey& aOther);
ImageCacheKey(ImageCacheKey&& aOther);
bool operator==(const ImageCacheKey& aOther) const;
uint32_t Hash() const { return mHash; }
/// A weak pointer to the URI spec for this cache entry. For logging only.
const char* Spec() const;
/// Is this cache entry for a chrome image?
bool IsChrome() const { return mIsChrome; }
private:
static uint32_t ComputeHash(ImageURL* aURI);
nsRefPtr<ImageURL> mURI;
uint32_t mHash;
bool mIsChrome;
};
} // namespace image
} // namespace mozilla
#endif // mozilla_image_src_ImageCacheKey_h

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

@ -44,6 +44,9 @@ public:
return NS_OK;
}
/// A weak pointer to the URI spec for this ImageURL. For logging only.
const char* Spec() const { return mSpec.get(); }
nsresult GetScheme(nsACString& result)
{
result = mScheme;
@ -74,6 +77,13 @@ public:
return newURI.forget();
}
bool operator==(const ImageURL& aOther) const
{
// Note that we don't need to consider mScheme and mRef, because they're
// already represented in mSpec.
return mSpec == aOther.mSpec;
}
private:
// Since this is a basic storage class, no duplication of spec parsing is
// included in the functionality. Instead, the class depends upon the

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

@ -549,9 +549,10 @@ nsProgressNotificationProxy::GetInterface(const nsIID& iid,
static void
NewRequestAndEntry(bool aForcePrincipalCheckForCacheEntry, imgLoader* aLoader,
const ImageCacheKey& aKey,
imgRequest** aRequest, imgCacheEntry** aEntry)
{
nsRefPtr<imgRequest> request = new imgRequest(aLoader);
nsRefPtr<imgRequest> request = new imgRequest(aLoader, aKey);
nsRefPtr<imgCacheEntry> entry =
new imgCacheEntry(aLoader, request, aForcePrincipalCheckForCacheEntry);
aLoader->AddToUncachedImages(request);
@ -894,18 +895,12 @@ void
imgCacheEntry::SetHasNoProxies(bool hasNoProxies)
{
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<ImageURL> uri;
mRequest->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
if (uri) {
uri->GetSpec(spec);
}
if (hasNoProxies) {
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgCacheEntry::SetHasNoProxies true",
"uri", spec.get());
"uri", mRequest->CacheKey().Spec());
} else {
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgCacheEntry::SetHasNoProxies false",
"uri", spec.get());
"uri", mRequest->CacheKey().Spec());
}
}
@ -1078,15 +1073,11 @@ imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
nsRefPtr<imgCacheEntry> kungFuDeathGrip(entry);
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<imgRequest> req(entry->GetRequest());
nsRefPtr<imgRequest> req = entry->GetRequest();
if (req) {
nsRefPtr<ImageURL> uri;
req->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_FUNC_WITH_PARAM(GetImgLog(),
"imgCacheExpirationTracker::NotifyExpired",
"entry", spec.get());
"entry", req->CacheKey().Spec());
}
}
@ -1100,60 +1091,6 @@ imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
}
///////////////////////////////////////////////////////////////////////////////
// ImageCacheKey
///////////////////////////////////////////////////////////////////////////////
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
aURI->GetSpec(mSpec);
mHash = ComputeHash(mSpec);
}
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
{
MOZ_ASSERT(aURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
aURI->GetSpec(mSpec);
mHash = ComputeHash(mSpec);
}
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
: mSpec(aOther.mSpec)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
: mSpec(Move(aOther.mSpec))
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
bool
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
{
return mSpec == aOther.mSpec;
}
/* static */ uint32_t
ImageCacheKey::ComputeHash(const nsACString& aSpec)
{
// Since we frequently call Hash() several times in a row on the same
// ImageCacheKey, as an optimization we compute our hash once and store it.
return HashString(aSpec);
}
///////////////////////////////////////////////////////////////////////////////
// imgLoader
///////////////////////////////////////////////////////////////////////////////
@ -1513,15 +1450,9 @@ imgLoader::PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* entry)
bool
imgLoader::SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry)
{
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<ImageURL> uri;
aRequest->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::SetHasNoProxies", "uri", spec.get());
}
"imgLoader::SetHasNoProxies", "uri",
aRequest->CacheKey().Spec());
aEntry->SetHasNoProxies(true);
@ -1552,10 +1483,7 @@ imgLoader::SetHasProxies(imgRequest* aRequest)
{
VerifyCacheSizes();
nsRefPtr<ImageURL> uri;
aRequest->GetURI(getter_AddRefs(uri));
ImageCacheKey key(uri);
const ImageCacheKey& key = aRequest->CacheKey();
imgCacheTable& cache = GetCache(key);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
@ -1606,15 +1534,11 @@ imgLoader::CheckCacheLimits(imgCacheTable& cache, imgCacheQueue& queue)
NS_ASSERTION(entry, "imgLoader::CheckCacheLimits -- NULL entry pointer");
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<imgRequest> req(entry->GetRequest());
nsRefPtr<imgRequest> req = entry->GetRequest();
if (req) {
nsRefPtr<ImageURL> uri;
req->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::CheckCacheLimits",
"entry", spec.get());
"entry", req->CacheKey().Spec());
}
}
@ -1932,18 +1856,13 @@ imgLoader::RemoveFromCache(imgCacheEntry* entry)
nsRefPtr<imgRequest> request = entry->GetRequest();
if (request) {
nsRefPtr<ImageURL> uri;
if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(uri))) && uri) {
ImageCacheKey key(uri);
const ImageCacheKey& key = request->CacheKey();
imgCacheTable& cache = GetCache(key);
imgCacheQueue& queue = GetCacheQueue(key);
#ifdef DEBUG
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::RemoveFromCache", "entry's uri",
key.Spec());
#endif
cache.Remove(key);
@ -1962,7 +1881,6 @@ imgLoader::RemoveFromCache(imgCacheEntry* entry)
return true;
}
}
return false;
}
@ -2243,7 +2161,8 @@ imgLoader::LoadImage(nsIURI* aURI,
MOZ_ASSERT(NS_UsePrivateBrowsing(newChannel) == mRespectPrivacy);
NewRequestAndEntry(forcePrincipalCheck, this, getter_AddRefs(request),
NewRequestAndEntry(forcePrincipalCheck, this, key,
getter_AddRefs(request),
getter_AddRefs(entry));
PR_LOG(GetImgLog(), PR_LOG_DEBUG,
@ -2494,16 +2413,24 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
requestFlags, _retval);
static_cast<imgRequestProxy*>(*_retval)->NotifyListener();
} else {
// Default to doing a principal check because we don't know who
// started that load and whether their principal ended up being
// inherited on the channel.
NewRequestAndEntry(true, this, getter_AddRefs(request),
getter_AddRefs(entry));
// We use originalURI here to fulfil the imgIRequest contract on GetURI.
nsCOMPtr<nsIURI> originalURI;
channel->GetOriginalURI(getter_AddRefs(originalURI));
// XXX(seth): We should be able to just use |key| here, except that |key| is
// constructed above with the *current URI* and not the *original URI*. I'm
// pretty sure this is a bug, and it's preventing us from ever getting a
// cache hit in LoadImageWithChannel when redirects are involved.
ImageCacheKey originalURIKey(originalURI);
// Default to doing a principal check because we don't know who
// started that load and whether their principal ended up being
// inherited on the channel.
NewRequestAndEntry(/* aForcePrincipalCheckForCacheEntry = */ true,
this, originalURIKey,
getter_AddRefs(request),
getter_AddRefs(entry));
// No principal specified here, because we're not passed one.
// In LoadImageWithChannel, the redirects that may have been
// assoicated with this load would have gone through necko.
@ -2521,7 +2448,7 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
pl.forget(listener);
// Try to add the new request into the cache.
PutIntoCache(ImageCacheKey(originalURI), entry);
PutIntoCache(originalURIKey, entry);
rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
requestFlags, _retval);
@ -2773,6 +2700,7 @@ imgCacheValidator::imgCacheValidator(nsProgressNotificationProxy* progress,
mHadInsecureRedirect(false)
{
NewRequestAndEntry(forcePrincipalCheckForCacheEntry, loader,
mRequest->CacheKey(),
getter_AddRefs(mNewRequest),
getter_AddRefs(mNewEntry));
}
@ -2901,7 +2829,7 @@ imgCacheValidator::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
// Try to add the new request into the cache. Note that the entry must be in
// the cache before the proxies' ownership changes, because adding a proxy
// changes the caching behaviour for imgRequests.
mImgLoader->PutIntoCache(ImageCacheKey(originalURI), mNewEntry);
mImgLoader->PutIntoCache(mNewRequest->CacheKey(), mNewEntry);
uint32_t count = mProxies.Count();
for (int32_t i = count-1; i>=0; i--) {

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

@ -17,6 +17,7 @@
#include "nsRefPtrHashtable.h"
#include "nsExpirationTracker.h"
#include "nsAutoPtr.h"
#include "ImageCacheKey.h"
#include "imgRequest.h"
#include "nsIProgressEventSink.h"
#include "nsIChannel.h"
@ -214,38 +215,6 @@ enum class AcceptedMimeTypes : uint8_t {
IMAGES_AND_DOCUMENTS,
};
/**
* An ImageLib cache entry key.
*
* We key the cache on the initial URI (before any redirects), with some
* canonicalization applied. See ComputeHash() for the details.
*/
class ImageCacheKey final
{
public:
explicit ImageCacheKey(nsIURI* aURI);
explicit ImageCacheKey(mozilla::image::ImageURL* aURI);
ImageCacheKey(const ImageCacheKey& aOther);
ImageCacheKey(ImageCacheKey&& aOther);
bool operator==(const ImageCacheKey& aOther) const;
uint32_t Hash() const { return mHash; }
/// A weak pointer to the URI spec for this cache entry. For logging only.
const char* Spec() const { return mSpec.get(); }
/// Is this cache entry for a chrome image?
bool IsChrome() const { return mIsChrome; }
private:
static uint32_t ComputeHash(const nsACString& aSpec);
nsCString mSpec;
uint32_t mHash;
bool mIsChrome;
};
class imgLoader final : public imgILoader,
public nsIContentSniffer,
public imgICache,
@ -255,6 +224,7 @@ class imgLoader final : public imgILoader,
virtual ~imgLoader();
public:
typedef mozilla::image::ImageCacheKey ImageCacheKey;
typedef mozilla::image::ImageURL ImageURL;
typedef nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>,
imgCacheEntry> imgCacheTable;

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

@ -60,8 +60,10 @@ NS_IMPL_ISUPPORTS(imgRequest,
nsIInterfaceRequestor,
nsIAsyncVerifyRedirectCallback)
imgRequest::imgRequest(imgLoader* aLoader)
imgRequest::imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey)
: mLoader(aLoader)
, mCacheKey(aCacheKey)
, mLoadId(nullptr)
, mValidator(nullptr)
, mInnerWindowId(0)
, mCORSMode(imgIRequest::CORS_NONE)

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

@ -21,6 +21,7 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/Mutex.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "ImageCacheKey.h"
class imgCacheValidator;
class imgLoader;
@ -49,12 +50,13 @@ class imgRequest final : public nsIStreamListener,
public nsIAsyncVerifyRedirectCallback
{
typedef mozilla::image::Image Image;
typedef mozilla::image::ImageCacheKey ImageCacheKey;
typedef mozilla::image::ImageURL ImageURL;
typedef mozilla::image::ProgressTracker ProgressTracker;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
public:
explicit imgRequest(imgLoader* aLoader);
imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
@ -143,6 +145,9 @@ public:
// Get the current principal of the image. No AddRefing.
inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
/// Get the ImageCacheKey associated with this request.
const ImageCacheKey& CacheKey() const { return mCacheKey; }
// Resize the cache entry to 0 if it exists
void ResetCacheEntry();
@ -246,6 +251,9 @@ private:
/* we hold on to this to this so long as we have observers */
nsRefPtr<imgCacheEntry> mCacheEntry;
/// The key under which this imgRequest is stored in the image cache.
ImageCacheKey mCacheKey;
void* mLoadId;
imgCacheValidator* mValidator;

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

@ -34,6 +34,7 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'imglib2'
EXPORTS += [
'ImageCacheKey.h',
'ImageLogging.h',
'ImageOps.h',
'ImageRegion.h',
@ -53,6 +54,7 @@ UNIFIED_SOURCES += [
'FrameAnimator.cpp',
'FrozenImage.cpp',
'Image.cpp',
'ImageCacheKey.cpp',
'ImageFactory.cpp',
'ImageMetadata.cpp',
'ImageOps.cpp',

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

@ -21,7 +21,12 @@ ParseContext<ParseHandler>::init(TokenStream& ts)
if (!frontend::GenerateBlockId(ts, this, this->bodyid))
return false;
return decls_.init() && lexdeps.ensureMap(sc->context);
if (!decls_.init() || !lexdeps.ensureMap(sc->context)) {
ReportOutOfMemory(sc->context);
return false;
}
return true;
}
template <typename ParseHandler>

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

@ -1123,6 +1123,7 @@ inline uintptr_t
ArenaHeader::address() const
{
uintptr_t addr = reinterpret_cast<uintptr_t>(this);
MOZ_ASSERT(addr);
MOZ_ASSERT(!(addr & ArenaMask));
MOZ_ASSERT(Chunk::withinArenasRange(addr));
return addr;
@ -1186,6 +1187,7 @@ ArenaHeader::setNextDelayedMarking(ArenaHeader* aheader)
MOZ_ASSERT(!(uintptr_t(aheader) & ArenaMask));
MOZ_ASSERT(!auxNextLink && !hasDelayedMarking);
hasDelayedMarking = 1;
if (aheader)
auxNextLink = aheader->arenaAddress() >> ArenaShift;
}
@ -1209,6 +1211,7 @@ ArenaHeader::setNextAllocDuringSweep(ArenaHeader* aheader)
{
MOZ_ASSERT(!auxNextLink && !allocatedDuringIncremental);
allocatedDuringIncremental = 1;
if (aheader)
auxNextLink = aheader->arenaAddress() >> ArenaShift;
}

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

@ -1948,7 +1948,9 @@ js::TenuringTracer::traceObjectSlots(NativeObject* nobj, uint32_t start, uint32_
HeapSlot* dynStart;
HeapSlot* dynEnd;
nobj->getSlotRange(start, length, &fixedStart, &fixedEnd, &dynStart, &dynEnd);
if (fixedStart)
traceSlots(fixedStart->unsafeGet(), fixedEnd->unsafeGet());
if (dynStart)
traceSlots(dynStart->unsafeGet(), dynEnd->unsafeGet());
}

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

@ -397,9 +397,9 @@ js::TenuringTracer::~TenuringTracer()
runtime()->setNeedsIncrementalBarrier(savedRuntimeNeedBarrier);
}
#define TIME_START(name) int64_t timstampStart_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_END(name) int64_t timstampEnd_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_TOTAL(name) (timstampEnd_##name - timstampStart_##name)
#define TIME_START(name) int64_t timestampStart_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_END(name) int64_t timestampEnd_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_TOTAL(name) (timestampEnd_##name - timestampStart_##name)
void
js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList* pretenureGroups)
@ -427,7 +427,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
TraceMinorGCStart();
TIME_START(total);
int64_t timestampStart_total = PRMJ_Now();
AutoTraceSession session(rt, MinorCollecting);
AutoStopVerifyingBarriers av(rt, false);
@ -554,11 +554,14 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes())
disable();
TIME_END(total);
int64_t totalTime = PRMJ_Now() - timestampStart_total;
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime);
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, reason);
if (totalTime > 1000)
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason);
TraceMinorGCEnd();
int64_t totalTime = TIME_TOTAL(total);
if (enableProfiling_ && totalTime >= profileThreshold_) {
static bool printedHeader = false;
if (!printedHeader) {

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

@ -397,7 +397,7 @@ struct AllPhaseIterator {
size_t activeSlot;
mozilla::Vector<Phase>::Range descendants;
explicit AllPhaseIterator(int64_t (*table)[PHASE_LIMIT])
explicit AllPhaseIterator(Statistics::PhaseTimeTable table)
: current(0)
, baseLevel(0)
, activeSlot(PHASE_DAG_NONE)
@ -444,7 +444,7 @@ struct AllPhaseIterator {
};
static void
FormatPhaseTimes(StatisticsSerializer& ss, const char* name, int64_t (*times)[PHASE_LIMIT])
FormatPhaseTimes(StatisticsSerializer& ss, const char* name, Statistics::PhaseTimeTable times)
{
ss.beginObject(name);
@ -585,8 +585,55 @@ Join(const FragmentVector& fragments) {
return UniqueChars(joined);
}
static int64_t
SumChildTimes(size_t phaseSlot, Phase phase, Statistics::PhaseTimeTable phaseTimes)
{
// Sum the contributions from single-parented children.
int64_t total = 0;
for (unsigned i = 0; i < PHASE_LIMIT; i++) {
if (phases[i].parent == phase)
total += phaseTimes[phaseSlot][i];
}
// Sum the contributions from multi-parented children.
size_t dagSlot = phaseExtra[phase].dagSlot;
if (dagSlot != PHASE_DAG_NONE) {
for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
if (dagChildEdges[i].parent == phase) {
Phase child = dagChildEdges[i].child;
total += phaseTimes[dagSlot][child];
}
}
}
return total;
}
UniqueChars
Statistics::formatDescription()
Statistics::formatDetailedMessage()
{
FragmentVector fragments;
if (!fragments.append(formatDetailedDescription()))
return UniqueChars(nullptr);
if (slices.length() > 1) {
for (unsigned i = 0; i < slices.length(); i++) {
if (!fragments.append(formatDetailedSliceDescription(i, slices[i])))
return UniqueChars(nullptr);
if (!fragments.append(formatDetailedPhaseTimes(slices[i].phaseTimes)))
return UniqueChars(nullptr);
}
}
if (!fragments.append(formatDetailedTotals()))
return UniqueChars(nullptr);
if (!fragments.append(formatDetailedPhaseTimes(phaseTimes)))
return UniqueChars(nullptr);
return Join(fragments);
}
UniqueChars
Statistics::formatDetailedDescription()
{
const double bytesPerMiB = 1024 * 1024;
@ -632,7 +679,7 @@ Statistics::formatDescription()
}
UniqueChars
Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
Statistics::formatDetailedSliceDescription(unsigned i, const SliceData& slice)
{
char budgetDescription[200];
slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
@ -656,48 +703,7 @@ Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
}
UniqueChars
Statistics::formatTotals()
{
int64_t total, longest;
gcDuration(&total, &longest);
const char* format =
"\
---- Totals ----\n\
Total Time: %.3fms\n\
Max Pause: %.3fms\n\
";
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
JS_snprintf(buffer, sizeof(buffer), format, t(total), t(longest));
return make_string_copy(buffer);
}
static int64_t
SumChildTimes(size_t phaseSlot, Phase phase, int64_t (*phaseTimes)[PHASE_LIMIT])
{
// Sum the contributions from single-parented children.
int64_t total = 0;
for (unsigned i = 0; i < PHASE_LIMIT; i++) {
if (phases[i].parent == phase)
total += phaseTimes[phaseSlot][i];
}
// Sum the contributions from multi-parented children.
size_t dagSlot = phaseExtra[phase].dagSlot;
if (dagSlot != PHASE_DAG_NONE) {
for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
if (dagChildEdges[i].parent == phase) {
Phase child = dagChildEdges[i].child;
total += phaseTimes[dagSlot][child];
}
}
}
return total;
}
UniqueChars
Statistics::formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT])
Statistics::formatDetailedPhaseTimes(PhaseTimeTable phaseTimes)
{
static const char* LevelToIndent[] = { "", " ", " ", " " };
static const int64_t MaxUnaccountedChildTimeUS = 50;
@ -732,27 +738,21 @@ Statistics::formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT])
}
UniqueChars
Statistics::formatDetailedMessage()
Statistics::formatDetailedTotals()
{
FragmentVector fragments;
int64_t total, longest;
gcDuration(&total, &longest);
if (!fragments.append(formatDescription()))
return UniqueChars(nullptr);
if (slices.length() > 1) {
for (unsigned i = 0; i < slices.length(); i++) {
if (!fragments.append(formatSliceDescription(i, slices[i])))
return UniqueChars(nullptr);
if (!fragments.append(formatPhaseTimes(slices[i].phaseTimes)))
return UniqueChars(nullptr);
}
}
if (!fragments.append(formatTotals()))
return UniqueChars(nullptr);
if (!fragments.append(formatPhaseTimes(phaseTimes)))
return UniqueChars(nullptr);
return Join(fragments);
const char* format =
"\
---- Totals ----\n\
Total Time: %.3fms\n\
Max Pause: %.3fms\n\
";
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
JS_snprintf(buffer, sizeof(buffer), format, t(total), t(longest));
return make_string_copy(buffer);
}
char16_t*
@ -775,7 +775,6 @@ Statistics::Statistics(JSRuntime* rt)
: runtime(rt),
startupTime(PRMJ_Now()),
fp(nullptr),
fullFormat(false),
gcDepth(0),
nonincrementalReason_(nullptr),
timedGCStart(0),
@ -840,29 +839,24 @@ Statistics::Statistics(JSRuntime* rt)
}
char* env = getenv("MOZ_GCTIMER");
if (!env || strcmp(env, "none") == 0) {
if (env) {
if (strcmp(env, "none") == 0) {
fp = nullptr;
return;
}
if (strcmp(env, "stdout") == 0) {
fullFormat = false;
} else if (strcmp(env, "stdout") == 0) {
fp = stdout;
} else if (strcmp(env, "stderr") == 0) {
fullFormat = false;
fp = stderr;
} else {
fullFormat = true;
fp = fopen(env, "a");
MOZ_ASSERT(fp);
if (!fp)
MOZ_CRASH("Failed to open MOZ_GCTIMER log file.");
}
}
}
Statistics::~Statistics()
{
if (fp) {
if (fullFormat) {
StatisticsSerializer ss(StatisticsSerializer::AsText);
FormatPhaseTimes(ss, "", phaseTotals);
char* msg = ss.finishCString();
@ -870,7 +864,6 @@ Statistics::~Statistics()
fprintf(fp, "TOTALS\n%s\n\n-------\n", msg);
js_free(msg);
}
}
if (fp != stdout && fp != stderr)
fclose(fp);
@ -900,7 +893,7 @@ Statistics::getMaxGCPauseSinceClear()
}
static int64_t
SumPhase(Phase phase, int64_t (*times)[PHASE_LIMIT])
SumPhase(Phase phase, Statistics::PhaseTimeTable times)
{
int64_t sum = 0;
for (size_t i = 0; i < Statistics::MAX_MULTIPARENT_PHASES + 1; i++)
@ -912,26 +905,11 @@ void
Statistics::printStats()
{
if (aborted) {
if (fullFormat)
fprintf(fp, "OOM during GC statistics collection. The report is unavailable for this GC.\n");
fflush(fp);
return;
}
if (fullFormat) {
} else {
UniqueChars msg = formatDetailedMessage();
if (msg)
fprintf(fp, "GC(T+%.3fs) %s\n", t(slices[0].start - startupTime) / 1000.0, msg.get());
} else {
int64_t total, longest;
gcDuration(&total, &longest);
int64_t markTotal = SumPhase(PHASE_MARK, phaseTimes);
fprintf(fp, "%f %f %f\n",
t(total),
t(markTotal),
t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP]));
MOZ_ASSERT(phaseExtra[PHASE_SWEEP].dagSlot == PHASE_DAG_NONE);
}
fflush(fp);
}

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

@ -232,13 +232,16 @@ struct Statistics
SliceRange sliceRange() const { return slices.all(); }
size_t slicesLength() const { return slices.length(); }
/* Create a convenient typedef for referring tables of phase times. */
typedef int64_t (*PhaseTimeTable)[PHASE_LIMIT];
private:
JSRuntime* runtime;
int64_t startupTime;
/* File pointer used for MOZ_GCTIMER output. */
FILE* fp;
bool fullFormat;
/*
* GCs can't really nest, but a second GC can be triggered from within the
@ -311,10 +314,10 @@ struct Statistics
void printStats();
bool formatData(StatisticsSerializer& ss, uint64_t timestamp);
UniqueChars formatDescription();
UniqueChars formatSliceDescription(unsigned i, const SliceData& slice);
UniqueChars formatTotals();
UniqueChars formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT]);
UniqueChars formatDetailedDescription();
UniqueChars formatDetailedSliceDescription(unsigned i, const SliceData& slice);
UniqueChars formatDetailedPhaseTimes(PhaseTimeTable phaseTimes);
UniqueChars formatDetailedTotals();
double computeMMU(int64_t resolution);
};

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

@ -107,8 +107,10 @@ BaselineCompiler::compile()
if (!emitOutOfLinePostBarrierSlot())
return Method_Error;
if (masm.oom())
if (masm.oom()) {
ReportOutOfMemory(cx);
return Method_Error;
}
Linker linker(masm);
AutoFlushICache afc("Baseline");
@ -170,8 +172,10 @@ BaselineCompiler::compile()
previousOffset = entry.nativeOffset;
}
if (pcEntries.oom())
if (pcEntries.oom()) {
ReportOutOfMemory(cx);
return Method_Error;
}
prologueOffset_.fixup(&masm);
epilogueOffset_.fixup(&masm);
@ -282,6 +286,7 @@ BaselineCompiler::compile()
JitcodeGlobalTable* globalTable = cx->runtime()->jitRuntime()->getJitcodeGlobalTable();
if (!globalTable->addEntry(entry, cx->runtime())) {
entry.destroy();
ReportOutOfMemory(cx);
return Method_Error;
}
@ -936,8 +941,10 @@ BaselineCompiler::emitBody()
bool addIndexEntry = (pc == script->code() || lastOpUnreachable || emittedOps > 100);
if (addIndexEntry)
emittedOps = 0;
if (!addPCMappingEntry(addIndexEntry))
if (!addPCMappingEntry(addIndexEntry)) {
ReportOutOfMemory(cx);
return Method_Error;
}
// Emit traps for breakpoints and step mode.
if (compileDebugInstrumentation_ && !emitDebugTrap())

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

@ -228,14 +228,19 @@ jit::BaselineCompile(JSContext* cx, JSScript* script, bool forceDebugInstrumenta
LifoAlloc alloc(TempAllocator::PreferredLifoChunkSize);
TempAllocator* temp = alloc.new_<TempAllocator>(&alloc);
if (!temp)
if (!temp) {
ReportOutOfMemory(cx);
return Method_Error;
}
JitContext jctx(cx, temp);
BaselineCompiler compiler(cx, *temp, script);
if (!compiler.init())
if (!compiler.init()) {
ReportOutOfMemory(cx);
return Method_Error;
}
if (forceDebugInstrumentation)
compiler.setCompileDebugInstrumentation();

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

@ -264,7 +264,7 @@ class RepatchIonCache::RepatchStubAppender : public IonCache::StubAttacher
public:
explicit RepatchStubAppender(RepatchIonCache& cache)
: StubAttacher(cache.rejoinLabel()),
: StubAttacher(cache.rejoinLabel_),
cache_(cache)
{
}
@ -302,6 +302,9 @@ RepatchIonCache::emitInitialJump(MacroAssembler& masm, AddCacheState& addState)
{
initialJump_ = masm.jumpWithPatch(&addState.repatchEntry);
lastJump_ = initialJump_;
Label label;
masm.bind(&label);
rejoinLabel_ = CodeOffsetLabel(label.offset());
}
void
@ -316,6 +319,7 @@ RepatchIonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
IonCache::updateBaseAddress(code, masm);
initialJump_.repoint(code, &masm);
lastJump_.repoint(code, &masm);
rejoinLabel_.repoint(code, &masm);
}
class DispatchIonCache::DispatchStubPrepender : public IonCache::StubAttacher

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

@ -354,26 +354,7 @@ class RepatchIonCache : public IonCache
CodeLocationJump initialJump_;
CodeLocationJump lastJump_;
// Offset from the initial jump to the rejoin label.
#ifdef JS_CODEGEN_ARM
static const size_t REJOIN_LABEL_OFFSET = 4;
#elif defined(JS_CODEGEN_MIPS)
// The size of jump created by MacroAssemblerMIPSCompat::jumpWithPatch.
static const size_t REJOIN_LABEL_OFFSET = 4 * sizeof(void*);
#else
static const size_t REJOIN_LABEL_OFFSET = 0;
#endif
CodeLocationLabel rejoinLabel() const {
uint8_t* ptr = initialJump_.raw();
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
uint32_t i = 0;
while (i < REJOIN_LABEL_OFFSET)
ptr = Assembler::NextInstruction(ptr, &i);
#endif
return CodeLocationLabel(ptr);
}
CodeLocationLabel rejoinLabel_;
public:
RepatchIonCache()
@ -395,7 +376,7 @@ class RepatchIonCache : public IonCache
void updateBaseAddress(JitCode* code, MacroAssembler& masm) override;
virtual void* rejoinAddress() override {
return rejoinLabel().raw();
return rejoinLabel_.raw();
}
};

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

@ -373,13 +373,10 @@ class JitFrameLayout : public CommonFrameLayout
return offsetof(JitFrameLayout, numActualArgs_);
}
static size_t offsetOfThis() {
JitFrameLayout* base = nullptr;
return reinterpret_cast<size_t>(&base->argv()[0]);
return sizeof(JitFrameLayout);
}
static size_t offsetOfActualArgs() {
JitFrameLayout* base = nullptr;
// +1 to skip |this|.
return reinterpret_cast<size_t>(&base->argv()[1]);
return offsetOfThis() + sizeof(Value);
}
static size_t offsetOfActualArg(size_t arg) {
return offsetOfActualArgs() + arg * sizeof(Value);

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

@ -888,6 +888,20 @@ template void
MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type,
TypedOrValueRegister output);
static void
StoreUnboxedFailure(MacroAssembler& masm, Label* failure)
{
// Storing a value to an unboxed property is a fallible operation and
// the caller must provide a failure label if a particular unboxed store
// might fail. Sometimes, however, a store that cannot succeed (such as
// storing a string to an int32 property) will be marked as infallible.
// This can only happen if the code involved is unreachable.
if (failure)
masm.jump(failure);
else
masm.assumeUnreachable("Incompatible write to unboxed property");
}
template <typename T>
void
MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
@ -899,12 +913,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isBoolean())
store8(Imm32(value.value().toBoolean()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Boolean)
store8(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure);
@ -917,12 +931,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isInt32())
store32(Imm32(value.value().toInt32()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Int32)
store32(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure);
@ -936,7 +950,7 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
loadConstantDouble(value.value().toNumber(), ScratchDoubleReg);
storeDouble(ScratchDoubleReg, address);
} else {
jump(failure);
StoreUnboxedFailure(*this, failure);
}
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Int32) {
@ -945,7 +959,7 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
} else if (value.reg().type() == MIRType_Double) {
storeDouble(value.reg().typedReg().fpu(), address);
} else {
jump(failure);
StoreUnboxedFailure(*this, failure);
}
} else {
ValueOperand reg = value.reg().valueReg();
@ -967,13 +981,13 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isObjectOrNull())
storePtr(ImmGCPtr(value.value().toObjectOrNull()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
MOZ_ASSERT(value.reg().type() != MIRType_Null);
if (value.reg().type() == MIRType_Object)
storePtr(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure) {
Label ok;
@ -990,12 +1004,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isString())
storePtr(ImmGCPtr(value.value().toString()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_String)
storePtr(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure);

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

@ -81,8 +81,10 @@ class BaselineCompilerShared
return nullptr;
// Create the entry and add it to the vector.
if (!icEntries_.append(ICEntry(script->pcToOffset(pc), kind)))
if (!icEntries_.append(ICEntry(script->pcToOffset(pc), kind))) {
ReportOutOfMemory(cx);
return nullptr;
}
ICEntry& vecEntry = icEntries_.back();
// Set the first stub for the IC entry to the fallback stub

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

@ -116,6 +116,9 @@ enum {
JS_TELEMETRY_GC_NON_INCREMENTAL,
JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
JS_TELEMETRY_GC_MINOR_REASON,
JS_TELEMETRY_GC_MINOR_REASON_LONG,
JS_TELEMETRY_GC_MINOR_US,
JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
JS_TELEMETRY_ADDON_EXCEPTIONS
};

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

@ -530,9 +530,9 @@ BytecodeParser::addJump(uint32_t offset, uint32_t* currentOffset,
Bytecode*& code = codeArray_[offset];
if (!code) {
code = alloc().new_<Bytecode>();
if (!code)
return false;
if (!code->captureOffsetStack(alloc(), offsetStack, stackDepth)) {
if (!code ||
!code->captureOffsetStack(alloc(), offsetStack, stackDepth))
{
reportOOM();
return false;
}

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

@ -3158,6 +3158,15 @@ AccumulateTelemetryCallback(int id, uint32_t sample, const char* key)
case JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS:
Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_MAX_PAUSE_MS, sample);
break;
case JS_TELEMETRY_GC_MINOR_REASON:
Telemetry::Accumulate(Telemetry::GC_MINOR_REASON, sample);
break;
case JS_TELEMETRY_GC_MINOR_REASON_LONG:
Telemetry::Accumulate(Telemetry::GC_MINOR_REASON_LONG, sample);
break;
case JS_TELEMETRY_GC_MINOR_US:
Telemetry::Accumulate(Telemetry::GC_MINOR_US, sample);
break;
case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT:
Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample);
break;

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

@ -46,13 +46,13 @@ span {
.test3 {
grid-template-areas:'. a .';
grid-template-columns: (a-start) 20px 20px (a-start-start) 20px (a-start-end);
grid-template-columns: [a-start] 20px 20px [a-start-start] 20px [a-start-end];
}
.test3 span { grid-column: a-start / 8; }
.test4, .test5 {
grid-template-areas:'. . . a';
grid-template-columns: 20px (a-start) 20px (a-start) 20px (a-end) 20px ;
grid-template-columns: 20px [a-start] 20px [a-start] 20px [a-end] 20px ;
}
.test4 span { grid-column: a-start 2 / 8; }
.test5 span { grid-column: a / 8; }

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

@ -24,7 +24,7 @@ span {
.grid {
display: grid;
grid-template-columns: (A) 20px (A) 20px;
grid-template-columns: [A] 20px [A] 20px;
grid-template-rows: 20px 20px;
grid-auto-columns: 20px;
}

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

@ -14,7 +14,7 @@ body,html { color:black; background:white; font-size:16px; padding:0; margin:0;
.grid {
display: grid;
grid-template-columns: 20px 20px (A) 20px;
grid-template-columns: 20px 20px [A] 20px;
grid-template-rows: 20px;
grid-auto-columns: 20px;
grid-auto-rows: 20px;

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

@ -1040,10 +1040,10 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
} else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
// Non-empty <line-names>
aValue.Append('(');
aValue.Append('[');
rowsItem->mValue.AppendToString(eCSSProperty_grid_template_rows,
aValue, aSerialization);
aValue.Append(')');
aValue.Append(']');
} else {
nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[row++], aValue);

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

@ -839,7 +839,7 @@ protected:
// to indicate that we parsed the empty list,
// or set it to a eCSSUnit_List of eCSSUnit_Ident.
//
// To parse an optional <line-names> (ie. if not finding an open paren
// To parse an optional <line-names> (ie. if not finding an open bracket
// is considered the same as an empty list),
// treat CSSParseResult::NotFound the same as CSSParseResult::Ok.
//
@ -8005,10 +8005,10 @@ CSSParserImpl::ParseGridAutoFlow()
CSSParseResult
CSSParserImpl::ParseGridLineNames(nsCSSValue& aValue)
{
if (!ExpectSymbol('(', true)) {
if (!ExpectSymbol('[', true)) {
return CSSParseResult::NotFound;
}
if (!GetToken(true) || mToken.IsSymbol(')')) {
if (!GetToken(true) || mToken.IsSymbol(']')) {
return CSSParseResult::Ok;
}
// 'return' so far leaves aValue untouched, to represent an empty list.
@ -8035,10 +8035,10 @@ CSSParserImpl::ParseGridLineNames(nsCSSValue& aValue)
if (!(eCSSToken_Ident == mToken.mType &&
ParseCustomIdent(item->mValue, mToken.mIdent))) {
UngetToken();
SkipUntil(')');
SkipUntil(']');
return CSSParseResult::Error;
}
if (!GetToken(true) || mToken.IsSymbol(')')) {
if (!GetToken(true) || mToken.IsSymbol(']')) {
return CSSParseResult::Ok;
}
item->mNext = new nsCSSValueList;

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

@ -1944,7 +1944,7 @@ AppendGridTemplateToString(const nsCSSValueList* val,
} else if (unit == eCSSUnit_Null) {
// Empty or omitted <line-names>.
if (isSubgrid) {
aResult.AppendLiteral("()");
aResult.AppendLiteral("[]");
} else {
// Serializes to nothing.
addSpaceSeparator = false; // Avoid a double space.
@ -1952,10 +1952,10 @@ AppendGridTemplateToString(const nsCSSValueList* val,
} else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
// Non-empty <line-names>
aResult.Append('(');
aResult.Append('[');
AppendValueListToString(val->mValue.GetListValue(), aProperty,
aResult, aSerialization);
aResult.Append(')');
aResult.Append(']');
} else {
// <track-size>

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

@ -2272,7 +2272,7 @@ nsComputedDOMStyle::GetGridLineNames(const nsTArray<nsString>& aLineNames)
nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
nsAutoString lineNamesString;
uint32_t i_end = aLineNames.Length();
lineNamesString.Assign('(');
lineNamesString.Assign('[');
if (i_end > 0) {
for (uint32_t i = 0;;) {
nsStyleUtil::AppendEscapedCSSIdent(aLineNames[i], lineNamesString);
@ -2282,7 +2282,7 @@ nsComputedDOMStyle::GetGridLineNames(const nsTArray<nsString>& aLineNames)
lineNamesString.Append(' ');
}
}
lineNamesString.Append(')');
lineNamesString.Append(']');
val->SetString(lineNamesString);
return val;
}

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

@ -5790,32 +5790,32 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
"auto",
"40px",
"2.5fr",
"(normal) 40px () auto ( ) 12%",
"(foo) 40px min-content ( bar ) calc(20px + 10%) max-content",
"[normal] 40px [] auto [ ] 12%",
"[foo] 40px min-content [ bar ] calc(20px + 10%) max-content",
"40px min-content calc(20px + 10%) max-content",
"minmax(min-content, auto)",
"minmax(auto, max-content)",
"m\\69nmax(20px, 4Fr)",
"40px MinMax(min-content, calc(20px + 10%)) max-content",
"40px 2em",
"() 40px (-foo) 2em (bar baz This\ is\ one\ ident)",
// TODO bug 978478: "(a) repeat(3, (b) 20px (c) 40px (d)) (e)",
"[] 40px [-foo] 2em [bar baz This\ is\ one\ ident]",
// TODO bug 978478: "[a] repeat(3, [b] 20px [c] 40px [d]) [e]",
"repeat(1, 20px)",
"repeat(1, (a) 20px)",
"(a) Repeat(4, (a) 20px () auto (b c)) (d)",
"(a) 2.5fr Repeat(4, (a) 20px () auto (b c)) (d)",
"(a) 2.5fr (z) Repeat(4, (a) 20px () auto (b c)) (d)",
"(a) 2.5fr (z) Repeat(4, (a) 20px () auto) (d)",
"(a) 2.5fr (z) Repeat(4, 20px (b c) auto (b c)) (d)",
"(a) 2.5fr (z) Repeat(4, 20px auto) (d)",
"repeat(1, [a] 20px)",
"[a] Repeat(4, [a] 20px [] auto [b c]) [d]",
"[a] 2.5fr Repeat(4, [a] 20px [] auto [b c]) [d]",
"[a] 2.5fr [z] Repeat(4, [a] 20px [] auto [b c]) [d]",
"[a] 2.5fr [z] Repeat(4, [a] 20px [] auto) [d]",
"[a] 2.5fr [z] Repeat(4, 20px [b c] auto [b c]) [d]",
"[a] 2.5fr [z] Repeat(4, 20px auto) [d]",
// See https://bugzilla.mozilla.org/show_bug.cgi?id=981300
"(none auto subgrid min-content max-content foo) 40px",
"[none auto subgrid min-content max-content foo] 40px",
"subgrid",
"subgrid () (foo bar)",
"subgrid repeat(1, ())",
"subgrid Repeat(4, (a) (b c) () (d))",
"subgrid [] [foo bar]",
"subgrid repeat(1, [])",
"subgrid Repeat(4, [a] [b c] [] [d])",
],
invalid_values: [
"",
@ -5833,7 +5833,7 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
"(5th) 40px",
"(foo() bar) 40px",
"(foo)) 40px",
"[foo] 40px",
"(foo) 40px",
"(foo) (bar) 40px",
"40px (foo) (bar)",
"minmax()",
@ -5917,32 +5917,32 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
"subgrid",
// <'grid-template-columns'> / <'grid-template-rows'>
"40px / 100px",
"(foo) 40px (bar) / (baz) 100px (fizz)",
"[foo] 40px [bar] / [baz] 100px [fizz]",
" none/100px",
"40px/none",
"subgrid/40px 20px",
"subgrid (foo) () (bar baz) / 40px 20px",
"subgrid [foo] [] [bar baz] / 40px 20px",
"40px 20px/subgrid",
"40px 20px/subgrid (foo) () repeat(3, (a) (b)) (bar baz)",
"40px 20px/subgrid [foo] [] repeat(3, [a] [b]) [bar baz]",
"subgrid/subgrid",
"subgrid (foo) () (bar baz)/subgrid (foo) () (bar baz)",
"subgrid [foo] [] [bar baz]/subgrid [foo] [] [bar baz]",
// [ <track-list> / ]? [ <line-names>? <string> <track-size>? <line-names>? ]+
"'fizz'",
"(bar) 'fizz'",
"(foo) 40px / 'fizz'",
"(foo) 40px / (bar) 'fizz'",
"(foo) 40px / 'fizz' 100px",
"(foo) 40px / (bar) 'fizz' 100px",
"(foo) 40px / (bar) 'fizz' 100px (buzz)",
"(foo) 40px / (bar) 'fizz' 100px (buzz) \n (a) '.' 200px (b)",
"[bar] 'fizz'",
"[foo] 40px / 'fizz'",
"[foo] 40px / [bar] 'fizz'",
"[foo] 40px / 'fizz' 100px",
"[foo] 40px / [bar] 'fizz' 100px",
"[foo] 40px / [bar] 'fizz' 100px [buzz]",
"[foo] 40px / [bar] 'fizz' 100px [buzz] \n [a] '.' 200px [b]",
],
invalid_values: [
"subgrid ()",
"subgrid () / 'fizz'",
"subgrid []",
"subgrid [] / 'fizz'",
"subgrid / 'fizz'",
"(foo) (bar) 40px / 100px",
"40px / (fizz) (buzz) 100px",
"40px / (fizz) (buzz) 'foo'",
"[foo] [bar] 40px / 100px",
"40px / [fizz] [buzz] 100px",
"40px / [fizz] [buzz] 'foo'",
"none / 'foo'"
]
};

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

@ -34,9 +34,9 @@ var grid_template_test_cases = [
gridTemplateRows: "100px",
},
{
specified: "(foo) 40px (bar) / (baz) 100px (fizz)",
gridTemplateColumns: "(foo) 40px (bar)",
gridTemplateRows: "(baz) 100px (fizz)",
specified: "[foo] 40px [bar] / [baz] 100px [fizz]",
gridTemplateColumns: "[foo] 40px [bar]",
gridTemplateRows: "[baz] 100px [fizz]",
},
{
specified: " none/100px",
@ -54,54 +54,54 @@ var grid_template_test_cases = [
gridTemplateRows: "20px",
},
{
specified: "40px/(a)repeat(1, 20px)",
specified: "40px/[a]repeat(1, 20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a) 20px",
gridTemplateRows: "[a] 20px",
},
{
specified: "40px/repeat(1, (a) 20px)",
specified: "40px/repeat(1, [a] 20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a) 20px",
gridTemplateRows: "[a] 20px",
},
{
specified: "40px/(a)repeat(2, (b)20px)",
specified: "40px/[a]repeat(2, [b]20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a b) 20px (b) 20px",
gridTemplateRows: "[a b] 20px [b] 20px",
},
{
specified: "40px/(a)repeat(2, 20px)",
specified: "40px/[a]repeat(2, 20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a) 20px 20px",
gridTemplateRows: "[a] 20px 20px",
},
{
specified: "40px/repeat(2, (a) 20px)",
specified: "40px/repeat(2, [a] 20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a) 20px (a) 20px",
gridTemplateRows: "[a] 20px [a] 20px",
},
{
specified: "40px/(a)repeat(2, (b)20px)",
specified: "40px/[a]repeat(2, [b]20px)",
gridTemplateColumns: "40px",
gridTemplateRows: "(a b) 20px (b) 20px",
gridTemplateRows: "[a b] 20px [b] 20px",
},
{
specified: "40px/repeat(2, 20px(a))",
specified: "40px/repeat(2, 20px[a])",
gridTemplateColumns: "40px",
gridTemplateRows: "20px (a) 20px (a)",
gridTemplateRows: "20px [a] 20px [a]",
},
{
specified: "40px/repeat(2, 20px(a)) (b)",
specified: "40px/repeat(2, 20px[a]) [b]",
gridTemplateColumns: "40px",
gridTemplateRows: "20px (a) 20px (a b)",
gridTemplateRows: "20px [a] 20px [a b]",
},
{
specified: "40px/repeat(2, (a) 20px(b)) (c)",
specified: "40px/repeat(2, [a] 20px[b]) [c]",
gridTemplateColumns: "40px",
gridTemplateRows: "(a) 20px (b a) 20px (b c)",
gridTemplateRows: "[a] 20px [b a] 20px [b c]",
},
{
specified: "40px/(a) repeat(3, (b c) 20px (d) 100px (e f)) (g)",
specified: "40px/[a] repeat(3, [b c] 20px [d] 100px [e f]) [g]",
gridTemplateColumns: "40px",
gridTemplateRows: "(a b c) 20px (d) 100px (e f b c) 20px (d) 100px (e f b c) 20px (d) 100px (e f g)",
gridTemplateRows: "[a b c] 20px [d] 100px [e f b c] 20px [d] 100px [e f b c] 20px [d] 100px [e f g]",
},
{
specified: "'fizz'",
@ -109,33 +109,33 @@ var grid_template_test_cases = [
gridTemplateRows: "auto",
},
{
specified: "(bar) 'fizz'",
specified: "[bar] 'fizz'",
gridTemplateAreas: "\"fizz\"",
gridTemplateRows: "(bar) auto",
gridTemplateRows: "[bar] auto",
},
{
specified: "(foo) 40px / 'fizz'",
specified: "[foo] 40px / 'fizz'",
gridTemplateAreas: "\"fizz\"",
gridTemplateColumns: "(foo) 40px",
gridTemplateColumns: "[foo] 40px",
gridTemplateRows: "auto",
},
{
specified: "(foo) 40px / (bar) 'fizz'",
specified: "[foo] 40px / [bar] 'fizz'",
gridTemplateAreas: "\"fizz\"",
gridTemplateColumns: "(foo) 40px",
gridTemplateRows: "(bar) auto",
gridTemplateColumns: "[foo] 40px",
gridTemplateRows: "[bar] auto",
},
{
specified: "(foo) 40px / 'fizz' 100px",
specified: "[foo] 40px / 'fizz' 100px",
gridTemplateAreas: "\"fizz\"",
gridTemplateColumns: "(foo) 40px",
gridTemplateColumns: "[foo] 40px",
gridTemplateRows: "100px",
},
{
specified: "(foo) 40px / (bar) 'fizz' 100px (buzz) \n (a) '.' 200px (b)",
specified: "[foo] 40px / [bar] 'fizz' 100px [buzz] \n [a] '.' 200px [b]",
gridTemplateAreas: "\"fizz\" \".\"",
gridTemplateColumns: "(foo) 40px",
gridTemplateRows: "(bar) 100px (buzz a) 200px (b)",
gridTemplateColumns: "[foo] 40px",
gridTemplateRows: "[bar] 100px [buzz a] 200px [b]",
},
{
specified: "subgrid",
@ -148,28 +148,28 @@ var grid_template_test_cases = [
gridTemplateRows: "subgrid",
},
{
specified: "subgrid / subgrid (foo)",
specified: "subgrid / subgrid [foo]",
gridTemplateColumns: "subgrid",
gridTemplateRows: "subgrid (foo)",
gridTemplateRows: "subgrid [foo]",
},
{
specified: "subgrid / subgrid (foo) repeat(3, () (a b) (c))",
specified: "subgrid / subgrid [foo] repeat(3, [] [a b] [c])",
gridTemplateColumns: "subgrid",
gridTemplateRows: "subgrid (foo) () (a b) (c) () (a b) (c) () (a b) (c)",
gridTemplateRows: "subgrid [foo] [] [a b] [c] [] [a b] [c] [] [a b] [c]",
},
{
// https://bugzilla.mozilla.org/show_bug.cgi?id=978478#c1
// The number of repetitions is clamped to
// #define GRID_TEMPLATE_MAX_REPETITIONS 10000
specified: "subgrid / subgrid (foo) repeat(999999999, (a))",
specified: "subgrid / subgrid [foo] repeat(999999999, [a])",
gridTemplateColumns: "subgrid",
// Array(n + 1).join(s) is a hack for the non-standard s.repeat(n)
gridTemplateRows: "subgrid (foo)" + Array(10000 + 1).join(" (a)"),
gridTemplateRows: "subgrid [foo]" + Array(10000 + 1).join(" [a]"),
},
{
specified: "subgrid () (foo)/ subgrid (bar",
gridTemplateColumns: "subgrid () (foo)",
gridTemplateRows: "subgrid (bar)",
specified: "subgrid [] [foo]/ subgrid [bar",
gridTemplateColumns: "subgrid [] [foo]",
gridTemplateRows: "subgrid [bar]",
},
];

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

@ -38,9 +38,9 @@ var grid_template_test_cases = [
shorthand: "40px / subgrid",
},
{
gridTemplateColumns: "(foo) 40px (bar)",
gridTemplateRows: "(baz) 100px (fizz)",
shorthand: "(foo) 40px (bar) / (baz) 100px (fizz)",
gridTemplateColumns: "[foo] 40px [bar]",
gridTemplateRows: "[baz] 100px [fizz]",
shorthand: "[foo] 40px [bar] / [baz] 100px [fizz]",
},
{
gridTemplateAreas: "\"a\"",
@ -49,8 +49,8 @@ var grid_template_test_cases = [
},
{
gridTemplateAreas: "\"a\"",
gridTemplateRows: "(foo) 20px (bar)",
shorthand: "(foo) \"a\" 20px (bar)",
gridTemplateRows: "[foo] 20px [bar]",
shorthand: "[foo] \"a\" 20px [bar]",
},
// Combinations of longhands that make the shorthand non-serializable:
{
@ -70,7 +70,7 @@ var grid_template_test_cases = [
},
{
gridTemplateAreas: "\"a\"",
gridTemplateRows: "subgrid (foo)",
gridTemplateRows: "subgrid [foo]",
shorthand: "",
},
{

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

@ -313,7 +313,7 @@ function runTest() {
}
SimpleTest.waitForExplicitFinish();
SimpleTest.requestLongerTimeout(4);
SimpleTest.requestLongerTimeout(5);
SpecialPowers.pushPrefEnv({ set: [["layout.css.variables.enabled", true]] },
runTest);

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

@ -1635,6 +1635,87 @@ void nsMenuPopupFrame::EnsureMenuItemIsVisible(nsMenuFrame* aMenuItem)
}
}
void nsMenuPopupFrame::ChangeByPage(bool aIsUp)
{
nsIFrame* parentMenu = GetParent();
if (parentMenu) {
// Only scroll by page within menulists.
nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(parentMenu->GetContent());
if (!menulist) {
return;
}
}
nsMenuFrame* newMenu = nullptr;
nsIFrame* currentMenu = mCurrentMenu;
if (!currentMenu) {
// If there is no current menu item, get the first item. When moving up,
// just use this as the newMenu and leave currentMenu null so that no
// check for a later element is performed. When moving down, set currentMenu
// so that we look for one page down from the first item.
newMenu = nsXULPopupManager::GetNextMenuItem(this, nullptr, true);
if (!aIsUp) {
currentMenu = newMenu;
}
}
if (currentMenu) {
nscoord scrollHeight = mRect.height;
nsIScrollableFrame *scrollframe = GetScrollFrame(this);
if (scrollframe) {
scrollHeight = scrollframe->GetScrollPortRect().height;
}
// Get the position of the current item and add or subtract one popup's
// height to or from it.
nscoord targetPosition = aIsUp ? currentMenu->GetRect().YMost() - scrollHeight :
currentMenu->GetRect().y + scrollHeight;
// Indicates that the last visible child was a valid menuitem.
bool lastWasValid = false;
// Look for the next child which is just past the target position. This child
// will need to be selected.
while (currentMenu) {
// Only consider menu frames.
nsMenuFrame* menuFrame = do_QueryFrame(currentMenu);
if (menuFrame &&
nsXULPopupManager::IsValidMenuItem(PresContext(), menuFrame->GetContent(), true)) {
// If the right position was found, break out. Otherwise, look for another item.
if ((!aIsUp && currentMenu->GetRect().YMost() > targetPosition) ||
(aIsUp && currentMenu->GetRect().y < targetPosition)) {
// If the last visible child was not a valid menuitem or was disabled,
// use this as the menu to select, skipping over any non-valid items at
// the edge of the page.
if (!lastWasValid) {
newMenu = menuFrame;
}
break;
}
// Assign this item to newMenu. This item will be selected in case we
// don't find any more.
lastWasValid = true;
newMenu = menuFrame;
}
else {
lastWasValid = false;
}
currentMenu = aIsUp ? currentMenu->GetPrevSibling() :
currentMenu->GetNextSibling();
}
}
// Select the new menuitem.
if (newMenu) {
ChangeMenuItem(newMenu, false);
}
}
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsMenuFrame* aMenuItem)
{
if (mCurrentMenu == aMenuItem)

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

@ -326,6 +326,8 @@ public:
void EnsureMenuItemIsVisible(nsMenuFrame* aMenuFrame);
void ChangeByPage(bool aIsUp);
// Move the popup to the screen coordinate (aLeft, aTop) in CSS pixels.
// If aUpdateAttrs is true, and the popup already has left or top attributes,
// then those attributes are updated to the new location.

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

@ -2172,6 +2172,13 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
HandleKeyboardNavigation(keyCode);
break;
case nsIDOMKeyEvent::DOM_VK_PAGE_DOWN:
case nsIDOMKeyEvent::DOM_VK_PAGE_UP:
if (aTopVisibleMenuItem) {
aTopVisibleMenuItem->Frame()->ChangeByPage(keyCode == nsIDOMKeyEvent::DOM_VK_PAGE_UP);
}
break;
case nsIDOMKeyEvent::DOM_VK_ESCAPE:
// Pressing Escape hides one level of menus only. If no menu is open,
// check if a menubar is active and inform it that a menu closed. Even

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

@ -1307,6 +1307,8 @@ JsepSessionImpl::SetLocalDescription(JsepSdpType type, const std::string& sdp)
{
mLastError.clear();
MOZ_MTLOG(ML_DEBUG, "SetLocalDescription type=" << type << "\nSDP=\n"
<< sdp);
switch (mState) {
case kJsepStateStable:
if (type != kJsepSdpOffer) {

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

@ -301,12 +301,15 @@ void AudioSendAndReceive::GenerateAndReadSamples()
FILE* inFile = fopen( iFile.c_str(), "wb+");
if(!inFile) {
cerr << "Input File Creation Failed " << endl;
free(inbuf);
return;
}
FILE* outFile = fopen( oFile.c_str(), "wb+");
if(!outFile) {
cerr << "Output File Creation Failed " << endl;
free(inbuf);
fclose(inFile);
return;
}
@ -323,6 +326,8 @@ void AudioSendAndReceive::GenerateAndReadSamples()
{
if(!memcpy(audioInput.get(), inbuf, sampleLengthInBytes))
{
free(inbuf);
fclose(outFile);
return;
}
@ -350,6 +355,7 @@ void AudioSendAndReceive::GenerateAndReadSamples()
}while(numSamplesReadFromInput < SAMPLES);
FinishWaveHeader(outFile);
free(inbuf);
fclose(outFile);
}

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

@ -407,10 +407,17 @@ NS_IMPL_ADDREF(nsProtocolProxyService)
NS_IMPL_RELEASE(nsProtocolProxyService)
NS_IMPL_CLASSINFO(nsProtocolProxyService, nullptr, nsIClassInfo::SINGLETON,
NS_PROTOCOLPROXYSERVICE_CID)
NS_IMPL_QUERY_INTERFACE_CI(nsProtocolProxyService,
nsIProtocolProxyService,
nsIProtocolProxyService2,
nsIObserver)
// NS_IMPL_QUERY_INTERFACE_CI with the nsProtocolProxyService QI change
NS_INTERFACE_MAP_BEGIN(nsProtocolProxyService)
NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyService)
NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyService2)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
if ( aIID.Equals(NS_GET_IID(nsProtocolProxyService)) ) foundInterface = static_cast<nsIProtocolProxyService2*>(this); else
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIProtocolProxyService)
NS_IMPL_QUERY_CLASSINFO(nsProtocolProxyService)
NS_INTERFACE_MAP_END
NS_IMPL_CI_INTERFACE_GETTER(nsProtocolProxyService,
nsIProtocolProxyService,
nsIProtocolProxyService2)

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

@ -4822,6 +4822,8 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
return rv;
}
// On error BeginConnect() should call AsyncAbort() before exiting until
// ContineBeginConnect after that it should not call it.
nsresult
nsHttpChannel::BeginConnect()
{
@ -4845,12 +4847,17 @@ nsHttpChannel::BeginConnect()
mURI->GetUsername(mUsername);
if (NS_SUCCEEDED(rv))
rv = mURI->GetAsciiSpec(mSpec);
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
AsyncAbort(rv);
return rv;
}
// Reject the URL if it doesn't specify a host
if (host.IsEmpty())
return NS_ERROR_MALFORMED_URI;
if (host.IsEmpty()) {
rv = NS_ERROR_MALFORMED_URI;
AsyncAbort(rv);
return rv;
}
LOG(("host=%s port=%d\n", host.get(), port));
LOG(("uri=%s\n", mSpec.get()));
@ -4923,8 +4930,10 @@ nsHttpChannel::BeginConnect()
&rv);
if (NS_SUCCEEDED(rv))
rv = mAuthProvider->Init(this);
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
AsyncAbort(rv);
return rv;
}
// check to see if authorization headers should be included
mAuthProvider->AddAuthorizationHeaders();
@ -4935,7 +4944,11 @@ nsHttpChannel::BeginConnect()
// Check to see if we should redirect this channel elsewhere by
// nsIHttpChannel.redirectTo API request
if (mAPIRedirectToURI) {
return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
rv = AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
if (NS_FAILED(rv)) {
AsyncAbort(rv);
}
return rv;
}
// Check to see if this principal exists on local blocklists.
nsRefPtr<nsChannelClassifier> channelClassifier = new nsChannelClassifier();
@ -5028,6 +5041,8 @@ nsHttpChannel::BeginConnect()
mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
}
if (!(mLoadFlags & LOAD_CLASSIFY_URI)) {
// On error ContinueBeginConnect() will call AsyncAbort so do not do it
// here
return ContinueBeginConnect();
}
// mLocalBlocklist is true only if tracking protection is enabled and the
@ -5038,6 +5053,8 @@ nsHttpChannel::BeginConnect()
if (mCanceled || !mLocalBlocklist) {
rv = ContinueBeginConnect();
if (NS_FAILED(rv)) {
// On error ContinueBeginConnect() will call AsyncAbort so do not do
// it here
return rv;
}
callContinueBeginConnect = false;
@ -5161,21 +5178,15 @@ nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
LOG(("nsHttpChannel::OnProxyAvailable [this=%p] "
"Handler no longer active.\n", this));
rv = NS_ERROR_NOT_AVAILABLE;
AsyncAbort(rv);
}
else {
// On error BeginConnect() will call AsyncAbort.
rv = BeginConnect();
}
if (NS_FAILED(rv)) {
Cancel(rv);
// Calling OnStart/OnStop synchronously here would mean doing it before
// returning from AsyncOpen which is a contract violation. Do it async.
nsRefPtr<nsRunnableMethod<HttpBaseChannel> > event =
NS_NewRunnableMethod(this, &nsHttpChannel::DoNotifyListener);
rv = NS_DispatchToCurrentThread(event);
if (NS_FAILED(rv)) {
NS_WARNING("Failed To Dispatch DoNotifyListener");
}
}
return rv;
}

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

@ -1,29 +1,31 @@
var ScriptableUnicodeConverter =
"use strict";
let ScriptableUnicodeConverter =
Components.Constructor("@mozilla.org/intl/scriptableunicodeconverter",
"nsIScriptableUnicodeConverter");
function getHMAC(data, key, alg)
{
var converter = new ScriptableUnicodeConverter();
converter.charset = 'utf8';
var dataarray = converter.convertToByteArray(data);
function getHMAC(data, key, alg) {
let converter = new ScriptableUnicodeConverter();
converter.charset = "utf8";
let dataArray = converter.convertToByteArray(data);
var keyObject = Components.classes["@mozilla.org/security/keyobjectfactory;1"]
.getService(Components.interfaces.nsIKeyObjectFactory)
.keyFromString(Components.interfaces.nsIKeyObject.HMAC, key);
let keyObject = Cc["@mozilla.org/security/keyobjectfactory;1"]
.getService(Ci.nsIKeyObjectFactory)
.keyFromString(Ci.nsIKeyObject.HMAC, key);
var cryptoHMAC = Components.classes["@mozilla.org/security/hmac;1"]
.createInstance(Components.interfaces.nsICryptoHMAC);
let cryptoHMAC = Cc["@mozilla.org/security/hmac;1"]
.createInstance(Ci.nsICryptoHMAC);
cryptoHMAC.init(alg, keyObject);
cryptoHMAC.update(dataarray, dataarray.length);
var digest1 = cryptoHMAC.finish(false);
cryptoHMAC.update(dataArray, dataArray.length);
let digest1 = cryptoHMAC.finish(false);
cryptoHMAC.reset();
cryptoHMAC.update(dataarray, dataarray.length);
var digest2 = cryptoHMAC.finish(false);
cryptoHMAC.update(dataArray, dataArray.length);
let digest2 = cryptoHMAC.finish(false);
do_check_eq(digest1, digest2);
equal(digest1, digest2,
"Initial digest and digest after calling reset() should match");
return digest1;
}
@ -35,19 +37,18 @@ function testHMAC(alg) {
const dataA = "Secret message";
const dataB = "Secres message";
var diegest1a = getHMAC(key1, dataA, alg);
var diegest2 = getHMAC(key2, dataA, alg);
var diegest1b = getHMAC(key1, dataA, alg);
let digest1a = getHMAC(key1, dataA, alg);
let digest2 = getHMAC(key2, dataA, alg);
let digest1b = getHMAC(key1, dataA, alg);
do_check_eq(diegest1a, diegest1b);
do_check_neq(diegest1a, diegest2);
equal(digest1a, digest1b,
"The digests for the same key, data and algorithm should match");
notEqual(digest1a, digest2, "The digests for different keys should not match");
var diegest1 = getHMAC(key1, dataA, alg);
diegest2 = getHMAC(key1, dataB, alg);
let digest1 = getHMAC(key1, dataA, alg);
digest2 = getHMAC(key1, dataB, alg);
do_check_neq(diegest1, diegest2);
return diegest1;
notEqual(digest1, digest2, "The digests for different data should not match");
}
function hexdigest(data) {
@ -56,35 +57,32 @@ function hexdigest(data) {
function testVectors() {
// These are test vectors taken from RFC 4231, section 4.3. (Test Case 2)
const keyTestVector = "Jefe";
const dataTestVector = "what do ya want for nothing?";
var diegest;
/*
Bug 356713
diegest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Components.interfaces.nsICryptoHMAC.SHA224));
do_check_eq(diegest, "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44");
*/
let digest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Ci.nsICryptoHMAC.SHA256));
equal(digest,
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
"Actual and expected SHA-256 digests should match");
diegest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Components.interfaces.nsICryptoHMAC.SHA256));
do_check_eq(diegest, "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
digest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Ci.nsICryptoHMAC.SHA384));
equal(digest,
"af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649",
"Actual and expected SHA-384 digests should match");
diegest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Components.interfaces.nsICryptoHMAC.SHA384));
do_check_eq(diegest, "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649");
diegest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Components.interfaces.nsICryptoHMAC.SHA512));
do_check_eq(diegest, "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737");
digest = hexdigest(getHMAC(dataTestVector, keyTestVector,
Ci.nsICryptoHMAC.SHA512));
equal(digest,
"164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737",
"Actual and expected SHA-512 digests should match");
}
function run_test() {
testVectors();
testHMAC(Components.interfaces.nsICryptoHMAC.SHA1);
testHMAC(Components.interfaces.nsICryptoHMAC.SHA512);
testHMAC(Components.interfaces.nsICryptoHMAC.MD5);
testHMAC(Ci.nsICryptoHMAC.SHA1);
testHMAC(Ci.nsICryptoHMAC.SHA512);
testHMAC(Ci.nsICryptoHMAC.MD5);
}

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

@ -134,7 +134,7 @@ FrameManager.prototype = {
frameMessageManager.sendAsyncMessage("aliveCheck", {});
} catch (e) {
if (e.result == Components.results.NS_ERROR_NOT_INITIALIZED) {
remoteFrames.splice(i, 1);
remoteFrames.splice(i--, 1);
continue;
}
}

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

@ -331,6 +331,25 @@
"n_buckets": 50,
"description": "Time spent sweeping slowest compartment SCC (ms)"
},
"GC_MINOR_REASON": {
"expires_in_version": "never",
"kind": "enumerated",
"n_values": "JS::gcreason::NUM_TELEMETRY_REASONS",
"description": "Reason (enum value) for initiating a minor GC"
},
"GC_MINOR_REASON_LONG": {
"expires_in_version": "never",
"kind": "enumerated",
"n_values": "JS::gcreason::NUM_TELEMETRY_REASONS",
"description": "Reason (enum value) that caused a long (>1ms) minor GC"
},
"GC_MINOR_US": {
"expires_in_version": "never",
"kind": "exponential",
"high": "1000000",
"n_buckets": 100,
"description": "Time spent running JS minor GC (us)"
},
"GEOLOCATION_ACCURACY_EXPONENTIAL": {
"expires_in_version": "default",
"kind": "exponential",

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

@ -116,6 +116,7 @@ skip-if = buildapp == 'mulet'
skip-if = buildapp == 'mulet'
[test_menulist_keynav.xul]
[test_menulist_null_value.xul]
[test_menulist_paging.xul]
[test_mousecapture.xul]
skip-if = buildapp == 'mulet'
[test_mousescroll.xul]

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

@ -0,0 +1,133 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Menulist Tests"
onload="setTimeout(startTest, 0);"
onpopupshown="menulistShown()" onpopuphidden="runTest()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<menulist id="menulist1">
<menupopup id="menulist-popup1">
<menuitem label="One"/>
<menuitem label="Two"/>
<menuitem label="Three"/>
<menuitem label="Four"/>
<menuitem label="Five"/>
<menuitem label="Six"/>
<menuitem label="Seven"/>
<menuitem label="Eight"/>
<menuitem label="Nine"/>
<menuitem label="Ten"/>
</menupopup>
</menulist>
<menulist id="menulist2">
<menupopup id="menulist-popup2">
<menuitem label="One" disabled="true"/>
<menuitem label="Two" selected="true"/>
<menuitem label="Three"/>
<menuitem label="Four"/>
<menuitem label="Five"/>
<menuitem label="Six"/>
<menuitem label="Seven"/>
<menuitem label="Eight"/>
<menuitem label="Nine"/>
<menuitem label="Ten" disabled="true"/>
</menupopup>
</menulist>
<menulist id="menulist3">
<menupopup id="menulist-popup3">
<label value="One"/>
<menuitem label="Two" selected="true"/>
<menuitem label="Three"/>
<menuitem label="Four"/>
<menuitem label="Five" disabled="true"/>
<menuitem label="Six" disabled="true"/>
<menuitem label="Seven"/>
<menuitem label="Eight"/>
<menuitem label="Nine"/>
<label value="Ten"/>
</menupopup>
</menulist>
<script class="testbody" type="application/javascript">
<![CDATA[
SimpleTest.waitForExplicitFinish();
let test;
// Windows allows disabled items to be selected.
let isWindows = navigator.platform.indexOf("Win") >= 0;
let tests = [
{ list: "menulist1", initial: 0, downs: [3, 6, 9, 9],
ups: [6, 3, 0, 0] },
{ list: "menulist2", initial: 1, downs: [4, 7, isWindows ? 9 : 8, isWindows ? 9 : 8],
ups: [isWindows ? 6 : 5, isWindows ? 3 : 2, isWindows ? 0 : 1] },
{ list: "menulist3", initial: 1, downs: [isWindows ? 4 : 6, isWindows ? 7 : 8, 8],
ups: [isWindows ? 5 : 3, isWindows ? 2 : 1, 1] }
];
function startTest()
{
let popup = document.getElementById("menulist-popup1");
let menupopupHeight = popup.getBoundingClientRect().height;
let menuitemHeight = popup.firstChild.getBoundingClientRect().height;
// First, set the height of each popup to the height of four menuitems plus
// any padding and border on the menupopup.
let height = menuitemHeight * 4 + (menupopupHeight - menuitemHeight * 10);
popup.height = height;
document.getElementById("menulist-popup2").height = height;
document.getElementById("menulist-popup3").height = height;
runTest();
}
function runTest()
{
if (!tests.length) {
SimpleTest.finish();
return;
}
test = tests.shift();
document.getElementById(test.list).open = true;
}
function menulistShown()
{
let menulist = document.getElementById(test.list);
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.initial).label, test.list + " initial selection");
for (let i = 0; i < test.downs.length; i++) {
sendKey("PAGE_DOWN");
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.downs[i]).label, test.list + " page down " + i);
}
for (let i = 0; i < test.ups.length; i++) {
sendKey("PAGE_UP");
is(menulist.menuBoxObject.activeChild.label, menulist.getItemAtIndex(test.ups[i]).label, test.list + " page up " + i);
}
menulist.open = false;
}
]]>
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</window>

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

@ -694,6 +694,47 @@ CleanUpSandboxEnvironment()
// Get and remove the low integrity Mozilla temp directory.
// This function already warns if the deletion fails.
unused << GetAndCleanLowIntegrityTemp(tempDirSuffix);
#if defined(NIGHTLY_BUILD)
// Temporary code to clean up the old low integrity temp directories.
// The removal of this is tracked by bug 1165818.
nsCOMPtr<nsIFile> lowIntegrityMozilla;
nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOW_INTEGRITY_TEMP_BASE,
getter_AddRefs(lowIntegrityMozilla));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsISimpleEnumerator> iter;
rv = lowIntegrityMozilla->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool more;
nsCOMPtr<nsISupports> elem;
while (NS_SUCCEEDED(iter->HasMoreElements(&more)) && more) {
rv = iter->GetNext(getter_AddRefs(elem));
if (NS_FAILED(rv)) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(elem);
if (!file) {
continue;
}
nsAutoString leafName;
rv = file->GetLeafName(leafName);
if (NS_FAILED(rv)) {
continue;
}
if (leafName.Find(NS_LITERAL_STRING("MozTemp-{")) == 0) {
file->Remove(/* aRecursive */ true);
}
}
#endif
}
#endif

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

@ -16,6 +16,7 @@
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsUnicharUtils.h"
#include "nsVersionComparator.h"
#include "mozilla/Services.h"
#include "mozilla/Observer.h"
#include "nsIObserver.h"
@ -26,6 +27,7 @@
#include "nsIDOMNodeList.h"
#include "nsTArray.h"
#include "nsXULAppAPI.h"
#include "nsIXULAppInfo.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/2D.h"
@ -144,6 +146,9 @@ GetPrefNameForFeature(int32_t aFeature)
case nsIGfxInfo::FEATURE_STAGEFRIGHT:
name = BLACKLIST_PREF_BRANCH "stagefright";
break;
case nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION:
name = BLACKLIST_PREF_BRANCH "webrtc.hw.acceleration";
break;
default:
break;
};
@ -217,6 +222,29 @@ BlacklistNodeToTextValue(nsIDOMNode *aBlacklistNode, nsAString& aValue)
return true;
}
// <foo attr=Hello/> finds "Hello" if the aAttrName is "attr".
static bool
BlacklistAttrToTextValue(nsIDOMNode *aBlacklistNode,
const nsAString& aAttrName,
nsAString& aValue)
{
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aBlacklistNode);
if (!element) {
return false;
}
nsAutoString value;
if (NS_FAILED(element->GetAttribute(aAttrName, value))) {
return false;
}
value.Trim(" \t\r\n");
aValue = value;
return true;
}
static OperatingSystem
BlacklistOSToOperatingSystem(const nsAString& os)
{
@ -307,6 +335,8 @@ BlacklistFeatureToGfxFeature(const nsAString& aFeature)
return nsIGfxInfo::FEATURE_WEBGL_MSAA;
else if (aFeature.EqualsLiteral("STAGEFRIGHT"))
return nsIGfxInfo::FEATURE_STAGEFRIGHT;
else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION"))
return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION;
return 0;
}
@ -408,6 +438,42 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
nsCOMPtr<nsIDOMNode> dataNode;
nsAutoString dataValue;
// If we get an application version to be zero, something is not working
// and we are not going to bother checking the blocklist versions.
// See TestGfxWidgets.cpp for how version comparison works.
// <versionRange minVersion="42.0a1" maxVersion="45.0"></versionRange>
static mozilla::Version zeroV("0");
static mozilla::Version appV(GfxInfoBase::GetApplicationVersion().get());
if (appV <= zeroV) {
gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Invalid application version " << GfxInfoBase::GetApplicationVersion().get();
} else if (BlacklistNodeGetChildByName(element,
NS_LITERAL_STRING("versionRange"),
getter_AddRefs(dataNode))) {
if (BlacklistAttrToTextValue(dataNode,
NS_LITERAL_STRING("minVersion"),
dataValue)) {
mozilla::Version minV(NS_ConvertUTF16toUTF8(dataValue).get());
if (minV > zeroV && appV < minV) {
// The version of the application is less than the minimal version
// this blocklist entry applies to, so we can just ignore it by
// returning false and letting the caller deal with it.
return false;
}
}
if (BlacklistAttrToTextValue(dataNode,
NS_LITERAL_STRING("maxVersion"),
dataValue)) {
mozilla::Version maxV(NS_ConvertUTF16toUTF8(dataValue).get());
if (maxV > zeroV && appV > maxV) {
// The version of the application is more than the maximal version
// this blocklist entry applies to, so we can just ignore it by
// returning false and letting the caller deal with it.
return false;
}
}
}
// <os>WINNT 6.0</os>
if (BlacklistNodeGetChildByName(element, NS_LITERAL_STRING("os"),
getter_AddRefs(dataNode))) {
@ -532,11 +598,11 @@ BlacklistEntriesToDriverInfo(nsIDOMHTMLCollection* aBlacklistEntries,
GfxDriverInfo di;
if (BlacklistEntryToDriverInfo(blacklistEntry, di)) {
aDriverInfo[i] = di;
}
// Prevent di falling out of scope from destroying the devices.
di.mDeleteDevices = false;
}
}
}
}
NS_IMETHODIMP
@ -613,6 +679,21 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
uint32_t i = 0;
for (; i < info.Length(); i++) {
// Do the operating system check first, no point in getting the driver
// info if we won't need to use it. Note we also catch and skips the
// application version mismatches that would leave operating system
// set to unknown.
if (info[i].mOperatingSystem == DRIVER_OS_UNKNOWN ||
(info[i].mOperatingSystem != DRIVER_OS_ALL &&
info[i].mOperatingSystem != os))
{
continue;
}
if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
continue;
}
// XXX: it would be better not to do this everytime round the loop
nsAutoString adapterVendorID;
nsAutoString adapterDeviceID;
@ -638,17 +719,6 @@ GfxInfoBase::FindBlocklistedDeviceInList(const nsTArray<GfxDriverInfo>& info,
ParseDriverVersion(adapterDriverVersionString, &driverVersion);
#endif
if (info[i].mOperatingSystem != DRIVER_OS_ALL &&
info[i].mOperatingSystem != os)
{
continue;
}
if (info[i].mOperatingSystemVersion && info[i].mOperatingSystemVersion != OperatingSystemVersion()) {
continue;
}
if (!info[i].mAdapterVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorAll), nsCaseInsensitiveStringComparator()) &&
!info[i].mAdapterVendor.Equals(adapterVendorID, nsCaseInsensitiveStringComparator())) {
continue;
@ -870,6 +940,7 @@ GfxInfoBase::EvaluateDownloadedBlacklist(nsTArray<GfxDriverInfo>& aDriverInfo)
nsIGfxInfo::FEATURE_WEBGL_ANGLE,
nsIGfxInfo::FEATURE_WEBGL_MSAA,
nsIGfxInfo::FEATURE_STAGEFRIGHT,
nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION,
0
};
@ -1019,6 +1090,24 @@ nsresult GfxInfoBase::GetInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aResu
return NS_OK;
}
const nsCString&
GfxInfoBase::GetApplicationVersion()
{
static nsAutoCString version;
static bool versionInitialized = false;
if (!versionInitialized) {
// If we fail to get the version, we will not try again.
versionInitialized = true;
// Get the version from xpcom/system/nsIXULAppInfo.idl
nsCOMPtr<nsIXULAppInfo> app = do_GetService("@mozilla.org/xre/app-info;1");
if (app) {
app->GetVersion(version);
}
}
return version;
}
void
GfxInfoBase::AddCollector(GfxInfoCollectorBase* collector)
{

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

@ -82,6 +82,9 @@ public:
virtual nsString Manufacturer() { return EmptyString(); }
virtual uint32_t OperatingSystemVersion() { return 0; }
// Convenience to get the application version
static const nsCString& GetApplicationVersion();
protected:
virtual ~GfxInfoBase();

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

@ -207,13 +207,15 @@ public:
HasMoreElements(bool* aRetvalue) override
{
MOZ_ASSERT(aRetvalue);
*aRetvalue = mFiles.Length() >= mIndex;
*aRetvalue = mIndex < mFiles.Length();
return NS_OK;
}
NS_IMETHOD
GetNext(nsISupports** aSupports) override
{
NS_ENSURE_TRUE(mIndex < mFiles.Length(), NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMBlob> blob = mFiles[mIndex++].get();
blob.forget(aSupports);
return NS_OK;

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

@ -825,6 +825,10 @@ static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
// If you are looking for NS_IMPL_CYCLE_COLLECTION_INHERITED_0(_class, _base)
// you should instead not declare any cycle collected stuff in _class, so it
// will just inherit the CC declarations from _base.
#define NS_IMPL_CYCLE_COLLECTION_INHERITED(_class, _base, ...) \
NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base) \