merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2017-02-28 11:24:33 +01:00
Родитель bb298790fe 93e2a0ae63
Коммит 9c1c7106ee
48 изменённых файлов: 922 добавлений и 256 удалений

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

@ -520,6 +520,9 @@
@RESPATH@/components/remotebrowserutils.manifest
@RESPATH@/components/RemoteWebNavigation.js
@RESPATH@/components/ProcessSelector.js
@RESPATH@/components/ProcessSelector.manifest
@RESPATH@/components/SlowScriptDebug.manifest
@RESPATH@/components/SlowScriptDebug.js

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

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import('resource://gre/modules/Services.jsm');
const BASE_PREF = "dom.ipc.processCount"
const PREF_BRANCH = BASE_PREF + ".";
// Utilities:
function getMaxContentParents(processType) {
let maxContentParents = -1;
try {
maxContentParents = Services.prefs.getIntPref(PREF_BRANCH + processType);
} catch (e) {
// Pref probably didn't exist, get the default number of processes.
try {
maxContentParents = Services.prefs.getIntPref(BASE_PREF);
} catch (e) {
// No prefs? That's odd, use only one process.
maxContentParents = 1;
}
}
return maxContentParents;
}
// Fills up aProcesses until max and then selects randomly from the available
// ones.
function RandomSelector() {
}
RandomSelector.prototype = {
classID: Components.ID("{c616fcfd-9737-41f1-aa74-cee72a38f91b}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentProcessProvider]),
provideProcess(aType, aOpener, aProcesses, aCount) {
let maxContentParents = getMaxContentParents(aType);
if (aCount < maxContentParents) {
return Ci.nsIContentProcessProvider.NEW_PROCESS;
}
let startIdx = Math.floor(Math.random() * maxContentParents);
let curIdx = startIdx;
do {
if (aProcesses[curIdx].opener === aOpener) {
return curIdx;
}
curIdx = (curIdx + 1) % maxContentParents;
} while (curIdx !== startIdx);
return Ci.nsIContentProcessProvider.NEW_PROCESS;
},
};
var components = [RandomSelector];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

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

@ -0,0 +1,2 @@
component {c616fcfd-9737-41f1-aa74-cee72a38f91b} ProcessSelector.js
contract @mozilla.org/ipc/processselector;1 {c616fcfd-9737-41f1-aa74-cee72a38f91b}

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

@ -71,6 +71,11 @@ uint32_t TimeoutManager::sNestingLevel = 0;
namespace {
// The maximum number of timer callbacks we will try to run in a single event
// loop runnable.
#define DEFAULT_TARGET_MAX_CONSECUTIVE_CALLBACKS 5
uint32_t gTargetMaxConsecutiveCallbacks;
// The number of queued runnables within the TabGroup ThrottledEventQueue
// at which to begin applying back pressure to the window.
#define DEFAULT_THROTTLED_EVENT_QUEUE_BACK_PRESSURE 5000
@ -182,6 +187,10 @@ TimeoutManager::Initialize()
Preferences::AddUintVarCache(&gBackPressureDelayMinimumMS,
"dom.timeout.back_pressure_delay_minimum_ms",
DEFAULT_BACK_PRESSURE_DELAY_MINIMUM_MS);
Preferences::AddUintVarCache(&gTargetMaxConsecutiveCallbacks,
"dom.timeout.max_consecutive_callbacks",
DEFAULT_TARGET_MAX_CONSECUTIVE_CALLBACKS);
}
uint32_t
@ -444,6 +453,10 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
mTrackingTimeouts,
nullptr,
nullptr);
uint32_t numTimersToRun = 0;
bool targetTimerSeen = false;
while (true) {
Timeout* timeout = expiredIter.Next();
if (!timeout || timeout->When() > deadline) {
@ -461,19 +474,29 @@ TimeoutManager::RunTimeout(Timeout* aTimeout)
last_expired_tracking_timeout = timeout;
}
// Run available timers until we see our target timer. After
// that, however, stop coalescing timers so we can yield the
// main thread. Further timers that are ready will get picked
// up by their own nsITimer runnables when they execute.
// Note that we have seen our target timer. This means we can now
// stop processing timers once we hit our threshold below.
if (timeout == aTimeout) {
targetTimerSeen = true;
}
// Run only a limited number of timers based on the configured
// maximum. Note, we must always run our target timer however.
// Further timers that are ready will get picked up by their own
// nsITimer runnables when they execute.
//
// For chrome windows, however, we do coalesce all timers and
// do not yield the main thread. This is partly because we
// trust chrome windows not to misbehave and partly because a
// number of browser chrome tests have races that depend on this
// coalescing.
if (timeout == aTimeout && !mWindow.IsChromeWindow()) {
if (targetTimerSeen &&
numTimersToRun >= gTargetMaxConsecutiveCallbacks &&
!mWindow.IsChromeWindow()) {
break;
}
numTimersToRun += 1;
}
expiredIter.UpdateIterator();

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

@ -62,6 +62,12 @@ attribute OfflineResourceList.onupdateready
attribute OfflineResourceList.oncached
attribute OfflineResourceList.onobsolete
// Non-standard IndexedDB API
method IDBDatabase.createMutableFile
method IDBDatabase.mozCreateFileHandle
method IDBMutableFile.open
method IDBMutableFile.getFile
// DataTransfer API (gecko-only methods)
method DataTransfer.addElement
attribute DataTransfer.mozItemCount

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

@ -401,6 +401,8 @@ EXTRA_COMPONENTS += [
'contentAreaDropListener.manifest',
'messageWakeupService.js',
'messageWakeupService.manifest',
'ProcessSelector.js',
'ProcessSelector.manifest',
'SlowScriptDebug.js',
'SlowScriptDebug.manifest',
]

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

@ -11,6 +11,7 @@ XPIDL_SOURCES += [
'nsIContentPermissionPrompt.idl',
'nsIContentPrefService.idl',
'nsIContentPrefService2.idl',
'nsIContentProcess.idl',
'nsIContentURIGrouper.idl',
'nsIDOMChromeWindow.idl',
'nsIDOMClientRect.idl',

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

@ -0,0 +1,53 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMElement;
interface nsIMessageSender;
interface nsIURI;
[scriptable, builtinclass, uuid(456f58be-29dd-4973-885b-95aece1c9a8a)]
interface nsIContentProcessInfo : nsISupports
{
/**
* Is this content process alive?
*/
readonly attribute boolean isAlive;
/**
* The content process's PID.
* Throws if the process is not alive.
*/
readonly attribute int32_t processId;
/**
* This content process's opener.
*/
readonly attribute nsIContentProcessInfo opener;
/**
* The process manager for this ContentParent (so a process message manager
* as opposed to a frame message manager.
*/
readonly attribute nsIMessageSender messageManager;
};
[scriptable, uuid(83ffb063-5f65-4c45-ae07-3f553e0809bb)]
interface nsIContentProcessProvider : nsISupports
{
/**
* Return this from provideProcess to create a new process.
*/
const int32_t NEW_PROCESS = -1;
/**
* Given aAliveProcesses (with an opener aOpener), choose which process of
* aType to use. Return nsIContentProcessProvider.NEW_PROCESS to ask the
* caller to create a new content process.
*/
int32_t provideProcess(in AString aType, in nsIContentProcessInfo aOpener,
[array, size_is(aCount)] in nsIContentProcessInfo aAliveProcesses,
in uint32_t aCount);
};

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

@ -112,6 +112,7 @@
#include "nsIAlertsService.h"
#include "nsIClipboard.h"
#include "nsContentPermissionHelper.h"
#include "nsIContentProcess.h"
#include "nsICycleCollectorListener.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDocument.h"
@ -435,6 +436,90 @@ ContentParentsMemoryReporter::CollectReports(
}
nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
namespace {
class ScriptableCPInfo final : public nsIContentProcessInfo
{
public:
explicit ScriptableCPInfo(ContentParent* aParent)
: mContentParent(aParent)
{
MOZ_ASSERT(mContentParent);
}
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPROCESSINFO
void ProcessDied()
{
mContentParent = nullptr;
}
private:
~ScriptableCPInfo()
{
MOZ_ASSERT(!mContentParent, "must call ProcessDied");
}
ContentParent* mContentParent;
};
NS_IMPL_ISUPPORTS(ScriptableCPInfo, nsIContentProcessInfo)
NS_IMETHODIMP
ScriptableCPInfo::GetIsAlive(bool* aIsAlive)
{
*aIsAlive = mContentParent != nullptr;
return NS_OK;
}
NS_IMETHODIMP
ScriptableCPInfo::GetProcessId(int32_t* aPID)
{
if (!mContentParent) {
*aPID = -1;
return NS_ERROR_NOT_INITIALIZED;
}
*aPID = mContentParent->Pid();
if (*aPID == -1) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
ScriptableCPInfo::GetOpener(nsIContentProcessInfo** aInfo)
{
*aInfo = nullptr;
if (!mContentParent) {
return NS_ERROR_NOT_INITIALIZED;
}
if (ContentParent* opener = mContentParent->Opener()) {
nsCOMPtr<nsIContentProcessInfo> info = opener->ScriptableHelper();
info.forget(aInfo);
}
return NS_OK;
}
NS_IMETHODIMP
ScriptableCPInfo::GetMessageManager(nsIMessageSender** aMessenger)
{
*aMessenger = nullptr;
if (!mContentParent) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<nsIMessageSender> manager = mContentParent->GetMessageManager();
manager.forget(aMessenger);
return NS_OK;
}
} // anonymous namespace
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
@ -697,38 +782,65 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
ContentParent* aOpener)
{
nsTArray<ContentParent*>& contentParents = GetOrCreatePool(aRemoteType);
uint32_t maxContentParents = GetMaxProcessCount(aRemoteType);
RefPtr<ContentParent> p;
if (contentParents.Length() >= maxContentParents) {
if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
// We never want to re-use Large-Allocation processes.
if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
if (contentParents.Length() >= maxContentParents) {
return GetNewOrUsedBrowserProcess(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
aPriority,
aOpener);
}
} else {
nsTArray<nsIContentProcessInfo*> infos(contentParents.Length());
for (auto* cp : contentParents) {
infos.AppendElement(cp->mScriptableHelper);
}
if ((p = RandomSelect(contentParents, aOpener, maxContentParents))) {
nsCOMPtr<nsIContentProcessProvider> cpp =
do_GetService("@mozilla.org/ipc/processselector;1");
nsIContentProcessInfo* openerInfo = aOpener ? aOpener->mScriptableHelper.get() : nullptr;
int32_t index;
if (cpp &&
NS_SUCCEEDED(cpp->ProvideProcess(aRemoteType, openerInfo,
infos.Elements(), infos.Length(),
&index))) {
// If the provider returned an existing ContentParent, use that one.
if (0 <= index && static_cast<uint32_t>(index) <= maxContentParents) {
RefPtr<ContentParent> retval = contentParents[index];
return retval.forget();
}
} else {
// If there was a problem with the JS chooser, fall back to a random
// selection.
NS_WARNING("nsIContentProcessProvider failed to return a process");
RefPtr<ContentParent> random;
if (contentParents.Length() >= maxContentParents &&
(random = RandomSelect(contentParents, aOpener, maxContentParents))) {
return random.forget();
}
}
// Try to take the preallocated process only for the default process type.
RefPtr<ContentParent> p;
if (aRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE) &&
(p = PreallocatedProcessManager::Take())) {
// For pre-allocated process we have not set the opener yet.
p->mOpener = aOpener;
contentParents.AppendElement(p);
return p.forget();
}
}
// Try to take the preallocated process only for the default process type.
if (aRemoteType.Equals(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE)) &&
(p = PreallocatedProcessManager::Take())) {
// For pre-allocated process we have not set the opener yet.
p->mOpener = aOpener;
} else {
p = new ContentParent(aOpener, aRemoteType);
// Create a new process from scratch.
RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType);
if (!p->LaunchSubprocess(aPriority)) {
return nullptr;
}
p->Init();
if (!p->LaunchSubprocess(aPriority)) {
return nullptr;
}
p->Init();
contentParents.AppendElement(p);
return p.forget();
}
@ -1204,6 +1316,8 @@ ContentParent::Init()
RefPtr<GeckoMediaPluginServiceParent> gmps(GeckoMediaPluginServiceParent::GetSingleton());
gmps->UpdateContentProcessGMPCapabilities();
mScriptableHelper = new ScriptableCPInfo(this);
}
namespace {
@ -1274,6 +1388,11 @@ ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
void
ContentParent::ShutDownProcess(ShutDownMethod aMethod)
{
if (mScriptableHelper) {
static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
mScriptableHelper = nullptr;
}
// Shutting down by sending a shutdown message works differently than the
// other methods. We first call Shutdown() in the child. After the child is
// ready, it calls FinishShutdown() on us. Then we close the channel.

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

@ -45,6 +45,7 @@
#define LARGE_ALLOCATION_REMOTE_TYPE "webLargeAllocation"
class nsConsoleService;
class nsIContentProcessInfo;
class nsICycleCollectorLogSink;
class nsIDumpGCAndCCLogsCallback;
class nsITabParent;
@ -371,6 +372,10 @@ public:
{
return mOpener;
}
nsIContentProcessInfo* ScriptableHelper() const
{
return mScriptableHelper;
}
bool NeedsPermissionsUpdate() const
{
@ -1173,6 +1178,7 @@ private:
RefPtr<nsConsoleService> mConsoleService;
nsConsoleService* GetConsoleService();
nsCOMPtr<nsIContentProcessInfo> mScriptableHelper;
nsTArray<nsCOMPtr<nsIObserver>> mIdleListeners;

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

@ -39,10 +39,10 @@ partial interface IDBDatabase {
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
readonly attribute StorageType storage;
[Exposed=Window, Throws]
[Exposed=Window, Throws, UseCounter]
IDBRequest createMutableFile (DOMString name, optional DOMString type);
// this is deprecated due to renaming in the spec
[Exposed=Window, Throws]
[Exposed=Window, Throws, UseCounter]
IDBRequest mozCreateFileHandle (DOMString name, optional DOMString type); // now createMutableFile
};

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

@ -10,10 +10,10 @@ interface IDBMutableFile : EventTarget {
readonly attribute IDBDatabase database;
[Throws]
[Throws, UseCounter]
IDBFileHandle open(optional FileMode mode = "readonly");
[Throws]
[Throws, UseCounter]
DOMRequest getFile();
attribute EventHandler onabort;

106
intl/hyphenation/hyphen/NEWS Executable file
Просмотреть файл

@ -0,0 +1,106 @@
2014-09-18 Hyphen 2.8.8:
- remove last coverity warning, 0 remaining
2014-06-27 Hyphen 2.8.7:
- various clang scan-build warning fixes
2012-09-13 Hyphen 2.8.6:
- righthyphenmin fix for 3-byte or more UTF-8
multibyte characters by Steven Dickson
- fix for fdo#43931 (removing hard hyphen hyphenation for LibreOffice)
2012-07-12 Hyphen 2.8.5:
- fix short alloc
2012-06-29 Hyphen 2.8.4:
- coverity warnings
2011-10-10 Hyphen 2.8.3:
- fix NOHYPHEN
- fix unbalanced hyphenation of LibreOffice/OOo
- set default COMPOUNDHYPHENMIN=3 at hyphens and apostrophes
- fix VERBOSE in hyphen.c
- new ./example option: -n to print hyphenation vector
2011-10-07 Hyphen 2.8.2:
- fix for explicite COMPOUNDHYPHENMIN values
2011-10-06 Hyphen 2.8.1:
- force minimal lefthyphenmin and righthyphenmin values of the dictionary
(eg. righthyphenmin=3 of English dictionaries in LibreOffice/OOo,
also the original TeX hyphenation patterns are correct only with this
righthyphenmin value).
2011-10-04 Hyphen 2.8:
- Ignore leading and ending numbers (eg. manual/field based indexes
in LibreOffice/OOo)
- Fix LibreOffice/OpenOffice.org hyphenation errors at apostrophes and
hyphens, n-dashes with default NOHYPHEN separators.
Eg. *o'c=lock -> o'clock.
2010-12-01 Hyphen 2.7.1 bug fix release
2010-11-27 Hyphen 2.7 release:
- The new hyphenation problem of OpenOffice.org 3.2, related to its
modified word breaking of words with hyphen characters, can be fixed
with the new NOHYPHEN feature. Also it's possible to solve the similar old
problem with apostrophes. More information: README.compound.
- improved English dictionaries
2010-08-10 Hyphen 2.6 release:
- maintainance release, fix all warnings, tidy up
make check with VALGRIND=memcheck, etc.
2010-02-23 Hyphen 2.5 release:
- add Unicode ligature support for correct hyphenmin calculation
(ff, fi, fl, St, st are 1-character, ffi and ffl are 2-character length for
hyphenation)
- fix lefthyphenmin calculation for UTF-8 encoded input
- en_US hyphenation dictionary:
- add OpenOffice.org patch to fix apostrophe handling
- add correct hyphenation for words with Unicode f-ligatures
(NOTE: hyphenation within ligatures is not supported yet
because of an implementation problem of OpenOffice.org,
see OOo issue 71608.)
- small patches from OpenOffice.org
2008-05-01 Hyphen 2.4 release:
- compound word hyphenation support by recursive pattern matching
based on two hyphenation pattern sets, see README.compound.
Especially useful for languages with arbitrary number of compounds (Danish,
Dutch, Finnish, German, Hungarian, Icelandic, Norwegian, Swedish etc.).
- new dictionary parameters (minimal character numbers for hyph. distances):
LEFTHYPHENMIN: minimal hyphenation distance from the left end of the word
RIGHTHYPHENMIN: minimal hyphenation distance from the right end of the word
COMPOUNDLEFTHYPHENMIN: min. hyph. dist. from the left compound word boundary
COMPOUNDRIGHTHYPHENMIN: min. hyph. dist. from the right comp. word boundary
- new API function: hnj_hyphen_hyphenate3() (like hyphenate2(), but
with hyphenmin options)
en_US hyphenation patterns:
- extended hyph_en_US.dic with TugBoat hyphenation log (fix thousand
incompletely or badly hyphenated words, for example acad-e-my, acro-nym,
acryl-amide, adren-a-line, aero-space, am-phet-a-mine, anom-aly etc.)
- fixed hyph_en_US.dic: set the right default hyphenation distance of
the original TeX hyphenation patterns:
LEFTHYPHENMIN 2
RIGHTHYPHENMIN 3 (not 2!)
It is not only a typographical issue. It seems, TeX hyphenation
patterns are right only with these settings, for example,
the bad "anoma-ly" is restricted in TeX only by the default
\righthyphenmin=3 (but not restricted in OpenOffice.org, until now).
- documentation (README_hyph_en_US.dic)
- fixes for automake configuration, compiling and checking, see ChangeLog
2008-02-19: Hyphen 2.3.1 release:
- fix obsolete API function hnj_hyphen_hyphenate()

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

@ -78,6 +78,7 @@ enum class DeclarationKind : uint8_t
Const,
Import,
BodyLevelFunction,
ModuleBodyLevelFunction,
LexicalFunction,
VarForAnnexBLexicalFunction,
SimpleCatchParameter,
@ -95,6 +96,7 @@ DeclarationKindToBindingKind(DeclarationKind kind)
case DeclarationKind::Var:
case DeclarationKind::BodyLevelFunction:
case DeclarationKind::ModuleBodyLevelFunction:
case DeclarationKind::VarForAnnexBLexicalFunction:
case DeclarationKind::ForOfVar:
return BindingKind::Var;

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

@ -117,6 +117,7 @@ DeclarationKindString(DeclarationKind kind)
case DeclarationKind::Import:
return "import";
case DeclarationKind::BodyLevelFunction:
case DeclarationKind::ModuleBodyLevelFunction:
case DeclarationKind::LexicalFunction:
return "function";
case DeclarationKind::VarForAnnexBLexicalFunction:
@ -1379,6 +1380,24 @@ Parser<ParseHandler>::noteDeclaredName(HandlePropertyName name, DeclarationKind
break;
}
case DeclarationKind::ModuleBodyLevelFunction: {
MOZ_ASSERT(pc->atModuleLevel());
AddDeclaredNamePtr p = pc->varScope().lookupDeclaredNameForAdd(name);
if (p) {
reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
return false;
}
if (!pc->varScope().addDeclaredName(pc, p, name, kind, pos.begin))
return false;
// Body-level functions in modules are always closed over.
pc->varScope().lookupDeclaredName(name)->value()->setClosedOver();
break;
}
case DeclarationKind::FormalParameter: {
// It is an early error if any non-positional formal parameter name
// (e.g., destructuring formal parameter) is duplicated.
@ -3718,12 +3737,11 @@ Parser<ParseHandler>::functionStmt(YieldHandling yieldHandling, DefaultHandling
if (!noteDeclaredName(name, DeclarationKind::LexicalFunction, pos()))
return null();
} else {
if (!noteDeclaredName(name, DeclarationKind::BodyLevelFunction, pos()))
DeclarationKind kind = pc->atModuleLevel()
? DeclarationKind::ModuleBodyLevelFunction
: DeclarationKind::BodyLevelFunction;
if (!noteDeclaredName(name, kind, pos()))
return null();
// Body-level functions in modules are always closed over.
if (pc->atModuleLevel())
pc->varScope().lookupDeclaredName(name)->value()->setClosedOver();
}
Node pn = handler.newFunctionStatement();

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

@ -1,4 +1,2 @@
function async() { return 42; } // overwritten by subsequent declaration
export default async // ASI occurs here due to the [no LineTerminator here] restriction on default-exporting an async function
function async() { return 17; }

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

@ -0,0 +1,94 @@
load(libdir + "asserts.js");
var functionDeclarations = [
"function f(){}",
"function* f(){}",
"async function f(){}",
];
var varDeclarations = [
"var f",
"{ var f; }",
"for (var f in null);",
"for (var f of null);",
"for (var f; ;);",
];
var lexicalDeclarations = [
"let f;",
"const f = 0;",
"class f {};",
];
var imports = [
"import f from '';",
"import f, {} from '';",
"import d, {f} from '';",
"import d, {f as f} from '';",
"import d, {foo as f} from '';",
"import f, * as d from '';",
"import d, * as f from '';",
"import {f} from '';",
"import {f as f} from '';",
"import {foo as f} from '';",
"import* as f from '';",
];
var exports = [
"export var f;",
...functionDeclarations.map(fn => `export ${fn};`),
...lexicalDeclarations.map(ld => `export ${ld};`),
...functionDeclarations.map(fn => `export default ${fn};`),
"export default class f {};",
];
var redeclarations = [
...functionDeclarations,
...varDeclarations,
...lexicalDeclarations,
...imports,
...exports,
];
var noredeclarations = [
...functionDeclarations.map(fn => `{ ${fn} }`),
...lexicalDeclarations.map(ld => `{ ${ld} }`),
...["let", "const"].map(ld => `for (${ld} f in null);`),
...["let", "const"].map(ld => `for (${ld} f of null);`),
...["let", "const"].map(ld => `for (${ld} f = 0; ;);`),
"export {f};",
"export {f as f};",
"export {foo as f}; var foo;",
"export {f} from '';",
"export {f as f} from '';",
"export {foo as f} from '';",
];
for (var decl of functionDeclarations) {
for (var redecl of redeclarations) {
assertThrowsInstanceOf(() => {
parseModule(`
${decl}
${redecl}
`);
}, SyntaxError);
assertThrowsInstanceOf(() => {
parseModule(`
${redecl}
${decl}
`);
}, SyntaxError);
}
for (var redecl of noredeclarations) {
parseModule(`
${decl}
${redecl}
`);
parseModule(`
${redecl}
${decl}
`);
}
}

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

@ -0,0 +1,88 @@
// Tests that function imports and function exports descriptors have
// signatures, in the test mode only, for fuzzers.
var module = new WebAssembly.Module(wasmTextToBinary(`(module
(import $vv "env" "v_v")
(export "v_v" $vv)
(import $vi "env" "v_i" (param i32))
(export "v_i" $vi)
(import $vI "env" "v_I" (param i64))
(export "v_I" $vI)
(import $vf "env" "v_f" (param f32))
(export "v_f" $vf)
(import $mem "env" "memory" (memory 0))
(export "mem" (memory $mem))
(import $vd "env" "v_d" (param f64))
(export "v_d" $vd)
(import $vfd "env" "v_fd" (param f32) (param f64))
(export "v_fd" $vfd)
(import $vIfifd "env" "v_Ififd" (param i64) (param f32) (param i32) (param f32) (param f64))
(export "v_Ififd" $vIfifd)
(import $iv "env" "i_v" (result i32))
(export "i_v" $iv)
(import $Ii "env" "I_i" (result i64) (param i32))
(export "I_i" $Ii)
(import $table "env" "table" (table 0 anyfunc))
(export "table" (table $table))
(import $fd "env" "f_d" (result f32) (param f64))
(export "f_d" $fd)
(import $dffd "env" "d_ffd" (result f64) (param f32) (param f32) (param f64))
(export "d_ffd" $dffd)
)`));
for (let desc of WebAssembly.Module.imports(module)) {
assertEq(typeof desc.signature, 'undefined');
}
for (let desc of WebAssembly.Module.exports(module)) {
assertEq(typeof desc.signature, 'undefined');
}
setJitCompilerOption('wasm.test-mode', 1);
function shortToType(s) {
switch (s) {
case 'v': return "";
case 'i': return "i32";
case 'I': return "i64";
case 'f': return "f32";
case 'd': return "f64";
}
throw new Error("unexpected shorthand type");
}
function expectedSignature(name) {
let [ret, args] = name.split('_');
args = args.split('').map(shortToType).join(', ');
ret = shortToType(ret);
return `(${args}) -> (${ret})`;
}
for (let desc of WebAssembly.Module.imports(module)) {
if (desc.kind !== 'function') {
assertEq(typeof desc.signature, 'undefined');
} else {
assertEq(desc.signature, expectedSignature(desc.name))
}
}
for (let desc of WebAssembly.Module.exports(module)) {
if (desc.kind !== 'function') {
assertEq(typeof desc.signature, 'undefined');
} else {
assertEq(desc.signature, expectedSignature(desc.name))
}
}

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

@ -3,5 +3,12 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Call the shell helper to add experimental features to the Intl object.
if (typeof addIntlExtras === "function")
addIntlExtras(Intl);
if (typeof addIntlExtras === "function") {
let intlExtras = {};
addIntlExtras(intlExtras);
Object.defineProperty(Intl, "PluralRules", {
value: intlExtras.PluralRules,
writable: true, enumerable: false, configurable: true
});
}

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

@ -4,5 +4,12 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Call the shell helper to add experimental features to the Intl object.
if (typeof addIntlExtras === "function")
addIntlExtras(Intl);
if (typeof addIntlExtras === "function") {
let intlExtras = {};
addIntlExtras(intlExtras);
Object.defineProperty(Intl, "PluralRules", {
value: intlExtras.PluralRules,
writable: true, enumerable: false, configurable: true
});
}

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

@ -1500,8 +1500,19 @@ SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleId id, HandleVa
}
}
if (obj->isNative() && !JSID_IS_INT(id) && !JSObject::setHadElementsAccess(cx, obj))
return false;
// Set the HadElementsAccess flag on the object if needed. This flag is
// used to do more eager dictionary-mode conversion for objects that are
// used as hashmaps. Set this flag only for objects with many properties,
// to avoid unnecessary Shape changes.
if (obj->isNative() &&
JSID_IS_ATOM(id) &&
!obj->as<NativeObject>().inDictionaryMode() &&
!obj->hadElementsAccess() &&
obj->as<NativeObject>().slotSpan() > PropertyTree::MAX_HEIGHT_WITH_ELEMENTS_ACCESS / 3)
{
if (!JSObject::setHadElementsAccess(cx, obj))
return false;
}
ObjectOpResult result;
return SetProperty(cx, obj, id, value, receiver, result) &&

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

@ -28,6 +28,7 @@
#include "jit/JitOptions.h"
#include "vm/Interpreter.h"
#include "vm/String.h"
#include "vm/StringBuffer.h"
#include "wasm/WasmCompile.h"
#include "wasm/WasmInstance.h"
#include "wasm/WasmModule.h"
@ -554,8 +555,9 @@ struct KindNames
RootedPropertyName kind;
RootedPropertyName table;
RootedPropertyName memory;
RootedPropertyName signature;
explicit KindNames(JSContext* cx) : kind(cx), table(cx), memory(cx) {}
explicit KindNames(JSContext* cx) : kind(cx), table(cx), memory(cx), signature(cx) {}
};
static bool
@ -576,6 +578,11 @@ InitKindNames(JSContext* cx, KindNames* names)
return false;
names->memory = memory->asPropertyName();
JSAtom* signature = Atomize(cx, "signature", strlen("signature"));
if (!signature)
return false;
names->signature = signature->asPropertyName();
return true;
}
@ -596,6 +603,40 @@ KindToString(JSContext* cx, const KindNames& names, DefinitionKind kind)
MOZ_CRASH("invalid kind");
}
static JSString*
SigToString(JSContext* cx, const Sig& sig)
{
StringBuffer buf(cx);
if (!buf.append('('))
return nullptr;
bool first = true;
for (ValType arg : sig.args()) {
if (!first && !buf.append(", ", strlen(", ")))
return nullptr;
const char* argStr = ToCString(arg);
if (!buf.append(argStr, strlen(argStr)))
return nullptr;
first = false;
}
if (!buf.append(") -> (", strlen(") -> (")))
return nullptr;
if (sig.ret() != ExprType::Void) {
const char* retStr = ToCString(sig.ret());
if (!buf.append(retStr, strlen(retStr)))
return nullptr;
}
if (!buf.append(')'))
return nullptr;
return buf.finishString();
}
static JSString*
UTF8CharsToString(JSContext* cx, const char* chars)
{
@ -619,6 +660,7 @@ WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp)
if (!elems.reserve(module->imports().length()))
return false;
size_t numFuncImport = 0;
for (const Import& import : module->imports()) {
Rooted<IdValueVector> props(cx, IdValueVector(cx));
if (!props.reserve(3))
@ -639,6 +681,14 @@ WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp)
return false;
props.infallibleAppend(IdValuePair(NameToId(names.kind), StringValue(kindStr)));
if (JitOptions.wasmTestMode && import.kind == DefinitionKind::Function) {
JSString* sigStr = SigToString(cx, module->metadata().funcImports[numFuncImport++].sig());
if (!sigStr)
return false;
if (!props.append(IdValuePair(NameToId(names.signature), StringValue(sigStr))))
return false;
}
JSObject* obj = ObjectGroup::newPlainObject(cx, props.begin(), props.length(), GenericObject);
if (!obj)
return false;
@ -671,6 +721,7 @@ WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp)
if (!elems.reserve(module->exports().length()))
return false;
size_t numFuncExport = 0;
for (const Export& exp : module->exports()) {
Rooted<IdValueVector> props(cx, IdValueVector(cx));
if (!props.reserve(2))
@ -686,6 +737,14 @@ WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp)
return false;
props.infallibleAppend(IdValuePair(NameToId(names.kind), StringValue(kindStr)));
if (JitOptions.wasmTestMode && exp.kind() == DefinitionKind::Function) {
JSString* sigStr = SigToString(cx, module->metadata().funcExports[numFuncExport++].sig());
if (!sigStr)
return false;
if (!props.append(IdValuePair(NameToId(names.signature), StringValue(sigStr))))
return false;
}
JSObject* obj = ObjectGroup::newPlainObject(cx, props.begin(), props.length(), GenericObject);
if (!obj)
return false;

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

