merge m-i to m-c a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-09-12 15:07:38 +02:00
commit 6d0df443bf
119 changed files with 1535 additions and 1055 deletions

View File

@ -239,7 +239,7 @@ function getAccessible(aAccOrElmOrID, aInterfaces, aElmObj, aDoNotFailIf)
if (!acc) {
if (!(aDoNotFailIf & DONOTFAIL_IF_NO_ACC))
ok(false, "Can't get accessible for " + aAccOrElmOrID);
ok(false, "Can't get accessible for " + prettyName(aAccOrElmOrID));
return null;
}

View File

@ -59,7 +59,11 @@
this.match = function browserReorderChecker_match(aEvent)
{
// Reorder event might be duped because of temporary document creation.
if (aEvent.accessible == getAccessible(currentBrowser())) {
var browserAcc = getAccessible(currentBrowser());
if (!browserAcc)
ok(false, "opa opa sralslasya");
if (aEvent.accessible == browserAcc) {
this.cnt++;
return this.cnt != 2;
}
@ -83,8 +87,11 @@
this.finalCheck = function loadURI_finalCheck()
{
testRelation(browserDocument(), RELATION_EMBEDS,
getAccessible(currentTabDocument()));
var acc = getAccessible(currentTabDocument());
if (!acc)
ok(false, "ahahahaha");
testRelation(browserDocument(), RELATION_EMBEDS, acc);
}
this.getID = function loadOneTab_getID()

View File

@ -186,7 +186,7 @@ skip-if = e10s # Bug ?????? - test doesn't wait for document to be created befor
[browser_bug550565.js]
skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome (which is how gBrowser.getIcon works)
[browser_bug553455.js]
skip-if = buildapp == 'mulet' || e10s # Bug ????? - I don't think either popup notifications nor addon install stuff works?
skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?
[browser_bug555224.js]
skip-if = e10s # Bug 691614 - no e10s zoom support yet
[browser_bug555767.js]

View File

@ -35,4 +35,6 @@ skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug
skip-if = toolkit == "gtk2" || toolkit == "gtk3" # disabled on Linux due to bug 513558
[test_feed_discovery.html]
[test_offlineNotification.html]
skip-if = buildapp == 'mulet' # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?
[test_offline_gzip.html]
skip-if = buildapp == 'mulet' # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?

View File

@ -28,10 +28,11 @@ AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
esac
fi
# if we are debugging, profiling or using ASAN, we want a frame pointer.
# if we are debugging, profiling or using sanitizers, we want a frame pointer.
if test -z "$MOZ_OPTIMIZE" -o \
-n "$MOZ_PROFILING" -o \
-n "$MOZ_DEBUG" -o \
-n "$MOZ_MSAN" -o \
-n "$MOZ_ASAN"; then
MOZ_FRAMEPTR_FLAGS="$MOZ_ENABLE_FRAME_PTR"
else

View File

@ -23,8 +23,6 @@ __all__ = [
"dumpLeakLog",
"isURL",
"processLeakLog",
"getDebuggerInfo",
"DEBUGGER_INFO",
"replaceBackSlashes",
'KeyValueParseError',
'parseKeyValue',
@ -48,54 +46,6 @@ def setAutomationLog(alt_logger):
global log
log = alt_logger
# Map of debugging programs to information about them, like default arguments
# and whether or not they are interactive.
DEBUGGER_INFO = {
# gdb requires that you supply the '--args' flag in order to pass arguments
# after the executable name to the executable.
"gdb": {
"interactive": True,
"args": "-q --args"
},
"cgdb": {
"interactive": True,
"args": "-q --args"
},
"lldb": {
"interactive": True,
"args": "--",
"requiresEscapedArgs": True
},
# Visual Studio Debugger Support
"devenv.exe": {
"interactive": True,
"args": "-debugexe"
},
# Visual C++ Express Debugger Support
"wdexpress.exe": {
"interactive": True,
"args": "-debugexe"
},
# valgrind doesn't explain much about leaks unless you set the
# '--leak-check=full' flag. But there are a lot of objects that are
# semi-deliberately leaked, so we set '--show-possibly-lost=no' to avoid
# uninteresting output from those objects. We set '--smc-check==all-non-file'
# and '--vex-iropt-register-updates=allregs-at-mem-access' so that valgrind
# deals properly with JIT'd JavaScript code.
"valgrind": {
"interactive": False,
"args": " ".join(["--leak-check=full",
"--show-possibly-lost=no",
"--smc-check=all-non-file",
"--vex-iropt-register-updates=allregs-at-mem-access"])
}
}
class ZipFileReader(object):
"""
Class to read zip files in Python 2.5 and later. Limited to only what we
@ -224,58 +174,6 @@ def addCommonOptions(parser, defaults={}):
help = "prevents the test harness from redirecting "
"stdout and stderr for interactive debuggers")
def getFullPath(directory, path):
"Get an absolute path relative to 'directory'."
return os.path.normpath(os.path.join(directory, os.path.expanduser(path)))
def searchPath(directory, path):
"Go one step beyond getFullPath and try the various folders in PATH"
# Try looking in the current working directory first.
newpath = getFullPath(directory, path)
if os.path.isfile(newpath):
return newpath
# At this point we have to fail if a directory was given (to prevent cases
# like './gdb' from matching '/usr/bin/./gdb').
if not os.path.dirname(path):
for dir in os.environ['PATH'].split(os.pathsep):
newpath = os.path.join(dir, path)
if os.path.isfile(newpath):
return newpath
return None
def getDebuggerInfo(directory, debugger, debuggerArgs, debuggerInteractive = False):
debuggerInfo = None
if debugger:
debuggerPath = searchPath(directory, debugger)
if not debuggerPath:
print "Error: Path %s doesn't exist." % debugger
sys.exit(1)
debuggerName = os.path.basename(debuggerPath).lower()
def getDebuggerInfo(type, default):
if debuggerName in DEBUGGER_INFO and type in DEBUGGER_INFO[debuggerName]:
return DEBUGGER_INFO[debuggerName][type]
return default
debuggerInfo = {
"path": debuggerPath,
"interactive" : getDebuggerInfo("interactive", False),
"args": getDebuggerInfo("args", "").split(),
"requiresEscapedArgs": getDebuggerInfo("requiresEscapedArgs", False)
}
if debuggerArgs:
debuggerInfo["args"] = debuggerArgs.split()
if debuggerInteractive:
debuggerInfo["interactive"] = debuggerInteractive
return debuggerInfo
def dumpLeakLog(leakLogFile, filter = False):
"""Process the leak log, without parsing it.

View File

@ -49,6 +49,7 @@ SEARCH_PATHS = [
'testing/marionette/client/marionette',
'testing/marionette/transport',
'testing/mozbase/mozcrash',
'testing/mozbase/mozdebug',
'testing/mozbase/mozdevice',
'testing/mozbase/mozfile',
'testing/mozbase/mozhttpd',

View File

@ -1264,6 +1264,22 @@ if test -n "$MOZ_ASAN"; then
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_ASAN)
dnl ========================================================
dnl = Use Memory Sanitizer
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(memory-sanitizer,
[ --enable-memory-sanitizer Enable Memory Sanitizer (default=no)],
MOZ_MSAN=1,
MOZ_MSAN= )
if test -n "$MOZ_MSAN"; then
MOZ_LLVM_HACKS=1
AC_DEFINE(MOZ_MSAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_MSAN)
# The LLVM symbolizer is used by all sanitizers
AC_SUBST(LLVM_SYMBOLIZER)
dnl ========================================================

View File

@ -71,7 +71,7 @@ skip-if = toolkit == 'android'
[test_bug677495.html]
[test_bug677495-1.html]
[test_bug741266.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size)
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size)
[test_non-ascii-cookie.html]
skip-if = buildapp == 'b2g' || e10s
[test_bug765780.html]

View File

@ -507,6 +507,20 @@ MediaSource::InitializationEvent()
}
}
#if defined(DEBUG)
void
MediaSource::Dump(const char* aPath)
{
char buf[255];
PR_snprintf(buf, sizeof(buf), "%s/mediasource-%p", aPath, this);
PR_MkDir(buf, 0700);
if (mSourceBuffers) {
mSourceBuffers->Dump(buf);
}
}
#endif
nsPIDOMWindow*
MediaSource::GetParentObject() const
{

View File

@ -98,6 +98,12 @@ public:
// initialization.
void QueueInitializationEvent();
#if defined(DEBUG)
// Dump the contents of each SourceBuffer to a series of files under aPath.
// aPath must exist. Debug only, invoke from your favourite debugger.
void Dump(const char* aPath);
#endif
private:
~MediaSource();

View File

@ -134,6 +134,23 @@ public:
return size;
}
#if defined(DEBUG)
void Dump(const char* aPath) {
for (uint32_t i = 0; i < uint32_t(GetSize()); ++i) {
ResourceItem* item = ResourceAt(i);
char buf[255];
PR_snprintf(buf, sizeof(buf), "%s/%08u.bin", aPath, i);
FILE* fp = fopen(buf, "wb");
if (!fp) {
return;
}
fwrite(item->mData.Elements(), item->mData.Length(), 1, fp);
fclose(fp);
}
}
#endif
private:
ResourceItem* ResourceAt(uint32_t aIndex) const {
return static_cast<ResourceItem*>(ObjectAt(aIndex));
@ -173,6 +190,5 @@ private:
uint64_t mOffset;
};
} // namespace mozilla
#endif /* MOZILLA_RESOURCEQUEUE_H_ */

View File

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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
@ -687,6 +688,16 @@ SourceBuffer::Evict(double aStart, double aEnd)
mTrackBuffer->EvictBefore(evictTime);
}
#if defined(DEBUG)
void
SourceBuffer::Dump(const char* aPath)
{
if (mTrackBuffer) {
mTrackBuffer->Dump(aPath);
}
}
#endif
NS_IMPL_CYCLE_COLLECTION_INHERITED(SourceBuffer, DOMEventTargetHelper,
mMediaSource)

View File

@ -109,6 +109,10 @@ public:
double GetBufferedStart();
double GetBufferedEnd();
#if defined(DEBUG)
void Dump(const char* aPath);
#endif
private:
~SourceBuffer();

View File

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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

View File

@ -167,6 +167,16 @@ SourceBufferList::QueueAsyncSimpleEvent(const char* aName)
NS_DispatchToMainThread(event);
}
#if defined(DEBUG)
void
SourceBufferList::Dump(const char* aPath)
{
for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
mSourceBuffers[i]->Dump(aPath);
}
}
#endif
SourceBufferList::SourceBufferList(MediaSource* aMediaSource)
: DOMEventTargetHelper(aMediaSource->GetParentObject())
, mMediaSource(aMediaSource)

View File

@ -79,6 +79,10 @@ public:
// Returns the highest end time of any of the Sourcebuffers.
double GetHighestBufferedEndTime();
#if defined(DEBUG)
void Dump(const char* aPath);
#endif
private:
~SourceBufferList();

View File

@ -120,6 +120,12 @@ public:
// Remove data from resource before the given offset.
void EvictBefore(uint64_t aOffset);
#if defined(DEBUG)
void Dump(const char* aPath) {
mInputBuffer.Dump(aPath);
}
#endif
private:
~SourceBufferResource();
nsresult SeekInternal(int64_t aOffset);

View File

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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
@ -19,6 +20,11 @@
#include "nsThreadUtils.h"
#include "prlog.h"
#if defined(DEBUG)
#include <sys/stat.h>
#include <sys/types.h>
#endif
struct JSContext;
class JSObject;
@ -349,4 +355,22 @@ TrackBuffer::Decoders()
return mInitializedDecoders;
}
#if defined(DEBUG)
void
TrackBuffer::Dump(const char* aPath)
{
char path[255];
PR_snprintf(path, sizeof(path), "%s/trackbuffer-%p", aPath, this);
PR_MkDir(path, 0700);
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
char buf[255];
PR_snprintf(buf, sizeof(buf), "%s/reader-%p", path, mDecoders[i]->GetReader());
PR_MkDir(buf, 0700);
mDecoders[i]->GetResource()->Dump(buf);
}
}
#endif
} // namespace mozilla

View File

@ -82,6 +82,10 @@ public:
// TODO: Refactor to a cleaner interface between TrackBuffer and MediaSourceReader.
const nsTArray<nsRefPtr<SourceBufferDecoder>>& Decoders();
#if defined(DEBUG)
void Dump(const char* aPath);
#endif
private:
~TrackBuffer();

View File

