Merge inbound to m-c. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-12-10 16:01:20 -05:00
commit 1235490c83
106 changed files with 1042 additions and 879 deletions

View File

@ -1506,9 +1506,9 @@ pref("devtools.gcli.hideIntro", false);
pref("devtools.gcli.eagerHelper", 2);
// Alias to the script URLs for inject command.
pref("devtools.gcli.jquerySrc", "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js");
pref("devtools.gcli.lodashSrc", "http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js");
pref("devtools.gcli.underscoreSrc", "http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js");
pref("devtools.gcli.jquerySrc", "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js");
pref("devtools.gcli.lodashSrc", "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js");
pref("devtools.gcli.underscoreSrc", "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js");
// Remember the Web Console filters
pref("devtools.webconsole.filter.network", true);

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
//****************************************************************************//
// Constants & Enumeration Values
@ -1846,10 +1848,9 @@ var gApplicationsPane = {
return this._getIconURLForSystemDefault(aHandlerInfo);
case Ci.nsIHandlerInfo.useHelperApp:
let (preferredApp = aHandlerInfo.preferredApplicationHandler) {
if (this.isValidHandlerApp(preferredApp))
return this._getIconURLForHandlerApp(preferredApp);
}
let preferredApp = aHandlerInfo.preferredApplicationHandler;
if (this.isValidHandlerApp(preferredApp))
return this._getIconURLForHandlerApp(preferredApp);
break;
// This should never happen, but if preferredAction is set to some weird

View File

@ -52,11 +52,15 @@ XPCOMUtils.defineLazyGetter(this, "_stringBundle", function() {
.createBundle("chrome://browser/locale/taskbar.properties");
});
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
return PlacesUtils;
});
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
Components.utils.import("resource://gre/modules/NetUtil.jsm");
return NetUtil;
});
XPCOMUtils.defineLazyServiceGetter(this, "_idle",
"@mozilla.org/widget/idleservice;1",
@ -73,16 +77,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gHistoryObserver", function() {
return Object.freeze({
onClearHistory() {
WinTaskbarJumpList.update();
},
QueryInterface: XPCOMUtils.generateQI(Ci.nsINavHistoryObserver),
__noSuchMethod__: () => {}, // Catch all of the other notifications.
});
});
/**
* Global functions
*/
@ -152,7 +146,7 @@ this.WinTaskbarJumpList =
/**
* Startup, shutdown, and update
*/
*/
startup: function WTBJL_startup() {
// exit if this isn't win7 or higher.
@ -161,7 +155,7 @@ this.WinTaskbarJumpList =
// Win shell shortcut maintenance. If we've gone through an update,
// this will update any pinned taskbar shortcuts. Not specific to
// jump lists, but this was a convienent place to call it.
// jump lists, but this was a convienent place to call it.
try {
// dev builds may not have helper.exe, ignore failures.
this._shortcutMaintenance();
@ -192,6 +186,14 @@ this.WinTaskbarJumpList =
_shutdown: function WTBJL__shutdown() {
this._shuttingDown = true;
// Correctly handle a clear history on shutdown. If there are no
// entries be sure to empty all history lists. Luckily Places caches
// this value, so it's a pretty fast call.
if (!PlacesUtils.history.hasHistoryEntries) {
this.update();
}
this._free();
},
@ -251,13 +253,13 @@ this.WinTaskbarJumpList =
/**
* Taskbar api wrappers
*/
*/
_startBuild: function WTBJL__startBuild() {
var removedItems = Cc["@mozilla.org/array;1"].
createInstance(Ci.nsIMutableArray);
this._builder.abortListBuild();
if (this._builder.initListBuild(removedItems)) {
if (this._builder.initListBuild(removedItems)) {
// Prior to building, delete removed items from history.
this._clearHistory(removedItems);
return true;
@ -281,7 +283,7 @@ this.WinTaskbarJumpList =
task.args, task.iconIndex, null);
items.appendElement(item, false);
}, this);
if (items.length > 0)
this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
},
@ -292,6 +294,11 @@ this.WinTaskbarJumpList =
},
_buildFrequent: function WTBJL__buildFrequent() {
// If history is empty, just bail out.
if (!PlacesUtils.history.hasHistoryEntries) {
return;
}
// Windows supports default frequent and recent lists,
// but those depend on internal windows visit tracking
// which we don't populate. So we build our own custom
@ -317,7 +324,7 @@ this.WinTaskbarJumpList =
let title = aResult.title || aResult.uri;
let faviconPageUri = Services.io.newURI(aResult.uri, null, null);
let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
let shortcut = this._getHandlerAppItem(title, title, aResult.uri, 1,
faviconPageUri);
items.appendElement(shortcut, false);
this._frequentHashList.push(aResult.uri);
@ -327,6 +334,11 @@ this.WinTaskbarJumpList =
},
_buildRecent: function WTBJL__buildRecent() {
// If history is empty, just bail out.
if (!PlacesUtils.history.hasHistoryEntries) {
return;
}
var items = Cc["@mozilla.org/array;1"].
createInstance(Ci.nsIMutableArray);
// Frequent items will be skipped, so we select a double amount of
@ -374,8 +386,8 @@ this.WinTaskbarJumpList =
* Jump list item creation helpers
*/
_getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description,
args, iconIndex,
_getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description,
args, iconIndex,
faviconPageUri) {
var file = Services.dirsvc.get("XREExeF", Ci.nsILocalFile);
@ -457,7 +469,7 @@ this.WinTaskbarJumpList =
/**
* Prefs utilities
*/
*/
_refreshPrefs: function WTBJL__refreshPrefs() {
this._enabled = _prefs.getBoolPref(PREF_TASKBAR_ENABLED);
@ -469,7 +481,7 @@ this.WinTaskbarJumpList =
/**
* Init and shutdown utilities
*/
*/
_initTaskbar: function WTBJL__initTaskbar() {
this._builder = _taskbarService.createJumpListBuilder();
@ -486,14 +498,12 @@ this.WinTaskbarJumpList =
Services.obs.addObserver(this, "profile-before-change", false);
Services.obs.addObserver(this, "browser:purge-session-history", false);
_prefs.addObserver("", this, false);
PlacesUtils.history.addObserver(gHistoryObserver, false);
},
_freeObs: function WTBJL__freeObs() {
Services.obs.removeObserver(this, "profile-before-change");
Services.obs.removeObserver(this, "browser:purge-session-history");
_prefs.removeObserver("", this);
PlacesUtils.history.removeObserver(gHistoryObserver);
},
_updateTimer: function WTBJL__updateTimer() {

View File

@ -33,7 +33,7 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then
AC_MSG_ERROR([Cannot find an llvm-config binary for building a clang plugin])
fi
LLVM_CXXFLAGS=`$LLVMCONFIG --cxxflags`
LLVM_LDFLAGS=`$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader | xargs`
LLVM_LDFLAGS=`$LLVMCONFIG --ldflags --system-libs --libs core mc analysis asmparser mcparser bitreader option | xargs`
if test "${OS_ARCH}" = "Darwin"; then
CLANG_LDFLAGS="-lclangFrontend -lclangDriver -lclangSerialization"

View File

@ -12,12 +12,19 @@
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/DenseMap.h"
#include <memory>
#define CLANG_VERSION_FULL (CLANG_VERSION_MAJOR * 100 + CLANG_VERSION_MINOR)
using namespace llvm;
using namespace clang;
#if CLANG_VERSION_FULL >= 306
typedef std::unique_ptr<ASTConsumer> ASTConsumerPtr;
#else
typedef ASTConsumer *ASTConsumerPtr;
#endif
namespace {
using namespace clang::ast_matchers;
@ -25,7 +32,7 @@ class DiagnosticsMatcher {
public:
DiagnosticsMatcher();
ASTConsumer *makeASTConsumer() {
ASTConsumerPtr makeASTConsumer() {
return astMatcher.newASTConsumer();
}
@ -54,7 +61,7 @@ class MozChecker : public ASTConsumer, public RecursiveASTVisitor<MozChecker> {
public:
MozChecker(const CompilerInstance &CI) : Diag(CI.getDiagnostics()), CI(CI) {}
ASTConsumer *getOtherConsumer() {
ASTConsumerPtr getOtherConsumer() {
return matcher.makeASTConsumer();
}
@ -375,15 +382,24 @@ void DiagnosticsMatcher::NonHeapClassChecker::noteInferred(QualType T,
class MozCheckAction : public PluginASTAction {
public:
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef fileName) {
ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, StringRef fileName) override {
#if CLANG_VERSION_FULL >= 306
std::unique_ptr<MozChecker> checker(make_unique<MozChecker>(CI));
std::vector<std::unique_ptr<ASTConsumer>> consumers;
consumers.push_back(std::move(checker));
consumers.push_back(checker->getOtherConsumer());
return make_unique<MultiplexConsumer>(std::move(consumers));
#else
MozChecker *checker = new MozChecker(CI);
ASTConsumer *consumers[] = { checker, checker->getOtherConsumer() };
return new MultiplexConsumer(consumers);
#endif
}
bool ParseArgs(const CompilerInstance &CI,
const std::vector<std::string> &args) {
const std::vector<std::string> &args) override {
return true;
}
};

View File

@ -71,7 +71,7 @@ GCONF_VERSION=1.2.1
GIO_VERSION=2.20
STARTUP_NOTIFICATION_VERSION=0.8
DBUS_VERSION=0.60
SQLITE_VERSION=3.8.7.2
SQLITE_VERSION=3.8.7.4
MSMANIFEST_TOOL=

View File

@ -1,4 +1,4 @@
This is SQLite 3.8.7.2
This is SQLite 3.8.7.4
See http://www.sqlite.org/ for more info.

View File

@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.7.2. By combining all the individual C code files into this
** version 3.8.7.4. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@ -231,9 +231,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.8.7.2"
#define SQLITE_VERSION "3.8.7.4"
#define SQLITE_VERSION_NUMBER 3008007
#define SQLITE_SOURCE_ID "2014-11-18 20:57:56 2ab564bf9655b7c7b97ab85cafc8a48329b27f93"
#define SQLITE_SOURCE_ID "2014-12-09 01:34:36 f66f7a17b78ba617acde90fc810107f34f1a1f2e"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -11537,7 +11537,7 @@ struct Expr {
/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
#define EP_Error 0x000008 /* Expression contains one or more errors */
@ -11557,6 +11557,7 @@ struct Expr {
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_Constant 0x080000 /* Node is a constant */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
/*
** These macros can be used to test, set, or clear bits in the
@ -79504,6 +79505,10 @@ static int lookupName(
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
pExpr->pTab = pMatch->pTab;
assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
if( (pMatch->jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
pSchema = pExpr->pTab->pSchema;
}
} /* if( pSrcList ) */
@ -82040,7 +82045,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
assert( p->pTab!=0 );
return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
return ExprHasProperty(p, EP_CanBeNull) ||
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
@ -87415,7 +87421,7 @@ static void initAvgEq(Index *pIdx){
i64 nSum100 = 0; /* Number of terms contributing to sumEq */
i64 nDist100; /* Number of distinct values in index */
if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
nRow = pFinal->anLt[iCol];
nDist100 = (i64)100 * pFinal->anDLt[iCol];
nSample--;
@ -125888,6 +125894,16 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
for(j=0; j<db->nDb; j++){
struct Db *pDb = &db->aDb[j];
if( pDb->pBt ){
if( pDb->pSchema ){
/* Must clear the KeyInfo cache. See ticket [e4a18565a36884b00edf] */
sqlite3BtreeEnter(pDb->pBt);
for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3KeyInfoUnref(pIdx->pKeyInfo);
pIdx->pKeyInfo = 0;
}
sqlite3BtreeLeave(pDb->pBt);
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 ){
@ -127535,7 +127551,9 @@ static int openDatabase(
sqlite3Error(db, rc);
goto opendb_out;
}
sqlite3BtreeEnter(db->aDb[0].pBt);
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
sqlite3BtreeLeave(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
/* The default safety_level for the main database is 'full'; for the temp

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.8.7.2"
#define SQLITE_VERSION "3.8.7.4"
#define SQLITE_VERSION_NUMBER 3008007
#define SQLITE_SOURCE_ID "2014-11-18 20:57:56 2ab564bf9655b7c7b97ab85cafc8a48329b27f93"
#define SQLITE_SOURCE_ID "2014-12-09 01:34:36 f66f7a17b78ba617acde90fc810107f34f1a1f2e"
/*
** CAPI3REF: Run-Time Library Version Numbers

View File

@ -326,13 +326,12 @@ AutoJSAPI::~AutoJSAPI()
errorGlobal = xpc::PrivilegedJunkScope();
JSAutoCompartment ac(cx(), errorGlobal);
nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
const char *category = nsContentUtils::IsCallerChrome() ? "chrome javascript"
: "content javascript";
JS::Rooted<JS::Value> exn(cx());
js::ErrorReport jsReport(cx());
if (StealException(&exn) && jsReport.init(cx(), exn)) {
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(jsReport.report(), jsReport.message(), category,
xpcReport->Init(jsReport.report(), jsReport.message(),
nsContentUtils::IsCallerChrome(),
win ? win->WindowID() : 0);
if (win) {
DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
@ -483,10 +482,9 @@ WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aR
{
MOZ_ASSERT(JSREPORT_IS_WARNING(aRep->flags));
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
const char* category = nsContentUtils::IsCallerChrome() ? "chrome javascript"
: "content javascript";
nsPIDOMWindow* win = xpc::WindowGlobalOrNull(JS::CurrentGlobalOrNull(aCx));
xpcReport->Init(aRep, aMessage, category, win ? win->WindowID() : 0);
xpcReport->Init(aRep, aMessage, nsContentUtils::IsCallerChrome(),
win ? win->WindowID() : 0);
xpcReport->LogToConsole();
}

View File

@ -23,13 +23,13 @@ namespace dom {
// JSContext.
// Accept strings.
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const nsAString& aArgument,
JS::MutableHandle<JS::Value> aValue);
// Accept booleans.
inline bool
MOZ_WARN_UNUSED_RESULT inline bool
ToJSValue(JSContext* aCx,
bool aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -125,7 +125,7 @@ ToJSValue(JSContext* aCx,
}
// Accept CallbackObjects
inline bool
MOZ_WARN_UNUSED_RESULT inline bool
ToJSValue(JSContext* aCx,
CallbackObject& aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -141,6 +141,7 @@ ToJSValue(JSContext* aCx,
// Accept objects that inherit from nsWrapperCache (e.g. most
// DOM objects).
template <class T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<IsBaseOf<nsWrapperCache, T>::value, bool>::Type
ToJSValue(JSContext* aCx,
T& aArgument,
@ -156,6 +157,7 @@ ToJSValue(JSContext* aCx,
// Accept typed arrays built from appropriate nsTArray values
template<typename T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<IsBaseOf<AllTypedArraysBase, T>::value, bool>::Type
ToJSValue(JSContext* aCx,
const TypedArrayCreator<T>& aArgument,
@ -184,6 +186,7 @@ ISupportsToJSValue(JSContext* aCx,
// Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
// nsIDOMFile).
template <class T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&
!IsBaseOf<CallbackObject, T>::value &&
IsBaseOf<nsISupports, T>::value, bool>::Type
@ -199,7 +202,7 @@ ToJSValue(JSContext* aCx,
// Accept nsRefPtr/nsCOMPtr
template <typename T>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const nsCOMPtr<T>& aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -208,7 +211,7 @@ ToJSValue(JSContext* aCx,
}
template <typename T>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const nsRefPtr<T>& aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -218,6 +221,7 @@ ToJSValue(JSContext* aCx,
// Accept WebIDL dictionaries
template <class T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<IsBaseOf<DictionaryBase, T>::value, bool>::Type
ToJSValue(JSContext* aCx,
const T& aArgument,
@ -227,7 +231,7 @@ ToJSValue(JSContext* aCx,
}
// Accept existing JS values (which may not be same-compartment with us
inline bool
MOZ_WARN_UNUSED_RESULT inline bool
ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
JS::MutableHandle<JS::Value> aValue)
{
@ -236,7 +240,7 @@ ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
}
// Accept existing JS values on the Heap (which may not be same-compartment with us
inline bool
MOZ_WARN_UNUSED_RESULT inline bool
ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
@ -245,7 +249,7 @@ ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
}
// Accept existing rooted JS values (which may not be same-compartment with us
inline bool
MOZ_WARN_UNUSED_RESULT inline bool
ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
@ -255,7 +259,7 @@ ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
// Accept nsresult, for use in rejections, and create an XPCOM
// exception object representing that nsresult.
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
nsresult aArgument,
JS::MutableHandle<JS::Value> aValue);
@ -263,13 +267,14 @@ ToJSValue(JSContext* aCx,
// Accept ErrorResult, for use in rejections, and create an exception
// representing the failure. Note, the ErrorResult must indicate a failure
// with aArgument.Failure() returning true.
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
ErrorResult& aArgument,
JS::MutableHandle<JS::Value> aValue);
// Accept pointers to other things we accept
template <typename T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<IsPointer<T>::value, bool>::Type
ToJSValue(JSContext* aCx,
T aArgument,
@ -280,7 +285,7 @@ ToJSValue(JSContext* aCx,
// Accept arrays of other things we accept
template <typename T>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
T* aArguments,
size_t aLength,
@ -307,7 +312,7 @@ ToJSValue(JSContext* aCx,
}
template <typename T>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const nsTArray<T>& aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -317,7 +322,7 @@ ToJSValue(JSContext* aCx,
}
template <typename T>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const FallibleTArray<T>& aArgument,
JS::MutableHandle<JS::Value> aValue)
@ -327,7 +332,7 @@ ToJSValue(JSContext* aCx,
}
template <typename T, int N>
bool
MOZ_WARN_UNUSED_RESULT bool
ToJSValue(JSContext* aCx,
const T(&aArgument)[N],
JS::MutableHandle<JS::Value> aValue)

View File

@ -1003,9 +1003,8 @@ ContactDB.prototype = {
}
// Invalidate the entire cache. It will be incrementally regenerated on demand
// See getCacheForQuery
let (getAllStore = txn.objectStore(SAVED_GETALL_STORE_NAME)) {
getAllStore.clear().onerror = errorCb;
}
let getAllStore = txn.objectStore(SAVED_GETALL_STORE_NAME);
getAllStore.clear().onerror = errorCb;
}.bind(this);
this.incrementRevision(txn);

View File

@ -3233,7 +3233,11 @@ ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
PPrintingParent*
ContentParent::AllocPPrintingParent()
{
#ifdef NS_PRINTING
return new PrintingParent();
#else
return nullptr;
#endif
}
bool

View File

@ -14,6 +14,8 @@
#include "mozilla/Base64.h"
#include "nsIRandomGenerator.h"
#include "nsIServiceManager.h"
#include "MediaTaskQueue.h"
#include <stdint.h>
namespace mozilla {
@ -269,5 +271,24 @@ GenerateRandomPathName(nsCString& aOutSalt, uint32_t aLength)
return NS_OK;
}
class CreateTaskQueueTask : public nsRunnable {
public:
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool());
return NS_OK;
}
nsRefPtr<MediaTaskQueue> mTaskQueue;
};
already_AddRefed<MediaTaskQueue>
CreateMediaDecodeTaskQueue()
{
// We must create the MediaTaskQueue/SharedThreadPool on the main thread.
nsRefPtr<CreateTaskQueueTask> t(new CreateTaskQueueTask());
nsresult rv = NS_DispatchToMainThread(t, NS_DISPATCH_SYNC);
NS_ENSURE_SUCCESS(rv, nullptr);
return t->mTaskQueue.forget();
}
} // end namespace mozilla

View File

@ -263,6 +263,11 @@ ExtractH264CodecDetails(const nsAString& aCodecs,
nsresult
GenerateRandomPathName(nsCString& aOutSalt, uint32_t aLength);
class MediaTaskQueue;
already_AddRefed<MediaTaskQueue>
CreateMediaDecodeTaskQueue();
} // end namespace mozilla
#endif

View File

@ -319,7 +319,8 @@ bool
MP4Reader::IsSupportedVideoMimeType(const char* aMimeType)
{
return (!strcmp(aMimeType, "video/mp4") ||
!strcmp(aMimeType, "video/avc")) &&
!strcmp(aMimeType, "video/avc") ||
!strcmp(aMimeType, "video/x-vnd.on2.vp6")) &&
mPlatform->SupportsVideoMimeType(aMimeType);
}
@ -339,11 +340,6 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
// To decode, we need valid video and a place to put it.
mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasValidVideo() &&
mDecoder->GetImageContainer();
const VideoDecoderConfig& video = mDemuxer->VideoConfig();
// If we have video, we *only* allow H.264 to be decoded.
if (mInfo.mVideo.mHasVideo && strcmp(video.mime_type, "video/avc")) {
return NS_ERROR_FAILURE;
}
mInfo.mAudio.mHasAudio = mAudio.mActive = mDemuxer->HasValidAudio();

View File

@ -75,26 +75,6 @@ PlatformDecoderModule::Init()
}
#ifdef MOZ_EME
class CreateTaskQueueTask : public nsRunnable {
public:
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool());
return NS_OK;
}
nsRefPtr<MediaTaskQueue> mTaskQueue;
};
static already_AddRefed<MediaTaskQueue>
CreateTaskQueue()
{
// We must create the MediaTaskQueue/SharedThreadPool on the main thread.
nsRefPtr<CreateTaskQueueTask> t(new CreateTaskQueueTask());
nsresult rv = NS_DispatchToMainThread(t, NS_DISPATCH_SYNC);
NS_ENSURE_SUCCESS(rv, nullptr);
return t->mTaskQueue.forget();
}
/* static */
PlatformDecoderModule*
PlatformDecoderModule::CreateCDMWrapper(CDMProxy* aProxy,
@ -123,8 +103,7 @@ PlatformDecoderModule::CreateCDMWrapper(CDMProxy* aProxy,
return new EMEDecoderModule(aProxy,
pdm.forget(),
cdmDecodesAudio,
cdmDecodesVideo,
CreateTaskQueue());
cdmDecodesVideo);
}
#endif

View File

@ -20,6 +20,7 @@
#include "mozilla/EMELog.h"
#include "EMEH264Decoder.h"
#include "EMEAudioDecoder.h"
#include "mozilla/unused.h"
#include <string>
namespace mozilla {
@ -31,19 +32,19 @@ public:
EMEDecryptor(MediaDataDecoder* aDecoder,
MediaDataDecoderCallback* aCallback,
MediaTaskQueue* aTaskQueue,
CDMProxy* aProxy)
: mDecoder(aDecoder)
, mCallback(aCallback)
, mTaskQueue(aTaskQueue)
, mTaskQueue(CreateMediaDecodeTaskQueue())
, mProxy(aProxy)
{
}
virtual nsresult Init() MOZ_OVERRIDE {
return mTaskQueue->SyncDispatch(
NS_NewRunnableMethod(mDecoder,
&MediaDataDecoder::Init));
nsresult rv = mTaskQueue->SyncDispatch(
NS_NewRunnableMethod(mDecoder, &MediaDataDecoder::Init));
unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
class RedeliverEncryptedInput : public nsRunnable {
@ -123,40 +124,44 @@ public:
}
void Decrypted(mp4_demuxer::MP4Sample* aSample) {
mTaskQueue->Dispatch(
nsresult rv = mTaskQueue->Dispatch(
NS_NewRunnableMethodWithArg<mp4_demuxer::MP4Sample*>(
mDecoder,
&MediaDataDecoder::Input,
aSample));
unused << NS_WARN_IF(NS_FAILED(rv));
}
virtual nsresult Flush() MOZ_OVERRIDE {
mTaskQueue->SyncDispatch(
nsresult rv = mTaskQueue->SyncDispatch(
NS_NewRunnableMethod(
mDecoder,
&MediaDataDecoder::Flush));
return NS_OK;
unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
virtual nsresult Drain() MOZ_OVERRIDE {
mTaskQueue->Dispatch(
nsresult rv = mTaskQueue->Dispatch(
NS_NewRunnableMethod(
mDecoder,
&MediaDataDecoder::Drain));
return NS_OK;
unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
virtual nsresult Shutdown() MOZ_OVERRIDE {
mTaskQueue->SyncDispatch(
nsresult rv = mTaskQueue->SyncDispatch(
NS_NewRunnableMethod(
mDecoder,
&MediaDataDecoder::Shutdown));
unused << NS_WARN_IF(NS_FAILED(rv));
mDecoder = nullptr;
mTaskQueue->BeginShutdown();
mTaskQueue->AwaitShutdownAndIdle();
mTaskQueue = nullptr;
mProxy = nullptr;
return NS_OK;
return rv;
}
private:
@ -170,11 +175,9 @@ private:
EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy,
PlatformDecoderModule* aPDM,
bool aCDMDecodesAudio,
bool aCDMDecodesVideo,
already_AddRefed<MediaTaskQueue> aTaskQueue)
bool aCDMDecodesVideo)
: mProxy(aProxy)
, mPDM(aPDM)
, mTaskQueue(aTaskQueue)
, mCDMDecodesAudio(aCDMDecodesAudio)
, mCDMDecodesVideo(aCDMDecodesVideo)
{
@ -190,8 +193,6 @@ EMEDecoderModule::Shutdown()
if (mPDM) {
return mPDM->Shutdown();
}
mTaskQueue->BeginShutdown();
mTaskQueue->AwaitShutdownAndIdle();
return NS_OK;
}
@ -227,7 +228,6 @@ EMEDecoderModule::CreateVideoDecoder(const VideoDecoderConfig& aConfig,
nsRefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(decoder,
aCallback,
mTaskQueue,
mProxy));
return emeDecoder.forget();
}
@ -258,7 +258,6 @@ EMEDecoderModule::CreateAudioDecoder(const AudioDecoderConfig& aConfig,
nsRefPtr<MediaDataDecoder> emeDecoder(new EMEDecryptor(decoder,
aCallback,
mTaskQueue,
mProxy));
return emeDecoder.forget();
}

View File

@ -24,8 +24,7 @@ public:
EMEDecoderModule(CDMProxy* aProxy,
PlatformDecoderModule* aPDM,
bool aCDMDecodesAudio,
bool aCDMDecodesVideo,
already_AddRefed<MediaTaskQueue> aDecodeTaskQueue);
bool aCDMDecodesVideo);
virtual ~EMEDecoderModule();

View File

@ -52,6 +52,11 @@ public:
{
return FFmpegAudioDecoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE;
}
virtual bool SupportsVideoMimeType(const char* aMimeType) MOZ_OVERRIDE
{
return FFmpegH264Decoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE;
}
};
} // namespace mozilla

View File

@ -27,7 +27,7 @@ FFmpegH264Decoder<LIBAV_VER>::FFmpegH264Decoder(
MediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
const mp4_demuxer::VideoDecoderConfig& aConfig,
ImageContainer* aImageContainer)
: FFmpegDataDecoder(aTaskQueue, AV_CODEC_ID_H264)
: FFmpegDataDecoder(aTaskQueue, GetCodecId(aConfig.mime_type))
, mCallback(aCallback)
, mImageContainer(aImageContainer)
{
@ -174,6 +174,10 @@ FFmpegH264Decoder<LIBAV_VER>::AllocateYUV420PVideoBuffer(
bool needAlign = aCodecContext->codec->capabilities & CODEC_CAP_DR1;
int edgeWidth = needAlign ? avcodec_get_edge_width() : 0;
int decodeWidth = aCodecContext->width + edgeWidth * 2;
// Make sure the decodeWidth is a multiple of 32, so a UV plane stride will be
// a multiple of 16. FFmpeg uses SSE2 accelerated code to copy a frame line by
// line.
decodeWidth = (decodeWidth + 31) & ~31;
int decodeHeight = aCodecContext->height + edgeWidth * 2;
if (needAlign) {
@ -275,4 +279,18 @@ FFmpegH264Decoder<LIBAV_VER>::~FFmpegH264Decoder()
MOZ_COUNT_DTOR(FFmpegH264Decoder);
}
AVCodecID
FFmpegH264Decoder<LIBAV_VER>::GetCodecId(const char* aMimeType)
{
if (!strcmp(aMimeType, "video/avc")) {
return AV_CODEC_ID_H264;
}
if (!strcmp(aMimeType, "video/x-vnd.on2.vp6")) {
return AV_CODEC_ID_VP6F;
}
return AV_CODEC_ID_NONE;
}
} // namespace mozilla

View File

@ -40,6 +40,7 @@ public:
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Flush() MOZ_OVERRIDE;
static AVCodecID GetCodecId(const char* aMimeType);
private:
void DecodeFrame(mp4_demuxer::MP4Sample* aSample);

View File

@ -16,6 +16,7 @@ extern "C" {
}
#if LIBAVCODEC_VERSION_MAJOR < 55
#define AV_CODEC_ID_VP6F CODEC_ID_VP6F
#define AV_CODEC_ID_H264 CODEC_ID_H264
#define AV_CODEC_ID_AAC CODEC_ID_AAC
#define AV_CODEC_ID_MP3 CODEC_ID_MP3

View File

@ -22,7 +22,7 @@
# do ok(true, "Type not supported") and stop the test.
[DEFAULT]
skip-if = buildapp == 'mulet' || (os == 'win' && contentSandbox != 'off') # contentSandbox(Bug 1042735)
skip-if = buildapp == 'mulet' || (os == 'win' && strictContentSandbox) # strictContentSandbox (Bug 1042735)
support-files =
320x240.ogv
320x240.ogv^headers^

View File

@ -1,6 +1,6 @@
[DEFAULT]
# contentSandbox - bug 1042735, Android 2.3 - bug 981881
skip-if = (os == 'win' && contentSandbox != 'off') || android_version == '10'
# strictContentSandbox - bug 1042735, Android 2.3 - bug 981881
skip-if = (os == 'win' && strictContentSandbox) || android_version == '10'
support-files =
head.js
constraints.js

View File

@ -1,5 +1,5 @@
[DEFAULT]
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && (toolkit != 'gonk' || debug)) || (os == 'win' && contentSandbox != 'off') #b2g-debug,b2g-desktop(bug 916135); contentSandbox(Bug 1042735)
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && (toolkit != 'gonk' || debug)) || (os == 'win' && strictContentSandbox) #b2g-debug,b2g-desktop(bug 916135); strictContentSandbox(Bug 1042735)
support-files =
audio-expected.wav
audio-mono-expected-2.wav

View File

@ -14,7 +14,7 @@ DIRS += [
'commandhandler',
]
if CONFIG['MOZ_XUL'] and CONFIG['NS_PRINTING']:
if CONFIG['MOZ_XUL']:
DIRS += ['printingui']
DIRS += ['build']

View File

@ -8,13 +8,14 @@ EXPORTS.mozilla.embedding.printingui += [
'PrintingParent.h',
]
UNIFIED_SOURCES += [
'nsPrintingPromptServiceProxy.cpp',
'PrintDataUtils.cpp',
'PrintingParent.cpp',
'PrintProgressDialogChild.cpp',
'PrintProgressDialogParent.cpp',
]
if CONFIG['NS_PRINTING']:
UNIFIED_SOURCES += [
'nsPrintingPromptServiceProxy.cpp',
'PrintDataUtils.cpp',
'PrintingParent.cpp',
'PrintProgressDialogChild.cpp',
'PrintProgressDialogParent.cpp',
]
IPDL_SOURCES += [
'PPrinting.ipdl',

View File

@ -8,9 +8,10 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
DIRS += ['ipc']
if toolkit == 'windows':
DIRS += ['win']
elif toolkit == 'cocoa':
DIRS += ['mac']
elif CONFIG['MOZ_PDF_PRINTING']:
DIRS += ['unixshared']
if CONFIG['NS_PRINTING']:
if toolkit == 'windows':
DIRS += ['win']
elif toolkit == 'cocoa':
DIRS += ['mac']
elif CONFIG['MOZ_PDF_PRINTING']:
DIRS += ['unixshared']

View File

@ -8,6 +8,7 @@
#include "gfxPoint.h" // for gfxIntSize
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
#include "mozilla/gfx/Logging.h" // for gfxDebug
#include "mozilla/gfx/Tools.h" // for GetAlignedStride, etc
#include "mozilla/mozalloc.h" // for operator delete, etc
@ -34,11 +35,11 @@ using namespace gfx;
namespace {
struct SurfaceBufferInfo
{
uint32_t width;
uint32_t height;
int32_t width;
int32_t height;
SurfaceFormat format;
static uint32_t GetOffset()
static int32_t GetOffset()
{
return GetAlignedStride<16>(sizeof(SurfaceBufferInfo));
}
@ -65,19 +66,39 @@ ImageDataSerializer::InitializeBufferInfo(IntSize aSize,
Validate();
}
static inline uint32_t
ComputeStride(SurfaceFormat aFormat, uint32_t aWidth)
static inline int32_t
ComputeStride(SurfaceFormat aFormat, int32_t aWidth)
{
return GetAlignedStride<4>(BytesPerPixel(aFormat) * aWidth);
CheckedInt<int32_t> size = BytesPerPixel(aFormat);
size *= aWidth;
if (!size.isValid() || size.value() <= 0) {
gfxDebug() << "ComputeStride overflow " << aWidth;
return 0;
}
return GetAlignedStride<4>(size.value());
}
uint32_t
ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
SurfaceFormat aFormat)
SurfaceFormat aFormat)
{
uint32_t bufsize = aSize.height * ComputeStride(aFormat, aSize.width);
MOZ_ASSERT(aSize.height >= 0 && aSize.width >= 0);
if (aSize.height <= 0 || aSize.width <= 0) {
gfxDebug() << "Non-positive image buffer size request " << aSize.width << "x" << aSize.height;
return 0;
}
CheckedInt<int32_t> bufsize = ComputeStride(aFormat, aSize.width);
bufsize *= aSize.height;
if (!bufsize.isValid() || bufsize.value() <= 0) {
gfxDebug() << "Buffer size overflow " << aSize.width << "x" << aSize.height;
return 0;
}
return SurfaceBufferInfo::GetOffset()
+ GetAlignedStride<16>(bufsize);
+ GetAlignedStride<16>(bufsize.value());
}
void

View File

@ -8,6 +8,7 @@
#include "gfx2DGlue.h" // for ToIntSize
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Logging.h" // for gfxDebug
#include "mozilla/gfx/Types.h"
#include "mozilla/mozalloc.h" // for operator delete
#include "yuv_convert.h" // for ConvertYCbCrToRGB32, etc
@ -73,7 +74,7 @@ void YCbCrImageDataDeserializerBase::Validate()
info->mYStride,
IntSize(info->mCbCrWidth, info->mCbCrHeight),
info->mCbCrStride);
mIsValid = requiredSize <= mDataSize;
mIsValid = requiredSize && requiredSize <= mDataSize;
}
@ -140,10 +141,15 @@ static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
// Minimum required shmem size in bytes
size_t
YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
uint32_t aYStride,
const gfx::IntSize& aCbCrSize,
uint32_t aCbCrStride)
uint32_t aYStride,
const gfx::IntSize& aCbCrSize,
uint32_t aCbCrStride)
{
MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
if (aYSize.height <= 0 || aYSize.width <= 0 || aCbCrSize.height <= 0 || aCbCrSize.width <= 0) {
gfxDebug() << "Non-positive YCbCr buffer size request " << aYSize.height << "x" << aYSize.width << ", " << aCbCrSize.height << "x" << aCbCrSize.width;
return 0;
}
return ComputeOffset(aYSize.height, aYStride)
+ 2 * ComputeOffset(aCbCrSize.height, aCbCrStride)
+ MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));

View File

@ -8,6 +8,7 @@
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/ShadowLayerUtilsX11.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h"
#include "gfxXlibSurface.h"
#include "gfx2DGlue.h"
@ -38,6 +39,8 @@ TextureClientX11::CreateSimilar(TextureFlags aFlags,
{
RefPtr<TextureClient> tex = new TextureClientX11(mAllocator, mFormat, mFlags);
// mSize is guaranteed to be non-negative
MOZ_ASSERT(mSize.width >= 0 && mSize.height >= 0);
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
return nullptr;
}
@ -107,6 +110,11 @@ TextureClientX11::AllocateForSurface(IntSize aSize, TextureAllocationFlags aText
MOZ_ASSERT(!IsAllocated());
//MOZ_ASSERT(mFormat != gfx::FORMAT_YUV, "This TextureClient cannot use YCbCr data");
MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
if (aSize.width <= 0 || aSize.height <= 0) {
gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height;
return false;
}
gfxContentType contentType = ContentForFormat(mFormat);
nsRefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, contentType);
if (!surface || surface->GetType() != gfxSurfaceType::Xlib) {

View File

@ -17,6 +17,7 @@
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "ImageContainer.h" // for PlanarYCbCrData, etc
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h" // for gfxDebug
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/layers/PTextureChild.h"
#include "SharedSurface.h"
@ -584,8 +585,10 @@ bool
ShmemTextureClient::Allocate(uint32_t aSize)
{
MOZ_ASSERT(mValid);
SharedMemory::SharedMemoryType memType = OptimalShmemType();
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
if (aSize > 0) {
SharedMemory::SharedMemoryType memType = OptimalShmemType();
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
}
return mAllocated;
}
@ -716,8 +719,12 @@ BufferTextureClient::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFla
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV, "This textureClient cannot use YCbCr data");
MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
int bufSize
= ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
if (aSize.width <= 0 || aSize.height <= 0) {
gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
return false;
}
uint32_t bufSize = ImageDataSerializer::ComputeMinBufferSize(aSize, mFormat);
if (!Allocate(bufSize)) {
return false;
}

View File

@ -111,6 +111,9 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
gfx::SurfaceFormat format =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
size_t size = ImageDataSerializer::ComputeMinBufferSize(aSize, format);
if (!size) {
return false;
}
if (IsSameProcess()) {
uint8_t *data = new (std::nothrow) uint8_t[size];
if (!data) {

View File

@ -8,6 +8,7 @@
#include "base/task.h" // for NewRunnableFunction, etc
#include "base/thread.h" // for Thread
#include "base/tracked.h" // for FROM_HERE
#include "mozilla/gfx/Logging.h" // for gfxDebug
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/layers/SharedBufferManagerParent.h"
#include "mozilla/StaticPtr.h" // for StaticRefPtr
@ -239,6 +240,11 @@ SharedBufferManagerChild::AllocGrallocBuffer(const gfx::IntSize& aSize,
const uint32_t& aUsage,
mozilla::layers::MaybeMagicGrallocBufferHandle* aBuffer)
{
if (aSize.width <= 0 || aSize.height <= 0) {
gfxDebug() << "Asking for gralloc of invalid size " << aSize.width << "x" << aSize.height;
return false;
}
if (InSharedBufferManagerChildThread()) {
return SharedBufferManagerChild::AllocGrallocBufferNow(aSize, aFormat, aUsage, aBuffer);
}
@ -264,6 +270,9 @@ SharedBufferManagerChild::AllocGrallocBufferNow(const IntSize& aSize,
const uint32_t& aUsage,
mozilla::layers::MaybeMagicGrallocBufferHandle* aHandle)
{
// These are protected functions, we can just assert and ask the caller to test
MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
#ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
mozilla::layers::MaybeMagicGrallocBufferHandle handle;
SendAllocateGrallocBuffer(aSize, aFormat, aUsage, &handle);

View File

@ -106,6 +106,9 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
{
NS_ABORT_IF_FALSE(!mTextureClient, "This image already has allocated data");
size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize);
if (!size) {
return nullptr;
}
mTextureClient = TextureClient::CreateWithBufferSize(mCompositable->GetForwarder(),
gfx::SurfaceFormat::YUV, size,
@ -219,7 +222,7 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
mData.mCbCrSize);
mSize = mData.mPicSize;
return true;
return mBufferSize > 0;
}
} // namespace

View File

@ -12,6 +12,7 @@
#include <algorithm>
#include "mozilla/Attributes.h" // for MOZ_THIS_IN_INITIALIZER_LIST
#include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h"
#include "mozilla/Move.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
@ -385,6 +386,8 @@ public:
MOZ_ASSERT(mLockedCost <= mMaxCost, "Locked more than we can hold?");
} else {
mCosts.InsertElementSorted(costEntry);
// This may fail during XPCOM shutdown, so we need to ensure the object is
// tracked before calling RemoveObject in StopTracking.
mExpirationTracker.AddObject(aSurface);
}
}
@ -401,7 +404,14 @@ public:
MOZ_ASSERT(!mCosts.Contains(costEntry),
"Shouldn't have a cost entry for a locked surface");
} else {
mExpirationTracker.RemoveObject(aSurface);
if (MOZ_LIKELY(aSurface->GetExpirationState()->IsTracked())) {
mExpirationTracker.RemoveObject(aSurface);
} else {
// Our call to AddObject must have failed in StartTracking; most likely
// we're in XPCOM shutdown right now.
NS_WARNING("Not expiration-tracking an unlocked surface!");
}
DebugOnly<bool> foundInCosts = mCosts.RemoveElementSorted(costEntry);
MOZ_ASSERT(foundInCosts, "Lost track of costs for this surface");
}

View File

@ -116,26 +116,31 @@ static const unsigned PushedRetAddr = 0;
# endif
static const unsigned PushedFP = 10;
static const unsigned StoredFP = 14;
static const unsigned PostStorePrePopFP = 0;
#elif defined(JS_CODEGEN_X86)
# if defined(DEBUG)
static const unsigned PushedRetAddr = 0;
# endif
static const unsigned PushedFP = 8;
static const unsigned StoredFP = 11;
static const unsigned PostStorePrePopFP = 0;
#elif defined(JS_CODEGEN_ARM)
static const unsigned PushedRetAddr = 4;
static const unsigned PushedFP = 16;
static const unsigned StoredFP = 20;
static const unsigned PostStorePrePopFP = 4;
#elif defined(JS_CODEGEN_MIPS)
static const unsigned PushedRetAddr = 8;
static const unsigned PushedFP = 24;
static const unsigned StoredFP = 28;
static const unsigned PostStorePrePopFP = 4;
#elif defined(JS_CODEGEN_NONE)
# if defined(DEBUG)
static const unsigned PushedRetAddr = 0;
# endif
static const unsigned PushedFP = 1;
static const unsigned StoredFP = 1;
static const unsigned PostStorePrePopFP = 0;
#else
# error "Unknown architecture!"
#endif
@ -221,21 +226,29 @@ GenerateProfilingEpilogue(MacroAssembler &masm, unsigned framePushed, AsmJSExit:
if (reason != AsmJSExit::None)
masm.store32(Imm32(AsmJSExit::None), Address(scratch, AsmJSActivation::offsetOfExitReason()));
// AsmJSProfilingFrameIterator assumes that there is only a single 'ret'
// instruction (whose offset is recorded by profilingReturn) after the store
// which sets AsmJSActivation::fp to the caller's fp. Use AutoForbidPools to
// ensure that a pool is not inserted before the return (a pool inserts a
// jump instruction).
// AsmJSProfilingFrameIterator assumes fixed offsets of the last few
// instructions from profilingReturn, so AutoForbidPools to ensure that
// unintended instructions are not automatically inserted.
{
#if defined(JS_CODEGEN_ARM)
AutoForbidPools afp(&masm, /* number of instructions in scope = */ 3);
AutoForbidPools afp(&masm, /* number of instructions in scope = */ 4);
#endif
// sp protects the stack from clobber via asynchronous signal handlers
// and the async interrupt exit. Since activation.fp can be read at any
// time and still points to the current frame, be careful to only update
// sp after activation.fp has been repointed to the caller's frame.
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
masm.pop(scratch2);
masm.loadPtr(Address(StackPointer, 0), scratch2);
masm.storePtr(scratch2, Address(scratch, AsmJSActivation::offsetOfFP()));
DebugOnly<uint32_t> prePop = masm.currentOffset();
masm.add32(Imm32(4), StackPointer);
MOZ_ASSERT(PostStorePrePopFP == masm.currentOffset() - prePop);
#else
masm.pop(Address(scratch, AsmJSActivation::offsetOfFP()));
MOZ_ASSERT(PostStorePrePopFP == 0);
#endif
masm.bind(profilingReturn);
masm.ret();
}
@ -439,9 +452,9 @@ AsmJSProfilingFrameIterator::initFromFP(const AsmJSActivation &activation)
return;
}
// Since we don't have the pc for fp, start unwinding at the caller of fp,
// whose pc we do have via fp->returnAddress. This means that the innermost
// frame is skipped but this is fine because:
// Since we don't have the pc for fp, start unwinding at the caller of fp
// (ReturnAddressFromFP(fp)). This means that the innermost frame is
// skipped. This is fine because:
// - for FFI calls, the innermost frame is a thunk, so the first frame that
// shows up is the function calling the FFI;
// - for Math and other builtin calls, when profiling is activated, we
@ -472,13 +485,13 @@ AsmJSProfilingFrameIterator::initFromFP(const AsmJSActivation &activation)
MOZ_CRASH("Unexpected CodeRange kind");
}
// Since, despite the above reasoning for skipping a frame, we do want FFI
// Despite the above reasoning for skipping a frame, we do actually want FFI
// trampolines and interrupts to show up in the profile (so they can
// accumulate self time and explain performance faults), an "exit reason" is
// stored on all the paths leaving asm.js and the iterator logic treats this
// reason as its own frame. If we have exited asm.js code without setting an
// exit reason, the reason will be None and this means the code was
// asynchronously interrupted.
// accumulate self time and explain performance faults). To do this, an
// "exit reason" is stored on all the paths leaving asm.js and this iterator
// treats this exit reason as its own frame. If we have exited asm.js code
// without setting an exit reason, the reason will be None and this means
// the code was asynchronously interrupted.
exitReason_ = activation.exitReason();
if (exitReason_ == AsmJSExit::None)
exitReason_ = AsmJSExit::Interrupt;
@ -523,16 +536,14 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
case AsmJSModule::CodeRange::SlowFFI:
case AsmJSModule::CodeRange::Interrupt:
case AsmJSModule::CodeRange::Thunk: {
// While codeRange describes the *current* frame, the fp/pc state stored in
// the iterator is the *caller's* frame. The reason for this is that the
// activation.fp isn't always the AsmJSFrame for state.pc; during the
// prologue/epilogue, activation.fp will point to the caller's frame.
// Naively unwinding starting at activation.fp could thus lead to the
// second-to-innermost function being skipped in the callstack which will
// bork profiling stacks. Instead, we depend on the exact layout of the
// prologue/epilogue, as generated by GenerateProfiling(Prologue|Epilogue)
// below.
uint32_t offsetInModule = ((uint8_t*)state.pc) - module_->codeBase();
// When the pc is inside the prologue/epilogue, the innermost
// call's AsmJSFrame is not complete and thus fp points to the the
// second-to-innermost call's AsmJSFrame. Since fp can only tell you
// about its caller (via ReturnAddressFromFP(fp)), naively unwinding
// while pc is in the prologue/epilogue would skip the second-to-
// innermost call. To avoid this problem, we use the static structure of
// the code in the prologue and epilogue to do the Right Thing.
uint32_t offsetInModule = (uint8_t*)state.pc - module_->codeBase();
MOZ_ASSERT(offsetInModule < module_->codeBytes());
MOZ_ASSERT(offsetInModule >= codeRange->begin());
MOZ_ASSERT(offsetInModule < codeRange->end());
@ -540,21 +551,34 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
void **sp = (void**)state.sp;
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
if (offsetInCodeRange < PushedRetAddr) {
// First instruction of the ARM/MIPS function; the return address is
// still in lr and fp still holds the caller's fp.
callerPC_ = state.lr;
callerFP_ = fp;
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, sp - 2);
} else if (offsetInModule == codeRange->profilingReturn() - PostStorePrePopFP) {
// Second-to-last instruction of the ARM/MIPS function; fp points to
// the caller's fp; have not yet popped AsmJSFrame.
callerPC_ = ReturnAddressFromFP(sp);
callerFP_ = CallerFPFromFP(sp);
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, sp);
} else
#endif
if (offsetInCodeRange < PushedFP || offsetInModule == codeRange->profilingReturn()) {
// The return address has been pushed on the stack but not fp; fp
// still points to the caller's fp.
callerPC_ = *sp;
callerFP_ = fp;
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, sp - 1);
} else if (offsetInCodeRange < StoredFP) {
// The full AsmJSFrame has been pushed; fp still points to the
// caller's frame.
MOZ_ASSERT(fp == CallerFPFromFP(sp));
callerPC_ = ReturnAddressFromFP(sp);
callerFP_ = CallerFPFromFP(sp);
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, sp);
} else {
// Not in the prologue/epilogue.
callerPC_ = ReturnAddressFromFP(fp);
callerFP_ = CallerFPFromFP(fp);
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, fp);
@ -564,7 +588,7 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
case AsmJSModule::CodeRange::Entry: {
// The entry trampoline is the final frame in an AsmJSActivation. The entry
// trampoline also doesn't GenerateAsmJSPrologue/Epilogue so we can't use
// the general unwinding logic below.
// the general unwinding logic above.
MOZ_ASSERT(!fp);
callerPC_ = nullptr;
callerFP_ = nullptr;
@ -577,9 +601,11 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
return;
}
// Inline code ranges execute in the frame of the caller have no
// prologue/epilogue and thus don't require the general unwinding logic
// as below.
// Most inline code stubs execute after the prologue/epilogue have
// completed so we can simply unwind based on fp. The only exception is
// the async interrupt stub, since it can be executed at any time.
// However, the async interrupt is super rare, so we can tolerate
// skipped frames. Thus, we use simply unwind based on fp.
callerPC_ = ReturnAddressFromFP(fp);
callerFP_ = CallerFPFromFP(fp);
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, fp);
@ -617,7 +643,6 @@ AsmJSProfilingFrameIterator::operator++()
switch (codeRange->kind()) {
case AsmJSModule::CodeRange::Entry:
MOZ_ASSERT(callerFP_ == nullptr);
MOZ_ASSERT(callerPC_ != nullptr);
callerPC_ = nullptr;
break;
case AsmJSModule::CodeRange::Function:

View File

@ -5615,14 +5615,14 @@ CheckSimdLoadStoreArgs(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opTyp
{
ParseNode *view = CallArgList(call);
if (!view->isKind(PNK_NAME))
return f.fail(view, "expected Uint8Array view as SIMD.*.store first argument");
return f.fail(view, "expected Uint8Array view as SIMD.*.load/store first argument");
const ModuleCompiler::Global *global = f.lookupGlobal(view->name());
if (!global ||
global->which() != ModuleCompiler::Global::ArrayView ||
global->viewType() != Scalar::Uint8)
{
return f.fail(view, "expected Uint8Array view as SIMD.*.store first argument");
return f.fail(view, "expected Uint8Array view as SIMD.*.load/store first argument");
}
*needsBoundsCheck = NEEDS_BOUNDS_CHECK;
@ -5685,7 +5685,7 @@ CheckSimdStore(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefi
{
unsigned numArgs = CallArgListLength(call);
if (numArgs != 3)
return f.failf(call, "expected 3 arguments to SIMD load, got %u", numArgs);
return f.failf(call, "expected 3 arguments to SIMD store, got %u", numArgs);
Scalar::Type viewType;
MDefinition *index;
@ -5772,11 +5772,11 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
case AsmJSSimdOperation_fromFloat32x4Bits:
return CheckSimdCast<MSimdReinterpretCast>(f, call, AsmJSSimdType_float32x4, opType, def, type);
case AsmJSSimdOperation_shiftLeft:
case AsmJSSimdOperation_shiftLeftByScalar:
return CheckSimdBinary(f, call, opType, MSimdShift::lsh, def, type);
case AsmJSSimdOperation_shiftRight:
case AsmJSSimdOperation_shiftRightArithmeticByScalar:
return CheckSimdBinary(f, call, opType, MSimdShift::rsh, def, type);
case AsmJSSimdOperation_shiftRightLogical:
case AsmJSSimdOperation_shiftRightLogicalByScalar:
return CheckSimdBinary(f, call, opType, MSimdShift::ursh, def, type);
case AsmJSSimdOperation_abs:
@ -6213,9 +6213,12 @@ CheckConditional(FunctionCompiler &f, ParseNode *ternary, MDefinition **def, Typ
*type = Type::Double;
} else if (thenType.isFloat() && elseType.isFloat()) {
*type = Type::Float;
} else if (elseType.isSimd() && thenType <= elseType && elseType <= thenType) {
*type = thenType;
} else {
return f.failf(ternary, "then/else branches of conditional must both produce int or double, "
"current types are %s and %s", thenType.toChars(), elseType.toChars());
return f.failf(ternary, "then/else branches of conditional must both produce int, float, "
"double or SIMD types, current types are %s and %s",
thenType.toChars(), elseType.toChars());
}
if (!f.joinIfElse(thenBlocks, elseExpr))

View File

@ -97,9 +97,9 @@
V(notEqual, (CompareFunc<Int32x4, NotEqual>), 2, 0) \
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2, 0) \
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2, 0) \
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0) \
V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0) \
V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0) \
V(shiftLeftByScalar, (Int32x4BinaryScalar<ShiftLeft>), 2, 0) \
V(shiftRightArithmeticByScalar, (Int32x4BinaryScalar<ShiftRight>), 2, 0) \
V(shiftRightLogicalByScalar, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0) \
V(store, (Store<Int32x4, 4>), 3, 0) \
V(storeXYZ, (Store<Int32x4, 3>), 3, 0) \
V(storeXY, (Store<Int32x4, 2>), 3, 0) \
@ -130,9 +130,9 @@
#define FOREACH_INT32X4_SIMD_OP(_) \
_(fromFloat32x4) \
_(fromFloat32x4Bits) \
_(shiftLeft) \
_(shiftRight) \
_(shiftRightLogical)
_(shiftLeftByScalar) \
_(shiftRightArithmeticByScalar) \
_(shiftRightLogicalByScalar)
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
_(abs) \
_(sqrt) \

View File

@ -357,7 +357,7 @@ other kinds of objects.
`url`
: The script's `url` property must be equal to this value.
`source` <i>(not yet implemented)</i>
`source`
: The script's `source` property must be equal to this value.
`line`

View File

@ -269,11 +269,19 @@ js::ZonesIter::atAtomsZone(JSRuntime *rt)
return rt->isAtomsZone(*it);
}
bool Zone::isOnList()
bool
Zone::isOnList() const
{
return listNext_ != NotOnList;
}
Zone *
Zone::nextZone() const
{
MOZ_ASSERT(isOnList());
return listNext_;
}
ZoneList::ZoneList()
: head(nullptr), tail(nullptr)
{}

View File

@ -322,7 +322,8 @@ struct Zone : public JS::shadow::Zone,
friend class js::gc::ZoneList;
static Zone * const NotOnList;
Zone *listNext_;
bool isOnList();
bool isOnList() const;
Zone *nextZone() const;
friend bool js::CurrentThreadCanAccessZone(Zone *zone);
friend class js::gc::GCRuntime;

View File

@ -150,6 +150,7 @@ assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); retu
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4).y; return x|0;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); return (x.x > (1>>>0)) | 0;} return f");
// signMask
function CheckSignMask(innerBody, coerceBefore, coerceAfter, expected) {
var lanes = ['x', 'y', 'z', 'w'];
for (var i = 0; i < lanes.length; i++) {
@ -173,7 +174,6 @@ CheckSignMaskF4('var x=f4(' + (INT32_MAX + 1) + ', 2, 3, 4)', [INT32_MAX + 1, 2,
CheckSignMaskF4('var x=f4(1.3, 2.4, 3.5, 98.76)', [1.3, 2.4, 3.5, 98.76]);
CheckSignMaskF4('var x=f4(13.37, 2., 3., -0)', [13.37, 2, 3, -0]);
// signMask
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); var y=0.0; y=x.signMask;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=i4(1,2,3,4); return (x.signMask > (1>>>0)) | 0;} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + "function f() {var x=i4(1,2,3,4); var y=f32(0.0); y=x.signMask;} return f");
@ -231,6 +231,23 @@ CheckF4(FROUND, 'var x=f4(1,2,3,4); var y=f32(0); y=x.z; x=f4(y,y,y,y)', [3, 3,
CheckI4('', 'var x=i4(1,2,3,4); var c=0; var d=0; c=x.w|0; d=x.w|0; x=i4(c,d,d,c)', [4, 4, 4, 4]);
CheckF4(FROUND, 'var x=f4(1,2,3,4); var y=f32(0); var z=f32(0); y=x.z; z=x.z; x=f4(y,z,y,z)', [3, 3, 3, 3]);
// Uses in ternary conditionals
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; c=x?c:c;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=1?x:c;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + "function f() {var x=f4(1,2,3,4); var c=4; x=1?c:x;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?x:y;} return f");
assertAsmTypeFail('glob', USE_ASM + F32 + I32 + "function f() {var x=f4(1,2,3,4); var y=i4(1,2,3,4); x=1?y:y;} return f");
CheckF4('', 'var x=f4(1,2,3,4); var y=f4(4,3,2,1); x=3?y:x', [4, 3, 2, 1]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(x) {x=x|0; var v=f4(1,2,3,4); var w=f4(5,6,7,8); return f4(x?w:v);} return f"), this)(1), [5,6,7,8]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(v) {v=f4(v); var w=f4(5,6,7,8); return f4(4?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4)), [5,6,7,8]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + "function f(v, x) {v=f4(v); x=x|0; var w=f4(5,6,7,8); return f4(x?w:v);} return f"), this)(SIMD.float32x4(1,2,3,4), 0), [1,2,3,4]);
CheckI4('', 'var x=i4(1,2,3,4); var y=i4(4,3,2,1); x=(x.x|0)?y:x', [4, 3, 2, 1]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(x) {x=x|0; var v=i4(1,2,3,4); var w=i4(5,6,7,8); return i4(x?w:v);} return f"), this)(1), [5,6,7,8]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(v) {v=i4(v); var w=i4(5,6,7,8); return i4(4?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4)), [5,6,7,8]);
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + "function f(v, x) {v=i4(v); x=x|0; var w=i4(5,6,7,8); return i4(x?w:v);} return f"), this)(SIMD.int32x4(1,2,3,4), 0), [1,2,3,4]);
// 1.3.4 Return values
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1; return i4(x)} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + "function f() {var x=1; return i4(x + x)} return f");
@ -763,9 +780,9 @@ CheckF4(ORF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16
CheckF4(XORF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=xorr(x,y)', bitwise.xor([42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
// Logical ops
const LSHI = 'var lsh=i4.shiftLeft;'
const RSHI = 'var rsh=i4.shiftRight;'
const URSHI = 'var ursh=i4.shiftRightLogical;'
const LSHI = 'var lsh=i4.shiftLeftByScalar;'
const RSHI = 'var rsh=i4.shiftRightArithmeticByScalar;'
const URSHI = 'var ursh=i4.shiftRightLogicalByScalar;'
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,f32(42)));} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,42));} return f");