@ -21,8 +21,20 @@ function loadHandler() {
inner.height = "5px";
inner.offsetTop;
}
// This function is a hack to avoid sporadic test-failures with...
// "...timed out waiting for reftest-wait to be removed".
// Occasionally, it seems this test loses a race condition of some sort, and
// its resize handler isn't invoked. When that happens (and specifically, when
// the test runs for longer than 500ms), we clear reftest-wait and call the
// run a "pass" (which is kind of valid, because we didn't crash!) and move on.
function setupFailsafe() {
setTimeout(() => {
document.documentElement.removeAttribute("class");
}, 500);
}
</script>
<body>
<body onload="setupFailsafe()">
<iframe id="outer"
src="data:text/html,<html><body>"
onload="loadHandler()">

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

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
The git commit ID used was 25b593fa59d0c284ff2de54b10db927d48579f5e.
The git commit ID used was 25b593fa59d0c284ff2de54b10db927d48579f5e (2017-02-23 14:05:03 +0200)

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

@ -48,6 +48,7 @@ cp $1/test/test_mixer.cpp gtest
if [ -d $1/.git ]; then
rev=$(cd $1 && git rev-parse --verify HEAD)
date=$(cd $1 && git show -s --format=%ci HEAD)
dirty=$(cd $1 && git diff-index --name-only HEAD)
fi
@ -57,7 +58,7 @@ if [ -n "$rev" ]; then
version=$version-dirty
echo "WARNING: updating from a dirty git repository."
fi
sed -i.bak -e "/The git commit ID used was/ s/[0-9a-f]\{40\}\(-dirty\)\{0,1\}\./$version./" README_MOZILLA
sed -i.bak -e "/The git commit ID used was/ s/[0-9a-f]\{40\}\(-dirty\)\{0,1\} .\{1,100\}/$version ($date)/" README_MOZILLA
rm README_MOZILLA.bak
else
echo "Remember to update README_MOZILLA with the version details."

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