@ -18,6 +18,62 @@
#define TIMEOUT_DEQUEUE_INPUTBUFFER_MS 1000000ll
namespace android {
// General Template: MediaCodec::getOutputGraphicBufferFromIndex(...)
template <typename T, bool InterfaceSupported>
struct OutputGraphicBufferStub
{
static status_t GetOutputGraphicBuffer(T *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
return ERROR_UNSUPPORTED;
}
};
// Class Template Specialization: MediaCodec::getOutputGraphicBufferFromIndex(...)
template <typename T>
struct OutputGraphicBufferStub<T, true>
{
static status_t GetOutputGraphicBuffer(T *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
if (aMediaCodec == nullptr || aGraphicBuffer == nullptr) {
return BAD_VALUE;
}
*aGraphicBuffer = aMediaCodec->getOutputGraphicBufferFromIndex(aIndex);
return OK;
}
};
// Wrapper class to handle interface-difference of MediaCodec.
struct MediaCodecInterfaceWrapper
{
typedef int8_t Supported;
typedef int16_t Unsupported;
template <typename T>
static auto TestOutputGraphicBuffer(T *aMediaCodec) -> decltype(aMediaCodec->getOutputGraphicBufferFromIndex(0), Supported());
template <typename T>
static auto TestOutputGraphicBuffer(...) -> Unsupported;
// SFINAE: Substitution Failure Is Not An Error
static const bool OutputGraphicBufferSupported = sizeof(TestOutputGraphicBuffer<MediaCodec>(nullptr)) == sizeof(Supported);
// Class Template Specialization
static OutputGraphicBufferStub<MediaCodec, OutputGraphicBufferSupported> sOutputGraphicBufferStub;
// Wrapper Function
static status_t GetOutputGraphicBuffer(MediaCodec *aMediaCodec,
size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
return sOutputGraphicBufferStub.GetOutputGraphicBuffer(aMediaCodec, aIndex, aGraphicBuffer);
}
};
sp<MediaCodecProxy>
MediaCodecProxy::CreateByType(sp<ALooper> aLooper,
const char *aMime,
@ -363,6 +419,37 @@ MediaCodecProxy::requestActivityNotification(const sp<AMessage> &aNotify)
mCodec->requestActivityNotification(aNotify);
}
status_t
MediaCodecProxy::getOutputGraphicBufferFromIndex(size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer)
{
// Read Lock for mCodec
RWLock::AutoRLock arl(mCodecLock);
if (mCodec == nullptr) {
return NO_INIT;
}
return MediaCodecInterfaceWrapper::GetOutputGraphicBuffer(mCodec.get(), aIndex, aGraphicBuffer);
}
status_t
MediaCodecProxy::getCapability(uint32_t *aCapability)
{
if (aCapability == nullptr) {
return BAD_VALUE;
}
uint32_t capability = kEmptyCapability;
if (MediaCodecInterfaceWrapper::OutputGraphicBufferSupported) {
capability |= kCanExposeGraphicBuffer;
}
*aCapability = capability;
return OK;
}
// Called on a Binder thread
void
MediaCodecProxy::resourceReserved()

View File

@ -40,9 +40,15 @@ public:
virtual void codecCanceled() = 0;
};
enum Capability {
kEmptyCapability = 0x00000000,
kCanExposeGraphicBuffer = 0x00000001,
};
enum {
kKeyBufferIndex = 'bfin',
};
// Check whether MediaCodec has been allocated.
bool allocated() const;
@ -112,6 +118,14 @@ public:
// an input/output buffer has become available, a format change is
// pending, an error is pending.
void requestActivityNotification(const sp<AMessage> &aNotify);
status_t getOutputGraphicBufferFromIndex(size_t aIndex,
sp<GraphicBuffer> *aGraphicBuffer);
status_t getCapability(uint32_t *aCapability);
// Utility functions
// If aData is null, will notify decoder input EOS
status_t Input(const uint8_t* aData, uint32_t aDataSize,
int64_t aTimestampUsecs, uint64_t flags);
@ -120,6 +134,7 @@ public:
bool IsWaitingResources();
bool IsDormantNeeded();
void ReleaseMediaResources();
protected:
virtual ~MediaCodecProxy();
@ -165,6 +180,7 @@ private:
// MediaCodec instance
mutable RWLock mCodecLock;
sp<MediaCodec> mCodec;
//MediaCodec buffers to hold input/output data.
Vector<sp<ABuffer> > mInputBuffers;
Vector<sp<ABuffer> > mOutputBuffers;

View File

@ -29,7 +29,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_bug279495.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug344861.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s
[test_bug386782.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
[test_bug430624.html]

View File

@ -6,6 +6,6 @@ support-files =
AudioChannelChromeScript.js
[test_telephonyPolicy.html]
skip-if = buildapp == 'mulet' || (toolkit == 'gonk' || e10s)
skip-if = buildapp == 'mulet' || (toolkit == 'gonk' || e10s) || os == "android"
[test_audioChannelChange.html]
skip-if = (toolkit != 'gonk')

View File

@ -416,12 +416,11 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType,
RefPtr<DataSourceSurface> emptyCanvas =
Factory::CreateDataSourceSurfaceWithStride(IntSize(aSize.width, aSize.height),
SurfaceFormat::B8G8R8A8,
4 * aSize.width);
4 * aSize.width, true);
if (NS_WARN_IF(!emptyCanvas)) {
return NS_ERROR_INVALID_ARG;
}
ClearDataSourceSurface(emptyCanvas);
DataSourceSurface::MappedSurface map;
if (!emptyCanvas->Map(DataSourceSurface::MapType::WRITE, &map)) {
return NS_ERROR_INVALID_ARG;

View File

@ -91,6 +91,10 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::Activity',
},
'MozAbortablePromise': {
'nativeType': 'mozilla::dom::AbortablePromise',
},
'AbstractWorker': {
'concrete': False
},

View File