View File

@ -0,0 +1,9 @@
// |jit-test| error: InternalError
enableSPSProfiling();
var g = newGlobal();
g.parent = this;
g.eval("new Debugger(parent).onExceptionUnwind = function () { hits++; };");
function f() {
var x = f();
}
f();

View File

@ -0,0 +1,7 @@
// |jit-test| error: TypeError
var g = newGlobal();
g.parent = this;
g.eval("new Debugger(parent).onExceptionUnwind = function () {};");
Object.preventExtensions(this);
evaluate("function testcase() { }", { noScriptRval : true, compileAndGo : true });

View File

@ -0,0 +1,15 @@
// |jit-test| slow
if (helperThreadCount() == 0)
quit(0);
var s = '';
for (var i = 0; i < 70000; i++)
{
s += 'function x' + i + '() { x' + i + '(); }\n';
}
evaluate(s);
var g = newGlobal();
(new Debugger).addDebuggee(g);
g.offThreadCompileScript('debugger;',{});
g.runOffThreadScript();

View File

@ -181,7 +181,7 @@ uint32_t
jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
ResumeFromException *rfe,
const ExceptionBailoutInfo &excInfo,
bool *overrecursed)
bool *overrecursed, bool *poppedLastSPSFrameOut)
{
// We can be propagating debug mode exceptions without there being an
// actual exception pending. For instance, when we return false from an
@ -196,9 +196,8 @@ jit::ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
JitFrameIterator iter(jitActivations);
BaselineBailoutInfo *bailoutInfo = nullptr;
bool poppedLastSPSFrame = false;
uint32_t retval = BailoutIonToBaseline(cx, bailoutData.activation(), iter, true,
&bailoutInfo, &excInfo, &poppedLastSPSFrame);
&bailoutInfo, &excInfo, poppedLastSPSFrameOut);
if (retval == BAILOUT_RETURN_OK) {
MOZ_ASSERT(bailoutInfo);

View File

@ -209,7 +209,7 @@ class ExceptionBailoutInfo
uint32_t ExceptionHandlerBailout(JSContext *cx, const InlineFrameIterator &frame,
ResumeFromException *rfe,
const ExceptionBailoutInfo &excInfo,
bool *overrecursed);
bool *overrecursed, bool *poppedLastSPSFrameOut);
uint32_t FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo);