@ -5,10 +5,12 @@
package org.mozilla.gecko;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -61,15 +63,42 @@ public class FilePicker implements BundleEventListener {
mimeType = GeckoAppShell.getMimeTypeFromExtensions(message.getString("extensions", ""));
}
showFilePickerAsync(title, mimeType, new ResultHandler() {
@Override
public void gotFile(final String filename) {
callback.sendSuccess(filename);
}
}, tabId);
final String[] requiredPermission = getPermissionsForMimeType(mimeType);
final String finalMimeType = mimeType;
// Use activity context cause we want to prompt for runtime permission. (bug 1337692)
Permissions.from(GeckoAppShell.getGeckoInterface().getActivity())
.withPermissions(requiredPermission)
.andFallback(new Runnable() {
@Override
public void run() {
callback.sendError(null);
}
})
.run(new Runnable() {
@Override
public void run() {
showFilePickerAsync(title, finalMimeType, new ResultHandler() {
@Override
public void gotFile(final String filename) {
callback.sendSuccess(filename);
}
}, tabId);
}
});
}
}
private static String[] getPermissionsForMimeType(final String mimeType) {
if (mimeType.startsWith("audio/")) {
return new String[] { Manifest.permission.RECORD_AUDIO };
} else if (mimeType.startsWith("image/")) {
return new String[] { Manifest.permission.CAMERA };
} else if (mimeType.startsWith("video/")) {
return new String[] { Manifest.permission.CAMERA };
}
return new String[] { Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO };
}
private void addActivities(Intent intent, HashMap<String, Intent> intents, HashMap<String, Intent> filters) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> lri = pm.queryIntentActivities(intent, 0);

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