@ -897,10 +897,13 @@ CanvasRenderingContext2D::CheckSizeForSkiaGL(IntSize size) {
// Cache the number of pixels on the primary screen
static int32_t gScreenPixels = -1;
if (gScreenPixels < 0) {
// Default to historical mobile screen size of 980x480. In addition,
// allow skia use up to this size even if the screen is smaller. A lot
// content expects this size to work well.
gScreenPixels = 980 * 480;
// Default to historical mobile screen size of 980x480, like FishIEtank.
// In addition, allow skia use up to this size even if the screen is smaller.
// A lot content expects this size to work well.
// See Bug 999841
if (gfxPlatform::GetPlatform()->HasEnoughTotalSystemMemoryForSkiaGL()) {
gScreenPixels = 980 * 480;
}
nsCOMPtr<nsIScreenManager> screenManager =
do_GetService("@mozilla.org/gfx/screenmanager;1");
@ -916,22 +919,8 @@ CanvasRenderingContext2D::CheckSizeForSkiaGL(IntSize size) {
}
}
// On high DPI devices the screen pixels may be scaled up. Make
// sure to apply that scaling here as well if we are hooked up
// to a widget.
static double gDefaultScale = 0.0;
if (gDefaultScale < 1.0) {
nsIPresShell* ps = GetPresShell();
if (ps) {
nsIFrame* frame = ps->GetRootFrame();
if (frame) {
nsIWidget* widget = frame->GetNearestWidget();
if (widget) {
gDefaultScale = widget->GetDefaultScale().scale;
}
}
}
}
// Just always use a scale of 1.0. It can be changed if a lot of contents need it.
static double gDefaultScale = 1.0;
double scale = gDefaultScale > 0 ? gDefaultScale : 1.0;
int32_t threshold = ceil(scale * scale * gScreenPixels);

View File

@ -1875,6 +1875,9 @@ TabChild::RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
bool
TabChild::RecvHandleDoubleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
{
TABC_LOG("Handling double tap at %s with %p %p\n",
Stringify(aPoint).c_str(), mGlobal.get(), mTabChildGlobal.get());
if (!mGlobal || !mTabChildGlobal) {
return true;
}
@ -1895,6 +1898,9 @@ TabChild::RecvHandleDoubleTap(const CSSPoint& aPoint, const ScrollableLayerGuid&
bool
TabChild::RecvHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
{
TABC_LOG("Handling single tap at %s with %p %p %d\n",
Stringify(aPoint).c_str(), mGlobal.get(), mTabChildGlobal.get(), mTouchEndCancelled);
if (!mGlobal || !mTabChildGlobal) {
return true;
}
@ -1924,6 +1930,8 @@ TabChild::FireSingleTapEvent(LayoutDevicePoint aPoint)
if (mDestroyed) {
return;
}
TABC_LOG("Dispatching single-tap component events to %s\n",
Stringify(aPoint).c_str());
int time = 0;
DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, aPoint, mWidget);
DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, aPoint, mWidget);
@ -1933,6 +1941,9 @@ TabChild::FireSingleTapEvent(LayoutDevicePoint aPoint)
bool
TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
{
TABC_LOG("Handling long tap at %s with %p %p\n",
Stringify(aPoint).c_str(), mGlobal.get(), mTabChildGlobal.get());
if (!mGlobal || !mTabChildGlobal) {
return true;
}
@ -1945,6 +1956,8 @@ TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& a
2, 1, 0, true,
nsIDOMMouseEvent::MOZ_SOURCE_TOUCH);
TABC_LOG("Contextmenu event handled: %d\n", eventHandled);
// If no one handle context menu, fire MOZLONGTAP event
if (!eventHandled) {
LayoutDevicePoint currentPoint =
@ -1953,6 +1966,7 @@ TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& a
nsEventStatus status =
DispatchSynthesizedMouseEvent(NS_MOUSE_MOZLONGTAP, time, currentPoint, mWidget);
eventHandled = (status == nsEventStatus_eConsumeNoDefault);
TABC_LOG("MOZLONGTAP event handled: %d\n", eventHandled);
}
SendContentReceivedTouch(aGuid, eventHandled);
@ -2226,6 +2240,8 @@ bool
TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid)
{
TABC_LOG("Receiving touch event of type %d\n", aEvent.message);
WidgetTouchEvent localEvent(aEvent);
localEvent.widget = mWidget;
for (size_t i = 0; i < localEvent.touches.Length(); i++) {

View File

@ -0,0 +1,118 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "mozilla/dom/AbortablePromise.h"
#include "mozilla/dom/AbortablePromiseBinding.h"
#include "mozilla/dom/PromiseNativeAbortCallback.h"
#include "mozilla/ErrorResult.h"
#include "nsThreadUtils.h"
#include "PromiseCallback.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(PromiseNativeAbortCallback)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PromiseNativeAbortCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PromiseNativeAbortCallback)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_0(PromiseNativeAbortCallback)
NS_IMPL_ADDREF_INHERITED(AbortablePromise, Promise)
NS_IMPL_RELEASE_INHERITED(AbortablePromise, Promise)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AbortablePromise)
NS_INTERFACE_MAP_END_INHERITING(Promise)
NS_IMPL_CYCLE_COLLECTION_INHERITED(AbortablePromise, Promise, mAbortCallback)
AbortablePromise::AbortablePromise(nsIGlobalObject* aGlobal,
PromiseNativeAbortCallback& aAbortCallback)
: Promise(aGlobal)
, mAbortCallback(&aAbortCallback)
{
}
AbortablePromise::AbortablePromise(nsIGlobalObject* aGlobal)
: Promise(aGlobal)
{
}
AbortablePromise::~AbortablePromise()
{
}
/* static */ already_AddRefed<AbortablePromise>
AbortablePromise::Create(nsIGlobalObject* aGlobal,
PromiseNativeAbortCallback& aAbortCallback,
ErrorResult& aRv)
{
nsRefPtr<AbortablePromise> p = new AbortablePromise(aGlobal, aAbortCallback);
p->CreateWrapper(aRv);
if (aRv.Failed()) {
return nullptr;
}
return p.forget();
}
JSObject*
AbortablePromise::WrapObject(JSContext* aCx)
{
return MozAbortablePromiseBinding::Wrap(aCx, this);
}
/* static */ already_AddRefed<AbortablePromise>
AbortablePromise::Constructor(const GlobalObject& aGlobal, PromiseInit& aInit,
AbortCallback& aAbortCallback, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global;
global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<AbortablePromise> promise = new AbortablePromise(global);
promise->CreateWrapper(aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->CallInitFunction(aGlobal, aInit, aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->mAbortCallback = &aAbortCallback;
return promise.forget();
}
void
AbortablePromise::Abort()
{
if (IsPending()) {
return;
}
MaybeReject(NS_ERROR_ABORT);
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(this, &AbortablePromise::DoAbort);
Promise::DispatchToMainOrWorkerThread(runnable);
}
void
AbortablePromise::DoAbort()
{
if (mAbortCallback.HasWebIDLCallback()) {
ErrorResult rv;
mAbortCallback.GetWebIDLCallback()->Call(rv);
return;
}
mAbortCallback.GetXPCOMCallback()->Call();
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,66 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_AbortablePromise_h__
#define mozilla_dom_AbortablePromise_h__
#include "js/TypeDecls.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/CallbackObject.h"
namespace mozilla {
namespace dom {
class AbortCallback;
class PromiseNativeAbortCallback;
class AbortablePromise
: public Promise
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AbortablePromise, Promise)
public:
// It is the same as Promise::Create except that this takes an extra
// aAbortCallback parameter to set the abort callback handler.
static already_AddRefed<AbortablePromise>
Create(nsIGlobalObject* aGlobal, PromiseNativeAbortCallback& aAbortCallback,
ErrorResult& aRv);
protected:
// Constructor used to create native AbortablePromise with C++.
AbortablePromise(nsIGlobalObject* aGlobal,
PromiseNativeAbortCallback& aAbortCallback);
// Constructor used to create AbortablePromise for JavaScript. It should be
// called by the static AbortablePromise::Constructor.
AbortablePromise(nsIGlobalObject* aGlobal);
virtual ~AbortablePromise();
public:
virtual JSObject*
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
static already_AddRefed<AbortablePromise>
Constructor(const GlobalObject& aGlobal, PromiseInit& aInit,
AbortCallback& aAbortCallback, ErrorResult& aRv);
void Abort();
private:
void DoAbort();
// The callback functions to abort the promise.
CallbackObjectHolder<AbortCallback,
PromiseNativeAbortCallback> mAbortCallback;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_AbortablePromise_h__

View File

@ -325,26 +325,33 @@ Promise::WrapObject(JSContext* aCx)
already_AddRefed<Promise>
Promise::Create(nsIGlobalObject* aGlobal, ErrorResult& aRv)
{
AutoJSAPI jsapi;
if (!jsapi.Init(aGlobal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
nsRefPtr<Promise> p = new Promise(aGlobal);
p->CreateWrapper(aRv);
if (aRv.Failed()) {
return nullptr;
}
return p.forget();
}
void
Promise::CreateWrapper(ErrorResult& aRv)
{
AutoJSAPI jsapi;
if (!jsapi.Init(mGlobal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JSContext* cx = jsapi.cx();
nsRefPtr<Promise> p = new Promise(aGlobal);
JS::Rooted<JS::Value> ignored(cx);
if (!WrapNewBindingObject(cx, p, &ignored)) {
if (!WrapNewBindingObject(cx, this, &ignored)) {
JS_ClearPendingException(cx);
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
// Need the .get() bit here to get template deduction working right
dom::PreserveWrapper(p.get());
return p.forget();
dom::PreserveWrapper(this);
}
void
@ -483,8 +490,6 @@ Promise::CreateThenableFunction(JSContext* aCx, Promise* aPromise, uint32_t aTas
Promise::Constructor(const GlobalObject& aGlobal,
PromiseInit& aInit, ErrorResult& aRv)
{
JSContext* cx = aGlobal.Context();
nsCOMPtr<nsIGlobalObject> global;
global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
@ -497,20 +502,34 @@ Promise::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
JS::Rooted<JSObject*> resolveFunc(cx,
CreateFunction(cx, aGlobal.Get(), promise,
PromiseCallback::Resolve));
if (!resolveFunc) {
aRv.Throw(NS_ERROR_UNEXPECTED);
promise->CallInitFunction(aGlobal, aInit, aRv);
if (aRv.Failed()) {
return nullptr;
}
return promise.forget();
}
void
Promise::CallInitFunction(const GlobalObject& aGlobal,
PromiseInit& aInit, ErrorResult& aRv)
{
JSContext* cx = aGlobal.Context();
JS::Rooted<JSObject*> resolveFunc(cx,
CreateFunction(cx, aGlobal.Get(), this,
PromiseCallback::Resolve));
if (!resolveFunc) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JS::Rooted<JSObject*> rejectFunc(cx,
CreateFunction(cx, aGlobal.Get(), promise,
CreateFunction(cx, aGlobal.Get(), this,
PromiseCallback::Reject));
if (!rejectFunc) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
aInit.Call(resolveFunc, rejectFunc, aRv, CallbackObject::eRethrowExceptions);
@ -524,13 +543,11 @@ Promise::Constructor(const GlobalObject& aGlobal,
// function Promise(arg) { try { arg(a, b); } catch (e) { this.reject(e); }}
if (!JS_WrapValue(cx, &value)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
promise->MaybeRejectInternal(cx, value);
MaybeRejectInternal(cx, value);
}
return promise.forget();
}
/* static */ already_AddRefed<Promise>

View File

@ -50,9 +50,9 @@ public:
Notify(JSContext* aCx, workers::Status aStatus) MOZ_OVERRIDE;
};
class Promise MOZ_FINAL : public nsISupports,
public nsWrapperCache,
public SupportsWeakPtr<Promise>
class Promise : public nsISupports,
public nsWrapperCache,
public SupportsWeakPtr<Promise>
{
friend class NativePromiseCallback;
friend class PromiseResolverTask;
@ -65,8 +65,6 @@ class Promise MOZ_FINAL : public nsISupports,
friend class ThenableResolverTask;
friend class WrapperPromiseCallback;
~Promise();
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
@ -159,11 +157,32 @@ public:
void AppendNativeHandler(PromiseNativeHandler* aRunnable);
private:
protected:
// Do NOT call this unless you're Promise::Create. I wish we could enforce
// that from inside this class too, somehow.
explicit Promise(nsIGlobalObject* aGlobal);
virtual ~Promise();
// Queue an async task to current main or worker thread.
static void
DispatchToMainOrWorkerThread(nsIRunnable* aRunnable);
// Do JS-wrapping after Promise creation.
void CreateWrapper(ErrorResult& aRv);
// Create the JS resolving functions of resolve() and reject(). And provide
// references to the two functions by calling PromiseInit passed from Promise
// constructor.
void CallInitFunction(const GlobalObject& aGlobal, PromiseInit& aInit,
ErrorResult& aRv);
bool IsPending()
{
return mResolvePending;
}
private:
friend class PromiseDebugging;
enum PromiseState {
@ -189,10 +208,6 @@ private:
mResult = aValue;
}
// Queue an async task to current main or worker thread.
static void
DispatchToMainOrWorkerThread(nsIRunnable* aRunnable);
// This method processes promise's resolve/reject callbacks with promise's
// result. It's executed when the resolver.resolve() or resolver.reject() is
// called or when the promise already has a result and new callbacks are

View File

@ -20,13 +20,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PromiseCallback)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_CLASS(PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PromiseCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_0(PromiseCallback)
PromiseCallback::PromiseCallback()
{

View File

@ -0,0 +1,36 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_PromiseNativeAbortCallback_h
#define mozilla_dom_PromiseNativeAbortCallback_h
#include "nsISupports.h"
namespace mozilla {
namespace dom {
/*
* PromiseNativeAbortCallback allows C++ to react to an AbortablePromise being
* aborted.
*/
class PromiseNativeAbortCallback : public nsISupports
{
protected:
virtual ~PromiseNativeAbortCallback()
{ }
public:
// Implemented in AbortablePromise.cpp.
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(PromiseNativeAbortCallback)
virtual void Call() = 0;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PromiseNativeAbortCallback_h

View File

@ -5,13 +5,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'AbortablePromise.h',
'Promise.h',
'PromiseDebugging.h',
'PromiseNativeAbortCallback.h',
'PromiseNativeHandler.h',
'PromiseWorkerProxy.h',
]
UNIFIED_SOURCES += [
'AbortablePromise.cpp',
'Promise.cpp',
'PromiseCallback.cpp',
'PromiseDebugging.cpp'

View File

@ -4,3 +4,4 @@
[test_promise.html]
[test_promise_utils.html]
[test_resolve.html]
[test_abortable_promise.html]

View File

@ -0,0 +1,115 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Promise.resolve(anything) Test</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript"><!--
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.abortablepromise.enabled", true]]},
runTest);
var gTests = [testPending, testResolved, testRejected];
function runTest() {
if (gTests.length == 0) {
SimpleTest.finish();
return;
}
new Promise(gTests.shift()).then(runTest, SimpleTest.finish);
}
// Aborting pending promise should first reject the promise and then call the
// abortable callback.
// The test succeeds once both the rejection handler and the abort handler have
// been called.
function testPending(succeed, fail) {
var rejected = false;
var aborted = false;
var p = new MozAbortablePromise(function(resolve, reject) {
// Wait for a while so that the promise can be aborted before resolved.
SimpleTest.executeSoon(function() {
resolve(0);
});
}, function abortable() {
aborted = true;
ok(true, "Promise aborted.");
if (rejected) {
succeed();
}
});
p.then(function() {
ok(false, "Failed to abort pending promise.");
fail();
}, function(what) {
rejected = true;
var isAbortException = (what && what.name) == "NS_ERROR_ABORT";
ok(isAbortException, "Should have NS_ERROR_ABORT exception");
if (!isAbortException) {
fail();
}
if (aborted) {
succeed();
}
});
// Abort the promise on creation.
p.abort();
}
// Do nothing when aborting resolved promise.
function testResolved(succeed, fail) {
var p = new MozAbortablePromise(function(resolve, reject) {
resolve();
}, function abortable() {
ok(false, "Should not abort a resolved promise.");
fail();
});
p.then(function() {
ok(true, "Promise resolved.");
// Wait for a while to ensure abort handle won't be called.
setTimeout(succeed, 1000);
}, function(what) {
ok(false, "Failed to resolve promise: " + what);
fail();
});
p.abort();
}
// Do nothing when aborting rejected promise.
function testRejected(succeed, fail) {
var p = new MozAbortablePromise(function(resolve, reject) {
reject(0);
}, function abortable() {
ok(false, "Should not abort a rejected promise.");
fail();
});
p.then(function() {
ok(false, "Failed to reject promise.");
fail();
}, function(what) {
is(what, 0, "promise rejected: " + what);
// Wait for a while to ensure abort handle won't be called.
setTimeout(succeed, 1000);
});
p.abort();
}
// -->
</script>
</pre>
</body>
</html>

View File

@ -57,7 +57,7 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug351601.html]
[test_bug369306.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s #TIMED_OUT # b2g-debug(test timed out, can't focus back from popup window to opener?) b2g-desktop(test timed out, can't focus back from popup window to opener?)
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s #TIMED_OUT # b2g-debug(test timed out, can't focus back from popup window to opener?) b2g-desktop(test timed out, can't focus back from popup window to opener?)
[test_bug370098.html]
[test_bug377539.html]
[test_bug384122.html]
@ -163,5 +163,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #Windows can't change size on Android # b2g(Windows can't change size on B2G) b2g-debug(Windows can't change size on B2G) b2g-desktop(Windows can't change size on B2G)
[test_toJSON.html]
[test_window_bar.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s
[test_bug1022869.html]

View File

@ -118,6 +118,8 @@ var legacyMozPrefixedInterfaces =
// IMPORTANT: Do not change the list below without review from a DOM peer!
var interfaceNamesInGlobalScope =
[
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozAbortablePromise", pref: "dom.abortablepromise.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "AlarmsManager", pref: "dom.mozAlarms.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -0,0 +1,19 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
callback AbortCallback = void ();
[Constructor(PromiseInit init, AbortCallback abortCallback),
Pref="dom.abortablepromise.enabled"]
interface MozAbortablePromise : _Promise {
/*
* Aborts the promise.
* If the promise has not been resolved or rejected, it should be rejected
* with an Exception of type abort and then AbortCallback is called
* asynchronously. Otherwise, nothing should be done.
*/
void abort();
};

View File

@ -16,6 +16,7 @@ PREPROCESSED_WEBIDL_FILES = [
]
WEBIDL_FILES = [
'AbortablePromise.webidl',
'AbstractWorker.webidl',
'ActivityRequestHandler.webidl',
'AlarmsManager.webidl',

View File

@ -108,7 +108,7 @@ class UnregisterCallback MOZ_FINAL : public nsIServiceWorkerUnregisterCallback
public:
NS_DECL_ISUPPORTS
UnregisterCallback(Promise* aPromise)
explicit UnregisterCallback(Promise* aPromise)
: mPromise(aPromise)
{
MOZ_ASSERT(mPromise);

View File

@ -1117,20 +1117,20 @@ public:
* This creates a simple data source surface for a certain size. It allocates
* new memory for the surface. This memory is freed when the surface is
* destroyed. The caller is responsible for handing the case where nullptr
* is returned.
* is returned. The surface is not zeroed unless requested.
*/
static TemporaryRef<DataSourceSurface>
CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat);
CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat, bool aZero = false);
/**
* This creates a simple data source surface for a certain size with a
* specific stride, which must be large enough to fit all pixels.
* It allocates new memory for the surface. This memory is freed when
* the surface is destroyed. The caller is responsible for handling the case
* where nullptr is returned.
* where nullptr is returned. The surface is not zeroed unless requested.
*/
static TemporaryRef<DataSourceSurface>
CreateDataSourceSurfaceWithStride(const IntSize &aSize, SurfaceFormat aFormat, int32_t aStride);
CreateDataSourceSurfaceWithStride(const IntSize &aSize, SurfaceFormat aFormat, int32_t aStride, bool aZero = false);
/**
* This creates a simple data source surface for some existing data. It will

View File

@ -48,6 +48,8 @@ SurfaceToPackedBGR(DataSourceSurface *aSurface);
/**
* Clears all the bytes in a DataSourceSurface's data array to zero (so to
* transparent black for SurfaceFormat::B8G8R8A8, for example).
* Note that DataSourceSurfaces can be initialized to zero, which is
* more efficient than zeroing the surface after initialization.
*/
void
ClearDataSourceSurface(DataSourceSurface *aSurface);

View File

@ -1358,9 +1358,8 @@ DrawTargetCG::Init(BackendType aType,
}
static_assert(sizeof(decltype(mData[0])) == 1,
"mData.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mData.Realloc(/* actually an object count */ bufLen);
mData.Realloc(/* actually an object count */ bufLen, true);
aData = static_cast<unsigned char*>(mData);
memset(aData, 0, bufLen);
}
mSize = aSize;

View File

@ -700,7 +700,8 @@ Factory::CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
TemporaryRef<DataSourceSurface>
Factory::CreateDataSourceSurface(const IntSize &aSize,
SurfaceFormat aFormat)
SurfaceFormat aFormat,
bool aZero)
{
if (!CheckSurfaceSize(aSize)) {
gfxWarning() << "CreateDataSourceSurface failed with bad size";
@ -708,7 +709,7 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
}
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
if (newSurf->Init(aSize, aFormat)) {
if (newSurf->Init(aSize, aFormat, aZero)) {
return newSurf.forget();
}
@ -719,7 +720,8 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
TemporaryRef<DataSourceSurface>
Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
SurfaceFormat aFormat,
int32_t aStride)
int32_t aStride,
bool aZero)
{
if (aStride < aSize.width * BytesPerPixel(aFormat)) {
gfxWarning() << "CreateDataSourceSurfaceWithStride failed with bad stride";
@ -727,7 +729,7 @@ Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
}
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
if (newSurf->InitWithStride(aSize, aFormat, aStride)) {
if (newSurf->InitWithStride(aSize, aFormat, aStride, aZero)) {
return newSurf.forget();
}

View File

@ -492,16 +492,13 @@ GetDataSurfaceInRect(SourceSurface *aSurface,
IntRect intersectInDestSpace = intersect - aDestRect.TopLeft();
SurfaceFormat format = aSurface ? aSurface->GetFormat() : SurfaceFormat(SurfaceFormat::B8G8R8A8);
bool clear = aEdgeMode == EDGE_MODE_NONE && !aSurfaceRect.Contains(aDestRect);
RefPtr<DataSourceSurface> target =
Factory::CreateDataSourceSurface(aDestRect.Size(), format);
Factory::CreateDataSourceSurface(aDestRect.Size(), format, clear);
if (MOZ2D_WARN_IF(!target)) {
return nullptr;
}
if (aEdgeMode == EDGE_MODE_NONE && !aSurfaceRect.Contains(aDestRect)) {
ClearDataSourceSurface(target);
}
if (!aSurface) {
return target.forget();
}
@ -2371,11 +2368,10 @@ FilterNodeConvolveMatrixSoftware::DoRender(const IntRect& aRect,
DebugOnlyAutoColorSamplingAccessControl accessControl(input);
RefPtr<DataSourceSurface> target =
Factory::CreateDataSourceSurface(aRect.Size(), SurfaceFormat::B8G8R8A8);
Factory::CreateDataSourceSurface(aRect.Size(), SurfaceFormat::B8G8R8A8, true);
if (MOZ2D_WARN_IF(!target)) {
return nullptr;
}
ClearDataSourceSurface(target);
IntPoint offset = aRect.TopLeft() - srcRect.TopLeft();
@ -2776,15 +2772,13 @@ FilterNodeCompositeSoftware::Render(const IntRect& aRect)
RefPtr<DataSourceSurface> start =
GetInputDataSourceSurface(IN_COMPOSITE_IN_START, aRect, NEED_COLOR_CHANNELS);
RefPtr<DataSourceSurface> dest =
Factory::CreateDataSourceSurface(aRect.Size(), SurfaceFormat::B8G8R8A8);
Factory::CreateDataSourceSurface(aRect.Size(), SurfaceFormat::B8G8R8A8, !start);
if (MOZ2D_WARN_IF(!dest)) {
return nullptr;
}
if (start) {
CopyRect(start, dest, aRect - aRect.TopLeft(), IntPoint());
} else {
ClearDataSourceSurface(dest);
}
for (size_t inputIndex = 1; inputIndex < NumberOfSetInputs(); inputIndex++) {

View File

@ -44,7 +44,8 @@ SourceSurfaceRawData::GuaranteePersistance()
bool
SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
SurfaceFormat aFormat)
SurfaceFormat aFormat,
bool aZero)
{
mFormat = aFormat;
mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
@ -53,7 +54,7 @@ SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
if (bufLen > 0) {
static_assert(sizeof(decltype(mArray[0])) == 1,
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mArray.Realloc(/* actually an object count */ bufLen);
mArray.Realloc(/* actually an object count */ bufLen, aZero);
mSize = aSize;
} else {
mArray.Dealloc();
@ -66,7 +67,8 @@ SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
bool
SourceSurfaceAlignedRawData::InitWithStride(const IntSize &aSize,
SurfaceFormat aFormat,
int32_t aStride)
int32_t aStride,
bool aZero)
{
mFormat = aFormat;
mStride = aStride;
@ -75,7 +77,7 @@ SourceSurfaceAlignedRawData::InitWithStride(const IntSize &aSize,
if (bufLen > 0) {
static_assert(sizeof(decltype(mArray[0])) == 1,
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mArray.Realloc(/* actually an object count */ bufLen);
mArray.Realloc(/* actually an object count */ bufLen, aZero);
mSize = aSize;
} else {
mArray.Dealloc();

View File

@ -56,10 +56,12 @@ public:
virtual SurfaceFormat GetFormat() const { return mFormat; }
bool Init(const IntSize &aSize,
SurfaceFormat aFormat);
SurfaceFormat aFormat,
bool aZero);
bool InitWithStride(const IntSize &aSize,
SurfaceFormat aFormat,
int32_t aStride);
int32_t aStride,
bool aZero);
private:
AlignedArray<uint8_t> mArray;

View File

@ -103,11 +103,11 @@ struct AlignedArray
{
}
explicit MOZ_ALWAYS_INLINE AlignedArray(size_t aCount)
explicit MOZ_ALWAYS_INLINE AlignedArray(size_t aCount, bool aZero = false)
: mStorage(nullptr)
, mCount(0)
{
Realloc(aCount);
Realloc(aCount, aZero);
}
MOZ_ALWAYS_INLINE ~AlignedArray()
@ -138,7 +138,7 @@ struct AlignedArray
mPtr = nullptr;
}
MOZ_ALWAYS_INLINE void Realloc(size_t aCount)
MOZ_ALWAYS_INLINE void Realloc(size_t aCount, bool aZero = false)
{
delete [] mStorage;
CheckedInt32 storageByteCount =
@ -151,7 +151,11 @@ struct AlignedArray
}
// We don't create an array of T here, since we don't want ctors to be
// invoked at the wrong places if we realign below.
mStorage = new (std::nothrow) uint8_t[storageByteCount.value()];
if (aZero) {
mStorage = static_cast<uint8_t *>(calloc(1, storageByteCount.value()));
} else {
mStorage = new (std::nothrow) uint8_t[storageByteCount.value()];
}
if (!mStorage) {
mStorage = nullptr;
mPtr = nullptr;

View File

@ -814,6 +814,14 @@ AsyncPanZoomController::AssertOnControllerThread() {
MOZ_ASSERT(sControllerThread == PR_GetCurrentThread());
}
void
AsyncPanZoomController::AssertOnCompositorThread()
{
if (GetThreadAssertionsEnabled()) {
Compositor::AssertOnCompositorThread();
}
}
/*static*/ void
AsyncPanZoomController::InitializeGlobalState()
{
@ -870,9 +878,7 @@ AsyncPanZoomController::~AsyncPanZoomController() {
PCompositorParent*
AsyncPanZoomController::GetSharedFrameMetricsCompositor()
{
if (GetThreadAssertionsEnabled()) {
Compositor::AssertOnCompositorThread();
}
AssertOnCompositorThread();
if (mSharingFrameMetricsAcrossProcesses) {
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(mLayersId);
@ -899,6 +905,8 @@ AsyncPanZoomController::GetGestureEventListener() const {
void
AsyncPanZoomController::Destroy()
{
AssertOnCompositorThread();
CancelAnimation();
mTouchBlockQueue.Clear();
@ -2357,6 +2365,8 @@ AsyncPanZoomController::FireAsyncScrollOnTimeout()
bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
Vector<Task*>* aOutDeferredTasks)
{
AssertOnCompositorThread();
// This function may get called multiple with the same sample time, because
// there may be multiple layers with this APZC, and each layer invokes this
// function during composition. However we only want to do one animation step
@ -2429,6 +2439,8 @@ void AsyncPanZoomController::GetOverscrollTransform(Matrix4x4* aTransform) const
bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime)
{
AssertOnCompositorThread();
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
// fling is happening, it has to keep compositing so that the animation is
@ -2574,6 +2586,8 @@ Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
}
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
AssertOnCompositorThread();
ReentrantMonitorAutoEnter lock(mMonitor);
bool isDefault = mFrameMetrics.IsDefault();

View File

@ -1105,10 +1105,16 @@ public:
static bool GetThreadAssertionsEnabled();
/**
* This can be used to assert that the current thread is the
* controller/UI thread (on which input events are received.
* controller/UI thread (on which input events are received).
* This does nothing if thread assertions are disabled.
*/
static void AssertOnControllerThread();
/**
* This can be used to assert that the current thread is the
* compositor thread (which applies the async transform).
* This does nothing if thread assertions are disabled.
*/
static void AssertOnCompositorThread();
/**
* Set an extra offset for testing async scrolling.
*/

View File

@ -149,6 +149,12 @@ CompositorThreadHolder::CreateCompositorThread()
* Compositor hangs seen in the wild, but is short enough to not miss getting
* native hang stacks. */
options.permanent_hang_timeout = 2048; // milliseconds
#if defined(_WIN32)
/* With d3d9 the compositor thread creates native ui, see DeviceManagerD3D9. As
* such the thread is a gui thread, and must process a windows message queue or
* risk deadlocks. Chromium message loop TYPE_UI does exactly what we need. */
options.message_loop_type = MessageLoop::TYPE_UI;
#endif
if (!compositorThread->StartWithOptions(options)) {
delete compositorThread;

View File

@ -278,6 +278,7 @@ gfxPlatform::gfxPlatform()
uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
InitBackendPrefs(canvasMask, BackendType::CAIRO,
contentMask, BackendType::CAIRO);
mTotalSystemMemory = mozilla::hal::GetTotalSystemMemory();
}
gfxPlatform*
@ -852,14 +853,12 @@ gfxPlatform::InitializeSkiaCacheLimits()
cacheSizeLimit *= 1024*1024;
if (usingDynamicCache) {
uint32_t totalMemory = mozilla::hal::GetTotalSystemMemory();
if (totalMemory < 512*1024*1024) {
if (mTotalSystemMemory < 512*1024*1024) {
// We need a very minimal cache on anything smaller than 512mb.
// Note the large jump as we cross 512mb (from 2mb to 32mb).
cacheSizeLimit = 2*1024*1024;
} else if (totalMemory > 0) {
cacheSizeLimit = totalMemory / 16;
} else if (mTotalSystemMemory > 0) {
cacheSizeLimit = mTotalSystemMemory / 16;
}
}
@ -912,6 +911,17 @@ gfxPlatform::PurgeSkiaCache()
#endif
}
bool
gfxPlatform::HasEnoughTotalSystemMemoryForSkiaGL()
{
#ifdef MOZ_WIDGET_GONK
if (mTotalSystemMemory < 250*1024*1024) {
return false;
}
#endif
return true;
}
TemporaryRef<DrawTarget>
gfxPlatform::CreateDrawTargetForBackend(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
{

View File

@ -547,6 +547,7 @@ public:
static bool UsesOffMainThreadCompositing();
bool HasEnoughTotalSystemMemoryForSkiaGL();
protected:
gfxPlatform();
virtual ~gfxPlatform();
@ -616,6 +617,8 @@ protected:
// max number of entries in word cache
int32_t mWordCacheMaxEntries;
uint32_t mTotalSystemMemory;
private:
/**
* Start up Thebes.

View File

@ -37,6 +37,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Move.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
@ -188,21 +189,21 @@ class ScaleRequest
public:
ScaleRequest(RasterImage* aImage,
const nsIntSize& aSize,
imgFrame* aSrcFrame)
: dstSize(aSize)
, dstLocked(false)
RawAccessFrameRef&& aSrcRef)
: weakImage(aImage)
, srcRef(Move(aSrcRef))
, srcRect(srcRef->GetRect())
, dstSize(aSize)
, done(false)
, stopped(false)
{
MOZ_ASSERT(!aSrcFrame->GetIsPaletted());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!srcRef->GetIsPaletted());
MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
weakImage = aImage;
srcRect = aSrcFrame->GetRect();
}
// This can only be called on the main thread.
bool GetSurfaces(imgFrame* srcFrame)
bool AcquireResources()
{
MOZ_ASSERT(NS_IsMainThread());
@ -211,80 +212,68 @@ public:
return false;
}
bool success = false;
if (!dstLocked) {
if (!dstFrame) {
// We need to hold a lock onto the RasterImage object itself so that
// it (and its associated imgFrames) aren't marked as discardable.
bool imgLocked = NS_SUCCEEDED(image->LockImage());
bool srcLocked = NS_SUCCEEDED(srcFrame->LockImageData());
srcSurface = srcFrame->GetSurface();
dstLocked = NS_SUCCEEDED(dstFrame->LockImageData());
dstSurface = dstFrame->GetSurface();
success = imgLocked && srcLocked && dstLocked && srcSurface && dstSurface;
if (success) {
srcData = srcFrame->GetImageData();
dstData = dstFrame->GetImageData();
srcStride = srcFrame->GetImageBytesPerRow();
dstStride = dstFrame->GetImageBytesPerRow();
srcFormat = srcFrame->GetFormat();
if (NS_FAILED(image->LockImage())) {
return false;
}
// We have references to the surfaces, so we don't need to leave
// the source frame (that we don't own) locked. We'll unlock the
// destination frame in ReleaseSurfaces(), below.
if (srcLocked) {
success = NS_SUCCEEDED(srcFrame->UnlockImageData()) && success;
// We'll need a destination frame. It's unconditionally ARGB32 because
// that's what the scaler outputs.
nsRefPtr<imgFrame> tentativeDstFrame = new imgFrame();
nsresult rv =
tentativeDstFrame->Init(0, 0, dstSize.width, dstSize.height,
SurfaceFormat::B8G8R8A8);
if (NS_FAILED(rv)) {
return false;
}
// We need a strong reference to the raw data for the destination frame.
// (We already got one for the source frame in the constructor.)
RawAccessFrameRef tentativeDstRef = tentativeDstFrame->RawAccessRef();
if (!tentativeDstRef) {
return false;
}
dstFrame = tentativeDstFrame.forget();
dstRef = Move(tentativeDstRef);
}
return success;
return true;
}
// This can only be called on the main thread.
bool ReleaseSurfaces()
void ReleaseResources()
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<RasterImage> image = weakImage.get();
if (!image) {
return false;
if (image) {
image->UnlockImage();
}
bool success = false;
if (dstLocked) {
if (DiscardingEnabled())
dstFrame->SetDiscardable();
success = NS_SUCCEEDED(dstFrame->UnlockImageData());
success = success && NS_SUCCEEDED(image->UnlockImage());
dstLocked = false;
srcData = nullptr;
dstData = nullptr;
srcSurface = nullptr;
dstSurface = nullptr;
if (DiscardingEnabled() && dstFrame) {
dstFrame->SetDiscardable();
}
return success;
// Release everything except dstFrame, which we keep around for RasterImage
// to retrieve.
srcRef.reset();
dstRef.reset();
}
// These values may only be touched on the main thread.
// These values may only be modified on the main thread.
WeakPtr<RasterImage> weakImage;
nsRefPtr<imgFrame> dstFrame;
RefPtr<SourceSurface> srcSurface;
RefPtr<SourceSurface> dstSurface;
RawAccessFrameRef srcRef;
RawAccessFrameRef dstRef;
// Below are the values that may be touched on the scaling thread.
uint8_t* srcData;
uint8_t* dstData;
// Below are the values that may be modified on the scaling thread.
nsIntRect srcRect;
nsIntSize dstSize;
uint32_t srcStride;
uint32_t dstStride;
SurfaceFormat srcFormat;
bool dstLocked;
bool done;
// This boolean is accessed from both threads simultaneously without locking.
// That's safe because stopping a ScaleRequest is strictly an optimization;
// if we're not cache-coherent, at worst we'll do extra work.
@ -300,11 +289,13 @@ public:
NS_IMETHOD Run()
{
// ScaleWorker is finished with this request, so we can unlock the data now.
mScaleRequest->ReleaseSurfaces();
// Grab the weak image pointer before the request releases it.
nsRefPtr<RasterImage> image = mScaleRequest->weakImage.get();
// ScaleWorker is finished with this request, so release everything that we
// don't need anymore.
mScaleRequest->ReleaseResources();
if (image) {
RasterImage::ScaleStatus status;
if (mScaleRequest->done) {
@ -328,36 +319,36 @@ class ScaleRunner : public nsRunnable
public:
ScaleRunner(RasterImage* aImage,
const nsIntSize& aSize,
imgFrame* aSrcFrame)
RawAccessFrameRef&& aSrcRef)
{
nsAutoPtr<ScaleRequest> request(new ScaleRequest(aImage, aSize, aSrcFrame));
// Destination is unconditionally ARGB32 because that's what the scaler
// outputs.
request->dstFrame = new imgFrame();
nsresult rv = request->dstFrame->Init(0, 0, request->dstSize.width, request->dstSize.height,
SurfaceFormat::B8G8R8A8);
if (NS_FAILED(rv) || !request->GetSurfaces(aSrcFrame)) {
nsAutoPtr<ScaleRequest> req(new ScaleRequest(aImage, aSize, Move(aSrcRef)));
if (!req->AcquireResources()) {
return;
}
aImage->ScalingStart(request);
mScaleRequest = request;
aImage->ScalingStart(req);
mScaleRequest = req;
}
NS_IMETHOD Run()
{
// An alias just for ease of typing
ScaleRequest* request = mScaleRequest;
ScaleRequest* req = mScaleRequest.get();
if (!request->stopped) {
request->done = gfx::Scale(request->srcData, request->srcRect.width, request->srcRect.height, request->srcStride,
request->dstData, request->dstSize.width, request->dstSize.height, request->dstStride,
request->srcFormat);
if (!req->stopped) {
// Collect information from the frames that we need to scale.
uint8_t* srcData = req->srcRef->GetImageData();
uint8_t* dstData = req->dstRef->GetImageData();
uint32_t srcStride = req->srcRef->GetImageBytesPerRow();
uint32_t dstStride = req->dstRef->GetImageBytesPerRow();
SurfaceFormat srcFormat = req->srcRef->GetFormat();
// Actually do the scaling.
req->done =
gfx::Scale(srcData, req->srcRect.width, req->srcRect.height, srcStride,
dstData, req->dstSize.width, req->dstSize.height, dstStride,
srcFormat);
} else {
request->done = false;
req->done = false;
}
// OK, we've got a new scaled image. Let's get the main thread to unlock and
@ -863,7 +854,9 @@ RasterImage::CopyFrame(uint32_t aWhichFrame,
IntSize size(mSize.width, mSize.height);
RefPtr<DataSourceSurface> surf =
Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
Factory::CreateDataSourceSurface(size,
SurfaceFormat::B8G8R8A8,
/* aZero = */ true);
if (NS_WARN_IF(!surf)) {
return nullptr;
}
@ -2622,8 +2615,8 @@ RasterImage::RequestScale(imgFrame* aFrame, nsIntSize aSize)
}
// We also can't scale if we can't lock the image data for this frame.
if (NS_FAILED(aFrame->LockImageData())) {
aFrame->UnlockImageData();
RawAccessFrameRef frameRef = aFrame->RawAccessRef();
if (!frameRef) {
return;
}
@ -2632,7 +2625,7 @@ RasterImage::RequestScale(imgFrame* aFrame, nsIntSize aSize)
mScaleRequest->stopped = true;
}
nsRefPtr<ScaleRunner> runner = new ScaleRunner(this, aSize, aFrame);
nsRefPtr<ScaleRunner> runner = new ScaleRunner(this, aSize, Move(frameRef));
if (runner->IsOK()) {
if (!sScaleWorkerThread) {
NS_NewNamedThread("Image Scaler", getter_AddRefs(sScaleWorkerThread));
@ -2641,8 +2634,6 @@ RasterImage::RequestScale(imgFrame* aFrame, nsIntSize aSize)
sScaleWorkerThread->Dispatch(runner, NS_DISPATCH_NORMAL);
}
aFrame->UnlockImageData();
}
bool

View File

@ -742,15 +742,17 @@ bool imgFrame::ImageComplete() const
}
// A hint from the image decoders that this image has no alpha, even
// though we created is ARGB32. This changes our format to RGB24,
// which in turn will cause us to Optimize() to RGB24. Has no effect
// after Optimize() is called, though in all cases it will be just a
// performance win -- the pixels are still correct and have the A byte
// set to 0xff.
// though we're decoding it as B8G8R8A8.
// Since this is only called during decoding, there is a mImageSurface
// that should be updated to use B8G8R8X8. This doesn't change the
// underlying data at all, but allows DrawTargets to avoid blending
// when drawing known opaque images.
void imgFrame::SetHasNoAlpha()
{
if (mFormat == SurfaceFormat::B8G8R8A8) {
mFormat = SurfaceFormat::B8G8R8X8;
MOZ_ASSERT(mImageSurface);
mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat);
}
}

View File

@ -274,7 +274,8 @@ NS_IMETHODIMP imgTools::EncodeCroppedImage(imgIContainer *aContainer,
RefPtr<DataSourceSurface> dataSurface =
Factory::CreateDataSourceSurface(IntSize(aWidth, aHeight),
SurfaceFormat::B8G8R8A8);
SurfaceFormat::B8G8R8A8,
/* aZero = */ true);
if (NS_WARN_IF(!dataSurface)) {
return NS_ERROR_FAILURE;
}

View File

@ -1077,6 +1077,22 @@ if test -n "$MOZ_ASAN"; then
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_ASAN)
dnl ========================================================
dnl = Use Memory Sanitizer
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(memory-sanitizer,
[ --enable-memory-sanitizer Enable Memory Sanitizer (default=no)],
MOZ_MSAN=1,
MOZ_MSAN= )
if test -n "$MOZ_MSAN"; then
MOZ_LLVM_HACKS=1
AC_DEFINE(MOZ_MSAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_MSAN)
# The LLVM symbolizer is used by all sanitizers
AC_SUBST(LLVM_SYMBOLIZER)
dnl ========================================================
@ -1968,7 +1984,7 @@ case "$target" in
;;
*-solaris*)
if test -z "$GNU_CC"; then
eOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-M $(BUILD_TOOLS)/gnu-ld-scripts/components-mapfile'
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-M $(BUILD_TOOLS)/gnu-ld-scripts/components-mapfile'
else
if test -z "$GCC_USE_GNU_LD"; then
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,-M -Wl,$(BUILD_TOOLS)/gnu-ld-scripts/components-mapfile'

View File

@ -2034,7 +2034,8 @@ IonCompile(JSContext *cx, JSScript *script,
const OptimizationInfo *optimizationInfo = js_IonOptimizations.get(optimizationLevel);
const JitCompileOptions options(cx);
IonBuilder *builder = alloc->new_<IonBuilder>(CompileCompartment::get(cx->compartment()),
IonBuilder *builder = alloc->new_<IonBuilder>((JSContext *) nullptr,
CompileCompartment::get(cx->compartment()),
options, temp, graph, constraints,
inspector, info, optimizationInfo,
baselineFrameInspector);

View File

@ -2792,7 +2792,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
BaselineInspector inspector(script);
const JitCompileOptions options(cx);
IonBuilder builder(CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
IonBuilder builder(cx, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
&inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
if (!builder.build()) {
@ -3019,7 +3019,7 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
BaselineInspector inspector(script);
const JitCompileOptions options(cx);
IonBuilder builder(CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
IonBuilder builder(nullptr, CompileCompartment::get(cx->compartment()), options, &temp, &graph, constraints,
&inspector, &info, optimizationInfo, /* baselineFrame = */ nullptr);
if (!builder.build()) {

View File

@ -106,7 +106,7 @@ jit::NewBaselineFrameInspector(TempAllocator *temp, BaselineFrame *frame, Compil
return inspector;
}
IonBuilder::IonBuilder(CompileCompartment *comp,
IonBuilder::IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
const JitCompileOptions &options, TempAllocator *temp,
MIRGraph *graph, types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info,
@ -115,6 +115,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
uint32_t loopDepth)
: MIRGenerator(comp, options, temp, graph, info, optimizationInfo),
backgroundCodegen_(nullptr),
analysisContext(analysisContext),
baselineFrame_(baselineFrame),
constraints_(constraints),
analysis_(*temp, info->script()),
@ -146,6 +147,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
abortReason_ = AbortReason_Disable;
JS_ASSERT(script()->hasBaselineScript() == (info->executionMode() != ArgumentsUsageAnalysis));
JS_ASSERT(!!analysisContext == (info->executionMode() == DefinitePropertiesAnalysis));
if (!info->executionModeIsAnalysis())
script()->baselineScript()->setIonCompiledOrInlined();
@ -154,6 +156,7 @@ IonBuilder::IonBuilder(CompileCompartment *comp,
void
IonBuilder::clearForBackEnd()
{
JS_ASSERT(!analysisContext);
baselineFrame_ = nullptr;
// The caches below allocate data from the malloc heap. Release this before
@ -346,6 +349,22 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
if (!target->isInterpreted())
return DontInline(nullptr, "Non-interpreted target");
// Allow constructing lazy scripts when performing the definite properties
// analysis, as baseline has not been used to warm the caller up yet.
if (target->isInterpreted() && info().executionMode() == DefinitePropertiesAnalysis) {
RootedScript script(analysisContext, target->getOrCreateScript(analysisContext));
if (!script)
return InliningDecision_Error;
if (!script->hasBaselineScript() && script->canBaselineCompile()) {
MethodStatus status = BaselineCompile(analysisContext, script);
if (status == Method_Error)
return InliningDecision_Error;
if (status != Method_Compiled)
return InliningDecision_DontInline;
}
}
if (!target->hasScript())
return DontInline(nullptr, "Lazy script");
@ -4184,10 +4203,16 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
AutoAccumulateReturns aar(graph(), returns);
// Build the graph.
IonBuilder inlineBuilder(compartment, options, &alloc(), &graph(), constraints(),
IonBuilder inlineBuilder(analysisContext, compartment, options, &alloc(), &graph(), constraints(),
&inspector, info, &optimizationInfo(), nullptr, inliningDepth_ + 1,
loopDepth_);
if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
if (analysisContext && analysisContext->isExceptionPending()) {
JitSpew(JitSpew_Abort, "Inline builder raised exception.");
abortReason_ = AbortReason_Error;
return false;
}
// Inlining the callee failed. Mark the callee as uninlineable only if
// the inlining was aborted for a non-exception reason.
if (inlineBuilder.abortReason_ == AbortReason_Disable) {
@ -6418,6 +6443,8 @@ IonBuilder::testSingletonProperty(JSObject *obj, PropertyName *name)
return nullptr;
types::TypeObjectKey *objType = types::TypeObjectKey::get(obj);
if (analysisContext)
objType->ensureTrackedProperty(analysisContext, NameToId(name));
if (objType->unknownProperties())
return nullptr;
@ -6499,6 +6526,8 @@ IonBuilder::testSingletonPropertyTypes(MDefinition *obj, JSObject *singleton, Pr
types::TypeObjectKey *object = types->getObject(i);
if (!object)
continue;
if (analysisContext)
object->ensureTrackedProperty(analysisContext, NameToId(name));
const Class *clasp = object->clasp();
if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name))
@ -6706,6 +6735,8 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
}
types::TypeObjectKey *staticType = types::TypeObjectKey::get(staticObject);
if (analysisContext)
staticType->ensureTrackedProperty(analysisContext, NameToId(name));
if (staticType->unknownProperties()) {
*psucceeded = false;
@ -6724,7 +6755,7 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
}
types::TemporaryTypeSet *types = bytecodeTypes(pc);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), staticType,
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), staticType,
name, types, /* updateObserved = */ true);
JSObject *singleton = types->getSingleton();
@ -7540,7 +7571,8 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index)
// Emit GetElementCache.
types::TemporaryTypeSet *types = bytecodeTypes(pc);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, types);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj,
nullptr, types);
// Always add a barrier if the index might be a string or symbol, so that
// the cache can attach stubs for particular properties.
@ -7588,7 +7620,8 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
AddObjectsForPropertyRead(obj, nullptr, types);
}
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, types);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj,
nullptr, types);
bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
// Reads which are on holes in the object do not have to bail out if
@ -8904,7 +8937,8 @@ IonBuilder::jsop_getprop(PropertyName *name)
if (!getPropTryArgumentsCallee(&emitted, obj, name) || emitted)
return emitted;
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, name, types);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, name, types);
// Always use a call if we are performing analysis and
// not actually emitting code, to simplify later analysis. Also skip deeper
@ -9586,7 +9620,8 @@ IonBuilder::getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *na
// Passing the inner object to GetProperty IC is safe, see the
// needsOuterizedThisObject check in IsCacheableGetPropCallNative.
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), inner, name, types);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
inner, name, types);
if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted)
return *emitted;

View File

@ -214,7 +214,7 @@ class IonBuilder
static int CmpSuccessors(const void *a, const void *b);
public:
IonBuilder(CompileCompartment *comp,
IonBuilder(JSContext *analysisContext, CompileCompartment *comp,
const JitCompileOptions &options, TempAllocator *temp,
MIRGraph *graph, types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info,
@ -865,6 +865,7 @@ class IonBuilder
private:
bool init();
JSContext *analysisContext;
BaselineFrameInspector *baselineFrame_;
// Constraints for recording dependencies on type information.

View File

@ -433,7 +433,8 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED);
bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
BarrierKind barrier = PropertyReadNeedsTypeBarrier(constraints(), obj, nullptr, returnTypes);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, nullptr, returnTypes);
if (barrier != BarrierKind::NoBarrier)
returnType = MIRType_Value;

View File

@ -3667,7 +3667,8 @@ PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
}
BarrierKind
jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeObjectKey *object, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved)
{
@ -3687,6 +3688,8 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
break;
types::TypeObjectKey *typeObj = types::TypeObjectKey::get(obj);
if (propertycx)
typeObj->ensureTrackedProperty(propertycx, NameToId(name));
if (!typeObj->unknownProperties()) {
types::HeapTypeSetKey property = typeObj->property(NameToId(name));
@ -3712,7 +3715,8 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
}
BarrierKind
jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed)
{
@ -3729,7 +3733,7 @@ jit::PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
for (size_t i = 0; i < types->getObjectCount(); i++) {
types::TypeObjectKey *object = types->getObject(i);
if (object) {
BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, object, name,
BarrierKind kind = PropertyReadNeedsTypeBarrier(propertycx, constraints, object, name,
observed, updateObserved);
if (kind == BarrierKind::TypeSet)
return BarrierKind::TypeSet;

View File

@ -11772,10 +11772,12 @@ bool ElementAccessMightBeCopyOnWrite(types::CompilerConstraintList *constraints,
bool ElementAccessHasExtraIndexedProperty(types::CompilerConstraintList *constraints,
MDefinition *obj);
MIRType DenseNativeElementType(types::CompilerConstraintList *constraints, MDefinition *obj);
BarrierKind PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
types::TypeObjectKey *object, PropertyName *name,
types::TemporaryTypeSet *observed, bool updateObserved);
BarrierKind PropertyReadNeedsTypeBarrier(types::CompilerConstraintList *constraints,
BarrierKind PropertyReadNeedsTypeBarrier(JSContext *propertycx,
types::CompilerConstraintList *constraints,
MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *observed);
BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(types::CompilerConstraintList *constraints,

View File

@ -1091,6 +1091,21 @@ TypeObjectKey::property(jsid id)
return property;
}
void
TypeObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
{
// If we are accessing a lazily defined property which actually exists in
// the VM and has not been instantiated yet, instantiate it now if we are
// on the main thread and able to do so.
if (!JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
JS_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
if (JSObject *obj = singleton()) {
if (obj->isNative() && obj->nativeLookupPure(id))
EnsureTrackPropertyTypes(cx, obj, id);
}
}
}
bool
HeapTypeSetKey::instantiate(JSContext *cx)
{

View File

@ -1465,6 +1465,7 @@ struct TypeObjectKey
void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
void watchStateChangeForTypedArrayData(CompilerConstraintList *constraints);
HeapTypeSetKey property(jsid id);
void ensureTrackedProperty(JSContext *cx, jsid id);
TypeObject *maybeType();
};

View File

@ -106,6 +106,12 @@ bool
js::DecompressString(const unsigned char *inp, size_t inplen, unsigned char *out, size_t outlen)
{
JS_ASSERT(inplen <= UINT32_MAX);
// Mark the memory we pass to zlib as initialized for MSan.
#ifdef MOZ_MSAN
__msan_unpoison(out, outlen);
#endif
z_stream zs;
zs.zalloc = zlib_alloc;
zs.zfree = zlib_free;

View File

@ -2235,7 +2235,7 @@ nsDisplayBackgroundImage::GetInsideClipRegion(nsDisplayItem* aItem,
clipRect = frame->GetPaddingRect() - frame->GetPosition() + aItem->ToReferenceFrame();
break;
case NS_STYLE_BG_CLIP_CONTENT:
clipRect = frame->GetContentRect() - frame->GetPosition() + aItem->ToReferenceFrame();
clipRect = frame->GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
break;
default:
NS_NOTREACHED("Unknown clip type");

View File

@ -23,7 +23,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' # b2g(needs copy support) b2
[test_bug477531.html]
[test_bug477700.html]
[test_bug478219.xhtml]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #window.closed not working, bug 907795 # b2g(window.closed not working, bug 907795) b2g-debug(window.closed not working, bug 907795) b2g-desktop(window.closed not working, bug 907795)
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #window.closed not working, bug 907795 # b2g(window.closed not working, bug 907795) b2g-debug(window.closed not working, bug 907795) b2g-desktop(window.closed not working, bug 907795)
[test_bug534785.html]
[test_bug542914.html]
skip-if = (toolkit == 'gonk' && debug) #debug-only failure
@ -31,7 +31,7 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure
[test_bug562447.html]
[test_bug563642.html]
[test_bug564115.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s #TIMED_OUT # b2g-debug(times out on window.open and focus event) b2g-desktop(times out on window.open and focus event)
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' || e10s #TIMED_OUT # b2g-debug(times out on window.open and focus event) b2g-desktop(times out on window.open and focus event)
[test_bug571352.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(shift-click multi-select not working?) b2g-debug(shift-click multi-select not working?) b2g-desktop(shift-click multi-select not working?)
[test_bug572406.html]

View File

@ -215,7 +215,7 @@ public:
friend struct AutoApplyUserSelectStyle;
struct MOZ_STACK_CLASS AutoApplyUserSelectStyle
{
AutoApplyUserSelectStyle(Selection* aSelection
explicit AutoApplyUserSelectStyle(Selection* aSelection
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mSavedValue(aSelection->mApplyUserSelectStyle)
{

View File

@ -5873,7 +5873,7 @@ nsresult
nsFrame::GetPointFromOffset(int32_t inOffset, nsPoint* outPoint)
{
NS_PRECONDITION(outPoint != nullptr, "Null parameter");
nsRect contentRect = GetContentRect() - GetPosition();
nsRect contentRect = GetContentRectRelativeToSelf();
nsPoint pt = contentRect.TopLeft();
if (mContent)
{

View File

@ -241,6 +241,8 @@ nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext,
// FIXME taken from nsImageFrame, but then had splittable frame stuff
// removed. That needs to be fixed.
// XXXdholbert As in nsImageFrame, this function's clients should probably
// just be calling GetContentRectRelativeToSelf().
nsRect
nsHTMLCanvasFrame::GetInnerArea() const
{
@ -259,7 +261,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters)
{
nsRect area = GetContentRect() - GetPosition() + aItem->ToReferenceFrame();
nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(GetContent());
nsIntSize canvasSize = GetCanvasSize();

View File

@ -812,10 +812,12 @@ nsImageFrame::ComputeSize(nsRenderingContext *aRenderingContext,
aPadding);
}
// XXXdholbert This function's clients should probably just be calling
// GetContentRectRelativeToSelf() directly.
nsRect
nsImageFrame::GetInnerArea() const
{
return GetContentRect() - GetPosition();
return GetContentRectRelativeToSelf();
}
Element*

View File

@ -174,7 +174,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters)
{
nsRect area = GetContentRect() - GetPosition() + aItem->ToReferenceFrame();
nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
HTMLVideoElement* element = static_cast<HTMLVideoElement*>(GetContent());
nsIntSize videoSize;
if (NS_FAILED(element->GetVideoSize(&videoSize)) || area.IsEmpty()) {
@ -393,7 +393,7 @@ public:
{
*aSnap = true;
nsIFrame* f = Frame();
return f->GetContentRect() - f->GetPosition() + ToReferenceFrame();
return f->GetContentRectRelativeToSelf() + ToReferenceFrame();
}
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,

View File

@ -53,7 +53,7 @@ GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuil
// we need to be careful here to ensure that we call ToReferenceFrame
// on aContainerFrame and not its parent.
nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
(aContainerFrame->GetContentRect().TopLeft() - aContainerFrame->GetPosition());
aContainerFrame->GetContentRectRelativeToSelf().TopLeft();
return frameOffset.ToNearestPixels(auPerDevPixel);
}

View File

@ -55,18 +55,11 @@ CSSStyleSheet*
nsLayoutStylesheetCache::ScrollbarsSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
if (!gStyleCache->mScrollbarsSheet) {
nsCOMPtr<nsIURI> sheetURI;
NS_NewURI(getter_AddRefs(sheetURI),
NS_LITERAL_CSTRING("chrome://global/skin/scrollbars.css"));
// Scrollbars don't need access to unsafe rules
if (sheetURI)
LoadSheet(sheetURI, gStyleCache->mScrollbarsSheet, false);
NS_ASSERTION(gStyleCache->mScrollbarsSheet, "Could not load scrollbars.css.");
LoadSheetURL("chrome://global/skin/scrollbars.css",
gStyleCache->mScrollbarsSheet, false);
}
return gStyleCache->mScrollbarsSheet;
@ -76,19 +69,11 @@ CSSStyleSheet*
nsLayoutStylesheetCache::FormsSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
if (!gStyleCache->mFormsSheet) {
nsCOMPtr<nsIURI> sheetURI;
NS_NewURI(getter_AddRefs(sheetURI),
NS_LITERAL_CSTRING("resource://gre-resources/forms.css"));
// forms.css needs access to unsafe rules
if (sheetURI)
LoadSheet(sheetURI, gStyleCache->mFormsSheet, true);
NS_ASSERTION(gStyleCache->mFormsSheet, "Could not load forms.css.");
LoadSheetURL("resource://gre-resources/forms.css",
gStyleCache->mFormsSheet, true);
}
return gStyleCache->mFormsSheet;
@ -98,22 +83,14 @@ CSSStyleSheet*
nsLayoutStylesheetCache::NumberControlSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
if (!sNumberControlEnabled) {
return nullptr;
}
if (!gStyleCache->mNumberControlSheet) {
nsCOMPtr<nsIURI> sheetURI;
NS_NewURI(getter_AddRefs(sheetURI),
NS_LITERAL_CSTRING("resource://gre-resources/number-control.css"));
if (sheetURI)
LoadSheet(sheetURI, gStyleCache->mNumberControlSheet, false);
NS_ASSERTION(gStyleCache->mNumberControlSheet, "Could not load number-control.css");
LoadSheetURL("resource://gre-resources/number-control.css",
gStyleCache->mNumberControlSheet, false);
}
return gStyleCache->mNumberControlSheet;
@ -123,9 +100,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::UserContentSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mUserContentSheet;
}
@ -133,9 +107,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::UserChromeSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mUserChromeSheet;
}
@ -143,9 +114,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::UASheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mUASheet;
}
@ -153,9 +121,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::HTMLSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mHTMLSheet;
}
@ -163,9 +128,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::MinimalXULSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mMinimalXULSheet;
}
@ -173,9 +135,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::XULSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mXULSheet;
}
@ -183,9 +142,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::QuirkSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mQuirkSheet;
}
@ -193,9 +149,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::FullScreenOverrideSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mFullScreenOverrideSheet;
}
@ -203,9 +156,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::SVGSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mSVGSheet;
}
@ -213,16 +163,10 @@ CSSStyleSheet*
nsLayoutStylesheetCache::MathMLSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
if (!gStyleCache->mMathMLSheet) {
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/mathml.css");
if (uri) {
LoadSheet(uri, gStyleCache->mMathMLSheet, true);
}
NS_ASSERTION(gStyleCache->mMathMLSheet, "Could not load mathml.css");
LoadSheetURL("resource://gre-resources/mathml.css",
gStyleCache->mMathMLSheet, true);
}
return gStyleCache->mMathMLSheet;
@ -232,8 +176,6 @@ CSSStyleSheet*
nsLayoutStylesheetCache::CounterStylesSheet()
{
EnsureGlobal();
if (!gStyleCache)
return nullptr;
return gStyleCache->mCounterStylesSheet;
}
@ -265,22 +207,20 @@ nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
#define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
MEASURE(mScrollbarsSheet);
MEASURE(mFormsSheet);
MEASURE(mNumberControlSheet);
MEASURE(mUserContentSheet);
MEASURE(mUserChromeSheet);
MEASURE(mUASheet);
MEASURE(mHTMLSheet);
MEASURE(mMinimalXULSheet);
MEASURE(mXULSheet);
MEASURE(mQuirkSheet);
MEASURE(mFullScreenOverrideSheet);
MEASURE(mSVGSheet);
MEASURE(mCounterStylesSheet);
if (mMathMLSheet) {
MEASURE(mMathMLSheet);
}
MEASURE(mFormsSheet);
MEASURE(mFullScreenOverrideSheet);
MEASURE(mHTMLSheet);
MEASURE(mMathMLSheet);
MEASURE(mMinimalXULSheet);
MEASURE(mNumberControlSheet);
MEASURE(mQuirkSheet);
MEASURE(mSVGSheet);
MEASURE(mScrollbarsSheet);
MEASURE(mUASheet);
MEASURE(mUserChromeSheet);
MEASURE(mUserContentSheet);
MEASURE(mXULSheet);
// Measurement of the following members may be added later if DMD finds it is
// worthwhile:
@ -306,57 +246,25 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache()
// And make sure that we load our UA sheets. No need to do this
// per-profile, since they're profile-invariant.
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/ua.css");
if (uri) {
LoadSheet(uri, mUASheet, true);
}
NS_ASSERTION(mUASheet, "Could not load ua.css");
LoadSheetURL("resource://gre-resources/counterstyles.css",
mCounterStylesSheet, true);
LoadSheetURL("resource://gre-resources/full-screen-override.css",
mFullScreenOverrideSheet, true);
LoadSheetURL("resource://gre-resources/html.css",
mHTMLSheet, true);
LoadSheetURL("chrome://global/content/minimal-xul.css",
mMinimalXULSheet, true);
LoadSheetURL("resource://gre-resources/quirk.css",
mQuirkSheet, true);
LoadSheetURL("resource://gre/res/svg.css",
mSVGSheet, true);
LoadSheetURL("resource://gre-resources/ua.css",
mUASheet, true);
LoadSheetURL("chrome://global/content/xul.css",
mXULSheet, true);
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/html.css");
if (uri) {
LoadSheet(uri, mHTMLSheet, true);
}
NS_ASSERTION(mHTMLSheet, "Could not load xul.css");
NS_NewURI(getter_AddRefs(uri), "chrome://global/content/minimal-xul.css");
if (uri) {
LoadSheet(uri, mMinimalXULSheet, true);
}
NS_ASSERTION(mMinimalXULSheet, "Could not load minimal-xul.css");
NS_NewURI(getter_AddRefs(uri), "chrome://global/content/xul.css");
if (uri) {
LoadSheet(uri, mXULSheet, true);
}
NS_ASSERTION(mXULSheet, "Could not load xul.css");
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/quirk.css");
if (uri) {
LoadSheet(uri, mQuirkSheet, true);
}
NS_ASSERTION(mQuirkSheet, "Could not load quirk.css");
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/full-screen-override.css");
if (uri) {
LoadSheet(uri, mFullScreenOverrideSheet, true);
}
NS_ASSERTION(mFullScreenOverrideSheet, "Could not load full-screen-override.css");
NS_NewURI(getter_AddRefs(uri), "resource://gre/res/svg.css");
if (uri) {
LoadSheet(uri, mSVGSheet, true);
}
NS_ASSERTION(mSVGSheet, "Could not load svg.css");
NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/counterstyles.css");
if (uri) {
LoadSheet(uri, mCounterStylesSheet, true);
}
NS_ASSERTION(mCounterStylesSheet, "Could not load counterstyles.css");
// mMathMLSheet is created on-demand since its use is rare. This helps save
// memory for Firefox OS apps.
// The remaining sheets are created on-demand since their use is rarer. This
// helps save memory for Firefox OS apps.
}
nsLayoutStylesheetCache::~nsLayoutStylesheetCache()
@ -374,10 +282,11 @@ nsLayoutStylesheetCache::InitMemoryReporter()
void
nsLayoutStylesheetCache::EnsureGlobal()
{
MOZ_ASSERT(NS_IsMainThread());
if (gStyleCache) return;
gStyleCache = new nsLayoutStylesheetCache();
if (!gStyleCache) return;
gStyleCache->InitMemoryReporter();
@ -415,6 +324,19 @@ nsLayoutStylesheetCache::InitFromProfile()
LoadSheetFile(chromeFile, mUserChromeSheet);
}
/* static */ void
nsLayoutStylesheetCache::LoadSheetURL(const char* aURL,
nsRefPtr<CSSStyleSheet>& aSheet,
bool aEnableUnsafeRules)
{
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aURL);
LoadSheet(uri, aSheet, aEnableUnsafeRules);
if (!aSheet) {
NS_ERROR(nsPrintfCString("Could not load %s", aURL).get());
}
}
void
nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsRefPtr<CSSStyleSheet>& aSheet)
{

View File

@ -60,6 +60,9 @@ private:
static void EnsureGlobal();
void InitFromProfile();
void InitMemoryReporter();
static void LoadSheetURL(const char* aURL,
nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
bool aEnableUnsafeRules);
static void LoadSheetFile(nsIFile* aFile,
nsRefPtr<mozilla::CSSStyleSheet>& aSheet);
static void LoadSheet(nsIURI* aURI, nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
@ -67,20 +70,20 @@ private:
static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache;
static mozilla::css::Loader* gCSSLoader;
nsRefPtr<mozilla::CSSStyleSheet> mScrollbarsSheet;
nsRefPtr<mozilla::CSSStyleSheet> mFormsSheet;
nsRefPtr<mozilla::CSSStyleSheet> mNumberControlSheet;
nsRefPtr<mozilla::CSSStyleSheet> mUserContentSheet;
nsRefPtr<mozilla::CSSStyleSheet> mUserChromeSheet;
nsRefPtr<mozilla::CSSStyleSheet> mUASheet;
nsRefPtr<mozilla::CSSStyleSheet> mHTMLSheet;
nsRefPtr<mozilla::CSSStyleSheet> mMinimalXULSheet;
nsRefPtr<mozilla::CSSStyleSheet> mXULSheet;
nsRefPtr<mozilla::CSSStyleSheet> mQuirkSheet;
nsRefPtr<mozilla::CSSStyleSheet> mFullScreenOverrideSheet;
nsRefPtr<mozilla::CSSStyleSheet> mSVGSheet;
nsRefPtr<mozilla::CSSStyleSheet> mMathMLSheet;
nsRefPtr<mozilla::CSSStyleSheet> mCounterStylesSheet;
nsRefPtr<mozilla::CSSStyleSheet> mFormsSheet;
nsRefPtr<mozilla::CSSStyleSheet> mFullScreenOverrideSheet;
nsRefPtr<mozilla::CSSStyleSheet> mHTMLSheet;
nsRefPtr<mozilla::CSSStyleSheet> mMathMLSheet;
nsRefPtr<mozilla::CSSStyleSheet> mMinimalXULSheet;
nsRefPtr<mozilla::CSSStyleSheet> mNumberControlSheet;
nsRefPtr<mozilla::CSSStyleSheet> mQuirkSheet;
nsRefPtr<mozilla::CSSStyleSheet> mSVGSheet;
nsRefPtr<mozilla::CSSStyleSheet> mScrollbarsSheet;
nsRefPtr<mozilla::CSSStyleSheet> mUASheet;
nsRefPtr<mozilla::CSSStyleSheet> mUserChromeSheet;
nsRefPtr<mozilla::CSSStyleSheet> mUserContentSheet;
nsRefPtr<mozilla::CSSStyleSheet> mXULSheet;
};
#endif

View File

@ -148,7 +148,7 @@ protected:
struct nsSVGFrameReferenceFromProperty
{
nsSVGFrameReferenceFromProperty(nsIFrame* aFrame)
explicit nsSVGFrameReferenceFromProperty(nsIFrame* aFrame)
: mFrame(aFrame)
, mFramePresShell(aFrame->PresContext()->PresShell())
{}

View File

@ -724,7 +724,7 @@ nsTableCellFrame::GetCellBaseline() const
nscoord result;
if (nsLayoutUtils::GetFirstLineBaseline(GetWritingMode(), inner, &result))
return result + borderPadding;
return inner->GetContentRect().YMost() - inner->GetPosition().y +
return inner->GetContentRectRelativeToSelf().YMost() +
borderPadding;
}

View File

@ -23,10 +23,10 @@ sys.path.insert(0, SCRIPT_DIRECTORY)
from automation import Automation
from automationutils import (
addCommonOptions,
getDebuggerInfo,
isURL,
processLeakLog
)
import mozdebug
import mozprofile
def categoriesToRegex(categoryList):
@ -320,7 +320,7 @@ class RefTest(object):
return int(any(t.retcode != 0 for t in threads))
def runSerialTests(self, testPath, options, cmdlineArgs = None):
debuggerInfo = getDebuggerInfo(self.oldcwd, options.debugger, options.debuggerArgs,
debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
options.debuggerInteractive);
profileDir = None

View File

@ -54,6 +54,29 @@ __asan_unpoison_memory_region(void const volatile *addr, size_t size);
#define MOZ_MAKE_MEM_DEFINED(addr, size) \
__asan_unpoison_memory_region((addr), (size))
}
#elif defined(MOZ_MSAN)
#include <stddef.h>
#include "mozilla/Types.h"
extern "C" {
/* These definitions are usually provided through the
* sanitizer/msan_interface.h header installed by MSan.
*/
void MOZ_EXPORT
__msan_poison(void const volatile *addr, size_t size);
void MOZ_EXPORT
__msan_unpoison(void const volatile *addr, size_t size);
#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
__msan_poison((addr), (size))
#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \
__msan_poison((addr), (size))
#define MOZ_MAKE_MEM_DEFINED(addr, size) \
__msan_unpoison((addr), (size))
}
#elif defined(MOZ_VALGRIND)
#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
VALGRIND_MAKE_MEM_NOACCESS((addr), (size))

View File

@ -12,6 +12,7 @@ import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSContainer;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONException;
import org.json.JSONObject;
@ -227,12 +228,18 @@ public final class EventDispatcher {
@Deprecated
private static void sendResponseHelper(String status, JSONObject message, Object response) {
try {
final String topic = message.getString("type") + ":Response";
final JSONObject wrapper = new JSONObject();
wrapper.put(GUID, message.getString(GUID));
wrapper.put("status", status);
wrapper.put("response", response);
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(
message.getString("type") + ":Response", wrapper.toString()));
if (ThreadUtils.isOnGeckoThread()) {
GeckoAppShell.notifyGeckoObservers(topic, wrapper.toString());
} else {
GeckoAppShell.sendEventToGecko(
GeckoEvent.createBroadcastEvent(topic, wrapper.toString()));
}
} catch (final JSONException e) {
Log.e(LOGTAG, "Unable to send response", e);
}
@ -265,12 +272,18 @@ public final class EventDispatcher {
sent = true;
try {
final String topic = type + ":Response";
final JSONObject wrapper = new JSONObject();
wrapper.put(GUID, guid);
wrapper.put("status", status);
wrapper.put("response", response);
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(type + ":Response",
wrapper.toString()));
if (ThreadUtils.isOnGeckoThread()) {
GeckoAppShell.notifyGeckoObservers(topic, wrapper.toString());
} else {
GeckoAppShell.sendEventToGecko(
GeckoEvent.createBroadcastEvent(topic, wrapper.toString()));
}
} catch (final JSONException e) {
Log.e(LOGTAG, "Unable to send response for: " + type, e);
}

View File

@ -298,7 +298,12 @@ public class GeckoAppShell
private static LayerView sLayerView;
public static void setLayerView(LayerView lv) {
if (sLayerView == lv) {
return;
}
sLayerView = lv;
// Install new Gecko-to-Java editable listener.
editableListener = new GeckoEditable();
}
@RobocopTarget
@ -349,13 +354,6 @@ public class GeckoAppShell
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels;
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
geckoLoaded();
}
});
if (!AppConstants.MOZILLA_OFFICIAL) {
Log.d(LOGTAG, "GeckoLoader.nativeRun " + combinedArgs);
}
@ -366,13 +364,6 @@ public class GeckoAppShell
Looper.myQueue().removeIdleHandler(idleHandler);
}
// Called on the UI thread after Gecko loads.
private static void geckoLoaded() {
GeckoEditable editable = new GeckoEditable();
// install the gecko => editable listener
editableListener = editable;
}
static void sendPendingEventsToGecko() {
try {
while (!PENDING_EVENTS.isEmpty()) {
@ -447,6 +438,9 @@ public class GeckoAppShell
// Tell the Gecko event loop that an event is available.
public static native void notifyGeckoOfEvent(GeckoEvent event);
// Synchronously notify a Gecko observer; must be called from Gecko thread.
public static native void notifyGeckoObservers(String subject, String data);
/*
* The Gecko-side API: API methods that Gecko calls
*/

View File

@ -182,6 +182,13 @@ public final class ThreadUtils {
}
}
public static boolean isOnGeckoThread() {
if (sGeckoThread != null) {
return isOnThread(sGeckoThread);
}
return false;
}
public static boolean isOnUiThread() {
return isOnThread(getUiThread());
}

View File

@ -15,7 +15,7 @@ struct PRFileDesc;
interface nsIUTF8StringEnumerator;
interface nsIInputStream;
interface nsIFile;
interface nsICertificatePrincipal;
interface nsIX509Cert;
[scriptable, uuid(fad6f72f-13d8-4e26-9173-53007a4afe71)]
interface nsIZipEntry : nsISupports
@ -63,7 +63,7 @@ interface nsIZipEntry : nsISupports
readonly attribute unsigned long permissions;
};
[scriptable, uuid(38d6d07a-8a58-4fe7-be8b-ef6472fa83ff)]
[scriptable, uuid(894c8dc0-37c8-11e4-916c-0800200c9a66)]
interface nsIZipReader : nsISupports
{
/**
@ -190,8 +190,8 @@ interface nsIZipReader : nsISupports
* stored in the jar, verifyExternalFile (not yet implemented) must
* be called before getPrincipal.
*/
nsICertificatePrincipal getCertificatePrincipal(in AUTF8String aEntryName);
nsIX509Cert getSigningCert(in AUTF8String aEntryName);
readonly attribute uint32_t manifestEntriesCount;
};

View File

@ -6,7 +6,7 @@
#include "nsJARInputStream.h"
#include "nsJAR.h"
#include "nsIFile.h"
#include "nsICertificatePrincipal.h"
#include "nsIX509Cert.h"
#include "nsIConsoleService.h"
#include "nsICryptoHash.h"
#include "nsIDataSignatureVerifier.h"
@ -323,12 +323,13 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
}
NS_IMETHODIMP
nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsICertificatePrincipal** aPrincipal)
nsJAR::GetSigningCert(const nsACString& aFilename, nsIX509Cert** aSigningCert)
{
//-- Parameter check
if (!aPrincipal)
if (!aSigningCert) {
return NS_ERROR_NULL_POINTER;
*aPrincipal = nullptr;
}
*aSigningCert = nullptr;
// Don't check signatures in the omnijar - this is only
// interesting for extensions/XPIs.
@ -366,12 +367,11 @@ nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsICertificatePrinci
else // User wants identity of signer w/o verifying any entries
requestedStatus = mGlobalStatus;
if (requestedStatus != JAR_VALID_MANIFEST)
if (requestedStatus != JAR_VALID_MANIFEST) {
ReportError(aFilename, requestedStatus);
else // Valid signature
{
*aPrincipal = mPrincipal;
NS_IF_ADDREF(*aPrincipal);
} else { // Valid signature
*aSigningCert = mSigningCert;
NS_IF_ADDREF(*aSigningCert);
}
return NS_OK;
}
@ -589,14 +589,15 @@ nsJAR::ParseManifest()
//-- Verify that the signature file is a valid signature of the SF file
int32_t verifyError;
rv = verifier->VerifySignature(sigBuffer, sigLen, manifestBuffer, manifestLen,
&verifyError, getter_AddRefs(mPrincipal));
&verifyError, getter_AddRefs(mSigningCert));
if (NS_FAILED(rv)) return rv;
if (mPrincipal && verifyError == nsIDataSignatureVerifier::VERIFY_OK)
if (mSigningCert && verifyError == nsIDataSignatureVerifier::VERIFY_OK) {
mGlobalStatus = JAR_VALID_MANIFEST;
else if (verifyError == nsIDataSignatureVerifier::VERIFY_ERROR_UNKNOWN_ISSUER)
} else if (verifyError == nsIDataSignatureVerifier::VERIFY_ERROR_UNKNOWN_ISSUER) {
mGlobalStatus = JAR_INVALID_UNKNOWN_CA;
else
} else {
mGlobalStatus = JAR_INVALID_SIG;
}
//-- Parse the SF file. If the verification above failed, principal
// is null, and ParseOneFile will mark the relevant entries as invalid.

View File

@ -29,7 +29,7 @@
#include "nsIObserver.h"
#include "mozilla/Attributes.h"
class nsICertificatePrincipal;
class nsIX509Cert;
class nsIInputStream;
class nsJARManifestItem;
class nsZipReaderCache;
@ -106,7 +106,7 @@ class nsJAR MOZ_FINAL : public nsIZipReader
nsRefPtr<nsZipArchive> mZip; // The underlying zip archive
ManifestDataHashtable mManifestData; // Stores metadata for each entry
bool mParsedManifest; // True if manifest has been parsed
nsCOMPtr<nsICertificatePrincipal> mPrincipal; // The entity which signed this file
nsCOMPtr<nsIX509Cert> mSigningCert; // The entity which signed this file
int16_t mGlobalStatus; // Global signature verification status
PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries
nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in

View File

@ -45,14 +45,15 @@ function openZip(path) {
// Gets the pretty name from the signing cert or null if the zip is unsigned.
function getSigner(zip) {
var principal = zip.getCertificatePrincipal(null);
if (principal && principal.hasCertificate)
return principal.prettyName;
var signingCert = zip.getSigningCert(null);
if (signingCert) {
return signingCert.organization;
}
return null;
}
function verifySigning(zip) {
var principal = zip.getCertificatePrincipal(null);
var signingCert = zip.getSigningCert(null);
var count = 0;
var entries = zip.findEntries(null);
while (entries.hasMore()) {
@ -64,9 +65,10 @@ function verifySigning(zip) {
if (entry.substr(-1) == "/")
continue;
count++;
var entryPrincipal = zip.getCertificatePrincipal(entry);
if (!entryPrincipal || !principal.equals(entryPrincipal))
var entryCert = zip.getSigningCert(entry);
if (!entryCert || !signingCert.equals(entryCert)) {
return false;
}
}
return zip.manifestEntriesCount == count;
}

View File

@ -107,6 +107,9 @@ pref("offline-apps.quota.warn", 51200);
// cache compression turned off for now - see bug #715198
pref("browser.cache.compression_level", 0);
// Whether or not MozAbortablePromise is enabled.
pref("dom.abortablepromise.enabled", false);
// Whether or not testing features are enabled.
pref("dom.quotaManager.testing", false);

View File

@ -362,6 +362,25 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv * arg0, jclass ar
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers_t)(JNIEnv *, jclass, jstring, jstring);
static Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers_t f_Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers;
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers(JNIEnv * arg0, jclass arg1, jstring arg2, jstring arg3) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return ;
}
f_Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers(arg0, arg1, arg2, arg3);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers", &f_Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoObservers);
#endif
#ifdef JNI_STUBS
typedef jlong (*Java_org_mozilla_gecko_GeckoAppShell_runUiThreadCallback_t)(JNIEnv *, jclass);
static Java_org_mozilla_gecko_GeckoAppShell_runUiThreadCallback_t f_Java_org_mozilla_gecko_GeckoAppShell_runUiThreadCallback;
extern "C" NS_EXPORT jlong JNICALL

View File

@ -824,7 +824,7 @@ class DebugProgram(MachCommandBase):
@CommandArgument('+debugger', default=None, type=str,
help='Name of debugger to launch')
@CommandArgument('+debugparams', default=None, metavar='params', type=str,
help='Command-line arguments to pass to GDB or LLDB itself; split as the Bourne shell would.')
help='Command-line arguments to pass to the debugger itself; split as the Bourne shell would.')
# Bug 933807 introduced JS_DISABLE_SLOW_SCRIPT_SIGNALS to avoid clever
# segfaults induced by the slow-script-detecting logic for Ion/Odin JITted
# code. If we don't pass this, the user will need to periodically type
@ -833,26 +833,7 @@ class DebugProgram(MachCommandBase):
@CommandArgument('+slowscript', action='store_true',
help='Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; when not set, recoverable but misleading SIGSEGV instances may occur in Ion/Odin JIT code')
def debug(self, params, remote, background, debugger, debugparams, slowscript):
import which
if debugger:
try:
debugger = which.which(debugger)
except Exception as e:
print("You don't have %s in your PATH" % (debugger))
print(e)
return 1
else:
try:
debugger = which.which('gdb')
except Exception:
try:
debugger = which.which('lldb')
except Exception as e:
print("You don't have gdb or lldb in your PATH")
print(e)
return 1
args = [debugger]
extra_env = { 'MOZ_CRASHREPORTER_DISABLE' : '1' }
# Parameters come from the CLI. We need to convert them before their use.
if debugparams:
import pymake.process
argv, badchar = pymake.process.clinetoargv(debugparams, os.getcwd())
@ -860,7 +841,22 @@ class DebugProgram(MachCommandBase):
print("The +debugparams you passed require a real shell to parse them.")
print("(We can't handle the %r character.)" % (badchar,))
return 1
args.extend(argv)
debugparams = argv;
import mozdebug
if not debugger:
# No debugger name was provided. Look for the default ones on current OS.
debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)
# We could not find the information about the desired debugger.
if not self.debuggerInfo:
print("Could not find a suitable debugger in your PATH.")
return 1
extra_env = { 'MOZ_CRASHREPORTER_DISABLE' : '1' }
binpath = None
@ -872,17 +868,8 @@ class DebugProgram(MachCommandBase):
print(e)
return 1
# args added to separate the debugger and process arguments.
args_separator = {
'gdb': '--args',
'ddd': '--args',
'cgdb': '--args',
'lldb': '--'
}
debugger_name = os.path.basename(debugger)
if debugger_name in args_separator:
args.append(args_separator[debugger_name])
# Build the list of arguments to pass to run_process
args = [self.debuggerInfo.path] + self.debuggerInfo.args
args.append(binpath)
if not remote:

View File

@ -11,7 +11,6 @@ XPIDL_SOURCES += [
'nsIAssociatedContentSecurity.idl',
'nsIBadCertListener2.idl',
'nsICertificateDialogs.idl',
'nsICertificatePrincipal.idl',
'nsICertOverrideService.idl',
'nsICertPickDialogs.idl',
'nsIClientAuthDialogs.idl',

View File

@ -1,33 +0,0 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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"
/*
* Historically, principals, certificates, and signed JARs were all linked
* together in one big mess. When that mess was cleaned up, it turned out that
* the principals used to store certificate information didn't overlap at all
* with the principals used for security policy. So this interface was created
* so that real principals wouldn't have to carry around all that baggage.
*
* The name here is totally a misnomer. This isn't a principal at all, and would
* better be called nsICertificateHolder or something. But that would require
* renaming some APIs, so let's just let this be for now.
*/
[scriptable, uuid(7cd4af5a-64d3-44a8-9700-804a42a6109a)]
interface nsICertificatePrincipal : nsISupports
{
readonly attribute AUTF8String fingerprint;
readonly attribute AUTF8String prettyName;
readonly attribute AUTF8String subjectName;
readonly attribute nsISupports certificate;
readonly attribute boolean hasCertificate; // For compat; always true.
bool equals(in nsICertificatePrincipal aOther);
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -5,14 +5,13 @@
#include "nsISupports.idl"
// NB: This isn't actually a principal at all. The naming is just historical.
interface nsICertificatePrincipal;
interface nsIX509Cert;
/**
* An interface for verifying that a given string of data was signed by the
* private key matching the given public key.
*/
[scriptable, uuid(577f097f-15e4-4043-bc0e-6d2fadcacae2)]
[scriptable, uuid(94066a00-37c9-11e4-916c-0800200c9a66)]
interface nsIDataSignatureVerifier : nsISupports
{
/**
@ -32,10 +31,10 @@ interface nsIDataSignatureVerifier : nsISupports
const long VERIFY_ERROR_UNKNOWN_ISSUER = 1;
const long VERIFY_ERROR_OTHER = 2;
nsICertificatePrincipal verifySignature(in string aSignature,
in unsigned long aSignatureLen,
in string plaintext,
in unsigned long plaintextLen,
out long errorCode);
nsIX509Cert verifySignature(in string aSignature,
in unsigned long aSignatureLen,
in string plaintext,
in unsigned long plaintextLen,
out long errorCode);
};

View File

@ -19,7 +19,6 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'CryptoTask.cpp',
'nsCertificatePrincipal.cpp',
'nsCertOverrideService.cpp',
'nsCertPicker.cpp',
'nsCertVerificationThread.cpp',

View File

@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCertificatePrincipal.h"
NS_IMPL_ISUPPORTS(nsCertificatePrincipal, nsICertificatePrincipal)
NS_IMETHODIMP
nsCertificatePrincipal::GetFingerprint(nsACString& aFingerprint)
{
aFingerprint = mFingerprint;
return NS_OK;
}
NS_IMETHODIMP
nsCertificatePrincipal::GetSubjectName(nsACString& aSubjectName)
{
aSubjectName = mSubjectName;
return NS_OK;
}
NS_IMETHODIMP
nsCertificatePrincipal::GetPrettyName(nsACString& aPrettyName)
{
aPrettyName = mPrettyName;
return NS_OK;
}
NS_IMETHODIMP
nsCertificatePrincipal::GetCertificate(nsISupports** aCert)
{
nsCOMPtr<nsISupports> cert = mCert;
cert.forget(aCert);
return NS_OK;
}
NS_IMETHODIMP
nsCertificatePrincipal::GetHasCertificate(bool* rv)
{
*rv = true;
return NS_OK;
}
NS_IMETHODIMP
nsCertificatePrincipal::Equals(nsICertificatePrincipal* aOther, bool* rv)
{
nsAutoCString str;
aOther->GetFingerprint(str);
if (!str.Equals(mFingerprint)) {
*rv = false;
return NS_OK;
}
// If either subject name is empty, just let the result stand, but if they're
// both non-empty, only claim equality if they're equal.
if (!mSubjectName.IsEmpty()) {
// Check the other principal's subject name
aOther->GetSubjectName(str);
*rv = str.Equals(mSubjectName) || str.IsEmpty();
return NS_OK;
}
*rv = true;
return NS_OK;
}

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __NS_CERTIFICATEPRINCIPAL_H
#define __NS_CERTIFICATEPRINCIPAL_H
#include "nsICertificatePrincipal.h"
#include "nsString.h"
#include "nsCOMPtr.h"
class nsCertificatePrincipal : public nsICertificatePrincipal
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICERTIFICATEPRINCIPAL
nsCertificatePrincipal(const nsACString& aFingerprint,
const nsACString& aSubjectName,
const nsACString& aPrettyName,
nsISupports* aCert)
: mFingerprint(aFingerprint)
, mSubjectName(aSubjectName)
, mPrettyName(aPrettyName)
, mCert(aCert)
{}
protected:
virtual ~nsCertificatePrincipal() {}
private:
nsCString mFingerprint;
nsCString mSubjectName;
nsCString mPrettyName;
nsCOMPtr<nsISupports> mCert;
};
#endif /* __NS_CERTIFICATEPRINCIPAL_H */

View File

@ -7,7 +7,6 @@
#include "cms.h"
#include "cryptohi.h"
#include "keyhi.h"
#include "nsCertificatePrincipal.h"
#include "nsCOMPtr.h"
#include "nsNSSComponent.h"
#include "nssb64.h"
@ -222,7 +221,7 @@ namespace {
struct VerifyCertificateContext
{
nsCOMPtr<nsICertificatePrincipal> principal;
nsCOMPtr<nsIX509Cert> signingCert;
ScopedCERTCertList builtChain;
};
@ -242,27 +241,7 @@ VerifyCertificate(CERTCertificate* cert, void* voidContext, void* pinArg)
return NS_ERROR_OUT_OF_MEMORY;
}
nsAutoString fingerprint;
nsresult rv = xpcomCert->GetSha1Fingerprint(fingerprint);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoString orgName;
rv = xpcomCert->GetOrganization(orgName);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoString subjectName;
rv = xpcomCert->GetSubjectName(subjectName);
if (NS_FAILED(rv)) {
return rv;
}
context->principal =
new nsCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint),
NS_ConvertUTF16toUTF8(subjectName),
NS_ConvertUTF16toUTF8(orgName),
xpcomCert);
context->signingCert = xpcomCert;
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
@ -284,14 +263,14 @@ nsDataSignatureVerifier::VerifySignature(const char* aRSABuf,
const char* aPlaintext,
uint32_t aPlaintextLen,
int32_t* aErrorCode,
nsICertificatePrincipal** aPrincipal)
nsIX509Cert** aSigningCert)
{
if (!aPlaintext || !aPrincipal || !aErrorCode) {
if (!aPlaintext || !aSigningCert || !aErrorCode) {
return NS_ERROR_INVALID_ARG;
}
*aErrorCode = VERIFY_ERROR_OTHER;
*aPrincipal = nullptr;
*aSigningCert = nullptr;
nsNSSShutDownPreventionLock locker;
@ -325,7 +304,7 @@ nsDataSignatureVerifier::VerifySignature(const char* aRSABuf,
rv = NS_OK;
}
if (rv == NS_OK) {
context.principal.forget(aPrincipal);
context.signingCert.forget(aSigningCert);
}
return rv;

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