View File

@ -400,17 +400,31 @@ PatchBaselineFramesForDebugMode(JSContext *cx, const Debugger::ExecutionObservab
BaselineScript *bl = script->baselineScript();
ICEntry::Kind kind = entry.frameKind;
if (kind == ICEntry::Kind_Op) {
// Case A above.
//
// Patching this case needs to patch both the stub frame and
if (kind == ICEntry::Kind_Op || kind == ICEntry::Kind_NonOp) {
uint8_t *retAddr;
if (kind == ICEntry::Kind_Op) {
// Case A above.
retAddr = bl->returnAddressForIC(bl->icEntryFromPCOffset(pcOffset));
} else {
// Case H above.
//
// It could happen that the in-place Ion bailout chose the
// return-from-IC address of a NonOp IC for the frame
// iterators to report the correct bytecode pc.
//
// See note under propagatingIonExceptionForDebugMode in
// InitFromBailout.
MOZ_ASSERT(iter.baselineFrame()->isDebuggerHandlingException());
retAddr = bl->returnAddressForIC(bl->anyKindICEntryFromPCOffset(pcOffset));
}
// Patching these cases needs to patch both the stub frame and
// the baseline frame. The stub frame is patched below. For
// the baseline frame here, we resume right after the IC
// returns.
//
// Since we're using the same IC stub code, we can resume
// directly to the IC resume address.
uint8_t *retAddr = bl->returnAddressForIC(bl->icEntryFromPCOffset(pcOffset));
SpewPatchBaselineFrame(prev->returnAddress(), retAddr, script, kind, pc);
DebugModeOSRVolatileJitFrameIterator::forwardLiveIterators(
cx, prev->returnAddress(), retAddr);

View File

@ -576,7 +576,7 @@ BaselineScript::anyKindICEntryFromPCOffset(uint32_t pcOffset)
// Return any IC entry with a matching PC offset.
for (size_t i = mid; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i--)
return icEntry(i);
return icEntry(i);
for (size_t i = mid+1; i < numICEntries() && icEntry(i).pcOffset() == pcOffset; i++)
return icEntry(i);
MOZ_CRASH("Invalid PC offset for IC entry.");

View File

@ -7767,7 +7767,7 @@ static const VMFunctionsModal SetObjectElementInfo = VMFunctionsModal(
void
CodeGenerator::visitCallSetElement(LCallSetElement *lir)
{
pushArg(Imm32(current->mir()->strict()));
pushArg(Imm32(lir->mir()->strict()));
pushArg(ToValue(lir, LCallSetElement::Value));
pushArg(ToValue(lir, LCallSetElement::Index));
pushArg(ToRegister(lir->getOperand(0)));

View File

@ -8263,7 +8263,7 @@ IonBuilder::jsop_setelem()
return emitted;
// Emit call.
MInstruction *ins = MCallSetElement::New(alloc(), object, index, value);
MInstruction *ins = MCallSetElement::New(alloc(), object, index, value, IsStrictSetPC(pc));
current->add(ins);
current->push(value);

View File

@ -695,7 +695,7 @@ class InlineFrameIterator
}
template <class Op>
void unaliasedForEachActual(ThreadSafeContext *cx, Op op,
void unaliasedForEachActual(JSContext *cx, Op op,
ReadFrameArgsBehavior behavior,
MaybeReadFallback &fallback) const
{

View File

@ -412,7 +412,7 @@ CloseLiveIterator(JSContext *cx, const InlineFrameIterator &frame, uint32_t loca
static void
HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromException *rfe,
bool *overrecursed)
bool *overrecursed, bool *poppedLastSPSFrameOut)
{
RootedScript script(cx, frame.script());
jsbytecode *pc = frame.pc();
@ -444,7 +444,8 @@ HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromEx
// to the stack depth at the snapshot, as we could've thrown in the
// middle of a call.
ExceptionBailoutInfo propagateInfo;
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed);
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed,
poppedLastSPSFrameOut);
if (retval == BAILOUT_RETURN_OK)
return;
}
@ -486,7 +487,8 @@ HandleExceptionIon(JSContext *cx, const InlineFrameIterator &frame, ResumeFromEx
// Bailout at the start of the catch block.
jsbytecode *catchPC = script->main() + tn->start + tn->length;
ExceptionBailoutInfo excInfo(frame.frameNo(), catchPC, tn->stackDepth);
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed);
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed,
poppedLastSPSFrameOut);
if (retval == BAILOUT_RETURN_OK)
return;
@ -742,7 +744,8 @@ HandleException(ResumeFromException *rfe)
bool invalidated = iter.checkInvalidation(&ionScript);
for (;;) {
HandleExceptionIon(cx, frames, rfe, &overrecursed);
bool poppedLastSPSFrame = false;
HandleExceptionIon(cx, frames, rfe, &overrecursed, &poppedLastSPSFrame);
if (rfe->kind == ResumeFromException::RESUME_BAILOUT) {
if (invalidated)
@ -764,6 +767,11 @@ HandleException(ResumeFromException *rfe)
if (frames.more())
popSPSFrame = false;
// Don't pop the last SPS frame if it's already been popped by
// bailing out.
if (poppedLastSPSFrame)
popSPSFrame = false;
// When profiling, each frame popped needs a notification that
// the function has exited, so invoke the probe that a function
// is exiting.
@ -874,7 +882,8 @@ HandleParallelFailure(ResumeFromException *rfe)
SnapshotIterator snapIter(frameIter);
cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind());
cx->bailoutRecord->rematerializeFrames(cx, frameIter);
while (!frameIter.done())
++frameIter;
rfe->kind = ResumeFromException::RESUME_ENTRY_FRAME;

View File

@ -5746,6 +5746,10 @@ class LCallSetElement : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0>
static const size_t Index = 1;
static const size_t Value = 1 + BOX_PIECES;
const MCallSetElement *mir() const {
return mir_->toCallSetElement();
}
};
// Call js::InitElementArray.

View File

@ -10154,9 +10154,11 @@ class MSetPropertyInstruction : public MBinaryInstruction
class MSetElementInstruction
: public MTernaryInstruction
{
bool strict_;
protected:
MSetElementInstruction(MDefinition *object, MDefinition *index, MDefinition *value)
: MTernaryInstruction(object, index, value)
MSetElementInstruction(MDefinition *object, MDefinition *index, MDefinition *value, bool strict)
: MTernaryInstruction(object, index, value),
strict_(strict)
{
}
@ -10170,6 +10172,9 @@ class MSetElementInstruction
MDefinition *value() const {
return getOperand(2);
}
bool strict() const {
return strict_;
}
};
class MDeleteProperty
@ -10295,13 +10300,11 @@ class MSetElementCache
: public MSetElementInstruction,
public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
{
bool strict_;
bool guardHoles_;
MSetElementCache(MDefinition *obj, MDefinition *index, MDefinition *value, bool strict,
bool guardHoles)
: MSetElementInstruction(obj, index, value),
strict_(strict),
: MSetElementInstruction(obj, index, value, strict),
guardHoles_(guardHoles)
{
}
@ -10315,9 +10318,6 @@ class MSetElementCache
return new(alloc) MSetElementCache(obj, index, value, strict, guardHoles);
}
bool strict() const {
return strict_;
}
bool guardHoles() const {
return guardHoles_;
}
@ -10402,8 +10402,8 @@ class MCallSetElement
: public MSetElementInstruction,
public CallSetElementPolicy::Data
{
MCallSetElement(MDefinition *object, MDefinition *index, MDefinition *value)
: MSetElementInstruction(object, index, value)
MCallSetElement(MDefinition *object, MDefinition *index, MDefinition *value, bool strict)
: MSetElementInstruction(object, index, value, strict)
{
}
@ -10411,9 +10411,9 @@ class MCallSetElement
INSTRUCTION_HEADER(CallSetElement)
static MCallSetElement *New(TempAllocator &alloc, MDefinition *object, MDefinition *index,
MDefinition *value)
MDefinition *value, bool strict)
{
return new(alloc) MCallSetElement(object, index, value);
return new(alloc) MCallSetElement(object, index, value, strict);
}
bool possiblyCalls() const {

View File

@ -549,7 +549,8 @@ jit::BailoutPar(BailoutStack *sp, uint8_t **entryFramePointer)
SnapshotIterator snapIter(frameIter);
cx->bailoutRecord->setIonBailoutKind(snapIter.bailoutKind());
cx->bailoutRecord->rematerializeFrames(cx, frameIter);
while (!frameIter.done())
++frameIter;
MOZ_ASSERT(frameIter.done());
*entryFramePointer = frameIter.fp();

View File

@ -28,8 +28,8 @@ struct CopyValueToRematerializedFrame
}
};
RematerializedFrame::RematerializedFrame(ThreadSafeContext *cx, uint8_t *top,
unsigned numActualArgs, InlineFrameIterator &iter)
RematerializedFrame::RematerializedFrame(JSContext *cx, uint8_t *top, unsigned numActualArgs,
InlineFrameIterator &iter)
: prevUpToDate_(false),
isDebuggee_(iter.script()->isDebuggee()),
top_(top),
@ -46,7 +46,7 @@ RematerializedFrame::RematerializedFrame(ThreadSafeContext *cx, uint8_t *top,
}
/* static */ RematerializedFrame *
RematerializedFrame::New(ThreadSafeContext *cx, uint8_t *top, InlineFrameIterator &iter)
RematerializedFrame::New(JSContext *cx, uint8_t *top, InlineFrameIterator &iter)
{
unsigned numFormals = iter.isFunctionFrame() ? iter.callee()->nargs() : 0;
unsigned numActualArgs = Max(numFormals, iter.numActualArgs());
@ -62,7 +62,7 @@ RematerializedFrame::New(ThreadSafeContext *cx, uint8_t *top, InlineFrameIterato
}
/* static */ bool
RematerializedFrame::RematerializeInlineFrames(ThreadSafeContext *cx, uint8_t *top,
RematerializedFrame::RematerializeInlineFrames(JSContext *cx, uint8_t *top,
InlineFrameIterator &iter,
Vector<RematerializedFrame *> &frames)
{
@ -71,9 +71,19 @@ RematerializedFrame::RematerializeInlineFrames(ThreadSafeContext *cx, uint8_t *t
while (true) {
size_t frameNo = iter.frameNo();
frames[frameNo] = RematerializedFrame::New(cx, top, iter);
if (!frames[frameNo])
RematerializedFrame *frame = RematerializedFrame::New(cx, top, iter);
if (!frame)
return false;
if (frame->scopeChain()) {
// Frames are often rematerialized with the cx inside a Debugger's
// compartment. To create CallObjects, we need to be in that
// frame's compartment.
AutoCompartment ac(cx, frame->scopeChain());
if (!EnsureHasScopeObjects(cx, frame))
return false;
}
frames[frameNo] = frame;
if (!iter.more())
break;
@ -112,6 +122,26 @@ RematerializedFrame::callObj() const
return scope->as<CallObject>();
}
void
RematerializedFrame::pushOnScopeChain(ScopeObject &scope)
{
MOZ_ASSERT(*scopeChain() == scope.enclosingScope() ||
*scopeChain() == scope.as<CallObject>().enclosingScope().as<DeclEnvObject>().enclosingScope());
scopeChain_ = &scope;
}
bool
RematerializedFrame::initFunctionScopeObjects(JSContext *cx)
{
MOZ_ASSERT(isNonEvalFunctionFrame());
MOZ_ASSERT(fun()->isHeavyweight());
CallObject *callobj = CallObject::createForFunction(cx, this);
if (!callobj)
return false;
pushOnScopeChain(*callobj);
return true;
}
void
RematerializedFrame::mark(JSTracer *trc)
{

View File

@ -46,16 +46,15 @@ class RematerializedFrame
Value thisValue_;
Value slots_[1];
RematerializedFrame(ThreadSafeContext *cx, uint8_t *top, unsigned numActualArgs,
RematerializedFrame(JSContext *cx, uint8_t *top, unsigned numActualArgs,
InlineFrameIterator &iter);
public:
static RematerializedFrame *New(ThreadSafeContext *cx, uint8_t *top,
InlineFrameIterator &iter);
static RematerializedFrame *New(JSContext *cx, uint8_t *top, InlineFrameIterator &iter);
// Rematerialize all remaining frames pointed to by |iter| into |frames|
// in older-to-younger order, e.g., frames[0] is the oldest frame.
static bool RematerializeInlineFrames(ThreadSafeContext *cx, uint8_t *top,
static bool RematerializeInlineFrames(JSContext *cx, uint8_t *top,
InlineFrameIterator &iter,
Vector<RematerializedFrame *> &frames);
@ -104,8 +103,13 @@ class RematerializedFrame
JSObject *scopeChain() const {
return scopeChain_;
}
void pushOnScopeChain(ScopeObject &scope);
bool initFunctionScopeObjects(JSContext *cx);
bool hasCallObj() const {
return maybeFun() && fun()->isHeavyweight();
return maybeFun() &&
fun()->isHeavyweight() &&
scopeChain()->is<CallObject>();
}
CallObject &callObj() const;

View File

@ -560,12 +560,7 @@ void
JSCompartment::sweepGlobalObject(FreeOp *fop)
{
if (global_.unbarrieredGet() && IsObjectAboutToBeFinalizedFromAnyThread(global_.unsafeGet())) {
// For main thread compartments, the invariant is that debug mode
// implies having at least one Debugger still attached. However, for
// off-thread compartments, which are used in off-thread parsing, they
// may be isDebuggee() without there being any Debuggers to prohibit
// asm.js.
if (isDebuggee() && !global_->compartment()->options().invisibleToDebugger())
if (isDebuggee())
Debugger::detachAllDebuggersFromGlobal(fop, global_);
global_.set(nullptr);
}

View File

@ -430,8 +430,8 @@ struct JSCompartment
// InterpreterFrame::isDebuggee, and Baseline::isDebuggee are enumerated
// below.
//
// 1. When a compartment's isDebuggee() == true, relazification and lazy
// parsing are disabled.
// 1. When a compartment's isDebuggee() == true, relazification, lazy
// parsing, and asm.js are disabled.
//
// 2. When a compartment's debugObservesAllExecution() == true, all of the
// compartment's scripts are considered debuggee scripts.

View File

@ -546,12 +546,14 @@ FinalizeTypedArenas(FreeOp *fop,
if (!fop->onBackgroundThread())
maybeLock.emplace(fop->runtime());
/*
* During parallel sections, we sometimes finalize the parallel arenas,
* but in that case, we want to hold on to the memory in our arena
* lists, not offer it up for reuse.
*/
MOZ_ASSERT_IF(InParallelSection(), keepArenas);
// During background sweeping free arenas are released later on in
// sweepBackgroundThings().
MOZ_ASSERT_IF(fop->onBackgroundThread(), keepArenas == ArenaLists::KEEP_ARENAS);
// During parallel sections, we sometimes finalize the parallel arenas, but
// in that case, we want to hold on to the memory in our arena lists, not
// offer it up for reuse.
MOZ_ASSERT_IF(InParallelSection(), keepArenas == ArenaLists::KEEP_ARENAS);
size_t thingSize = Arena::thingSize(thingKind);
size_t thingsPerArena = Arena::thingsPerArena(thingSize);
@ -561,18 +563,12 @@ FinalizeTypedArenas(FreeOp *fop,
size_t nmarked = aheader->getArena()->finalize<T>(fop, thingKind, thingSize);
size_t nfree = thingsPerArena - nmarked;
if (nmarked) {
if (nmarked)
dest.insertAt(aheader, nfree);
} else if (keepArenas == ArenaLists::KEEP_ARENAS) {
else if (keepArenas == ArenaLists::KEEP_ARENAS)
aheader->chunk()->recycleArena(aheader, dest, thingKind, thingsPerArena);
} else if (fop->onBackgroundThread()) {
// When background sweeping, take the lock around each release so
// that we do not block the foreground for extended periods.
AutoLockGC lock(fop->runtime());
fop->runtime()->gc.releaseArena(aheader, lock);
} else {
else
fop->runtime()->gc.releaseArena(aheader, maybeLock.ref());
}
budget.step(thingsPerArena);
if (budget.isOverBudget())
@ -3438,11 +3434,10 @@ void
GCRuntime::sweepBackgroundThings(ZoneList &zones, ThreadType threadType)
{
// We must finalize thing kinds in the order specified by BackgroundFinalizePhases.
ArenaHeader *emptyArenas = nullptr;
FreeOp fop(rt, threadType);
while (!zones.isEmpty()) {
Zone *zone = zones.front();
ArenaHeader *emptyArenas = nullptr;
for (unsigned phase = 0 ; phase < ArrayLength(BackgroundFinalizePhases) ; ++phase) {
for (unsigned phase = 0 ; phase < ArrayLength(BackgroundFinalizePhases) ; ++phase) {
for (Zone *zone = zones.front(); zone; zone = zone->nextZone()) {
for (unsigned index = 0 ; index < BackgroundFinalizePhases[phase].length ; ++index) {
AllocKind kind = BackgroundFinalizePhases[phase].kinds[index];
ArenaHeader *arenas = zone->allocator.arenas.arenaListsToSweep[kind];
@ -3450,11 +3445,12 @@ GCRuntime::sweepBackgroundThings(ZoneList &zones, ThreadType threadType)
ArenaLists::backgroundFinalize(&fop, arenas, &emptyArenas);
}
}
AutoLockGC lock(rt);
ReleaseArenaList(rt, emptyArenas, lock);
zones.removeFront();
}
AutoLockGC lock(rt);
ReleaseArenaList(rt, emptyArenas, lock);
while (!zones.isEmpty())
zones.removeFront();
}
void

View File

@ -1,35 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 996076;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 lsh';
function test() {
print(BUGNUMBER + ": " + summary);
for (var bits = 0; bits < 32; bits++) {
var a = int32x4(-1, 2, -3, 4);
var c = SIMD.int32x4.shiftLeft(a, bits);
assertEq(c.x, -1 << bits);
assertEq(c.y, 2 << bits);
assertEq(c.z, -3 << bits);
assertEq(c.w, 4 << bits);
}
var INT32_MAX = Math.pow(2, 31) - 1;
var INT32_MIN = -Math.pow(2, 31);
var d = int32x4(INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN);
var f = SIMD.int32x4.shiftLeft(d, 1);
assertEq(f.x, (INT32_MAX << 1) | 0);
assertEq(f.y, (INT32_MIN << 1) | 0);
assertEq(f.z, (INT32_MAX << 1) | 0);
assertEq(f.w, (INT32_MIN << 1) | 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,34 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 996076;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 rsh';
function test() {
print(BUGNUMBER + ": " + summary);
for (var bits = 0; bits < 32; bits++) {
var a = int32x4(-1, 2, -3, 4);
var c = SIMD.int32x4.shiftRight(a, bits);
assertEq(c.x, -1 >> bits);
assertEq(c.y, 2 >> bits);
assertEq(c.z, -3 >> bits);
assertEq(c.w, 4 >> bits);
}
var INT32_MAX = Math.pow(2, 31) - 1;
var INT32_MIN = -Math.pow(2, 31);
var d = int32x4(INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN);
var f = SIMD.int32x4.shiftRight(d, 1);
assertEq(f.x, INT32_MAX >> 1);
assertEq(f.y, INT32_MIN >> 1);
assertEq(f.z, INT32_MAX >> 1);
assertEq(f.w, INT32_MIN >> 1);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,35 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
var BUGNUMBER = 996076;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 ursh';
function test() {
print(BUGNUMBER + ": " + summary);
for (var bits = 0; bits < 32; bits++) {
var a = int32x4(-1, 2, -3, 4);
var c = SIMD.int32x4.shiftRightLogical(a, bits);
assertEq(c.x >>> 0, -1 >>> bits);
assertEq(c.y >>> 0, 2 >>> bits);
assertEq(c.z >>> 0, -3 >>> bits);
assertEq(c.w >>> 0, 4 >>> bits);
}
var INT32_MAX = Math.pow(2, 31) - 1;
var INT32_MIN = -Math.pow(2, 31);
var d = int32x4(INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN);
var f = SIMD.int32x4.shiftRightLogical(d, 0);
assertEq(f.x, (INT32_MAX >>> 0) | 0);
assertEq(f.y, (INT32_MIN >>> 0) | 0);
assertEq(f.z, (INT32_MAX >>> 0) | 0);
assertEq(f.w, (INT32_MIN >>> 0) | 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -28,3 +28,13 @@ function testBinaryFunc(v, w, simdFunc, func) {
for (var i = 0; i < observed.length; i++)
assertEq(observed[i], expected[i]);
}
function testBinaryScalarFunc(v, scalar, simdFunc, func) {
var varr = simdToArray(v);
var observed = simdToArray(simdFunc(v, scalar));
var expected = varr.map(function(v, i) { return func(varr[i], scalar); });
for (var i = 0; i < observed.length; i++)
assertEq(observed[i], expected[i]);
}

View File

@ -0,0 +1,37 @@
// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
/*
* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/
*/
var int32x4 = SIMD.int32x4;
function lsh(a, b) {
return (a << b) | 0;
}
function rsh(a, b) {
return (a >> b) | 0;
}
function ursh(a, b) {
return (a >>> b) | 0;
}
function test() {
for (var v of [
int32x4(-1, 2, -3, 4),
int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
])
{
for (var bits = 0; bits < 32; bits++) {
testBinaryScalarFunc(v, bits, int32x4.shiftLeftByScalar, lsh);
testBinaryScalarFunc(v, bits, int32x4.shiftRightArithmeticByScalar, rsh);
testBinaryScalarFunc(v, bits, int32x4.shiftRightLogicalByScalar, ursh);
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -3560,43 +3560,35 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
if (!prepareQuery())
return false;
// Ensure that all of our debuggee globals are rooted so that they are
// visible in the RootList.
JS::AutoObjectVector debuggees(cx);
for (GlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) {
if (!debuggees.append(r.front()))
return false;
}
{
/*
* We can't tolerate the GC moving things around while we're
* searching the heap. Check that nothing we do causes a GC.
*/
JS::AutoCheckCannotGC autoCannotGC;
Maybe<JS::AutoCheckCannotGC> maybeNoGC;
RootedObject dbgObj(cx, dbg->object);
JS::ubi::RootList rootList(cx, maybeNoGC);
if (!rootList.init(cx, dbgObj))
return false;
Traversal traversal(cx, *this, autoCannotGC);
Traversal traversal(cx, *this, maybeNoGC.ref());
if (!traversal.init())
return false;
traversal.wantNames = false;
/* Add each debuggee global as a start point of our traversal. */
for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
if (!traversal.addStartVisited(JS::ubi::Node(static_cast<JSObject *>(r.front()))))
return false;
}
/*
* Iterate over all compartments and add traversal start points at
* objects that have CCWs in other compartments keeping them alive.
*/
for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
JSCompartment *comp = c.get();
if (!comp)
continue;
for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
const CrossCompartmentKey &key = e.front().key();
if (key.kind != CrossCompartmentKey::ObjectWrapper)
continue;
JSObject *obj = static_cast<JSObject *>(key.wrapped);
if (!traversal.addStartVisited(JS::ubi::Node(obj)))
return false;
}
}
if (!traversal.traverse())
if (!traversal.addStart(JS::ubi::Node(&rootList)) ||
!traversal.traverse())
{
return false;
}
/*
* Iterate over the visited set of nodes and accumulate all
@ -3604,8 +3596,9 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
*/
for (Traversal::NodeMap::Range r = traversal.visited.all(); !r.empty(); r.popFront()) {
JS::ubi::Node node = r.front().key();
if (!node.is<JSObject>() || !dbg->isDebuggee(node.compartment()))
if (!node.is<JSObject>())
continue;
MOZ_ASSERT(dbg->isDebuggee(node.compartment()));
JSObject *obj = node.as<JSObject>();
@ -3625,15 +3618,17 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
/*
* |ubi::Node::BreadthFirst| interface.
*
* We use an empty traversal function and just iterate over the traversal's
* visited set post-facto in |findObjects|.
*/
class NodeData {};
typedef JS::ubi::BreadthFirst<ObjectQuery> Traversal;
bool operator() (Traversal &, JS::ubi::Node, const JS::ubi::Edge &, NodeData *, bool)
bool operator() (Traversal &traversal, JS::ubi::Node origin, const JS::ubi::Edge &edge,
NodeData *, bool first)
{
/* Only follow edges within our set of debuggee compartments. */
JSCompartment *comp = edge.referent.compartment();
if (first && comp && !dbg->isDebuggee(edge.referent.compartment()))
traversal.abandonReferent();
return true;
}

View File

@ -1875,41 +1875,6 @@ ParallelBailoutRecord::reset()
cause = ParallelBailoutNone;
}
void
ParallelBailoutRecord::rematerializeFrames(ForkJoinContext *cx, JitFrameIterator &frameIter)
{
// This function is infallible. These are only called when we are already
// erroring out. If we OOM here, free what we've allocated and return. Error
// reporting is then unable to give the user detailed stack information.
MOZ_ASSERT(frames().empty());
for (; !frameIter.done(); ++frameIter) {
if (!frameIter.isIonJS())
continue;
InlineFrameIterator inlineIter(cx, &frameIter);
Vector<RematerializedFrame *> inlineFrames(cx);
if (!RematerializedFrame::RematerializeInlineFrames(cx, frameIter.fp(),
inlineIter, inlineFrames))
{
RematerializedFrame::FreeInVector(inlineFrames);
RematerializedFrame::FreeInVector(frames());
return;
}
// Reverse the inline frames into the main vector.
while (!inlineFrames.empty()) {
if (!frames().append(inlineFrames.popCopy())) {
RematerializedFrame::FreeInVector(inlineFrames);
RematerializedFrame::FreeInVector(frames());
return;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//

View File

@ -370,8 +370,6 @@ struct ParallelBailoutRecord
joinCause(ParallelBailoutExecution);
ionBailoutKind = kind;
}
void rematerializeFrames(ForkJoinContext *cx, jit::JitFrameIterator &frameIter);
};
class ForkJoinShared;

View File

@ -197,7 +197,17 @@ ParseTask::ParseTask(ExclusiveContext *cx, JSObject *exclusiveContextGlobal, JSC
bool
ParseTask::init(JSContext *cx, const ReadOnlyCompileOptions &options)
{
return this->options.copy(cx, options);
if (!this->options.copy(cx, options))
return false;
// If the main-thread global is a debuggee, disable asm.js
// compilation. This is preferred to marking the task compartment as a
// debuggee, as the task compartment is (1) invisible to Debugger and (2)
// cannot have any Debuggers.
if (cx->compartment()->isDebuggee())
this->options.asmJSOption = false;
return true;
}
void
@ -364,12 +374,6 @@ js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &optio
} else {
task->activate(cx->runtime());
if (cx->compartment()->isDebuggee()) {
task->cx->compartment()->setIsDebuggee();
if (cx->compartment()->debugObservesAllExecution())
task->cx->compartment()->setDebugObservesAllExecution();
}
AutoLockHelperThreadState lock;
if (!HelperThreadState().parseWorklist().append(task.get()))

View File

@ -463,7 +463,9 @@ AbstractFramePtr::initFunctionScopeObjects(JSContext *cx)
{
if (isInterpreterFrame())
return asInterpreterFrame()->initFunctionScopeObjects(cx);
return asBaselineFrame()->initFunctionScopeObjects(cx);
if (isBaselineFrame())
return asBaselineFrame()->initFunctionScopeObjects(cx);
return asRematerializedFrame()->initFunctionScopeObjects(cx);
}
inline JSCompartment *

View File

@ -963,7 +963,7 @@ FrameIter::isConstructing() const
}
bool
FrameIter::ensureHasRematerializedFrame(ThreadSafeContext *cx)
FrameIter::ensureHasRematerializedFrame(JSContext *cx)
{
MOZ_ASSERT(isIon());
return !!activation()->asJit()->getRematerializedFrame(cx, data_.jitFrames_);
@ -1445,7 +1445,7 @@ jit::JitActivation::clearRematerializedFrames()
}
jit::RematerializedFrame *
jit::JitActivation::getRematerializedFrame(ThreadSafeContext *cx, const JitFrameIterator &iter, size_t inlineDepth)
jit::JitActivation::getRematerializedFrame(JSContext *cx, const JitFrameIterator &iter, size_t inlineDepth)
{
// Only allow rematerializing from the same thread.
MOZ_ASSERT(cx->perThreadData == cx_->perThreadData);

View File

@ -1330,7 +1330,7 @@ class JitActivation : public Activation
// provided, as values need to be read out of snapshots.
//
// The inlineDepth must be within bounds of the frame pointed to by iter.
RematerializedFrame *getRematerializedFrame(ThreadSafeContext *cx, const JitFrameIterator &iter,
RematerializedFrame *getRematerializedFrame(JSContext *cx, const JitFrameIterator &iter,
size_t inlineDepth = 0);
// Look up a rematerialized frame by the fp. If inlineDepth is out of
@ -1636,7 +1636,7 @@ class FrameIter
// Ensures that we have rematerialized the top frame and its associated
// inline frames. Can only be called when isIon().
bool ensureHasRematerializedFrame(ThreadSafeContext *cx);
bool ensureHasRematerializedFrame(JSContext *cx);
// True when isInterp() or isBaseline(). True when isIon() if it
// has a rematerialized frame. False otherwise false otherwise.

View File

@ -149,4 +149,4 @@ fuzzy-if(d2d,47,400) == linear-onestopposition-1.html linear-onestopposition-1-r
fuzzy(1,800000) == large-gradient-1.html large-gradient-1-ref.html
== large-gradient-2.html large-gradient-2-ref.html
fails-if(browserIsRemote&&!B2G) fuzzy-if(!browserIsRemote||B2G,1,800000) == large-gradient-3.html large-gradient-3-ref.html
fails-if(browserIsRemote&&!B2G) == large-gradient-4.html large-gradient-4-ref.html
== large-gradient-4.html large-gradient-4-ref.html

View File

@ -1480,6 +1480,12 @@ function UpdateCurrentCanvasForInvalidation(rects)
var right = Math.ceil(r.right);
var bottom = Math.ceil(r.bottom);
// Clamp the values to the canvas size
left = Math.max(0, Math.min(left, gCurrentCanvas.width));
top = Math.max(0, Math.min(top, gCurrentCanvas.height));
right = Math.max(0, Math.min(right, gCurrentCanvas.width));
bottom = Math.max(0, Math.min(bottom, gCurrentCanvas.height));
ctx.save();
ctx.translate(left, top);
DoDrawWindow(ctx, left, top, right - left, bottom - top);

View File

@ -22,6 +22,7 @@ namespace stagefright {
extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
extern const char *MEDIA_MIMETYPE_VIDEO_VP6;
extern const char *MEDIA_MIMETYPE_VIDEO_VP8;
extern const char *MEDIA_MIMETYPE_VIDEO_VP9;
extern const char *MEDIA_MIMETYPE_VIDEO_AVC;

View File

@ -320,6 +320,9 @@ static const char *FourCC2MIME(uint32_t fourcc) {
case FOURCC('s', 'a', 'w', 'b'):
return MEDIA_MIMETYPE_AUDIO_AMR_WB;
case FOURCC('.', 'm', 'p', '3'):
return MEDIA_MIMETYPE_AUDIO_MPEG;
case FOURCC('m', 'p', '4', 'v'):
return MEDIA_MIMETYPE_VIDEO_MPEG4;
@ -332,6 +335,9 @@ static const char *FourCC2MIME(uint32_t fourcc) {
case FOURCC('a', 'v', 'c', '3'):
return MEDIA_MIMETYPE_VIDEO_AVC;
case FOURCC('V', 'P', '6', 'F'):
return MEDIA_MIMETYPE_VIDEO_VP6;
default:
CHECK(!"should not be here.");
return NULL;
@ -1216,6 +1222,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
}
case FOURCC('m', 'p', '4', 'a'):
case FOURCC('.', 'm', 'p', '3'):
case FOURCC('e', 'n', 'c', 'a'):
case FOURCC('s', 'a', 'm', 'r'):
case FOURCC('s', 'a', 'w', 'b'):
@ -1270,6 +1277,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
case FOURCC('h', '2', '6', '3'):
case FOURCC('a', 'v', 'c', '1'):
case FOURCC('a', 'v', 'c', '3'):
case FOURCC('V', 'P', '6', 'F'):
{
mHasVideo = true;

View File

@ -20,6 +20,7 @@ namespace stagefright {
const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg";
const char *MEDIA_MIMETYPE_VIDEO_VP6 = "video/x-vnd.on2.vp6";
const char *MEDIA_MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";

View File

@ -121,11 +121,14 @@ JsepSessionImpl::AddAudioRtpExtension(const std::string& extensionName)
return NS_ERROR_FAILURE;
}
mAudioRtpExtensions.push_back(
SdpExtmapAttributeList::Extmap extmap =
{ static_cast<uint16_t>(mAudioRtpExtensions.size() + 1),
SdpDirectionAttribute::kSendrecv,
false, // don't actually specify direction
extensionName, "" });
extensionName,
"" };
mAudioRtpExtensions.push_back(extmap);
return NS_OK;
}
@ -139,11 +142,13 @@ JsepSessionImpl::AddVideoRtpExtension(const std::string& extensionName)
return NS_ERROR_FAILURE;
}
mVideoRtpExtensions.push_back(
SdpExtmapAttributeList::Extmap extmap =
{ static_cast<uint16_t>(mVideoRtpExtensions.size() + 1),
SdpDirectionAttribute::kSendrecv,
false, // don't actually specify direction
extensionName, "" });
extensionName, "" };
mVideoRtpExtensions.push_back(extmap);
return NS_OK;
}
@ -392,7 +397,7 @@ JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection,
if (ourExtmap->mExtmaps.back().entry >= 4096) {
ourExtmap->mExtmaps.back().entry = j->entry;
}
}
}
}
}

View File

@ -256,8 +256,9 @@ public:
bool direction_specified, const std::string& extensionname,
const std::string& extensionattributes = "")
{
mExtmaps.push_back({ entry, direction, direction_specified, extensionname,
extensionattributes });
Extmap value = { entry, direction, direction_specified, extensionname,
extensionattributes };
mExtmaps.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -343,7 +344,8 @@ public:
void
PushEntry(HashAlgorithm hashFunc, const std::vector<uint8_t>& fingerprint)
{
mFingerprints.push_back({ hashFunc, fingerprint });
Fingerprint value = { hashFunc, fingerprint };
mFingerprints.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -420,7 +422,8 @@ public:
void
PushEntry(Semantics semantics, const std::vector<std::string>& tags)
{
mGroups.push_back({ semantics, tags });
Group value = { semantics, tags };
mGroups.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -600,7 +603,8 @@ public:
void
PushEntry(const std::string& identifier, const std::string& appdata = "")
{
mMsids.push_back({ identifier, appdata });
Msid value = { identifier, appdata };
mMsids.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -721,7 +725,8 @@ public:
PushEntry(const std::string& pt, Type type, const std::string& parameter = "",
const std::string& extra = "")
{
mFeedbacks.push_back({ pt, type, parameter, extra });
Feedback value = { pt, type, parameter, extra };
mFeedbacks.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -792,7 +797,8 @@ public:
PushEntry(const std::string& pt, CodecType codec, const std::string& name,
uint32_t clock, uint32_t channels = 0)
{
mRtpmaps.push_back({ pt, codec, name, clock, channels });
Rtpmap value = { pt, codec, name, clock, channels };
mRtpmaps.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -1068,7 +1074,8 @@ public:
PushEntry(const std::string& pt, const std::string& name,
uint32_t streams = 0)
{
mSctpmaps.push_back({ pt, name, streams });
Sctpmap value = { pt, name, streams };
mSctpmaps.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -1168,7 +1175,8 @@ public:
void
PushEntry(uint32_t ssrc, const std::string& attribute)
{
mSsrcs.push_back({ ssrc, attribute });
Ssrc value = { ssrc, attribute };
mSsrcs.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
@ -1204,7 +1212,8 @@ public:
void
PushEntry(Semantics semantics, const std::vector<uint32_t>& ssrcs)
{
mSsrcGroups.push_back({ semantics, ssrcs });
SsrcGroup value = { semantics, ssrcs };
mSsrcGroups.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;

View File

@ -444,8 +444,8 @@ tinybool sdp_timespec_valid (void *sdp_ptr)
}
if ((sdp_p->timespec_p == NULL) ||
(sdp_p->timespec_p->start_time == '\0') ||
(sdp_p->timespec_p->stop_time == '\0')) {
(sdp_p->timespec_p->start_time[0] == '\0') ||
(sdp_p->timespec_p->stop_time[0] == '\0')) {
return (FALSE);
} else {
return (TRUE);

View File

@ -926,8 +926,8 @@ sdp_result_e sdp_parse_timespec (sdp_t *sdp_p, uint16_t level, const char *ptr)
sdp_result_e sdp_build_timespec (sdp_t *sdp_p, uint16_t level, flex_string *fs)
{
if ((sdp_p->timespec_p == NULL) ||
(sdp_p->timespec_p->start_time == '\0') ||
(sdp_p->timespec_p->stop_time == '\0')) {
(sdp_p->timespec_p->start_time[0] == '\0') ||
(sdp_p->timespec_p->stop_time[0] == '\0')) {
if (sdp_p->conf_p->timespec_reqd == TRUE) {
CSFLogError(logTag, "%s Invalid params for t= time spec line, "
"build failed.", sdp_p->debug_str);

View File

@ -1246,7 +1246,8 @@ class SignalingAgent {
if (getRemoteDescription().empty()) {
// Not time to add this, because the unit-test code hasn't set the
// description yet.
deferredCandidates_.push_back({candidate, mid, level, true});
DeferredCandidate candidateStruct = {candidate, mid, level, true};
deferredCandidates_.push_back(candidateStruct);
} else {
AddIceCandidate(candidate, mid, level, true);
}

View File

@ -24,20 +24,13 @@ pref("security.ssl3.ecdhe_rsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_rsa_aes_256_sha", true);
pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true);
pref("security.ssl3.ecdhe_rsa_des_ede3_sha", false);
pref("security.ssl3.dhe_rsa_aes_128_sha", true);
pref("security.ssl3.dhe_rsa_camellia_128_sha", false);
pref("security.ssl3.dhe_rsa_aes_256_sha", true);
pref("security.ssl3.dhe_rsa_camellia_256_sha", false);
pref("security.ssl3.dhe_rsa_des_ede3_sha", false);
pref("security.ssl3.dhe_dss_aes_128_sha", true);
pref("security.ssl3.dhe_dss_aes_256_sha", false);
pref("security.ssl3.dhe_dss_aes_128_sha", false);
pref("security.ssl3.ecdhe_rsa_rc4_128_sha", true);
pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", true);
pref("security.ssl3.rsa_aes_128_sha", true);
pref("security.ssl3.rsa_camellia_128_sha", false);
pref("security.ssl3.rsa_aes_256_sha", true);
pref("security.ssl3.rsa_camellia_256_sha", false);
pref("security.ssl3.rsa_des_ede3_sha", true);
pref("security.ssl3.rsa_rc4_128_sha", true);
pref("security.ssl3.rsa_rc4_128_md5", true);

View File

@ -21,6 +21,7 @@
#include "mozilla/net/RemoteOpenFileParent.h"
#include "mozilla/net/ChannelDiverterParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/network/TCPSocketParent.h"
#include "mozilla/dom/network/TCPServerSocketParent.h"
@ -41,6 +42,7 @@
#include "mozilla/net/OfflineObserver.h"
using mozilla::dom::ContentParent;
using mozilla::dom::TabContext;
using mozilla::dom::TabParent;
using mozilla::net::PTCPSocketParent;
using mozilla::dom::TCPSocketParent;
@ -113,22 +115,23 @@ NeckoParent::GetValidatedAppInfo(const SerializedLoadContext& aSerialized,
}
}
const InfallibleTArray<PBrowserParent*>& browsers = aContent->ManagedPBrowserParent();
for (uint32_t i = 0; i < browsers.Length(); i++) {
nsRefPtr<TabParent> tabParent = static_cast<TabParent*>(browsers[i]);
uint32_t appId = tabParent->OwnOrContainingAppId();
nsTArray<TabContext> contextArray =
static_cast<ContentParent*>(aContent)->GetManagedTabContext();
for (uint32_t i = 0; i < contextArray.Length(); i++) {
TabContext tabContext = contextArray[i];
uint32_t appId = tabContext.OwnOrContainingAppId();
bool inBrowserElement = aSerialized.IsNotNull() ? aSerialized.mIsInBrowserElement
: tabParent->IsBrowserElement();
: tabContext.IsBrowserElement();
if (appId == NECKO_UNKNOWN_APP_ID) {
continue;
}
// We may get appID=NO_APP if child frame is neither a browser nor an app
if (appId == NECKO_NO_APP_ID) {
if (tabParent->HasOwnApp()) {
if (tabContext.HasOwnApp()) {
continue;
}
if (UsingNeckoIPCSecurity() && tabParent->IsBrowserElement()) {
if (UsingNeckoIPCSecurity() && tabContext.IsBrowserElement()) {
// <iframe mozbrowser> which doesn't have an <iframe mozapp> above it.
// This is not supported now, and we'll need to do a code audit to make
// sure we can handle it (i.e don't short-circuit using separate
@ -141,7 +144,7 @@ NeckoParent::GetValidatedAppInfo(const SerializedLoadContext& aSerialized,
return nullptr;
}
if (browsers.Length() != 0) {
if (contextArray.Length() != 0) {
return "App does not have permission";
}
@ -521,10 +524,11 @@ NeckoParent::AllocPRemoteOpenFileParent(const SerializedLoadContext& aSerialized
bool haveValidBrowser = false;
bool hasManage = false;
nsCOMPtr<mozIApplication> mozApp;
for (uint32_t i = 0; i < Manager()->ManagedPBrowserParent().Length(); i++) {
nsRefPtr<TabParent> tabParent =
static_cast<TabParent*>(Manager()->ManagedPBrowserParent()[i]);
uint32_t appId = tabParent->OwnOrContainingAppId();
nsTArray<TabContext> contextArray =
static_cast<ContentParent*>(Manager())->GetManagedTabContext();
for (uint32_t i = 0; i < contextArray.Length(); i++) {
TabContext tabContext = contextArray[i];
uint32_t appId = tabContext.OwnOrContainingAppId();
// Note: this enforces that SerializedLoadContext.appID is one of the apps
// in the child process, but there's currently no way to verify the
// request is not from a different app in that process.
@ -814,10 +818,11 @@ NeckoParent::OfflineNotification(nsISupports *aSubject)
uint32_t targetAppId = NECKO_UNKNOWN_APP_ID;
info->GetAppId(&targetAppId);
for (uint32_t i = 0; i < Manager()->ManagedPBrowserParent().Length(); ++i) {
nsRefPtr<TabParent> tabParent =
static_cast<TabParent*>(Manager()->ManagedPBrowserParent()[i]);
uint32_t appId = tabParent->OwnOrContainingAppId();
nsTArray<TabContext> contextArray =
static_cast<ContentParent*>(Manager())->GetManagedTabContext();
for (uint32_t i = 0; i < contextArray.Length(); ++i) {
TabContext tabContext = contextArray[i];
uint32_t appId = tabContext.OwnOrContainingAppId();
if (appId == targetAppId) {
if (gIOService) {

View File

@ -644,28 +644,14 @@ static const CipherPref sCipherPrefs[] = {
{ "security.ssl3.ecdhe_ecdsa_aes_256_sha",
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true },
{ "security.ssl3.ecdhe_rsa_des_ede3_sha",
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false }, // deprecated (3DES)
{ "security.ssl3.dhe_rsa_aes_128_sha",
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true },
{ "security.ssl3.dhe_rsa_camellia_128_sha",
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, false }, // deprecated (Camellia)
{ "security.ssl3.dhe_rsa_aes_256_sha",
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
{ "security.ssl3.dhe_rsa_camellia_256_sha",
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, false }, // deprecated (Camellia)
{ "security.ssl3.dhe_rsa_des_ede3_sha",
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false }, // deprecated (3DES)
{ "security.ssl3.dhe_dss_aes_128_sha",
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, true }, // deprecated (DSS)
{ "security.ssl3.dhe_dss_aes_256_sha",
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, false }, // deprecated (DSS)
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, false }, // deprecated (DSS)
{ "security.ssl3.ecdhe_rsa_rc4_128_sha",
TLS_ECDHE_RSA_WITH_RC4_128_SHA, true, true }, // deprecated (RC4)
@ -674,12 +660,8 @@ static const CipherPref sCipherPrefs[] = {
{ "security.ssl3.rsa_aes_128_sha",
TLS_RSA_WITH_AES_128_CBC_SHA, true }, // deprecated (RSA key exchange)
{ "security.ssl3.rsa_camellia_128_sha",
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, false }, // deprecated (RSA, Camellia)
{ "security.ssl3.rsa_aes_256_sha",
TLS_RSA_WITH_AES_256_CBC_SHA, true }, // deprecated (RSA key exchange)
{ "security.ssl3.rsa_camellia_256_sha",
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, false }, // deprecated (RSA, Camellia)
{ "security.ssl3.rsa_des_ede3_sha",
TLS_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (RSA key exchange, 3DES)

View File

@ -18,6 +18,12 @@ let gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
const isDebugBuild = Cc["@mozilla.org/xpcom/debug;1"]
.getService(Ci.nsIDebug2).isDebugBuild;
// The test EV roots are only enabled in debug builds as a security measure.
//
// Bug 1008316: B2G doesn't have EV enabled, so EV is not expected even in debug
// builds.
const gEVExpected = isDebugBuild && !("@mozilla.org/b2g-process-global;1" in Cc);
const SSS_STATE_FILE_NAME = "SiteSecurityServiceState.txt";
const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;

View File

@ -5,13 +5,6 @@
"use strict";
// XXX: The isDebugBuild tests you see are here because the test EV root is
// only enabled for EV in debug builds, as a security measure. An ugly hack.
//
// Bug 1008316: B2G doesn't have EV enabled, so EV is not expected even in debug
// builds.
const gEVExpected = isDebugBuild && !("@mozilla.org/b2g-process-global;1" in Cc);
do_get_profile(); // must be called before getting nsIX509CertDB
const certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
@ -33,7 +26,7 @@ let certList = [
// Testing a root that looks like EV but is not EV enabled
'int-non-ev-root',
'non-ev-root',
]
];
function load_ca(ca_name) {
var ca_filename = ca_name + ".der";

View File

@ -114,12 +114,12 @@ function checkForKeyType(keyType, inadequateKeySize, adequateKeySize) {
// in such a build.
let intFullName = intOKName + "-" + rootOKName;
let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName;
let expectedNamesForOCSP = isDebugBuild
let expectedNamesForOCSP = gEVExpected
? [ intFullName,
eeFullName ]
: [ eeFullName ];
addKeySizeTestForEV(expectedNamesForOCSP, rootOKCertFileName,
[ intFullName ], eeFullName, isDebugBuild);
[ intFullName ], eeFullName, gEVExpected);
// Chain with a root cert that has an inadequate size for EV, but
// adequate size for DV
@ -133,7 +133,7 @@ function checkForKeyType(keyType, inadequateKeySize, adequateKeySize) {
// adequate size for DV
intFullName = intNotOKName + "-" + rootOKName;
eeFullName = eeOKName + "-" + intNotOKName + "-" + rootOKName;
expectedNamesForOCSP = isDebugBuild
expectedNamesForOCSP = gEVExpected
? [ intFullName ]
: [ eeFullName ];
addKeySizeTestForEV(expectedNamesForOCSP, rootOKCertFileName,

View File

@ -24,9 +24,6 @@ support-files =
[test_hmac.js]
[test_sts_preloadlist_perwindowpb.js]
# Bug 978426: Test fails consistently only on B2G ARM
skip-if = buildapp == "b2g" && processor == "arm"
[test_sts_preloadlist_selfdestruct.js]
[test_sts_holepunch.js]
[test_sts_ipv4_ipv6.js]
@ -84,8 +81,6 @@ run-sequentially = hardcoded ports
[test_keysize.js]
[test_keysize_ev.js]
run-sequentially = hardcoded ports
# Bug 1008316: B2G doesn't have EV enabled
skip-if = buildapp == "b2g"
[test_cert_chains.js]
run-sequentially = hardcoded ports
[test_client_cert.js]

View File

@ -757,6 +757,12 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
case GeneralNameType::dNSName:
matches = PresentedDNSIDMatchesReferenceDNSID(
presentedID, ValidDNSIDMatchType::NameConstraint, base);
// If matches is not false, then base must be syntactically valid
// because PresentedDNSIDMatchesReferenceDNSID verifies that.
if (!matches &&
!IsValidDNSID(base, ValidDNSIDMatchType::NameConstraint)) {
return Result::ERROR_CERT_NOT_IN_NAME_SPACE;
}
break;
case GeneralNameType::iPAddress:
@ -846,15 +852,15 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
// follow NSS's stricter policy by accepting wildcards only of the form
// <x>*.<DNSID>, where <x> may be empty.
//
// An absolute presented DNS ID matches an absolute reference ID and a relative
// reference ID, and vice-versa. For example, all of these are matches:
// An relative presented DNS ID matches both an absolute reference ID and a
// relative reference ID. Absolute presented DNS IDs are not supported:
//
// Presented ID Reference ID
// ---------------------------
// example.com example.com
// example.com. example.com
// example.com example.com.
// example.com. exmaple.com.
// Presented ID Reference ID Result
// -------------------------------------
// example.com example.com Match
// example.com. example.com Mismatch
// example.com example.com. Match
// example.com. example.com. Mismatch
//
// There are more subtleties documented inline in the code.
//
@ -929,22 +935,16 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
// Q: Are name constraints allowed to be specified as absolute names?
// For example, does a presented ID of "example.com" match a name
// constraint of "example.com." and vice versa.
// A: Relative DNSNames match relative DNSName constraints but not
// absolute DNSName constraints. Absolute DNSNames match absolute
// DNSName constraints but not relative DNSName constraints (except "";
// see below). This follows from the requirement that matching DNSNames
// are constructed "by simply adding zero or more labels to the
// left-hand side" of the constraint.
// A: Absolute names are not supported as presented IDs or name
// constraints. Only reference IDs may be absolute.
//
// Q: Are "" and "." valid DNSName constraints? If so, what do they mean?
// A: Yes, both are valid. All relative and absolute DNSNames match
// a constraint of "" because any DNSName can be formed "by simply
// adding zero or more labels to the left-hand side" of "". In
// particular, an excludedSubtrees DNSName constraint of "" forbids all
// DNSNames. Only absolute names match a DNSName constraint of ".";
// relative DNSNames do not match "." because one cannot form a relative
// DNSName "by simply adding zero or more labels to the left-hand side"
// of "." (all such names would be absolute).
// Q: Is "" a valid DNSName constraints? If so, what does it mean?
// A: Yes. Any valid presented DNSName can be formed "by simply adding zero
// or more labels to the left-hand side" of "". In particular, an
// excludedSubtrees DNSName constraint of "" forbids all DNSNames.
//
// Q: Is "." a valid DNSName constraints? If so, what does it mean?
// A: No, because absolute names are not allowed (see above).
//
// [0] RFC 6265 (Cookies) Domain Matching rules:
// http://tools.ietf.org/html/rfc6265#section-5.1.3
@ -1043,55 +1043,42 @@ PresentedDNSIDMatchesReferenceDNSID(
return false;
}
bool isFirstPresentedByte = true;
do {
uint8_t presentedByte;
if (presented.Read(presentedByte) != Success) {
// We only allow wildcard labels that consist only of '*'.
if (presented.Peek('*')) {
Result rv = presented.Skip(1);
if (rv != Success) {
assert(false);
return false;
}
if (presentedByte == '*') {
// RFC 6125 is unclear about whether "www*.example.org" matches
// "www.example.org". The Chromium test suite has this test:
//
// { false, "w.bar.foo.com", "w*.bar.foo.com" },
//
// We agree with Chromium by forbidding "*" from expanding to the empty
// string.
do {
uint8_t referenceByte;
if (reference.Read(referenceByte) != Success) {
return false;
}
} while (!reference.Peek('.'));
// We also don't allow a non-IDN presented ID label to match an IDN
// reference ID label, except when the entire presented ID label is "*".
// This avoids confusion when matching a presented ID like
// "xn-*.example.org" against "xn--www.example.org" (which attempts to
// abuse the punycode syntax) or "www-*.example.org" against
// "xn--www--ep4c4a2kpf" (which makes sense to match, semantically, but
// no implementations actually do).
if (!isFirstPresentedByte && StartsWithIDNALabel(referenceDNSID)) {
return false;
}
} else {
// Allow an absolute presented DNS ID to match a relative reference DNS
// ID.
if (reference.AtEnd() && presented.AtEnd() && presentedByte == '.') {
return true;
}
do {
uint8_t referenceByte;
if (reference.Read(referenceByte) != Success) {
return false;
}
if (LocaleInsensitveToLower(presentedByte) !=
LocaleInsensitveToLower(referenceByte)) {
} while (!reference.Peek('.'));
}
for (;;) {
uint8_t presentedByte;
if (presented.Read(presentedByte) != Success) {
return false;
}
uint8_t referenceByte;
if (reference.Read(referenceByte) != Success) {
return false;
}
if (LocaleInsensitveToLower(presentedByte) !=
LocaleInsensitveToLower(referenceByte)) {
return false;
}
if (presented.AtEnd()) {
// Don't allow presented IDs to be absolute.
if (presentedByte == '.') {
return false;
}
break;
}
isFirstPresentedByte = false;
} while (!presented.AtEnd());
}
// Allow a relative presented DNS ID to match an absolute reference DNS ID,
// unless we're matching a name constraint.
@ -1577,16 +1564,34 @@ IsValidDNSID(Input hostname, ValidDNSIDMatchType matchType)
return true;
}
bool allowWildcard = matchType == ValidDNSIDMatchType::PresentedID;
bool isWildcard = false;
size_t dotCount = 0;
size_t labelLength = 0;
bool labelIsAllNumeric = false;
bool labelIsWildcard = false;
bool labelEndsWithHyphen = false;
bool isFirstByte = true;
// Only presented IDs are allowed to have wildcard labels. And, like
// Chromium, be stricter than RFC 6125 requires by insisting that a
// wildcard label consist only of '*'.
bool isWildcard = matchType == ValidDNSIDMatchType::PresentedID &&
input.Peek('*');
bool isFirstByte = !isWildcard;
if (isWildcard) {
Result rv = input.Skip(1);
if (rv != Success) {
assert(false);
return false;
}
uint8_t b;
rv = input.Read(b);
if (rv != Success) {
return false;
}
if (b != '.') {
return false;
}
++dotCount;
}
do {
static const size_t MAX_LABEL_LENGTH = 63;
@ -1595,14 +1600,6 @@ IsValidDNSID(Input hostname, ValidDNSIDMatchType matchType)
if (input.Read(b) != Success) {
return false;
}
if (labelIsWildcard) {
// Like NSS, be stricter than RFC6125 requires by insisting that the
// "*" must be the last character in the label. This also prevents
// multiple "*" in the label.
if (b != '.') {
return false;
}
}
switch (b) {
case '-':
if (labelLength == 0) {
@ -1657,20 +1654,6 @@ IsValidDNSID(Input hostname, ValidDNSIDMatchType matchType)
}
break;
case '*':
if (!allowWildcard) {
return false;
}
labelIsWildcard = true;
isWildcard = true;
labelIsAllNumeric = false;
labelEndsWithHyphen = false;
++labelLength;
if (labelLength > MAX_LABEL_LENGTH) {
return false;
}
break;
case '.':
++dotCount;
if (labelLength == 0 &&
@ -1681,8 +1664,6 @@ IsValidDNSID(Input hostname, ValidDNSIDMatchType matchType)
if (labelEndsWithHyphen) {
return false; // Labels must not end with a hyphen.
}
allowWildcard = false; // only allowed in the first label.
labelIsWildcard = false;
labelLength = 0;
break;
@ -1692,6 +1673,12 @@ IsValidDNSID(Input hostname, ValidDNSIDMatchType matchType)
isFirstByte = false;
} while (!input.AtEnd());
// Only reference IDs, not presented IDs or name constraints, may be
// absolute.
if (labelLength == 0 && matchType != ValidDNSIDMatchType::ReferenceID) {
return false;
}
if (labelEndsWithHyphen) {
return false; // Labels must not end with a hyphen.
}

View File

@ -89,24 +89,24 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
// digits
DNS_ID_MATCH("a1", "a1"),
// A trailing dot indicates an absolute name, and absolute names can match
// relative names, and vice-versa.
// A trailing dot indicates an absolute name. Absolute presented names are
// not allowed, but absolute reference names are allowed.
DNS_ID_MATCH("example", "example"),
DNS_ID_MATCH("example.", "example."),
DNS_ID_MISMATCH("example.", "example."),
DNS_ID_MATCH("example", "example."),
DNS_ID_MATCH("example.", "example"),
DNS_ID_MISMATCH("example.", "example"),
DNS_ID_MATCH("example.com", "example.com"),
DNS_ID_MATCH("example.com.", "example.com."),
DNS_ID_MISMATCH("example.com.", "example.com."),
DNS_ID_MATCH("example.com", "example.com."),
DNS_ID_MATCH("example.com.", "example.com"),
DNS_ID_MISMATCH("example.com.", "example.com"),
DNS_ID_MISMATCH("example.com..", "example.com."),
DNS_ID_MISMATCH("example.com..", "example.com"),
DNS_ID_MISMATCH("example.com...", "example.com."),
// xn-- IDN prefix
DNS_ID_MATCH("x*.b.a", "xa.b.a"),
DNS_ID_MATCH("x*.b.a", "xna.b.a"),
DNS_ID_MATCH("x*.b.a", "xn-a.b.a"),
DNS_ID_MISMATCH("x*.b.a", "xa.b.a"),
DNS_ID_MISMATCH("x*.b.a", "xna.b.a"),
DNS_ID_MISMATCH("x*.b.a", "xn-a.b.a"),
DNS_ID_MISMATCH("x*.b.a", "xn--a.b.a"),
DNS_ID_MISMATCH("xn*.b.a", "xn--a.b.a"),
DNS_ID_MISMATCH("xn-*.b.a", "xn--a.b.a"),
@ -150,7 +150,8 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
DNS_ID_MISMATCH("w*w.bar.foo.c0m", "wwww.bar.foo.com"),
DNS_ID_MATCH("wa*.bar.foo.com", "WALLY.bar.foo.com"),
// '*' must be the only character in the wildcard label
DNS_ID_MISMATCH("wa*.bar.foo.com", "WALLY.bar.foo.com"),
// We require "*" to be the last character in a wildcard label, but
// Chromium does not.
@ -199,8 +200,9 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
DNS_ID_MISMATCH("*.example.com", "example.com"),
// (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
// be taken to match baz1.example.net and foobaz.example.net and
// buzz.example.net, respectively
DNS_ID_MATCH("baz*.example.net", "baz1.example.net"),
// buzz.example.net, respectively. However, we don't allow any characters
// other than '*' in the wildcard label.
DNS_ID_MISMATCH("baz*.example.net", "baz1.example.net"),
// Both of these are different from Chromium, but match NSS, becaues the
// wildcard character "*" is not the last character of the label.
@ -245,17 +247,18 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
// Absolute vs relative DNS name tests. Although not explicitly specified
// in RFC 6125, absolute reference names (those ending in a .) should
// match either absolute or relative presented names.
// match either absolute or relative presented names. We don't allow
// absolute presented names.
// TODO: File errata against RFC 6125 about this.
DNS_ID_MATCH("foo.com.", "foo.com"),
DNS_ID_MISMATCH("foo.com.", "foo.com"),
DNS_ID_MATCH("foo.com", "foo.com."),
DNS_ID_MATCH("foo.com.", "foo.com."),
DNS_ID_MATCH("f.", "f"),
DNS_ID_MISMATCH("foo.com.", "foo.com."),
DNS_ID_MISMATCH("f.", "f"),
DNS_ID_MATCH("f", "f."),
DNS_ID_MATCH("f.", "f."),
DNS_ID_MATCH("*.bar.foo.com.", "www-3.bar.foo.com"),
DNS_ID_MISMATCH("f.", "f."),
DNS_ID_MISMATCH("*.bar.foo.com.", "www-3.bar.foo.com"),
DNS_ID_MATCH("*.bar.foo.com", "www-3.bar.foo.com."),
DNS_ID_MATCH("*.bar.foo.com.", "www-3.bar.foo.com."),
DNS_ID_MISMATCH("*.bar.foo.com.", "www-3.bar.foo.com."),
// We require the reference ID to be a valid DNS name, so we cannot test this
// case.
@ -269,8 +272,10 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
// The result is different than Chromium because we don't know that co.uk is
// a TLD.
DNS_ID_MATCH("*.co.uk.", "foo.co.uk"),
DNS_ID_MATCH("*.co.uk.", "foo.co.uk."),
DNS_ID_MATCH("*.co.uk", "foo.co.uk"),
DNS_ID_MATCH("*.co.uk", "foo.co.uk."),
DNS_ID_MISMATCH("*.co.uk.", "foo.co.uk"),
DNS_ID_MISMATCH("*.co.uk.", "foo.co.uk."),
};
struct InputValidity
@ -309,10 +314,10 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a.b..c", false, false),
I(".a.b.c.", false, false),
// absolute names
I("a.", true, true),
I("a.b.", true, true),
I("a.b.c.", true, true),
// absolute names (only allowed for reference names)
I("a.", true, false),
I("a.b.", true, false),
I("a.b.c.", true, false),
// absolute names with empty label at end
I("a..", false, false),
@ -432,17 +437,18 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a-----------------b", true, true),
// Wildcard specifications are not valid reference names, but are valid
// presented names if there are enough labels
// presented names if there are enough labels and if '*' is the only
// character in the wildcard label.
I("*.a", false, false),
I("a*", false, false),
I("a*.", false, false),
I("a*.a", false, false),
I("a*.a.", false, false),
I("*.a.b", false, true),
I("*.a.b.", false, true),
I("a*.b.c", false, true),
I("*.a.b.", false, false),
I("a*.b.c", false, false),
I("*.a.b.c", false, true),
I("a*.b.c.d", false, true),
I("a*.b.c.d", false, false),
// Multiple wildcards are not allowed.
I("a**.b.c", false, false),
@ -463,9 +469,9 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a*b.c.d", false, false),
// Wildcards not allowed with IDNA prefix
I("x*.a.b", false, true),
I("xn*.a.b", false, true),
I("xn-*.a.b", false, true),
I("x*.a.b", false, false),
I("xn*.a.b", false, false),
I("xn-*.a.b", false, false),
I("xn--*.a.b", false, false),
I("xn--w*.a.b", false, false),
@ -1074,7 +1080,6 @@ static const uint8_t ipv6_other_addr_bytes[] = {
static const uint8_t ipv4_other_addr_bytes[] = {
5, 6, 7, 8
};
static const uint8_t ipv4_other_addr_str[] = "5.6.7.8";
static const uint8_t ipv4_other_addr_bytes_FFFFFFFF[] = {
5, 6, 7, 8, 0xff, 0xff, 0xff, 0xff
};
@ -1762,25 +1767,30 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
// For example, does a presented ID of "example.com" match a name
// constraint of "example.com." and vice versa.
//
{ ByteString(), DNSName("example.com"),
{ // The DNSName in the constraint is not valid because constraint DNS IDs
// are not allowed to be absolute.
ByteString(), DNSName("example.com"),
GeneralSubtree(DNSName("example.com.")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE,
},
{ ByteString(), DNSName("example.com."),
{ // The DNSName in the SAN is not valid because presented DNS IDs are not
// allowed to be absolute.
ByteString(), DNSName("example.com."),
GeneralSubtree(DNSName("example.com")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success,
},
{ // The presented ID is the same length as the constraint, because the
// subdomain is only one character long and because the constraint both
// begins and ends with ".".
// begins and ends with ".". But, it doesn't matter because absolute names
// are not allowed for DNSName constraints.
ByteString(), DNSName("p.example.com"),
GeneralSubtree(DNSName(".example.com.")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE,
},
{ // Same as previous test case, but using a wildcard presented ID.
ByteString(), DNSName("*.example.com"),
GeneralSubtree(DNSName(".example.com.")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
// Q: Are "" and "." valid DNSName constraints? If so, what do they mean?
@ -1788,17 +1798,19 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
GeneralSubtree(DNSName("")),
Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
{ ByteString(), DNSName("example.com."),
{ // The malformed (absolute) presented ID does not match.
ByteString(), DNSName("example.com."),
GeneralSubtree(DNSName("")),
Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
},
{ ByteString(), DNSName("example.com"),
{ // Invalid syntax in name constraint -> ERROR_CERT_NOT_IN_NAME_SPACE.
ByteString(), DNSName("example.com"),
GeneralSubtree(DNSName(".")),
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success,
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE,
},
{ ByteString(), DNSName("example.com."),
GeneralSubtree(DNSName(".")),
Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
},
/////////////////////////////////////////////////////////////////////////////
@ -1908,12 +1920,12 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
},
{ // The presented IPv4 constraint is truncated
ByteString(), IPAddress(ipv4_addr_bytes),
GeneralSubtree(IPAddress(ipv4_addr_truncated_bytes)),
GeneralSubtree(IPAddress(ipv4_constraint_truncated_bytes)),
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
},
{ // The presented IPv4 constraint is too long
ByteString(), IPAddress(ipv4_addr_bytes),
GeneralSubtree(IPAddress(ipv4_addr_overlong_bytes)),
GeneralSubtree(IPAddress(ipv4_constraint_overlong_bytes)),
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
},
{ // The presented IPv6 address is empty
@ -1938,12 +1950,12 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
},
{ // The presented IPv6 constraint is truncated
ByteString(), IPAddress(ipv6_addr_bytes),
GeneralSubtree(IPAddress(ipv6_addr_truncated_bytes)),
GeneralSubtree(IPAddress(ipv6_constraint_truncated_bytes)),
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
},
{ // The presented IPv6 constraint is too long
ByteString(), IPAddress(ipv6_addr_bytes),
GeneralSubtree(IPAddress(ipv6_addr_overlong_bytes)),
GeneralSubtree(IPAddress(ipv6_constraint_overlong_bytes)),
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
},
@ -2161,4 +2173,4 @@ TEST_P(pkixnames_CheckNameConstraints,
INSTANTIATE_TEST_CASE_P(pkixnames_CheckNameConstraints,
pkixnames_CheckNameConstraints,
testing::ValuesIn(NAME_CONSTRAINT_PARAMS));
testing::ValuesIn(NAME_CONSTRAINT_PARAMS));

View File

@ -298,56 +298,60 @@ DataReportingService.prototype = Object.freeze({
}.bind(this));
},
_loadClientID: Task.async(function* () {
_loadClientID: function () {
if (this._loadClientIdTask) {
return this._loadClientIdTask;
}
// Previously we had the stable client ID managed in FHR.
// As we want to start correlating FHR and telemetry data (and moving towards
// unifying the two), we moved the ID management to the datareporting
// service. Consequently, we try to import the FHR ID first, so we can keep
// using it.
this._loadClientIdTask = Task.spawn(function* () {
// Previously we had the stable client ID managed in FHR.
// As we want to start correlating FHR and telemetry data (and moving towards
// unifying the two), we moved the ID management to the datareporting
// service. Consequently, we try to import the FHR ID first, so we can keep
// using it.
// Try to load the client id from the DRS state file first.
try {
let state = yield CommonUtils.readJSON(this._stateFilePath);
if (state && 'clientID' in state && typeof(state.clientID) == 'string') {
this._clientID = state.clientID;
this._loadClientIdTask = null;
return this._clientID;
// Try to load the client id from the DRS state file first.
try {
let state = yield CommonUtils.readJSON(this._stateFilePath);
if (state && 'clientID' in state && typeof(state.clientID) == 'string') {
this._clientID = state.clientID;
this._loadClientIdTask = null;
return this._clientID;
}
} catch (e) {
// fall through to next option
}
} catch (e) {
// fall through to next option
}
// If we dont have DRS state yet, try to import from the FHR state.
try {
let fhrStatePath = OS.Path.join(OS.Constants.Path.profileDir, "healthreport", "state.json");
let state = yield CommonUtils.readJSON(fhrStatePath);
if (state && 'clientID' in state && typeof(state.clientID) == 'string') {
this._clientID = state.clientID;
this._loadClientIdTask = null;
this._saveClientID();
return this._clientID;
// If we dont have DRS state yet, try to import from the FHR state.
try {
let fhrStatePath = OS.Path.join(OS.Constants.Path.profileDir, "healthreport", "state.json");
let state = yield CommonUtils.readJSON(fhrStatePath);
if (state && 'clientID' in state && typeof(state.clientID) == 'string') {
this._clientID = state.clientID;
this._loadClientIdTask = null;
this._saveClientID();
return this._clientID;
}
} catch (e) {
// fall through to next option
}
} catch (e) {
// fall through to next option
}
// We dont have an id from FHR yet, generate a new ID.
this._clientID = CommonUtils.generateUUID();
this._loadClientIdTask = null;
this._saveClientIdTask = this._saveClientID();
// We dont have an id from FHR yet, generate a new ID.
this._clientID = CommonUtils.generateUUID();
this._loadClientIdTask = null;
this._saveClientIdTask = this._saveClientID();
// Wait on persisting the id. Otherwise failure to save the ID would result in
// the client creating and subsequently sending multiple IDs to the server.
// This would appear as multiple clients submitting similar data, which would
// result in orphaning.
yield this._saveClientIdTask;
// Wait on persisting the id. Otherwise failure to save the ID would result in
// the client creating and subsequently sending multiple IDs to the server.
// This would appear as multiple clients submitting similar data, which would
// result in orphaning.
yield this._saveClientIdTask;
return this._clientID;
}),
return this._clientID;
}.bind(this));
return this._loadClientIdTask;
},
_saveClientID: Task.async(function* () {
let obj = { clientID: this._clientID };
@ -364,13 +368,8 @@ DataReportingService.prototype = Object.freeze({
* @return Promise<string> The stable client ID.
*/
getClientID: function() {
if (this._loadClientIdTask) {
return this._loadClientIdTask;
}
if (!this._clientID) {
this._loadClientIdTask = this._loadClientID();
return this._loadClientIdTask;
return this._loadClientID();
}
return Promise.resolve(this._clientID);

View File

@ -191,7 +191,7 @@ class MochitestRunner(MozbuildObject):
rerun_failures=False, no_autorun=False, repeat=0, run_until_failure=False,
slow=False, chunk_by_dir=0, total_chunks=None, this_chunk=None, extraPrefs=[],
jsdebugger=False, debug_on_failure=False, start_at=None, end_at=None,
e10s=False, content_sandbox='off', dmd=False, dump_output_directory=None,
e10s=False, strict_content_sandbox=False, dmd=False, dump_output_directory=None,
dump_about_memory_after_test=False, dump_dmd_after_test=False,
install_extension=None, quiet=False, environment=[], app_override=None, bisectChunk=None, runByDir=False,
useTestMediaDevices=False, timeout=None, **kwargs):
@ -313,9 +313,7 @@ class MochitestRunner(MozbuildObject):
options.startAt = start_at
options.endAt = end_at
options.e10s = e10s
options.contentSandbox = content_sandbox
if options.contentSandbox != 'off':
options.e10s = True
options.strictContentSandbox = strict_content_sandbox
options.dumpAboutMemoryAfterTest = dump_about_memory_after_test
options.dumpDMDAfterTest = dump_dmd_after_test
options.dumpOutputDirectory = dump_output_directory
@ -502,13 +500,13 @@ def MochitestCommand(func):
help='Start the browser JS debugger before running the test. Implies --no-autorun.')
func = jsdebugger(func)
this_chunk = CommandArgument('--e10s', action='store_true',
e10s = CommandArgument('--e10s', action='store_true',
help='Run tests with electrolysis preferences and test filtering enabled.')
func = this_chunk(func)
func = e10s(func)
this_chunk = CommandArgument('--content-sandbox', default='off', choices=['off', 'warn', 'on'],
help='Run tests with the content sandbox enabled or in warn only mode (Windows only). --e10s is assumed.')
func = this_chunk(func)
strict_content_sandbox = CommandArgument('--strict-content-sandbox', action='store_true',
help='Run tests with a more strict content sandbox (Windows only).')
func = strict_content_sandbox(func)
dmd = CommandArgument('--dmd', action='store_true',
help='Run tests with DMD active.')

View File

@ -363,11 +363,11 @@ class MochitestOptions(optparse.OptionParser):
"dest": "e10s",
"help": "Run tests with electrolysis preferences and test filtering enabled.",
}],
[["--content-sandbox"],
{ "choices": ["off", "warn", "on"],
"default": "off",
"dest": "contentSandbox",
"help": "Run tests with the content sandbox enabled or in warn only mode (Windows only). --e10s is assumed.",
[["--strict-content-sandbox"],
{ "action": "store_true",
"default": False,
"dest": "strictContentSandbox",
"help": "Run tests with a more strict content sandbox (Windows only).",
}],
[["--dmd-path"],
{ "action": "store",
@ -479,11 +479,8 @@ class MochitestOptions(optparse.OptionParser):
def verifyOptions(self, options, mochitest):
""" verify correct options and cleanup paths """
if options.contentSandbox != 'off':
options.e10s = True
mozinfo.update({"e10s": options.e10s}) # for test manifest parsing.
mozinfo.update({"contentSandbox": options.contentSandbox}) # for test manifest parsing.
mozinfo.update({"strictContentSandbox": options.strictContentSandbox}) # for test manifest parsing.
if options.app is None:
if build_obj is not None:

View File

@ -1159,7 +1159,8 @@ class Mochitest(MochitestUtilsMixin):
if options.browserChrome and options.timeout:
options.extraPrefs.append("testing.browserTestHarness.timeout=%d" % options.timeout)
options.extraPrefs.append("browser.tabs.remote.autostart=%s" % ('true' if options.e10s else 'false'))
options.extraPrefs.append("browser.tabs.remote.sandbox=%s" % options.contentSandbox)
if options.strictContentSandbox:
options.extraPrefs.append("security.sandbox.windows.content.moreStrict=true")
# get extensions to install
extensions = self.getExtensionsToInstall(options)

View File

@ -79,7 +79,7 @@ function run_test()
run_next_test();
}
add_task(function setup() {
add_task(function* setup() {
// Avoid creating smart bookmarks during the test.
Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1);
@ -107,7 +107,7 @@ add_task(function setup() {
remove_all_bookmarks();
});
add_task(function test_import_new()
add_task(function* test_import_new()
{
// Test importing a Places bookmarks.html file.
// 1. import bookmarks.exported.html
@ -121,7 +121,7 @@ add_task(function test_import_new()
remove_all_bookmarks();
});
add_task(function test_emptytitle_export()
add_task(function* test_emptytitle_export()
{
// Test exporting and importing with an empty-titled bookmark.
// 1. import bookmarks
@ -159,7 +159,7 @@ add_task(function test_emptytitle_export()
remove_all_bookmarks();
});
add_task(function test_import_chromefavicon()
add_task(function* test_import_chromefavicon()
{
// Test exporting and importing with a bookmark pointing to a chrome favicon.
// 1. import bookmarks
@ -225,7 +225,7 @@ add_task(function test_import_chromefavicon()
remove_all_bookmarks();
});
add_task(function test_import_ontop()
add_task(function* test_import_ontop()
{
// Test importing the exported bookmarks.html file *on top of* the existing
// bookmarks.
@ -244,7 +244,7 @@ add_task(function test_import_ontop()
remove_all_bookmarks();
});
function testImportedBookmarks()
function* testImportedBookmarks()
{
for (let group in test_bookmarks) {
do_print("[testImportedBookmarks()] Checking group '" + group + "'");
@ -273,37 +273,7 @@ function testImportedBookmarks()
}
}
function testImportedBookmarksToFolder(aFolder)
{
root = PlacesUtils.getFolderContents(aFolder).root;
// Menu bookmarks are put directly into the folder, while other roots are
// imported into subfolders.
let rootFolderCount = test_bookmarks.menu.length;
for (let i = 0; i < root.childCount; i++) {
let child = root.getChild(i);
// This check depends on all "menu" bookmarks being listed first in the imported file :-|
if (i < rootFolderCount) {
checkItem(test_bookmarks.menu[i], child);
}
else {
let container = child.QueryInterface(Ci.nsINavHistoryContainerResultNode);
let group = /Toolbar/.test(container.title) ? test_bookmarks.toolbar
: test_bookmarks.unfiled;
container.containerOpen = true;
do_print("[testImportedBookmarksToFolder()] Checking container '" + container.title + "'");
for (let t = 0; t < container.childCount; t++) {
checkItem(group[t], container.getChild(t));
}
container.containerOpen = false;
}
}
root.containerOpen = false;
}
function checkItem(aExpected, aNode)
function* checkItem(aExpected, aNode)
{
let id = aNode.itemId;
@ -373,7 +343,9 @@ function checkItem(aExpected, aNode)
folder.containerOpen = true;
do_check_eq(folder.childCount, aExpected.children.length);
aExpected.children.forEach(function (item, index) checkItem(item, folder.getChild(index)));
for (let index = 0; index < aExpected.children.length; index++) {
yield checkItem(aExpected.children[index], folder.getChild(index));
}
folder.containerOpen = false;
break;

View File

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -21,7 +22,7 @@ Prompter.prototype = {
QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory, Ci.nsIPromptService, Ci.nsIPromptService2]),
/* ---------- private memebers ---------- */
/* ---------- private members ---------- */
pickPrompter : function (domWin) {
return new ModalPrompter(domWin);
@ -210,7 +211,7 @@ let PromptUtilsTemp = {
// If the URI explicitly specified a port, only include it when
// it's not the default. (We never want "http://foo.com:80")
port = uri.port;
let port = uri.port;
if (port != -1) {
let handler = Services.io.getProtocolHandler(scheme);
if (port != handler.defaultPort)

Some files were not shown because too many files have changed in this diff Show More