@ -17,11 +17,11 @@ import android.util.DisplayMetrics;
public class PresentationView extends GeckoView {
private static final String LOGTAG = "PresentationView";
private static final String presentationViewURI = "chrome://browser/content/PresentationView.xul";
private static final String PRESENTATION_VIEW_URI = "chrome://browser/content/PresentationView.xul";
public PresentationView(Context context, String deviceId, int screenId) {
super(context);
this.chromeURI = presentationViewURI + "#" + deviceId;
this.screenId = screenId;
this.mChromeUri = PRESENTATION_VIEW_URI + "#" + deviceId;
this.mScreenId = screenId;
}
}

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

@ -7,7 +7,9 @@ var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "ViewContent");
var DEBUG = false;
function debug(aMsg) {
// dump(aMsg);
}
// This is copied from desktop's tab-content.js. See bug 1153485 about sharing this code somehow.
var DOMTitleChangedListener = {
@ -15,10 +17,8 @@ var DOMTitleChangedListener = {
addEventListener("DOMTitleChanged", this, false);
},
receiveMessage: function(message) {
if (DEBUG) {
dump("receiveMessage " + message.name);
}
receiveMessage: function(aMsg) {
debug("receiveMessage " + aMsg.name);
},
handleEvent: function(aEvent) {
@ -26,13 +26,12 @@ var DOMTitleChangedListener = {
return;
}
if (DEBUG) {
dump("handleEvent " + aEvent.type);
}
debug("handleEvent " + aEvent.type);
switch (aEvent.type) {
case "DOMTitleChanged":
sendAsyncMessage("GeckoView:DOMTitleChanged", { title: content.document.title });
sendAsyncMessage("GeckoView:DOMTitleChanged",
{ title: content.document.title });
break;
}
},

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

@ -29,19 +29,20 @@ var ModuleManager = {
this.modules = {};
},
add: function(resource, type, ...args) {
this.remove(type);
add: function(aResource, aType, ...aArgs) {
this.remove(aType);
let scope = {};
Cu.import(resource, scope);
this.modules[type] = new scope[type](
window, this.browser, WindowEventDispatcher, ...args);
Cu.import(aResource, scope);
this.modules[aType] = new scope[aType](
window, this.browser, WindowEventDispatcher, ...aArgs
);
},
remove: function(type) {
if (!(type in this.modules)) {
remove: function(aType) {
if (!(aType in this.modules)) {
return;
}
delete this.modules[type];
delete this.modules[aType];
}
};

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

@ -43,7 +43,7 @@ public class GeckoView extends LayerView
private static final boolean DEBUG = false;
private final EventDispatcher eventDispatcher = new EventDispatcher();
private final EventDispatcher mEventDispatcher = new EventDispatcher();
private ChromeDelegate mChromeDelegate;
/* package */ ContentListener mContentListener;
@ -53,9 +53,9 @@ public class GeckoView extends LayerView
private GeckoViewSettings mSettings;
protected boolean onAttachedToWindowCalled;
protected String chromeURI;
protected int screenId = 0; // default to the primary screen
protected boolean mOnAttachedToWindowCalled;
protected String mChromeUri;
protected int mScreenId = 0; // default to the primary screen
@WrapForJNI(dispatchTo = "proxy")
protected static final class Window extends JNIObject {
@ -64,7 +64,7 @@ public class GeckoView extends LayerView
static native void open(Window instance, GeckoView view,
Object compositor, EventDispatcher dispatcher,
String chromeURI, GeckoBundle settings,
String chromeUri, GeckoBundle settings,
int screenId);
@Override protected native void disposeNative();
@ -142,7 +142,7 @@ public class GeckoView extends LayerView
} else if ("GeckoView:LocationChange".equals(event)) {
if (mNavigationListener == null) {
// We shouldn't be getting this event.
eventDispatcher.dispatch("GeckoViewNavigation:Inactive", null);
mEventDispatcher.dispatch("GeckoViewNavigation:Inactive", null);
} else {
mNavigationListener.onLocationChange(GeckoView.this, message.getString("uri"));
mNavigationListener.onCanGoBack(GeckoView.this, message.getBoolean("canGoBack"));
@ -200,16 +200,14 @@ public class GeckoView extends LayerView
}
@Override
protected Parcelable onSaveInstanceState()
{
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
stateSaved = true;
return new StateBinder(superState, this.window);
}
@Override
protected void onRestoreInstanceState(final Parcelable state)
{
protected void onRestoreInstanceState(final Parcelable state) {
final StateBinder stateBinder = (StateBinder) state;
if (stateBinder.window != null) {
@ -217,7 +215,7 @@ public class GeckoView extends LayerView
}
stateSaved = false;
if (onAttachedToWindowCalled) {
if (mOnAttachedToWindowCalled) {
reattachWindow();
}
@ -227,39 +225,38 @@ public class GeckoView extends LayerView
}
protected void openWindow() {
if (chromeURI == null) {
chromeURI = getGeckoInterface().getDefaultChromeURI();
if (mChromeUri == null) {
mChromeUri = getGeckoInterface().getDefaultChromeURI();
}
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
Window.open(window, this, getCompositor(), eventDispatcher,
chromeURI, mSettings.asBundle(), screenId);
Window.open(window, this, getCompositor(), mEventDispatcher,
mChromeUri, mSettings.asBundle(), mScreenId);
} else {
GeckoThread.queueNativeCallUntil(
GeckoThread.State.PROFILE_READY,
Window.class, "open", window,
GeckoView.class, this,
Object.class, getCompositor(),
EventDispatcher.class, eventDispatcher,
String.class, chromeURI,
EventDispatcher.class, mEventDispatcher,
String.class, mChromeUri,
GeckoBundle.class, mSettings.asBundle(),
screenId);
mScreenId);
}
}
protected void reattachWindow() {
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
window.reattach(this, getCompositor(), eventDispatcher);
window.reattach(this, getCompositor(), mEventDispatcher);
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
window, "reattach", GeckoView.class, this,
Object.class, getCompositor(), EventDispatcher.class, eventDispatcher);
Object.class, getCompositor(), EventDispatcher.class, mEventDispatcher);
}
}
@Override
public void onAttachedToWindow()
{
public void onAttachedToWindow() {
final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
if (window == null) {
@ -272,12 +269,11 @@ public class GeckoView extends LayerView
super.onAttachedToWindow();
onAttachedToWindowCalled = true;
mOnAttachedToWindowCalled = true;
}
@Override
public void onDetachedFromWindow()
{
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
super.destroy();
@ -296,7 +292,7 @@ public class GeckoView extends LayerView
window, "disposeNative");
}
onAttachedToWindowCalled = false;
mOnAttachedToWindowCalled = false;
}
@WrapForJNI public static final int LOAD_DEFAULT = 0;
@ -320,6 +316,13 @@ public class GeckoView extends LayerView
}
}
/**
* Reload the current URI.
*/
public void reload() {
mEventDispatcher.dispatch("GeckoView:Reload", null);
}
/* package */ void setInputConnectionListener(final InputConnectionListener icl) {
mInputConnectionListener = icl;
}
@ -328,14 +331,14 @@ public class GeckoView extends LayerView
* Go back in history.
*/
public void goBack() {
eventDispatcher.dispatch("GeckoView:GoBack", null);
mEventDispatcher.dispatch("GeckoView:GoBack", null);
}
/**
* Go forward in history.
*/
public void goForward() {
eventDispatcher.dispatch("GeckoView:GoForward", null);
mEventDispatcher.dispatch("GeckoView:GoForward", null);
}
public GeckoViewSettings getSettings() {
@ -470,9 +473,9 @@ public class GeckoView extends LayerView
return;
}
if (listener == null) {
eventDispatcher.dispatch("GeckoViewNavigation:Inactive", null);
mEventDispatcher.dispatch("GeckoViewNavigation:Inactive", null);
} else if (mNavigationListener == null) {
eventDispatcher.dispatch("GeckoViewNavigation:Active", null);
mEventDispatcher.dispatch("GeckoViewNavigation:Active", null);
}
mNavigationListener = listener;
@ -504,7 +507,7 @@ public class GeckoView extends LayerView
}
public EventDispatcher getEventDispatcher() {
return eventDispatcher;
return mEventDispatcher;
}
/* Provides a means for the client to indicate whether a JavaScript

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

@ -17,9 +17,9 @@ import android.view.ViewGroup;
public class GeckoViewFragment extends android.support.v4.app.Fragment {
private static final String LOGTAG = "GeckoViewFragment";
private static Parcelable state = null;
private static GeckoViewFragment lastUsed = null;
private GeckoView geckoView = null;
private static Parcelable mSavedState = null;
private static GeckoViewFragment mLastUsed = null;
private GeckoView mGeckoView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -29,24 +29,24 @@ public class GeckoViewFragment extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
geckoView = new GeckoView(getContext());
return geckoView;
mGeckoView = new GeckoView(getContext());
return mGeckoView;
}
@Override
public void onResume() {
if (state != null && lastUsed != this) {
if (mSavedState != null && mLastUsed != this) {
// "Restore" the window from the previously used GeckoView to this GeckoView and attach it
geckoView.onRestoreInstanceState(state);
state = null;
mGeckoView.onRestoreInstanceState(mSavedState);
mSavedState = null;
}
super.onResume();
}
@Override
public void onPause() {
state = geckoView.onSaveInstanceState();
lastUsed = this;
mSavedState = mGeckoView.onSaveInstanceState();
mLastUsed = this;
super.onPause();
}
}

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

@ -13,7 +13,9 @@ Cu.import("resource://gre/modules/GeckoViewModule.jsm");
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewContent");
var DEBUG = false;
function debug(aMsg) {
// dump(aMsg);
}
class GeckoViewContent extends GeckoViewModule {
init() {
@ -23,21 +25,20 @@ class GeckoViewContent extends GeckoViewModule {
this.messageManager.addMessageListener("GeckoView:DOMTitleChanged", this);
}
handleEvent(event) {
if (DEBUG) {
dump("handleEvent: event.type=" + event.type);
}
handleEvent(aEvent) {
debug("handleEvent: aEvent.type=" + aEvent.type);
}
// Message manager event handler.
receiveMessage(msg) {
if (DEBUG) {
dump("receiveMessage " + msg.name);
}
receiveMessage(aMsg) {
debug("receiveMessage " + aMsg.name);
switch (msg.name) {
switch (aMsg.name) {
case "GeckoView:DOMTitleChanged":
this.eventDispatcher.sendRequest({ type: "GeckoView:DOMTitleChanged", title: msg.data.title });
this.eventDispatcher.sendRequest({
type: "GeckoView:DOMTitleChanged",
title: aMsg.data.title
});
break;
}
}

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

@ -11,15 +11,15 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewModule");
function debug(msg) {
// dump(msg);
function debug(aMsg) {
// dump(aMsg);
}
class GeckoViewModule {
constructor(window, browser, eventDispatcher) {
this.window = window;
this.browser = browser;
this.eventDispatcher = eventDispatcher;
constructor(aWindow, aBrowser, aEventDispatcher) {
this.window = aWindow;
this.browser = aBrowser;
this.eventDispatcher = aEventDispatcher;
this.eventDispatcher.registerListener(
() => this.onSettingsUpdate(),

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

@ -17,8 +17,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher",
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewNavigation");
function debug(msg) {
// dump(msg);
function debug(aMsg) {
// dump(aMsg);
}
// Handles navigation requests between Gecko and a GeckoView.
@ -42,14 +42,15 @@ class GeckoViewNavigation extends GeckoViewModule {
"GeckoViewNavigation:Inactive",
"GeckoView:GoBack",
"GeckoView:GoForward",
"GeckoView:Reload",
]);
}
// Bundle event handler.
onEvent(event, data, callback) {
debug("onEvent: event=" + event + ", data=" + JSON.stringify(data));
onEvent(aEvent, aData, aCallback) {
debug("onEvent: aEvent=" + aEvent + ", aData=" + JSON.stringify(aData));
switch (event) {
switch (aEvent) {
case "GeckoViewNavigation:Active":
this.registerProgressListener();
break;
@ -62,19 +63,22 @@ class GeckoViewNavigation extends GeckoViewModule {
case "GeckoView:GoForward":
this.browser.goForward();
break;
case "GeckoView:Reload":
this.browser.reload();
break;
}
}
// Message manager event handler.
receiveMessage(msg) {
debug("receiveMessage " + msg.name);
receiveMessage(aMsg) {
debug("receiveMessage " + aMsg.name);
}
// nsIBrowserDOMWindow::openURI implementation.
openURI(uri, opener, where, flags) {
debug("openURI: uri.spec=" + uri.spec);
openURI(aUri, aOpener, aWhere, aFlags) {
debug("openURI: aUri.spec=" + aUri.spec);
// nsIWebNavigation::loadURI(URI, loadFlags, referrer, postData, headers).
this.browser.loadURI(uri.spec, null, null, null);
this.browser.loadURI(aUri.spec, null, null, null);
}
// nsIBrowserDOMWindow::canClose implementation.
@ -103,13 +107,13 @@ class GeckoViewNavigation extends GeckoViewModule {
}
// WebProgress event handler.
onLocationChange(webProgress, request, locationURI, flags) {
onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
debug("onLocationChange");
let fixedURI = locationURI;
let fixedURI = aLocationURI;
try {
fixedURI = URIFixup.createExposableURI(locationURI);
fixedURI = URIFixup.createExposableURI(aLocationURI);
} catch (ex) { }
let message = {

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

@ -17,7 +17,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher",
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewNavigation");
var DEBUG = false;
function debug(aMsg) {
// dump(aMsg);
}
class GeckoViewProgress extends GeckoViewModule {
init() {
@ -27,9 +29,7 @@ class GeckoViewProgress extends GeckoViewModule {
}
registerProgressListener() {
if (DEBUG) {
dump("registerProgressListeners()");
}
debug("registerProgressListeners()");
let flags = Ci.nsIWebProgress.NOTIFY_STATE_NETWORK | Ci.nsIWebProgress.NOTIFY_SECURITY;
this.progressFilter =
@ -40,9 +40,7 @@ class GeckoViewProgress extends GeckoViewModule {
}
onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
if (DEBUG) {
dump("onStateChange()");
}
debug("onStateChange()");
if (!aWebProgress.isTopLevel) {
return;
@ -56,7 +54,8 @@ class GeckoViewProgress extends GeckoViewModule {
};
this.eventDispatcher.sendRequest(message);
} else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) && !aWebProgress.isLoadingDocument) {
} else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
!aWebProgress.isLoadingDocument) {
let message = {
type: "GeckoView:PageStop",
success: aStatus ? false : true
@ -67,9 +66,7 @@ class GeckoViewProgress extends GeckoViewModule {
}
onSecurityChange(aWebProgress, aRequest, aState) {
if (DEBUG) {
dump("onSecurityChange()");
}
debug("onSecurityChange()");
let message = {
type: "GeckoView:SecurityChanged",

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

@ -17,8 +17,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewSettings");
function debug(msg) {
// dump(msg);
function debug(aMsg) {
// dump(aMsg);
}
// Handles GeckoView settings including:
@ -39,17 +39,17 @@ class GeckoViewSettings extends GeckoViewModule {
return this._useTrackingProtection;
}
set useTrackingProtection(use) {
if (use && !this._isSafeBrowsingInit) {
set useTrackingProtection(aUse) {
if (aUse && !this._isSafeBrowsingInit) {
SafeBrowsing.init();
this._isSafeBrowsingInit = true;
}
if (use != this._useTrackingProtection) {
if (aUse != this._useTrackingProtection) {
this.messageManager.loadFrameScript('data:,' +
'docShell.useTrackingProtection = ' + use,
'docShell.useTrackingProtection = ' + aUse,
true
);
this._useTrackingProtection = use;
this._useTrackingProtection = aUse;
}
}
}

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

@ -57,6 +57,21 @@ public class TestStringUtils {
assertEquals(StringUtils.stripRef("https://mozilla.org/#BBBB"), "https://mozilla.org/");
}
@Test
public void testStripScheme() {
assertEquals("mozilla.org", StringUtils.stripScheme("http://mozilla.org"));
assertEquals("mozilla.org", StringUtils.stripScheme("http://mozilla.org/"));
assertEquals("https://mozilla.org", StringUtils.stripScheme("https://mozilla.org"));
assertEquals("https://mozilla.org", StringUtils.stripScheme("https://mozilla.org/"));
assertEquals("mozilla.org", StringUtils.stripScheme("https://mozilla.org/", StringUtils.UrlFlags.STRIP_HTTPS));
assertEquals("mozilla.org", StringUtils.stripScheme("https://mozilla.org", StringUtils.UrlFlags.STRIP_HTTPS));
assertEquals("", StringUtils.stripScheme("http://"));
assertEquals("", StringUtils.stripScheme("https://", StringUtils.UrlFlags.STRIP_HTTPS));
// This edge case is not handled properly yet
// assertEquals(StringUtils.stripScheme("https://"), "");
assertEquals(null, StringUtils.stripScheme(null));
}
@Test
public void testIsRTL() {
assertFalse(StringUtils.isRTL("mozilla.org"));

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

@ -1480,8 +1480,8 @@ bool
Http2Stream::Do0RTT()
{
MOZ_ASSERT(mTransaction);
mAttempting0RTT = true;
return mTransaction->Do0RTT();
mAttempting0RTT = mTransaction->Do0RTT();
return mAttempting0RTT;
}
nsresult

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

@ -19,9 +19,7 @@ ProfilerBacktrace::ProfilerBacktrace(SyncProfile* aProfile)
ProfilerBacktrace::~ProfilerBacktrace()
{
MOZ_COUNT_DTOR(ProfilerBacktrace);
if (mProfile->ShouldDestroy()) {
delete mProfile;
}
delete mProfile;
}
void

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

@ -9,7 +9,6 @@
SyncProfile::SyncProfile(int aThreadId, PseudoStack* aStack)
: ThreadInfo("SyncProfile", aThreadId, /* isMainThread = */ false, aStack,
/* stackTop = */ nullptr)
, mOwnerState(REFERENCED)
{
MOZ_COUNT_CTOR(SyncProfile);
SetProfile(new ProfileBuffer(GET_BACKTRACE_DEFAULT_ENTRIES));
@ -20,32 +19,6 @@ SyncProfile::~SyncProfile()
MOZ_COUNT_DTOR(SyncProfile);
}
bool
SyncProfile::ShouldDestroy()
{
mozilla::MutexAutoLock lock(GetMutex());
if (mOwnerState == OWNED) {
mOwnerState = OWNER_DESTROYING;
return true;
}
mOwnerState = ORPHANED;
return false;
}
void
SyncProfile::EndUnwind()
{
if (mOwnerState != ORPHANED) {
mOwnerState = OWNED;
}
// Save mOwnerState before we release the mutex
OwnerState ownerState = mOwnerState;
ThreadInfo::EndUnwind();
if (ownerState == ORPHANED) {
delete this;
}
}
// SyncProfiles' stacks are deduplicated in the context of the containing
// profile in which the backtrace is as a marker payload.
void

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

@ -19,22 +19,8 @@ public:
// profile in which the backtrace is as a marker payload.
void StreamJSON(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks);
virtual void EndUnwind();
private:
friend class ProfilerBacktrace;
enum OwnerState
{
REFERENCED, // ProfilerBacktrace has a pointer to this but doesn't own
OWNED, // ProfilerBacktrace is responsible for destroying this
OWNER_DESTROYING, // ProfilerBacktrace owns this and is destroying
ORPHANED // No owner, we must destroy ourselves
};
bool ShouldDestroy();
OwnerState mOwnerState;
};
#endif // __SYNCPROFILE_H

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

@ -237,18 +237,6 @@ ThreadInfo::FlushSamplesAndMarkers()
mBuffer->reset();
}
void
ThreadInfo::BeginUnwind()
{
mMutex->Lock();
}
void
ThreadInfo::EndUnwind()
{
mMutex->Unlock();
}
mozilla::Mutex&
ThreadInfo::GetMutex()
{

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

@ -70,9 +70,6 @@ public:
// become invalid, i.e., just before JS shutdown.
void FlushSamplesAndMarkers();
void BeginUnwind();
virtual void EndUnwind();
void DuplicateLastSample(const mozilla::TimeStamp& aStartTime);
ThreadResponsiveness* GetThreadResponsiveness() { return &mRespInfo; }

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

@ -181,18 +181,17 @@ SigprofHandler(int signal, siginfo_t* info, void* context)
// Avoid TSan warning about clobbering errno.
int savedErrno = errno;
TickSample sample_obj;
TickSample* sample = &sample_obj;
sample->context = context;
TickSample sample;
sample.context = context;
// Extract the current pc and sp.
SetSampleContext(sample, context);
sample->threadInfo = gCurrentThreadInfo;
sample->timestamp = mozilla::TimeStamp::Now();
sample->rssMemory = gRssMemory;
sample->ussMemory = gUssMemory;
SetSampleContext(&sample, context);
sample.threadInfo = gCurrentThreadInfo;
sample.timestamp = mozilla::TimeStamp::Now();
sample.rssMemory = gRssMemory;
sample.ussMemory = gUssMemory;
Tick(sample);
Tick(&sample);
sem_post(&gSignalHandlingDone);
errno = savedErrno;

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

@ -190,15 +190,14 @@ public:
thread_act_t profiled_thread =
aThreadInfo->GetPlatformData()->profiled_thread();
TickSample sample_obj;
TickSample* sample = &sample_obj;
TickSample sample;
// Unique Set Size is not supported on Mac.
sample->ussMemory = 0;
sample->rssMemory = 0;
sample.ussMemory = 0;
sample.rssMemory = 0;
if (isFirstProfiledThread && gProfileMemory) {
sample->rssMemory = nsMemoryReporterManager::ResidentFast();
sample.rssMemory = nsMemoryReporterManager::ResidentFast();
}
// We're using thread_suspend on OS X because pthread_kill (which is what
@ -233,15 +232,15 @@ public:
flavor,
reinterpret_cast<natural_t*>(&state),
&count) == KERN_SUCCESS) {
sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
sample->timestamp = mozilla::TimeStamp::Now();
sample->threadInfo = aThreadInfo;
sample.pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
sample.sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
sample.fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
sample.timestamp = mozilla::TimeStamp::Now();
sample.threadInfo = aThreadInfo;
#undef REGISTER_FIELD
Tick(sample);
Tick(&sample);
}
thread_resume(profiled_thread);
}

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

@ -202,21 +202,20 @@ class SamplerThread
CONTEXT context;
memset(&context, 0, sizeof(context));
TickSample sample_obj;
TickSample* sample = &sample_obj;
TickSample sample;
// Grab the timestamp before pausing the thread, to avoid deadlocks.
sample->timestamp = mozilla::TimeStamp::Now();
sample->threadInfo = aThreadInfo;
sample.timestamp = mozilla::TimeStamp::Now();
sample.threadInfo = aThreadInfo;
if (isFirstProfiledThread && gProfileMemory) {
sample->rssMemory = nsMemoryReporterManager::ResidentFast();
sample.rssMemory = nsMemoryReporterManager::ResidentFast();
} else {
sample->rssMemory = 0;
sample.rssMemory = 0;
}
// Unique Set Size is not supported on Windows.
sample->ussMemory = 0;
sample.ussMemory = 0;
static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
if (SuspendThread(profiled_thread) == kSuspendFailed)
@ -239,18 +238,18 @@ class SamplerThread
}
#if defined(GP_ARCH_amd64)
sample->pc = reinterpret_cast<Address>(context.Rip);
sample->sp = reinterpret_cast<Address>(context.Rsp);
sample->fp = reinterpret_cast<Address>(context.Rbp);
sample.pc = reinterpret_cast<Address>(context.Rip);
sample.sp = reinterpret_cast<Address>(context.Rsp);
sample.fp = reinterpret_cast<Address>(context.Rbp);
#else
sample->pc = reinterpret_cast<Address>(context.Eip);
sample->sp = reinterpret_cast<Address>(context.Esp);
sample->fp = reinterpret_cast<Address>(context.Ebp);
sample.pc = reinterpret_cast<Address>(context.Eip);
sample.sp = reinterpret_cast<Address>(context.Esp);
sample.fp = reinterpret_cast<Address>(context.Ebp);
#endif
sample->context = &context;
sample.context = &context;
Tick(sample);
Tick(&sample);
ResumeThread(profiled_thread);
}

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

@ -2459,9 +2459,7 @@ profiler_get_backtrace()
sample.isSamplingCurrentThread = true;
sample.timestamp = mozilla::TimeStamp::Now();
profile->BeginUnwind();
Tick(&sample);
profile->EndUnwind();
return UniqueProfilerBacktrace(new ProfilerBacktrace(profile));
}