merge mozilla-inbound to mozilla-central

This commit is contained in:
Carsten "Tomcat" Book 2013-12-10 13:02:55 +01:00
commit de91ddd9df
140 changed files with 1405 additions and 1885 deletions

View File

@ -621,7 +621,7 @@ TextAttrsMgr::FontWeightTextAttr::
if (font->IsSyntheticBold())
return 700;
#ifdef MOZ_PANGO
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
// On Linux, font->GetStyle()->weight will give the absolute weight requested
// of the font face. The Linux code uses the gfxFontEntry constructor which
// doesn't initialize the weight field.

View File

@ -377,11 +377,7 @@ function getPotentialLeaks() {
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager);
let enm = mgr.enumerateReporters();
while (enm.hasMoreElements()) {
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
mr.collectReports(logReporter, null);
}
mgr.getReportsForThisProcess(logReporter, null);
return { compartments: compartments, windows: windows };
}

View File

@ -3983,7 +3983,6 @@ LIBJPEG_TURBO_ASFLAGS=
LIBJPEG_TURBO_X86_ASM=
LIBJPEG_TURBO_X64_ASM=
LIBJPEG_TURBO_ARM_ASM=
MOZ_PANGO=1
MOZ_PERMISSIONS=1
MOZ_PLACES=1
MOZ_SOCIAL=1
@ -4731,34 +4730,16 @@ AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
AC_SUBST(MOZ_DISTRIBUTION_ID)
dnl ========================================================
dnl complex text support off by default
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(pango,
[ --disable-pango Disable usage of Pango ],
MOZ_PANGO=,
MOZ_PANGO=1)
dnl ========================================================
dnl = Pango
dnl ========================================================
if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
then
AC_SUBST(MOZ_PANGO)
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
if test "$MOZ_PANGO"
then
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
AC_SUBST(MOZ_PANGO_CFLAGS)
AC_SUBST(MOZ_PANGO_LIBS)
AC_DEFINE(MOZ_PANGO)
else
PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0)
AC_SUBST(FT2_CFLAGS)
AC_SUBST(FT2_LIBS)
fi
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
AC_SUBST(MOZ_PANGO_CFLAGS)
AC_SUBST(MOZ_PANGO_LIBS)
fi
dnl ========================================================

View File

@ -642,13 +642,13 @@ nsDOMMemoryFile::DataOwner::sDataOwners;
/* static */ bool
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(DOMMemoryFileDataOwnerMallocSizeOf)
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
: public MemoryMultiReporter
: public nsIMemoryReporter
{
public:
nsDOMMemoryFileDataOwnerMemoryReporter() {}
NS_DECL_THREADSAFE_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
nsISupports *aClosure)
@ -723,6 +723,8 @@ public:
}
};
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter, nsIMemoryReporter)
/* static */ void
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
{

View File

@ -1130,13 +1130,11 @@ struct MessageManagerReferentCount
namespace mozilla {
namespace dom {
class MessageManagerReporter MOZ_FINAL : public MemoryMultiReporter
class MessageManagerReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
MessageManagerReporter() {}
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aData);
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
static const size_t kSuspectReferentCount = 300;
protected:
@ -1144,6 +1142,8 @@ protected:
MessageManagerReferentCount* aReferentCount);
};
NS_IMPL_ISUPPORTS1(MessageManagerReporter, nsIMemoryReporter)
static PLDHashOperator
CollectMessageListenerData(const nsAString& aKey,
nsAutoTObserverArray<nsMessageListenerInfo, 1>* aListeners,

View File

@ -85,7 +85,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
return NS_OK;
}
NS_IMPL_ISUPPORTS_INHERITED0(WebGLMemoryTracker, MemoryMultiReporter)
NS_IMPL_ISUPPORTS1(WebGLMemoryTracker, nsIMemoryReporter)
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
@ -113,7 +113,7 @@ WebGLMemoryTracker::~WebGLMemoryTracker()
UnregisterWeakMemoryReporter(this);
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
int64_t
WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
@ -131,7 +131,7 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
return result;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
int64_t
WebGLMemoryTracker::GetShaderSize() {

View File

@ -19,9 +19,10 @@
namespace mozilla {
class WebGLMemoryTracker : public MemoryMultiReporter
class WebGLMemoryTracker : public nsIMemoryReporter
{
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
WebGLMemoryTracker();
virtual ~WebGLMemoryTracker();
@ -55,9 +56,6 @@ class WebGLMemoryTracker : public MemoryMultiReporter
}
}
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData);
private:
static int64_t GetTextureMemoryUsed() {
const ContextsArrayType & contexts = Contexts();

View File

@ -54,9 +54,10 @@ PRLogModuleInfo* gMediaDecoderLog;
#define DECODER_LOG(type, msg)
#endif
class MediaMemoryTracker : public MemoryMultiReporter
class MediaMemoryTracker : public nsIMemoryReporter
{
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
MediaMemoryTracker();
virtual ~MediaMemoryTracker();
@ -93,14 +94,11 @@ public:
sUniqueInstance = nullptr;
}
}
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData);
};
StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
NS_IMPL_ISUPPORTS_INHERITED0(MediaMemoryTracker, MemoryMultiReporter)
NS_IMPL_ISUPPORTS1(MediaMemoryTracker, nsIMemoryReporter)
NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver)

View File

@ -45,6 +45,7 @@ support-files =
skip-if = true # disabled-for-intermittent-failures--bug-701060
[test_length.xhtml]
skip-if = true
[test_lengthParsing.html]
[test_nonAnimStrings.xhtml]
[test_non-scaling-stroke.html]
[test_pathAnimInterpolation.xhtml]

View File

@ -0,0 +1,77 @@
<!doctype html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=946529
-->
<head>
<meta charset="utf-8">
<title>Test transform parsing</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946529">Mozilla Bug 946529</a>
<p id="display"></p>
<div id="content" style="display: none">
<svg width="100%" height="1" id="svg">
<rect id="rect"/>
</svg>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
// Test cases
checkParseOk("", 0);
checkParseOk("-.1", -0.1);
checkParseOk("1e1", 10);
checkParseOk("1em", 1, "em");
checkParseOk("1ex", 1, "ex");
checkParseOk("1e1em", 10, "em");
checkParseOk("1E+2", 100);
checkParseOk(".1e-2", 0.001);
// Fail cases
checkParseFail("1e");
checkParseFail("1 e");
checkParseFail("1 em");
checkParseFail("1ee");
function checkParseOk(spec, valueInUnits, units) {
var rect = document.getElementById("rect");
// Clear previous value
rect.removeAttribute("x");
rect.setAttribute("x", spec);
// Check number part
const tolerance = 1 / 65535;
var actual = rect.x.baseVal.valueInSpecifiedUnits;
ok(Math.abs(actual - valueInUnits) < tolerance,
spec + ' (value) - got ' + actual + ', expected ' + valueInUnits);
// Check unit part
var unitMapping = {
"unknown": SVGLength.SVG_LENGTHTYPE_UNKNOWN,
"": SVGLength.SVG_LENGTHTYPE_NUMBER,
"%": SVGLength.SVG_LENGTHTYPE_PERCENTAGE,
"em": SVGLength.SVG_LENGTHTYPE_EMS,
"ex": SVGLength.SVG_LENGTHTYPE_EXS,
"px": SVGLength.SVG_LENGTHTYPE_PX,
"cm": SVGLength.SVG_LENGTHTYPE_CM,
"mm": SVGLength.SVG_LENGTHTYPE_MM,
"in": SVGLength.SVG_LENGTHTYPE_IN,
"pt": SVGLength.SVG_LENGTHTYPE_PT,
"pc": SVGLength.SVG_LENGTHTYPE_PC
};
if (typeof units == "undefined") {
units = "";
}
ise(rect.x.baseVal.unitType, unitMapping[units], spec + " (unit)");
}
function checkParseFail(spec) {
checkParseOk(spec, 0);
}
</script>
</pre>
</body>
</html>

View File

@ -21,7 +21,6 @@
#include "mozilla/dom/quota/QuotaObject.h"
#include "mozilla/dom/quota/UsageInfo.h"
#include "mozilla/unused.h"
#include "nsContentUtils.h"
#include "nsIAtom.h"
#include "nsIFile.h"
#include "nsIPrincipal.h"
@ -975,7 +974,7 @@ DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
namespace {
bool
OpenFile(JS::Handle<JSObject*> aGlobal,
OpenFile(nsIPrincipal* aPrincipal,
OpenMode aOpenMode,
size_t aSizeToWrite,
File::AutoClose* aFile)
@ -998,17 +997,14 @@ OpenFile(JS::Handle<JSObject*> aGlobal,
return false;
}
// This assumes a non-worker global.
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
// If we are in a child process, we need to synchronously call into the
// parent process to open the file and interact with the QuotaManager. The
// child can then map the file into its address space to perform I/O.
nsRefPtr<File> file;
if (IsMainProcess()) {
file = new SingleProcessRunnable(principal, aOpenMode, aSizeToWrite);
file = new SingleProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
} else {
file = new ChildProcessRunnable(principal, aOpenMode, aSizeToWrite);
file = new ChildProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
}
if (!file->BlockUntilOpen(aFile)) {
@ -1028,7 +1024,7 @@ static const uint32_t sAsmJSCookie = 0x600d600d;
static const size_t sMinCachedModuleLength = 10000;
bool
OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
@ -1040,7 +1036,7 @@ OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
}
File::AutoClose file;
if (!OpenFile(aGlobal, eOpenForRead, 0, &file)) {
if (!OpenFile(aPrincipal, eOpenForRead, 0, &file)) {
return false;
}
@ -1082,7 +1078,7 @@ CloseEntryForRead(JS::Handle<JSObject*> global,
}
bool
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
OpenEntryForWrite(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,
@ -1097,7 +1093,7 @@ OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
aSize += sizeof(AsmJSCookieType);
File::AutoClose file;
if (!OpenFile(aGlobal, eOpenForWrite, aSize, &file)) {
if (!OpenFile(aPrincipal, eOpenForWrite, aSize, &file)) {
return false;
}

View File

@ -32,10 +32,20 @@ enum OpenMode
NUM_OPEN_MODES
};
// Implementation of AsmJSCacheOps, installed by nsJSEnvironment:
// Implementation of AsmJSCacheOps, installed for the main JSRuntime by
// nsJSEnvironment.cpp and DOM Worker JSRuntimes in RuntimeService.cpp.
//
// The Open* functions cannot be called directly from AsmJSCacheOps: they take
// an nsIPrincipal as the first argument instead of a Handle<JSObject*>. The
// caller must map the object to an nsIPrincipal.
//
// These methods may be called off the main thread and guarantee not to
// access the given aPrincipal except on the main thread. In exchange, the
// caller must ensure the given principal is alive from when OpenEntryForX is
// called to when CloseEntryForX returns.
bool
OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
OpenEntryForRead(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
@ -47,7 +57,7 @@ CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
const uint8_t* aMemory,
intptr_t aHandle);
bool
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
OpenEntryForWrite(nsIPrincipal* aPrincipal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,

View File

@ -1687,7 +1687,7 @@ ReportAndDump(JSContext *cx, unsigned argc, JS::Value *vp)
dmd::ClearReports();
fprintf(stderr, "DMD: running reporters...\n");
dmd::RunReporters();
dmd::RunReportersForThisProcess();
dmd::Writer writer(FpWrite, fp);
dmd::Dump(writer);
@ -2831,6 +2831,32 @@ NS_DOMStructuredCloneError(JSContext* cx,
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
}
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
{
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
aHandle);
}
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)
{
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
aHandle);
}
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
void
@ -2879,9 +2905,9 @@ nsJSContext::EnsureStatics()
// Set up the asm.js cache callbacks
static JS::AsmJSCacheOps asmJSCacheOps = {
asmjscache::OpenEntryForRead,
AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead,
asmjscache::OpenEntryForWrite,
AsmJSCacheOpenEntryForWrite,
asmjscache::CloseEntryForWrite,
asmjscache::GetBuildId
};

View File

@ -166,7 +166,7 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
}
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WindowsMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf)
// The key is the window ID.
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;

View File

@ -7652,8 +7652,13 @@ class CGProxySpecialOperation(CGPerSignatureCall):
"""
Base class for classes for calling an indexed or named special operation
(don't use this directly, use the derived classes below).
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
"""
def __init__(self, descriptor, operation):
def __init__(self, descriptor, operation, checkFound=True):
self.checkFound = checkFound;
nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
operation = descriptor.operations[operation]
assert len(operation.signatures()) == 1
@ -7699,15 +7704,26 @@ class CGProxySpecialOperation(CGPerSignatureCall):
return ""
wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
wrap = CGIfWrapper(wrap, "found")
if self.checkFound:
wrap = CGIfWrapper(wrap, "found")
else:
wrap = CGList([CGGeneric("MOZ_ASSERT(found);"), wrap], "\n")
return "\n" + wrap.define()
class CGProxyIndexedOperation(CGProxySpecialOperation):
"""
Class to generate a call to an indexed operation.
If doUnwrap is False, the caller is responsible for making sure a variable
named 'self' holds the C++ object somewhere where the code we generate
will see it.
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
"""
def __init__(self, descriptor, name):
CGProxySpecialOperation.__init__(self, descriptor, name)
def __init__(self, descriptor, name, doUnwrap=True, checkFound=True):
self.doUnwrap = doUnwrap
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound)
def define(self):
# Our first argument is the id we're getting.
argName = self.arguments[0].identifier.name
@ -7716,18 +7732,30 @@ class CGProxyIndexedOperation(CGProxySpecialOperation):
setIndex = ""
else:
setIndex = "uint32_t %s = index;\n" % argName
return (setIndex +
"%s* self = UnwrapProxy(proxy);\n" +
if self.doUnwrap:
unwrap = "%s* self = UnwrapProxy(proxy);\n"
else:
unwrap = ""
return (setIndex + unwrap +
CGProxySpecialOperation.define(self))
class CGProxyIndexedGetter(CGProxyIndexedOperation):
"""
Class to generate a call to an indexed getter. If templateValues is not None
the returned value will be wrapped with wrapForType using templateValues.
If doUnwrap is False, the caller is responsible for making sure a variable
named 'self' holds the C++ object somewhere where the code we generate
will see it.
If checkFound is False, will just assert that the prop is found instead of
checking that it is before wrapping the value.
"""
def __init__(self, descriptor, templateValues=None):
def __init__(self, descriptor, templateValues=None, doUnwrap=True,
checkFound=True):
self.templateValues = templateValues
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter')
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter',
doUnwrap, checkFound)
class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
"""
@ -8364,65 +8392,55 @@ class CGDOMJSProxyHandler_finalize(ClassMethod):
return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
class CGDOMJSProxyHandler_slice(ClassMethod):
def __init__(self, descriptor):
assert descriptor.supportsIndexedProperties()
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<JSObject*>', 'receiver'),
Argument('uint32_t', 'index'),
Argument('JS::MutableHandle<JS::Value>', 'vp'),
Argument('bool*', 'present')]
ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
Argument('uint32_t', 'begin'),
Argument('uint32_t', 'end'),
Argument('JS::Handle<JSObject*>', 'array')]
ClassMethod.__init__(self, "slice", "bool", args)
self.descriptor = descriptor
def getBody(self):
successCode = ("*present = found;\n"
"return true;")
templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp',
# Just like getOwnPropertyNames we'll assume that we have no holes, so
# we have all properties from 0 to length. If that ever changes
# (unlikely), we'll need to do something a bit more clever with how we
# forward on to our ancestor.
header = CGGeneric(
'JS::Rooted<JS::Value> temp(cx);\n'
'MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),\n'
' "Should not have a XrayWrapper here");\n'
'\n'
'%s* self = UnwrapProxy(proxy);\n'
'uint32_t length = self->Length();\n'
"// Compute the end of the indices we'll get ourselves\n"
'uint32_t ourEnd = std::max(begin, std::min(end, length));' %
self.descriptor.nativeType)
successCode = ("js::UnsafeDefineElement(cx, array, index - begin, temp);\n"
"continue;")
templateValues = {'jsvalRef': 'temp', 'jsvalHandle': '&temp',
'obj': 'proxy', 'successCode': successCode}
if self.descriptor.supportsIndexedProperties():
get = (CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
"// We skip the expando object and any named getters if\n"
"// there is an indexed getter.\n" +
"\n") % (self.descriptor.nativeType)
else:
if self.descriptor.supportsNamedProperties():
get = CGProxyNamedGetter(self.descriptor, templateValues,
"UINT_TO_JSVAL(index)").define()
get += """
get = CGProxyIndexedGetter(self.descriptor, templateValues, False, False)
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
if (expando) {
bool isPresent;
if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) {
return false;
}
if (isPresent) {
*present = true;
return true;
}
}
"""
getOurElements = CGWrapper(
CGIndenter(get),
pre="for (uint32_t index = begin; index < ourEnd; ++index) {\n",
post="\n}")
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
getProtoElements = CGIfWrapper(
CGGeneric("JS::Rooted<JSObject*> proto(cx);\n"
"if (!js::GetObjectProto(cx, proxy, &proto)) {\n"
" return false;\n"
"}\n"
"return js::SliceSlowly(cx, proto, proxy, ourEnd, end, array);"),
"end > ourEnd")
""" + get + """
JS::Rooted<JSObject*> proto(cx);
if (!js::GetObjectProto(cx, proxy, &proto)) {
return false;
}
if (proto) {
bool isPresent;
if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
return false;
}
*present = isPresent;
return true;
}
*present = false;
// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
return true;"""
return CGList([header, getOurElements, getProtoElements,
CGGeneric("return true;")], "\n\n").define();
class CGDOMJSProxyHandler_getInstance(ClassMethod):
def __init__(self):
@ -8446,9 +8464,11 @@ class CGDOMJSProxyHandler(CGClass):
CGDOMJSProxyHandler_className(descriptor),
CGDOMJSProxyHandler_finalizeInBackground(descriptor),
CGDOMJSProxyHandler_finalize(descriptor),
CGDOMJSProxyHandler_getElementIfPresent(descriptor),
CGDOMJSProxyHandler_getInstance(),
CGDOMJSProxyHandler_delete(descriptor)]
if descriptor.supportsIndexedProperties():
methods.append(CGDOMJSProxyHandler_slice(descriptor))
CGClass.__init__(self, 'DOMProxyHandler',
bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
constructors=constructors,

View File

@ -497,19 +497,12 @@ ContentChild::RecvPMemoryReportRequestConstructor(
GetProcessName(process);
AppendProcessId(process);
// Run each reporter. The callback will turn each measurement into a
// Run the reporters. The callback will turn each measurement into a
// MemoryReport.
nsCOMPtr<nsISimpleEnumerator> e;
mgr->EnumerateReporters(getter_AddRefs(e));
nsRefPtr<MemoryReportsWrapper> wrappedReports =
new MemoryReportsWrapper(&reports);
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
bool more;
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
nsCOMPtr<nsIMemoryReporter> r;
e->GetNext(getter_AddRefs(r));
r->CollectReports(cb, wrappedReports);
}
mgr->GetReportsForThisProcess(cb, wrappedReports);
child->Send__delete__(child, generation, reports);
return true;

View File

@ -193,15 +193,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
}
// A memory reporter for ContentParent objects themselves.
class ContentParentsMemoryReporter MOZ_FINAL : public MemoryMultiReporter
class ContentParentsMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
ContentParentsMemoryReporter() {}
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure);
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
};
NS_IMPL_ISUPPORTS1(ContentParentsMemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP
ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
nsISupports* aClosure)

View File

@ -169,7 +169,11 @@ function expandPermissions(aPerms) {
aPerms.forEach(function(el) {
var access = permTable[el].access ? "readwrite" : null;
var expanded = SpecialPowers.unwrap(expand(el, access));
perms = perms.concat(expanded.slice(0));
// COW arrays don't behave array-like enough, to allow
// using expanded.slice(0) here.
for (let i = 0; i < expanded.length; i++) {
perms.push(expanded[i]);
}
});
return perms;

View File

@ -27,6 +27,7 @@
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/AtomList.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ErrorEventBinding.h"
@ -766,6 +767,53 @@ CTypesActivityCallback(JSContext* aCx,
}
}
static nsIPrincipal*
GetPrincipalForAsmJSCacheOp()
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
if (!workerPrivate) {
return nullptr;
}
// asmjscache::OpenEntryForX guarnatee to only access the given nsIPrincipal
// from the main thread.
return workerPrivate->GetPrincipalDontAssertMainThread();
}
static bool
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aLimit,
size_t* aSize,
const uint8_t** aMemory,
intptr_t *aHandle)
{
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
if (!principal) {
return false;
}
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
aHandle);
}
static bool
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
const jschar* aBegin,
const jschar* aEnd,
size_t aSize,
uint8_t** aMemory,
intptr_t* aHandle)
{
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
if (!principal) {
return false;
}
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
aHandle);
}
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
{
WorkerPrivate* mWorkerPrivate;
@ -808,6 +856,16 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
};
SetDOMCallbacks(aRuntime, &DOMCallbacks);
// Set up the asm.js cache callbacks
static JS::AsmJSCacheOps asmJSCacheOps = {
AsmJSCacheOpenEntryForRead,
asmjscache::CloseEntryForRead,
AsmJSCacheOpenEntryForWrite,
asmjscache::CloseEntryForWrite,
asmjscache::GetBuildId
};
JS::SetAsmJSCacheOps(aRuntime, &asmJSCacheOps);
JSContext* workerCx = JS_NewContext(aRuntime, 0);
if (!workerCx) {
NS_WARNING("Could not create new context!");

View File

@ -94,7 +94,7 @@ using mozilla::AutoSafeJSContext;
USING_WORKERS_NAMESPACE
using namespace mozilla::dom;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(JsWorkerMallocSizeOf)
namespace {
@ -2006,8 +2006,10 @@ struct WorkerPrivate::TimeoutInfo
bool mCanceled;
};
class WorkerPrivate::MemoryReporter MOZ_FINAL : public MemoryMultiReporter
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
NS_DECL_THREADSAFE_ISUPPORTS
friend class WorkerPrivate;
SharedMutex mMutex;
@ -2119,6 +2121,8 @@ private:
}
};
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
template <class Derived>
WorkerPrivateParent<Derived>::WorkerPrivateParent(
JSContext* aCx,

View File

@ -600,6 +600,15 @@ public:
return mLoadInfo.mPrincipal;
}
// This method allows the principal to be retrieved off the main thread.
// Principals are main-thread objects so the caller must ensure that all
// access occurs on the main thread.
nsIPrincipal*
GetPrincipalDontAssertMainThread() const
{
return mLoadInfo.mPrincipal;
}
void
SetPrincipal(nsIPrincipal* aPrincipal);

View File

@ -60,4 +60,6 @@ LOCAL_INCLUDES += [
'/xpcom/build',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'gklayout'

View File

@ -431,7 +431,6 @@ public:
// XXX I expect we will want to move mWidget into this class and implement
// these methods properly.
virtual nsIWidget* GetWidget() const { return nullptr; }
virtual const nsIntSize& GetWidgetSize() = 0;
// Call before and after any rendering not done by this compositor but which
// might affect the compositor's internal state or the state of any APIs it

View File

@ -133,15 +133,6 @@ LayerManager::CreateDrawTarget(const IntSize &aSize,
CreateOffscreenCanvasDrawTarget(aSize, aFormat);
}
TextureFactoryIdentifier
LayerManager::GetTextureFactoryIdentifier()
{
//TODO[nrc] make pure virtual when all layer managers use Compositor
NS_ERROR("Should have been overridden");
return TextureFactoryIdentifier();
}
#ifdef DEBUG
void
LayerManager::Mutated(Layer* aLayer)

View File

@ -437,12 +437,6 @@ public:
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; }
/**
* Returns a TextureFactoryIdentifier which describes properties of the backend
* used to decide what kind of texture and buffer clients to create
*/
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier();
/**
* returns the maximum texture size on this layer backend, or INT32_MAX
* if there is no maximum

View File

@ -220,7 +220,6 @@ CreateBasicDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
: mWidget(aWidget)
, mWidgetSize(-1, -1)
{
MOZ_COUNT_CTOR(BasicCompositor);
sBackend = LAYERS_BASIC;
@ -540,7 +539,6 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
nsIntRect intRect;
mWidget->GetClientBounds(intRect);
Rect rect = Rect(0, 0, intRect.width, intRect.height);
mWidgetSize = intRect.Size();
nsIntRect invalidRect = aInvalidRegion.GetBounds();
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);

View File

@ -119,10 +119,6 @@ public:
virtual const char* Name() const { return "Basic"; }
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
return mWidgetSize;
}
gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }

View File

@ -73,7 +73,7 @@ public:
virtual already_AddRefed<ColorLayer> CreateColorLayer();
virtual already_AddRefed<RefLayer> CreateRefLayer();
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
TextureFactoryIdentifier GetTextureFactoryIdentifier()
{
return mForwarder->GetTextureFactoryIdentifier();
}

View File

@ -203,6 +203,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
EndTransactionFlags aFlags)
{
NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?");
NS_ASSERTION(!aCallback && !aCallbackData, "Not expecting callbacks here");
mInTransaction = false;
if (!mIsCompositorReady) {
@ -240,13 +241,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
Render();
mThebesLayerCallback = nullptr;
mThebesLayerCallbackData = nullptr;
}
mCompositor->SetTargetContext(nullptr);
@ -307,7 +302,7 @@ LayerManagerComposite::RootLayer() const
return nullptr;
}
return static_cast<LayerComposite*>(mRoot->ImplData());
return ToLayerComposite(mRoot);
}
static uint16_t sFrameCount = 0;
@ -723,7 +718,7 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
return;
}
mCompositable = static_cast<LayerComposite*>(aMaskLayer->ImplData())->GetCompositableHost();
mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
if (!mCompositable) {
NS_WARNING("Mask layer with no compositable host");
return;
@ -786,25 +781,6 @@ LayerComposite::Destroy()
}
}
const nsIntSize&
LayerManagerComposite::GetWidgetSize()
{
return mCompositor->GetWidgetSize();
}
void
LayerManagerComposite::SetCompositorID(uint32_t aID)
{
NS_ASSERTION(mCompositor, "No compositor");
mCompositor->SetCompositorID(aID);
}
void
LayerManagerComposite::NotifyShadowTreeTransaction()
{
mCompositor->NotifyLayersTransaction();
}
bool
LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
{
@ -812,18 +788,6 @@ LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
aSize.height));
}
TextureFactoryIdentifier
LayerManagerComposite::GetTextureFactoryIdentifier()
{
return mCompositor->GetTextureFactoryIdentifier();
}
int32_t
LayerManagerComposite::GetMaxTextureSize() const
{
return mCompositor->GetMaxTextureSize();
}
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
/*static*/ bool

View File

@ -110,8 +110,6 @@ public:
}
void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget);
void NotifyShadowTreeTransaction();
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData,
@ -119,11 +117,14 @@ public:
virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; }
// XXX[nrc]: never called, we should move this logic to ClientLayerManager
// (bug 946926).
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE;
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE;
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE
{
MOZ_CRASH("Call on compositor, not LayerManagerComposite");
}
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
@ -141,24 +142,16 @@ public:
virtual LayersBackend GetBackendType() MOZ_OVERRIDE
{
return LAYERS_NONE;
MOZ_CRASH("Shouldn't be called for composited layer manager");
}
virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE
{
MOZ_ASSERT(false, "Shouldn't be called for composited layer manager");
name.AssignLiteral("Composite");
MOZ_CRASH("Shouldn't be called for composited layer manager");
}
virtual already_AddRefed<gfxASurface>
CreateOptimalMaskSurface(const gfxIntSize &aSize) MOZ_OVERRIDE;
DrawThebesLayerCallback GetThebesLayerCallback() const
{ return mThebesLayerCallback; }
void* GetThebesLayerCallbackData() const
{ return mThebesLayerCallbackData; }
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
enum WorldTransforPolicy {
@ -195,11 +188,9 @@ public:
* layermanager.
*/
virtual TemporaryRef<mozilla::gfx::DrawTarget>
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
CreateDrawTarget(const mozilla::gfx::IntSize& aSize,
mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
const nsIntSize& GetWidgetSize();
/**
* Calculates the 'completeness' of the rendering that intersected with the
* screen on the last render. This is only useful when progressive tile
@ -217,8 +208,6 @@ public:
static void PlatformSyncBeforeReplyUpdate();
void SetCompositorID(uint32_t aID);
void AddInvalidRegion(const nsIntRegion& aRegion)
{
mInvalidRegion.Or(mInvalidRegion, aRegion);
@ -245,7 +234,7 @@ private:
nsIntRect mRenderBounds;
/** Current root layer. */
LayerComposite *RootLayer() const;
LayerComposite* RootLayer() const;
/**
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
@ -275,10 +264,6 @@ private:
/** Our more efficient but less powerful alter ego, if one is available. */
nsRefPtr<Composer2D> mComposer2D;
/* Thebes layer callbacks; valid at the end of a transaciton,
* while rendering */
DrawThebesLayerCallback mThebesLayerCallback;
void *mThebesLayerCallbackData;
gfxMatrix mWorldMatrix;
bool mInTransaction;

View File

@ -549,6 +549,8 @@ MemoryTextureHost::MemoryTextureHost(uint64_t aID,
MemoryTextureHost::~MemoryTextureHost()
{
DeallocateDeviceData();
NS_ASSERTION(!mBuffer || (mFlags & TEXTURE_DEALLOCATE_CLIENT),
"Leaking our buffer");
MOZ_COUNT_DTOR(MemoryTextureHost);
}

View File

@ -139,14 +139,6 @@ public:
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
"You should not do that outside of BeginFrame, so the best we can do is return "
"the last size we got, that might not be up to date. So you probably shouldn't "
"use this method.");
return mSize;
}
ID3D11Device* GetDevice() { return mDevice; }

View File

@ -86,14 +86,6 @@ public:
virtual void NotifyLayersTransaction() MOZ_OVERRIDE {}
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
{
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
"You should not do that outside of BeginFrame, so the best we can do is return "
"the last size we got, that might not be up to date. So you probably shouldn't "
"use this method.");
return mSize;
}
IDirect3DDevice9* device() const
{

View File

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et 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 "CompositorParent.h"
#include "CompositorCocoaWidgetHelper.h"
#include "nsDebug.h"
namespace mozilla {
namespace layers {
namespace compositor {
LayerManagerComposite*
GetLayerManager(CompositorParent* aParent)
{
return aParent->GetLayerManager();
}
}
}
}

View File

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 ts=8 et 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_layers_CompositorCocoaWidgetHelper_h
#define mozilla_layers_CompositorCocoaWidgetHelper_h
// Note we can't include IPDL-generated headers here, since this file is being
// used as a workaround for Bug 719036.
namespace mozilla {
namespace layers {
class CompositorParent;
class LayerManagerComposite;
namespace compositor {
// Needed when we cannot directly include CompositorParent.h since it includes
// an IPDL-generated header (e.g. in widget/cocoa/nsChildView.mm; see Bug 719036).
LayerManagerComposite* GetLayerManager(CompositorParent* aParent);
}
}
}
#endif // mozilla_layers_CompositorCocoaWidgetHelper_h

View File

@ -62,6 +62,7 @@ namespace layers {
CompositorParent::LayerTreeState::LayerTreeState()
: mParent(nullptr)
, mLayerManager(nullptr)
{
}
@ -237,6 +238,7 @@ CompositorParent::Destroy()
// Ensure that the layer manager is destructed on the compositor thread.
mLayerManager = nullptr;
mCompositor = nullptr;
mCompositionManager = nullptr;
mApzcTreeManager->ClearTree();
mApzcTreeManager = nullptr;
@ -263,10 +265,12 @@ CompositorParent::RecvWillStop()
LayerTreeState* lts = &it->second;
if (lts->mParent == this) {
mLayerManager->ClearCachedResources(lts->mRoot);
lts->mLayerManager = nullptr;
}
}
mLayerManager->Destroy();
mLayerManager = nullptr;
mCompositor = nullptr;
mCompositionManager = nullptr;
}
@ -371,7 +375,9 @@ CompositorParent::ActorDestroy(ActorDestroyReason why)
if (mLayerManager) {
mLayerManager->Destroy();
mLayerManager = nullptr;
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = nullptr;
mCompositionManager = nullptr;
mCompositor = nullptr;
}
}
@ -394,7 +400,7 @@ CompositorParent::PauseComposition()
if (!mPaused) {
mPaused = true;
mLayerManager->GetCompositor()->Pause();
mCompositor->Pause();
}
// if anyone's waiting to make sure that composition really got paused, tell them
@ -409,7 +415,7 @@ CompositorParent::ResumeComposition()
MonitorAutoLock lock(mResumeCompositionMonitor);
if (!mLayerManager->GetCompositor()->Resume()) {
if (!mCompositor->Resume()) {
#ifdef MOZ_WIDGET_ANDROID
// We can't get a surface. This could be because the activity changed between
// the time resume was scheduled and now.
@ -440,8 +446,8 @@ CompositorParent::SetEGLSurfaceSize(int width, int height)
{
NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
mEGLSurfaceSize.SizeTo(width, height);
if (mLayerManager) {
mLayerManager->GetCompositor()->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
if (mCompositor) {
mCompositor->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
}
}
@ -503,7 +509,7 @@ CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint)
AutoResolveRefLayers resolve(mCompositionManager);
mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId);
mLayerManager->AsLayerManagerComposite()->NotifyShadowTreeTransaction();
mCompositor->NotifyLayersTransaction();
}
ScheduleComposition();
}
@ -697,7 +703,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
}
}
ScheduleComposition();
mLayerManager->NotifyShadowTreeTransaction();
mCompositor->NotifyLayersTransaction();
}
void
@ -706,34 +712,32 @@ CompositorParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackend
NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
for (size_t i = 0; i < aBackendHints.Length(); ++i) {
RefPtr<LayerManagerComposite> layerManager;
RefPtr<Compositor> compositor;
if (aBackendHints[i] == LAYERS_OPENGL) {
layerManager =
new LayerManagerComposite(new CompositorOGL(mWidget,
mEGLSurfaceSize.width,
mEGLSurfaceSize.height,
mUseExternalSurfaceSize));
compositor = new CompositorOGL(mWidget,
mEGLSurfaceSize.width,
mEGLSurfaceSize.height,
mUseExternalSurfaceSize);
} else if (aBackendHints[i] == LAYERS_BASIC) {
layerManager =
new LayerManagerComposite(new BasicCompositor(mWidget));
compositor = new BasicCompositor(mWidget);
#ifdef XP_WIN
} else if (aBackendHints[i] == LAYERS_D3D11) {
layerManager =
new LayerManagerComposite(new CompositorD3D11(mWidget));
compositor = new CompositorD3D11(mWidget);
} else if (aBackendHints[i] == LAYERS_D3D9) {
layerManager =
new LayerManagerComposite(new CompositorD3D9(this, mWidget));
compositor = new CompositorD3D9(this, mWidget);
#endif
}
if (!layerManager) {
continue;
}
MOZ_ASSERT(compositor, "Passed invalid backend hint");
layerManager->SetCompositorID(mCompositorID);
compositor->SetCompositorID(mCompositorID);
RefPtr<LayerManagerComposite> layerManager = new LayerManagerComposite(compositor);
if (layerManager->Initialize()) {
mLayerManager = layerManager;
MOZ_ASSERT(compositor);
mCompositor = compositor;
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = layerManager;
return;
}
}
@ -765,7 +769,7 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aB
mCompositionManager = new AsyncCompositionManager(mLayerManager);
*aSuccess = true;
*aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier();
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
p->AddIPDLReference();
return p;
@ -851,6 +855,7 @@ void
CompositorParent::NotifyChildCreated(uint64_t aChild)
{
sIndirectLayerTrees[aChild].mParent = this;
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
}
/*static*/ uint64_t
@ -921,6 +926,17 @@ CompositorParent::GetAPZCTreeManager(uint64_t aLayersId)
return nullptr;
}
float
CompositorParent::ComputeRenderIntegrity()
{
if (mLayerManager) {
return mLayerManager->ComputeRenderIntegrity();
}
return 1.0f;
}
/**
* This class handles layer updates pushed directly from child
* processes to the compositor thread. It's associated with a
@ -1071,9 +1087,9 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
{
MOZ_ASSERT(aId != 0);
if (sIndirectLayerTrees[aId].mParent) {
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mParent->GetLayerManager();
*aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
if (sIndirectLayerTrees[aId].mLayerManager) {
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mLayerManager;
*aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
*aSuccess = true;
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
p->AddIPDLReference();

View File

@ -47,6 +47,7 @@ namespace layers {
class APZCTreeManager;
class AsyncCompositionManager;
class Compositor;
class LayerManagerComposite;
class LayerTransactionParent;
@ -107,8 +108,6 @@ public:
void ForceIsFirstPaint();
void Destroy();
LayerManagerComposite* GetLayerManager() { return mLayerManager; }
void NotifyChildCreated(uint64_t aChild);
void AsyncRender();
@ -203,6 +202,7 @@ public:
nsRefPtr<Layer> mRoot;
nsRefPtr<GeckoContentController> mController;
CompositorParent* mParent;
LayerManagerComposite* mLayerManager;
TargetConfig mTargetConfig;
};
@ -213,6 +213,8 @@ public:
*/
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
float ComputeRenderIntegrity();
/**
* Tell all CompositorParents to update their last refresh to aTime and sample
* animations at this time stamp. If aIsTesting is true, the
@ -295,6 +297,7 @@ private:
bool CanComposite();
nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor;
RefPtr<AsyncCompositionManager> mCompositionManager;
nsIWidget* mWidget;
CancelableTask *mCurrentCompositeTask;

View File

@ -128,7 +128,6 @@ EXPORTS.mozilla.layers += [
'ipc/CompositableForwarder.h',
'ipc/CompositableTransactionParent.h',
'ipc/CompositorChild.h',
'ipc/CompositorCocoaWidgetHelper.h',
'ipc/CompositorParent.h',
'ipc/GeckoContentController.h',
'ipc/GestureEventListener.h',
@ -240,7 +239,6 @@ UNIFIED_SOURCES += [
'ipc/Axis.cpp',
'ipc/CompositableTransactionParent.cpp',
'ipc/CompositorChild.cpp',
'ipc/CompositorCocoaWidgetHelper.cpp',
'ipc/CompositorParent.cpp',
'ipc/GestureEventListener.cpp',
'ipc/ImageBridgeChild.cpp',

View File

@ -158,9 +158,6 @@ public:
virtual bool Resume() MOZ_OVERRIDE;
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE {
return mWidgetSize;
}
GLContext* gl() const { return mGLContext; }
ShaderProgramType GetFBOLayerProgramType() const {

View File

@ -6,7 +6,6 @@
#include "GLManager.h"
#include "CompositorOGL.h" // for CompositorOGL
#include "GLContext.h" // for GLContext
#include "Layers.h" // for LayerManager
#include "mozilla/Assertions.h" // for MOZ_CRASH
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr
@ -15,7 +14,6 @@
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
using namespace mozilla::gl;
@ -49,21 +47,14 @@ private:
};
/* static */ GLManager*
GLManager::CreateGLManager(LayerManager* aManager)
GLManager::CreateGLManager(LayerManagerComposite* aManager)
{
if (!aManager) {
return nullptr;
if (aManager &&
Compositor::GetBackend() == LAYERS_OPENGL) {
return new GLManagerCompositor(static_cast<CompositorOGL*>(
aManager->GetCompositor()));
}
if (aManager->GetBackendType() == LAYERS_NONE) {
if (Compositor::GetBackend() == LAYERS_OPENGL) {
return new GLManagerCompositor(static_cast<CompositorOGL*>(
static_cast<LayerManagerComposite*>(aManager)->GetCompositor()));
} else {
return nullptr;
}
}
MOZ_CRASH("Cannot create GLManager for non-GL layer manager");
return nullptr;
}
}

View File

@ -16,7 +16,7 @@ class GLContext;
namespace layers {
class LayerManager;
class LayerManagerComposite;
/**
* Minimal interface to allow widgets to draw using OpenGL. Abstracts
@ -26,7 +26,7 @@ class LayerManager;
class GLManager
{
public:
static GLManager* CreateGLManager(LayerManager* aManager);
static GLManager* CreateGLManager(LayerManagerComposite* aManager);
virtual ~GLManager() {}

View File

@ -256,8 +256,17 @@ private:
nsRegion& Copy (const nsRect& aRect)
{
pixman_box32_t box = RectToBox(aRect);
pixman_region32_reset(&mImpl, &box);
// pixman needs to distinguish between an empty region and a region
// with one rect so that it can return a different number of rectangles.
// Empty rect: data = empty_box
// 1 rect: data = NULL
// >1 rect: data = rects
if (aRect.IsEmpty()) {
pixman_region32_clear(&mImpl);
} else {
pixman_box32_t box = RectToBox(aRect);
pixman_region32_reset(&mImpl, &box);
}
return *this;
}

View File

@ -631,10 +631,10 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 };
class SurfaceMemoryReporter MOZ_FINAL : public MemoryMultiReporter
class SurfaceMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
SurfaceMemoryReporter() { }
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure)
@ -651,8 +651,7 @@ public:
}
nsresult rv = aCb->Callback(EmptyCString(), nsCString(path),
nsIMemoryReporter::KIND_OTHER,
nsIMemoryReporter::UNITS_BYTES,
KIND_OTHER, UNITS_BYTES,
gSurfaceMemoryUsed[i],
nsCString(desc), aClosure);
NS_ENSURE_SUCCESS(rv, rv);
@ -663,6 +662,8 @@ public:
}
};
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
void
gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
int32_t aBytes)

View File

@ -1360,7 +1360,9 @@ gfxFontFamily::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
* shaped-word caches to free up memory.
*/
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(FontCacheMallocSizeOf)
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP
gfxFontCache::MemoryReporter::CollectReports

View File

@ -951,13 +951,11 @@ public:
FontCacheSizes* aSizes) const;
protected:
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
MemoryReporter() {}
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure);
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
};
// Observer for notifications that the font cache cares about

View File

@ -71,10 +71,9 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
return NS_OK;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(FontListMallocSizeOf)
gfxPlatformFontList::MemoryReporter::MemoryReporter()
{}
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
NS_IMETHODIMP
gfxPlatformFontList::MemoryReporter::CollectReports
@ -91,23 +90,20 @@ gfxPlatformFontList::MemoryReporter::CollectReports
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-list"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mFontListSize,
KIND_HEAP, UNITS_BYTES, sizes.mFontListSize,
NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."),
aClosure);
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mCharMapsSize,
KIND_HEAP, UNITS_BYTES, sizes.mCharMapsSize,
NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."),
aClosure);
if (sizes.mFontTableCacheSize) {
aCb->Callback(EmptyCString(),
NS_LITERAL_CSTRING("explicit/gfx/font-tables"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
sizes.mFontTableCacheSize,
KIND_HEAP, UNITS_BYTES, sizes.mFontTableCacheSize,
NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."),
aClosure);
}

View File

@ -178,12 +178,11 @@ public:
void RemoveCmap(const gfxCharacterMap *aCharMap);
protected:
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
MemoryReporter();
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
nsISupports *aClosure);
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
};
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);

View File

@ -3,10 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef MOZ_PANGO
#define PANGO_ENABLE_BACKEND
#define PANGO_ENABLE_ENGINE
#endif
#include "gfxPlatformGtk.h"
#include "prenv.h"
@ -14,16 +12,10 @@
#include "nsUnicharUtils.h"
#include "nsUnicodeProperties.h"
#include "gfxFontconfigUtils.h"
#ifdef MOZ_PANGO
#include "gfxPangoFonts.h"
#include "gfxContext.h"
#include "gfxUserFontSet.h"
#include "gfxFT2FontBase.h"
#else
#include <ft2build.h>
#include FT_FREETYPE_H
#include "gfxFT2Fonts.h"
#endif
#include "mozilla/gfx/2D.h"
@ -56,16 +48,6 @@ using namespace mozilla::unicode;
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
#ifndef MOZ_PANGO
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > PrefFontTable;
static FontTable *gPlatformFonts = nullptr;
static FontTable *gPlatformFontAliases = nullptr;
static PrefFontTable *gPrefFonts = nullptr;
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
static FT_Library gPlatformFTLibrary = nullptr;
#endif
static cairo_user_data_key_t cairo_gdk_drawable_key;
#ifdef MOZ_X11
@ -80,17 +62,6 @@ gfxPlatformGtk::gfxPlatformGtk()
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
#endif
#ifndef MOZ_PANGO
FT_Init_FreeType(&gPlatformFTLibrary);
gPlatformFonts = new FontTable();
gPlatformFonts->Init(100);
gPlatformFontAliases = new FontTable();
gPlatformFontAliases->Init(100);
gPrefFonts = new PrefFontTable();
gPrefFonts->Init(100);
gCodepointsWithNoFonts = new gfxSparseBitSet();
UpdateFontList();
#endif
uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
uint32_t contentMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
InitBackendPrefs(canvasMask, BACKEND_CAIRO,
@ -102,28 +73,7 @@ gfxPlatformGtk::~gfxPlatformGtk()
gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nullptr;
#ifdef MOZ_PANGO
gfxPangoFontGroup::Shutdown();
#else
delete gPlatformFonts;
gPlatformFonts = nullptr;
delete gPlatformFontAliases;
gPlatformFontAliases = nullptr;
delete gPrefFonts;
gPrefFonts = nullptr;
delete gCodepointsWithNoFonts;
gCodepointsWithNoFonts = nullptr;
#ifdef NS_FREE_PERMANENT_DATA
// do cairo cleanup *before* closing down the FTLibrary,
// otherwise we'll crash when the gfxPlatform destructor
// calls it (bug 605009)
cairo_debug_reset_static_data();
FT_Done_FreeType(gPlatformFTLibrary);
gPlatformFTLibrary = nullptr;
#endif
#endif
#if 0
// It would be nice to do this (although it might need to be after
@ -187,8 +137,6 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
return newSurface.forget();
}
#ifdef MOZ_PANGO
nsresult
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
@ -270,188 +218,6 @@ gfxPlatformGtk::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
return true;
}
#else
nsresult
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts)
{
return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
aListOfFonts);
}
nsresult
gfxPlatformGtk::UpdateFontList()
{
FcPattern *pat = nullptr;
FcObjectSet *os = nullptr;
FcFontSet *fs = nullptr;
int32_t result = -1;
pat = FcPatternCreate();
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
fs = FcFontList(nullptr, pat, os);
for (int i = 0; i < fs->nfont; i++) {
char *str;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
//printf("Family: %s\n", str);
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
nsAutoString key(name);
ToLowerCase(key);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(key, &ff)) {
ff = new FontFamily(name);
gPlatformFonts->Put(key, ff);
}
FontEntry *fe = new FontEntry(ff->Name());
ff->AddFontEntry(fe);
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
fe->mFilename = nsDependentCString(str);
//printf(" - file: %s\n", str);
}
int x;
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
//printf(" - index: %d\n", x);
fe->mFTFontIndex = x;
} else {
fe->mFTFontIndex = 0;
}
fe->mWeight = gfxFontconfigUtils::GetThebesWeight(fs->fonts[i]);
//printf(" - weight: %d\n", fe->mWeight);
fe->mItalic = false;
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
switch (x) {
case FC_SLANT_ITALIC:
case FC_SLANT_OBLIQUE:
fe->mItalic = true;
}
//printf(" - slant: %d\n", x);
}
//if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
//printf(" - width: %d\n", x);
// XXX deal with font-stretch stuff later
}
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
return sFontconfigUtils->UpdateFontList();
}
nsresult
gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure,
bool& aAborted)
{
nsAutoString name(aFontName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (gPlatformFonts->Get(name, &ff) ||
gPlatformFontAliases->Get(name, &ff)) {
aAborted = !(*aCallback)(ff->Name(), aClosure);
return NS_OK;
}
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
FcPattern *npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
{
npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcPatternDel(npat, FC_LANG);
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
FcDefaultSubstitute(npat);
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
nfs = FcFontList(nullptr, npat, nos);
FcResult fresult;
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
if (match)
FcFontSetAdd(nfs, match);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
}
DONE:
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
return NS_OK;
}
nsresult
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
{
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
}
gfxFontGroup *
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle,
gfxUserFontSet *aUserFontSet)
{
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
}
#endif
static int32_t sDPI = 0;
int32_t
@ -637,90 +403,6 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile()
}
#ifndef MOZ_PANGO
FT_Library
gfxPlatformGtk::GetFTLibrary()
{
return gPlatformFTLibrary;
}
FontFamily *
gfxPlatformGtk::FindFontFamily(const nsAString& aName)
{
nsAutoString name(aName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(name, &ff)) {
return nullptr;
}
return ff.get();
}
FontEntry *
gfxPlatformGtk::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
{
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
if (!ff)
return nullptr;
return ff->FindFontEntry(aFontStyle);
}
static PLDHashOperator
FindFontForCharProc(nsStringHashKey::KeyType aKey,
nsRefPtr<FontFamily>& aFontFamily,
void* aUserArg)
{
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
aFontFamily->FindFontForChar(data);
return PL_DHASH_NEXT;
}
already_AddRefed<gfxFont>
gfxPlatformGtk::FindFontForChar(uint32_t aCh, gfxFont *aFont)
{
if (!gPlatformFonts || !gCodepointsWithNoFonts)
return nullptr;
// is codepoint with no matching font? return null immediately
if (gCodepointsWithNoFonts->test(aCh)) {
return nullptr;
}
GlobalFontMatch data(aCh, GetScriptCode(aCh),
(aFont ? aFont->GetStyle() : nullptr));
// find fonts that support the character
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
if (data.mBestMatch) {
nsRefPtr<gfxFT2Font> font =
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
aFont->GetStyle());
gfxFont* ret = font.forget().get();
return already_AddRefed<gfxFont>(ret);
}
// no match? add to set of non-matching codepoints
gCodepointsWithNoFonts->set(aCh);
return nullptr;
}
bool
gfxPlatformGtk::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList)
{
return gPrefFonts->Get(aKey, aFontEntryList);
}
void
gfxPlatformGtk::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList)
{
gPrefFonts->Put(aKey, aFontEntryList);
}
#endif
#if (MOZ_WIDGET_GTK == 2)
void
gfxPlatformGtk::SetGdkDrawable(cairo_surface_t *target,

View File

@ -17,11 +17,6 @@ extern "C" {
#endif
class gfxFontconfigUtils;
#ifndef MOZ_PANGO
class FontFamily;
class FontEntry;
typedef struct FT_LibraryRec_ *FT_Library;
#endif
class gfxPlatformGtk : public gfxPlatform {
public:
@ -54,7 +49,6 @@ public:
const gfxFontStyle *aStyle,
gfxUserFontSet *aUserFontSet);
#ifdef MOZ_PANGO
/**
* Look up a local platform font using the full font face name (needed to
* support @font-face src local() )
@ -76,19 +70,6 @@ public:
*/
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
uint32_t aFormatFlags);
#endif
#ifndef MOZ_PANGO
FontFamily *FindFontFamily(const nsAString& aName);
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
#endif
#ifndef MOZ_PANGO
FT_Library GetFTLibrary();
#endif
#if (MOZ_WIDGET_GTK == 2)
static void SetGdkDrawable(cairo_surface_t *target,

View File

@ -27,13 +27,9 @@
#include "gfxQPainterSurface.h"
#include "nsUnicodeProperties.h"
#ifdef MOZ_PANGO
#include "gfxPangoFonts.h"
#include "gfxContext.h"
#include "gfxUserFontSet.h"
#else
#include "gfxFT2Fonts.h"
#endif
#include "nsUnicharUtils.h"
@ -47,11 +43,6 @@
#include "qcms.h"
#ifndef MOZ_PANGO
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
#include "mozilla/Preferences.h"
using namespace mozilla;
@ -75,16 +66,6 @@ static void do_qt_pixmap_unref (void *data)
static gfxImageFormat sOffscreenFormat = gfxImageFormatRGB24;
#ifndef MOZ_PANGO
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<FontEntry> > > PrefFontTable;
static FontTable *gPlatformFonts = nullptr;
static FontTable *gPlatformFontAliases = nullptr;
static PrefFontTable *gPrefFonts = nullptr;
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
static FT_Library gPlatformFTLibrary = nullptr;
#endif
gfxQtPlatform::gfxQtPlatform()
{
mPrefFonts.Init(50);
@ -92,20 +73,7 @@ gfxQtPlatform::gfxQtPlatform()
if (!sFontconfigUtils)
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
#ifdef MOZ_PANGO
g_type_init();
#else
FT_Init_FreeType(&gPlatformFTLibrary);
gPlatformFonts = new FontTable();
gPlatformFonts->Init(100);
gPlatformFontAliases = new FontTable();
gPlatformFontAliases->Init(100);
gPrefFonts = new PrefFontTable();
gPrefFonts->Init(100);
gCodepointsWithNoFonts = new gfxSparseBitSet();
UpdateFontList();
#endif
nsresult rv;
// 0 - default gfxQPainterSurface
@ -148,23 +116,7 @@ gfxQtPlatform::~gfxQtPlatform()
gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nullptr;
#ifdef MOZ_PANGO
gfxPangoFontGroup::Shutdown();
#else
delete gPlatformFonts;
gPlatformFonts = nullptr;
delete gPlatformFontAliases;
gPlatformFontAliases = nullptr;
delete gPrefFonts;
gPrefFonts = nullptr;
delete gCodepointsWithNoFonts;
gCodepointsWithNoFonts = nullptr;
cairo_debug_reset_static_data();
FT_Done_FreeType(gPlatformFTLibrary);
gPlatformFTLibrary = nullptr;
#endif
#if 0
// It would be nice to do this (although it might need to be after
@ -259,103 +211,6 @@ gfxQtPlatform::GetFontList(nsIAtom *aLangGroup,
nsresult
gfxQtPlatform::UpdateFontList()
{
#ifndef MOZ_PANGO
FcPattern *pat = nullptr;
FcObjectSet *os = nullptr;
FcFontSet *fs = nullptr;
pat = FcPatternCreate();
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
fs = FcFontList(nullptr, pat, os);
for (int i = 0; i < fs->nfont; i++) {
char *str;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
nsAutoString key(name);
ToLowerCase(key);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(key, &ff)) {
ff = new FontFamily(name);
gPlatformFonts->Put(key, ff);
}
FontEntry *fe = new FontEntry(ff->Name());
ff->AddFontEntry(fe);
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
fe->mFilename = nsDependentCString(str);
}
int x;
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
fe->mFTFontIndex = x;
} else {
fe->mFTFontIndex = 0;
}
if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) {
switch(x) {
case 0:
fe->mWeight = 100;
break;
case 40:
fe->mWeight = 200;
break;
case 50:
fe->mWeight = 300;
break;
case 75:
case 80:
fe->mWeight = 400;
break;
case 100:
fe->mWeight = 500;
break;
case 180:
fe->mWeight = 600;
break;
case 200:
fe->mWeight = 700;
break;
case 205:
fe->mWeight = 800;
break;
case 210:
fe->mWeight = 900;
break;
default:
// rough estimate
fe->mWeight = (((x * 4) + 100) / 100) * 100;
break;
}
}
fe->mItalic = false;
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
switch (x) {
case FC_SLANT_ITALIC:
case FC_SLANT_OBLIQUE:
fe->mItalic = true;
}
}
// XXX deal with font-stretch (FC_WIDTH) stuff later
}
if (pat)
FcPatternDestroy(pat);
if (os)
FcObjectSetDestroy(os);
if (fs)
FcFontSetDestroy(fs);
#endif
return sFontconfigUtils->UpdateFontList();
}
@ -365,80 +220,8 @@ gfxQtPlatform::ResolveFontName(const nsAString& aFontName,
void *aClosure,
bool& aAborted)
{
#ifdef MOZ_PANGO
return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
aClosure, aAborted);
#else
nsAutoString name(aFontName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (gPlatformFonts->Get(name, &ff) ||
gPlatformFontAliases->Get(name, &ff)) {
aAborted = !(*aCallback)(ff->Name(), aClosure);
return NS_OK;
}
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
FcPattern *npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
{
npat = FcPatternCreate();
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
FcPatternDel(npat, FC_LANG);
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
FcDefaultSubstitute(npat);
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
nfs = FcFontList(nullptr, npat, nos);
FcResult fresult;
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
if (match)
FcFontSetAdd(nfs, match);
for (int k = 0; k < nfs->nfont; k++) {
FcChar8 *str;
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
continue;
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
ToLowerCase(altName);
if (gPlatformFonts->Get(altName, &ff)) {
gPlatformFontAliases->Put(name, ff);
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
goto DONE;
}
}
}
DONE:
FcPatternDestroy(npat);
FcObjectSetDestroy(nos);
FcFontSetDestroy(nfs);
return NS_OK;
#endif
}
nsresult
@ -452,14 +235,9 @@ gfxQtPlatform::CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle,
gfxUserFontSet* aUserFontSet)
{
#ifdef MOZ_PANGO
return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
#else
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
#endif
}
#ifdef MOZ_PANGO
gfxFontEntry*
gfxQtPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
const nsAString& aFontName)
@ -501,7 +279,6 @@ gfxQtPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
// no format hint set, need to look at data
return true;
}
#endif
qcms_profile*
gfxQtPlatform::GetPlatformCMSOutputProfile()
@ -509,91 +286,6 @@ gfxQtPlatform::GetPlatformCMSOutputProfile()
return nullptr;
}
#ifndef MOZ_PANGO
FT_Library
gfxQtPlatform::GetFTLibrary()
{
return gPlatformFTLibrary;
}
FontFamily *
gfxQtPlatform::FindFontFamily(const nsAString& aName)
{
nsAutoString name(aName);
ToLowerCase(name);
nsRefPtr<FontFamily> ff;
if (!gPlatformFonts->Get(name, &ff)) {
return nullptr;
}
return ff.get();
}
FontEntry *
gfxQtPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
{
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
if (!ff)
return nullptr;
return ff->FindFontEntry(aFontStyle);
}
static PLDHashOperator
FindFontForCharProc(nsStringHashKey::KeyType aKey,
nsRefPtr<FontFamily>& aFontFamily,
void* aUserArg)
{
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
aFontFamily->FindFontForChar(data);
return PL_DHASH_NEXT;
}
already_AddRefed<gfxFont>
gfxQtPlatform::FindFontForChar(uint32_t aCh, gfxFont *aFont)
{
if (!gPlatformFonts || !gCodepointsWithNoFonts)
return nullptr;
// is codepoint with no matching font? return null immediately
if (gCodepointsWithNoFonts->test(aCh)) {
return nullptr;
}
GlobalFontMatch data(aCh, GetScriptCode(aCh),
(aFont ? aFont->GetStyle() : nullptr));
// find fonts that support the character
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
if (data.mBestMatch) {
nsRefPtr<gfxFT2Font> font =
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
aFont->GetStyle());
gfxFont* ret = font.forget().get();
return already_AddRefed<gfxFont>(ret);
}
// no match? add to set of non-matching codepoints
gCodepointsWithNoFonts->set(aCh);
return nullptr;
}
bool
gfxQtPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *array)
{
return mPrefFonts.Get(aKey, array);
}
void
gfxQtPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& array)
{
mPrefFonts.Put(aKey, array);
}
#endif
int32_t
gfxQtPlatform::GetDPI()
{

View File

@ -16,12 +16,6 @@
class gfxFontconfigUtils;
class QWidget;
#ifndef MOZ_PANGO
typedef struct FT_LibraryRec_ *FT_Library;
class FontFamily;
class FontEntry;
#endif
class gfxQtPlatform : public gfxPlatform {
public:
@ -63,7 +57,6 @@ public:
const gfxFontStyle *aStyle,
gfxUserFontSet* aUserFontSet);
#ifdef MOZ_PANGO
/**
* Look up a local platform font using the full font face name (needed to
* support @font-face src local() )
@ -85,22 +78,9 @@ public:
*/
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
uint32_t aFormatFlags);
#endif
#ifndef MOZ_PANGO
FontFamily *FindFontFamily(const nsAString& aName);
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
#endif
void ClearPrefFonts() { mPrefFonts.Clear(); }
#ifndef MOZ_PANGO
FT_Library GetFTLibrary();
#endif
RenderMode GetRenderMode() { return mRenderMode; }
void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }

View File

@ -209,7 +209,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
ID3D11DeviceContext *ppImmediateContext
);
class GPUAdapterReporter : public MemoryMultiReporter
class GPUAdapterReporter : public nsIMemoryReporter
{
// Callers must Release the DXGIAdapter after use or risk mem-leak
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
@ -229,7 +229,7 @@ class GPUAdapterReporter : public MemoryMultiReporter
}
public:
GPUAdapterReporter() {}
NS_DECL_ISUPPORTS
NS_IMETHOD
CollectReports(nsIMemoryReporterCallback* aCb,
@ -339,6 +339,8 @@ public:
}
};
NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
static __inline void
BuildKeyNameFromFontName(nsAString &aName)
{

View File

@ -103,6 +103,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
EXPORTS += [
'gfxFT2FontBase.h',
'gfxGdkNativeRenderer.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h',
'gfxPlatformGtk.h',
'gfxPSSurface.h',
@ -113,6 +114,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp',
'gfxGdkNativeRenderer.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp',
'gfxPlatformGtk.cpp',
'gfxPSSurface.cpp',
@ -129,16 +131,6 @@ elif CONFIG['MOZ_WIDGET_GTK']:
'gfxXlibSurface.cpp',
]
if CONFIG['MOZ_PANGO']:
EXPORTS += ['gfxPangoFonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
else:
EXPORTS += ['gfxFT2Fonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
EXPORTS += [
'gfxOS2Fonts.h',
@ -157,6 +149,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
EXPORTS += [
'gfxFT2FontBase.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h',
'gfxQPainterSurface.h',
'gfxQtNativeRenderer.h',
@ -166,6 +159,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
'gfxFontconfigUtils.cpp',
'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp',
'gfxQPainterSurface.cpp',
'gfxQtPlatform.cpp',
@ -181,16 +175,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
'gfxXlibSurface.cpp',
]
if CONFIG['MOZ_PANGO']:
EXPORTS += ['gfxPangoFonts.h']
SOURCES += [
'gfxPangoFonts.cpp',
]
else:
EXPORTS += ['gfxFT2Fonts.h']
SOURCES += [
'gfxFT2Fonts.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS += [
'gfxD2DSurface.h',

View File

@ -349,7 +349,7 @@ Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::k
}
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
mCurrentFrame->SetTimeout(aTimeout);
mCurrentFrame->SetRawTimeout(aTimeout);
mCurrentFrame->SetBlendMethod(aBlendMethod);
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());

View File

@ -13,36 +13,36 @@ using namespace mozilla;
FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender)
: mCurrentAnimationFrameIndex(0)
, mLoopCount(-1)
, mLoopCounter(-1)
, mFrameBlender(aFrameBlender)
, mAnimationMode(imgIContainer::kNormalAnimMode)
, mDoneDecoding(false)
{
}
uint32_t
int32_t
FrameAnimator::GetSingleLoopTime() const
{
// If we aren't done decoding, we don't know the image's full play time.
if (!mDoneDecoding) {
return 0;
return -1;
}
// If we're not looping, a single loop time has no meaning
if (mAnimationMode != imgIContainer::kNormalAnimMode) {
return 0;
return -1;
}
uint32_t looptime = 0;
for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) {
int32_t timeout = mFrameBlender.RawGetFrame(i)->GetTimeout();
if (timeout > 0) {
int32_t timeout = mFrameBlender.GetTimeoutForFrame(i);
if (timeout >= 0) {
looptime += static_cast<uint32_t>(timeout);
} else {
// If we have a frame that never times out, we're probably in an error
// case, but let's handle it more gracefully.
NS_WARNING("Negative frame timeout - how did this happen?");
return 0;
return -1;
}
}
@ -52,9 +52,8 @@ FrameAnimator::GetSingleLoopTime() const
TimeStamp
FrameAnimator::GetCurrentImgFrameEndTime() const
{
imgFrame* currentFrame = mFrameBlender.RawGetFrame(mCurrentAnimationFrameIndex);
TimeStamp currentFrameTime = mCurrentAnimationFrameTime;
int64_t timeout = currentFrame->GetTimeout();
int32_t timeout = mFrameBlender.GetTimeoutForFrame(mCurrentAnimationFrameIndex);
if (timeout < 0) {
// We need to return a sentinel value in this case, because our logic
@ -82,7 +81,7 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
uint32_t currentFrameIndex = mCurrentAnimationFrameIndex;
uint32_t nextFrameIndex = currentFrameIndex + 1;
uint32_t timeout = 0;
int32_t timeout = 0;
RefreshResult ret;
@ -101,17 +100,22 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
// If we're done decoding the next frame, go ahead and display it now and
// reinit with the next frame's delay time.
if (mFrameBlender.GetNumFrames() == nextFrameIndex) {
// End of Animation, unless we are looping forever
// End of an animation loop...
// If animation mode is "loop once", it's time to stop animating
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCount == 0) {
// If we are not looping forever, initialize the loop counter
if (mLoopCounter < 0 && mFrameBlender.GetLoopCount() >= 0) {
mLoopCounter = mFrameBlender.GetLoopCount();
}
// If animation mode is "loop once", or we're at end of loop counter, it's time to stop animating
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCounter == 0) {
ret.animationFinished = true;
}
nextFrameIndex = 0;
if (mLoopCount > 0) {
mLoopCount--;
if (mLoopCounter > 0) {
mLoopCounter--;
}
// If we're done, exit early.
@ -120,11 +124,11 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
}
}
timeout = mFrameBlender.GetFrame(nextFrameIndex)->GetTimeout();
timeout = mFrameBlender.GetTimeoutForFrame(nextFrameIndex);
}
// Bad data
if (!(timeout > 0)) {
if (timeout < 0) {
ret.animationFinished = true;
ret.error = true;
}
@ -246,12 +250,6 @@ FrameAnimator::UnionFirstFrameRefreshArea(const nsIntRect& aRect)
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, aRect);
}
void
FrameAnimator::SetLoopCount(int loopcount)
{
mLoopCount = loopcount;
}
uint32_t
FrameAnimator::GetCurrentAnimationFrameIndex() const
{

View File

@ -75,12 +75,6 @@ public:
*/
void ResetAnimation();
/**
* Number of times to loop the image.
* @note -1 means forever.
*/
void SetLoopCount(int32_t aLoopCount);
/**
* The animation mode of the image.
*
@ -125,9 +119,10 @@ private: // methods
* Gets the length of a single loop of this image, in milliseconds.
*
* If this image is not finished decoding, is not animated, or it is animated
* but does not loop, returns 0.
* but does not loop, returns -1. Can return 0 in the case of an animated image
* that has a 0ms delay between its frames and does not loop.
*/
uint32_t GetSingleLoopTime() const;
int32_t GetSingleLoopTime() const;
/**
* Advances the animation. Typically, this will advance a single frame, but it
@ -161,7 +156,7 @@ private: // data
uint32_t mCurrentAnimationFrameIndex;
//! number of loops remaining before animation stops (-1 no stop)
int32_t mLoopCount;
int32_t mLoopCounter;
//! All the frames of the image, shared with our owner
FrameBlender& mFrameBlender;

View File

@ -19,6 +19,7 @@ namespace image {
FrameBlender::FrameBlender(FrameSequence* aSequenceToUse /* = nullptr */)
: mFrames(aSequenceToUse)
, mAnim(nullptr)
, mLoopCount(-1)
{
if (!mFrames) {
mFrames = new FrameSequence();
@ -66,6 +67,40 @@ FrameBlender::GetNumFrames() const
return mFrames->GetNumFrames();
}
int32_t
FrameBlender::GetTimeoutForFrame(uint32_t framenum) const
{
const int32_t timeout = RawGetFrame(framenum)->GetRawTimeout();
// Ensure a minimal time between updates so we don't throttle the UI thread.
// consider 0 == unspecified and make it fast but not too fast. Unless we have
// a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug 207059.
// The behavior of recent IE and Opera versions seems to be:
// IE 6/Win:
// 10 - 50ms go 100ms
// >50ms go correct speed
// Opera 7 final/Win:
// 10ms goes 100ms
// >10ms go correct speed
// It seems that there are broken tools out there that set a 0ms or 10ms
// timeout when they really want a "default" one. So munge values in that
// range.
if (timeout >= 0 && timeout <= 10 && mLoopCount != 0)
return 100;
return timeout;
}
void
FrameBlender::SetLoopCount(int32_t aLoopCount)
{
mLoopCount = aLoopCount;
}
int32_t
FrameBlender::GetLoopCount() const
{
return mLoopCount;
}
void
FrameBlender::RemoveFrame(uint32_t framenum)
{
@ -381,8 +416,8 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
// Set timeout of CompositeFrame to timeout of frame we just composed
// Bug 177948
int32_t timeout = nextFrame->GetTimeout();
mAnim->compositingFrame->SetTimeout(timeout);
int32_t timeout = nextFrame->GetRawTimeout();
mAnim->compositingFrame->SetRawTimeout(timeout);
// Tell the image that it is fully 'downloaded'.
nsresult rv = mAnim->compositingFrame->ImageUpdated(mAnim->compositingFrame->GetRect());

View File

@ -59,6 +59,20 @@ public:
/* The total number of frames in this image. */
uint32_t GetNumFrames() const;
/*
* Returns the frame's adjusted timeout. If the animation loops and the timeout
* falls in between a certain range then the timeout is adjusted so that
* it's never 0. If the animation does not loop then no adjustments are made.
*/
int32_t GetTimeoutForFrame(uint32_t framenum) const;
/*
* Set number of times to loop the image.
* @note -1 means loop forever.
*/
void SetLoopCount(int32_t aLoopCount);
int32_t GetLoopCount() const;
void Discard();
void SetSize(nsIntSize aSize) { mSize = aSize; }
@ -169,6 +183,7 @@ private: // data
nsRefPtr<FrameSequence> mFrames;
nsIntSize mSize;
Anim* mAnim;
int32_t mLoopCount;
};
} // namespace image

View File

@ -29,8 +29,8 @@ ImageResource::SizeOfData()
return 0;
// This is not used by memory reporters, but for sizing the cache, which is
// why it uses |moz_malloc_size_of| rather than an
// |NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN|.
// why it uses |moz_malloc_size_of| rather than a
// |MOZ_DEFINE_MALLOC_SIZE_OF|.
return uint32_t(HeapSizeOfSourceWithComputedFallback(moz_malloc_size_of) +
HeapSizeOfDecodedWithComputedFallback(moz_malloc_size_of) +
NonHeapSizeOfDecoded() +

View File

@ -814,7 +814,7 @@ RasterImage::GetFirstFrameDelay()
if (NS_FAILED(GetAnimated(&animated)) || !animated)
return -1;
return mFrameBlender.GetFrame(0)->GetTimeout();
return mFrameBlender.GetTimeoutForFrame(0);
}
nsresult
@ -1439,7 +1439,7 @@ RasterImage::StartAnimation()
imgFrame* currentFrame = GetCurrentImgFrame();
// A timeout of -1 means we should display this frame forever.
if (currentFrame && currentFrame->GetTimeout() < 0) {
if (currentFrame && mFrameBlender.GetTimeoutForFrame(GetCurrentImgFrameIndex()) < 0) {
mAnimationFinished = true;
return NS_ERROR_ABORT;
}
@ -1536,7 +1536,8 @@ RasterImage::SetLoopCount(int32_t aLoopCount)
return;
if (mAnim) {
mAnim->SetLoopCount(aLoopCount);
// No need to set this if we're not an animation
mFrameBlender.SetLoopCount(aLoopCount);
}
}

View File

@ -745,28 +745,12 @@ void imgFrame::ApplyDirtToSurfaces()
}
}
int32_t imgFrame::GetTimeout() const
int32_t imgFrame::GetRawTimeout() const
{
// Ensure a minimal time between updates so we don't throttle the UI thread.
// consider 0 == unspecified and make it fast but not too fast. See bug
// 125137, bug 139677, and bug 207059. The behavior of recent IE and Opera
// versions seems to be:
// IE 6/Win:
// 10 - 50ms go 100ms
// >50ms go correct speed
// Opera 7 final/Win:
// 10ms goes 100ms
// >10ms go correct speed
// It seems that there are broken tools out there that set a 0ms or 10ms
// timeout when they really want a "default" one. So munge values in that
// range.
if (mTimeout >= 0 && mTimeout <= 10)
return 100;
else
return mTimeout;
return mTimeout;
}
void imgFrame::SetTimeout(int32_t aTimeout)
void imgFrame::SetRawTimeout(int32_t aTimeout)
{
mTimeout = aTimeout;
}

View File

@ -53,8 +53,8 @@ public:
void GetPaletteData(uint32_t **aPalette, uint32_t *length) const;
uint32_t* GetPaletteData() const;
int32_t GetTimeout() const;
void SetTimeout(int32_t aTimeout);
int32_t GetRawTimeout() const;
void SetRawTimeout(int32_t aTimeout);
int32_t GetFrameDisposalMethod() const;
void SetFrameDisposalMethod(int32_t aFrameDisposalMethod);

View File

@ -48,12 +48,12 @@
using namespace mozilla;
using namespace mozilla::image;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
class imgMemoryReporter MOZ_FINAL : public MemoryMultiReporter
class imgMemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
imgMemoryReporter() {}
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *callback,
nsISupports *closure)
@ -212,10 +212,12 @@ private:
}
};
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
NS_IMPL_ISUPPORTS3(nsProgressNotificationProxy,
nsIProgressEventSink,
nsIChannelEventSink,
nsIInterfaceRequestor)
nsIProgressEventSink,
nsIChannelEventSink,
nsIInterfaceRequestor)
NS_IMETHODIMP
nsProgressNotificationProxy::OnProgress(nsIRequest* request,

View File

@ -30,11 +30,7 @@ window.onload = function() {
amount += aAmount;
}
var e = mgr.enumerateReporters();
while (e.hasMoreElements()) {
var mr = e.getNext().QueryInterface(SpecialPowers.Ci.nsIMemoryReporter);
mr.collectReports(handleReport, null);
}
mgr.getReportsForThisProcess(handleReport, null);
ok(amount > 0, "we should be using a nonzero amount of memory");
ok(true, "yay, didn't crash!");

View File

@ -347,9 +347,6 @@ typedef bool
(* ElementIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index,
JS::MutableHandleValue vp);
typedef bool
(* ElementIfPresentOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
uint32_t index, JS::MutableHandleValue vp, bool* present);
typedef bool
(* SpecialIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
HandleSpecialId sid, JS::MutableHandleValue vp);
typedef bool
@ -383,6 +380,10 @@ typedef bool
typedef bool
(* UnwatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
typedef bool
(* SliceOp)(JSContext *cx, JS::HandleObject obj, uint32_t begin, uint32_t end,
JS::HandleObject result); // result is actually preallocted.
typedef JSObject *
(* ObjectOp)(JSContext *cx, JS::HandleObject obj);
typedef void
@ -459,7 +460,6 @@ struct ObjectOps
GenericIdOp getGeneric;
PropertyIdOp getProperty;
ElementIdOp getElement;
ElementIfPresentOp getElementIfPresent; /* can be null */
SpecialIdOp getSpecial;
StrictGenericIdOp setGeneric;
StrictPropertyIdOp setProperty;
@ -472,6 +472,7 @@ struct ObjectOps
DeleteSpecialOp deleteSpecial;
WatchOp watch;
UnwatchOp unwatch;
SliceOp slice; // Optimized slice, can be null.
JSNewEnumerateOp enumerate;
ObjectOp thisObject;
@ -480,7 +481,7 @@ struct ObjectOps
#define JS_NULL_OBJECT_OPS \
{nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}
nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}
} // namespace js

View File

@ -2081,15 +2081,6 @@ TypedDatum::obj_getProperty(JSContext *cx, HandleObject obj, HandleObject receiv
bool
TypedDatum::obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp)
{
bool present;
return obj_getElementIfPresent(cx, obj, receiver, index, vp, &present);
}
bool
TypedDatum::obj_getElementIfPresent(JSContext *cx, HandleObject obj,
HandleObject receiver, uint32_t index,
MutableHandleValue vp, bool *present)
{
RootedObject type(cx, GetType(*obj));
TypeRepresentation *typeRepr = typeRepresentation(*type);
@ -2106,8 +2097,6 @@ TypedDatum::obj_getElementIfPresent(JSContext *cx, HandleObject obj,
{
JS_ASSERT(IsArrayTypedDatum(*obj));
*present = true;
if (index >= DatumLength(*obj)) {
vp.setUndefined();
return true;
@ -2123,12 +2112,11 @@ TypedDatum::obj_getElementIfPresent(JSContext *cx, HandleObject obj,
RootedObject proto(cx, obj->getProto());
if (!proto) {
*present = false;
vp.setUndefined();
return true;
}
return JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present);
return JSObject::getElement(cx, proto, receiver, index, vp);
}
bool
@ -2499,7 +2487,6 @@ const Class TypedObject::class_ = {
TypedDatum::obj_getGeneric,
TypedDatum::obj_getProperty,
TypedDatum::obj_getElement,
TypedDatum::obj_getElementIfPresent,
TypedDatum::obj_getSpecial,
TypedDatum::obj_setGeneric,
TypedDatum::obj_setProperty,
@ -2511,6 +2498,7 @@ const Class TypedObject::class_ = {
TypedDatum::obj_deleteElement,
TypedDatum::obj_deleteSpecial,
nullptr, nullptr, // watch/unwatch
nullptr, /* slice */
TypedDatum::obj_enumerate,
nullptr, /* thisObject */
}
@ -2666,7 +2654,6 @@ const Class TypedHandle::class_ = {
TypedDatum::obj_getGeneric,
TypedDatum::obj_getProperty,
TypedDatum::obj_getElement,
TypedDatum::obj_getElementIfPresent,
TypedDatum::obj_getSpecial,
TypedDatum::obj_setGeneric,
TypedDatum::obj_setProperty,
@ -2678,6 +2665,7 @@ const Class TypedHandle::class_ = {
TypedDatum::obj_deleteElement,
TypedDatum::obj_deleteSpecial,
nullptr, nullptr, // watch/unwatch
nullptr, // slice
TypedDatum::obj_enumerate,
nullptr, /* thisObject */
}

View File

@ -293,9 +293,6 @@ class TypedDatum : public JSObject
static bool obj_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleSpecialId sid, MutableHandleValue vp);
static bool obj_getElementIfPresent(JSContext *cx, HandleObject obj,
HandleObject receiver, uint32_t index,
MutableHandleValue vp, bool *present);
static bool obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
MutableHandleValue vp, bool strict);
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,

View File

@ -1053,8 +1053,10 @@ MOZ_ARG_ENABLE_BOOL(address-sanitizer,
if test -n "$MOZ_ASAN"; then
MOZ_LLVM_HACKS=1
AC_DEFINE(MOZ_ASAN)
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
fi
AC_SUBST(MOZ_ASAN)
AC_SUBST(LLVM_SYMBOLIZER)
dnl ========================================================
dnl = Enable hacks required for LLVM instrumentations

View File

@ -0,0 +1,37 @@
let invoked = false;
Object.defineProperty(Array.prototype, '0', {set: function () {
invoked = true;
}});
let result = [1, 2, 3].slice(1);
assertEq(invoked, false);
let proxy = new Proxy({}, {
get: function (target, name, proxy) {
switch (name) {
case "length":
return 2;
case "0":
return 15;
case "1":
// Should not invoke [[Get]] for this hole.
default:
assertEq(false, true);
}
},
has: function (target, name) {
switch (name) {
case "0":
return true;
case "1":
return false;
default:
assertEq(false, true);
}
}
})
result = Array.prototype.slice.call(proxy, 0);
assertEq(result.length, 2);
assertEq(0 in result, true);
assertEq(1 in result, false);
assertEq(result[0], 15);

View File

@ -496,10 +496,8 @@ ICTypeMonitor_Fallback::resetMonitorStubChain(Zone *zone)
// We are removing edges from monitored stubs to gcthings (IonCode).
// Perform one final trace of all monitor stubs for incremental GC,
// as it must know about those edges.
if (hasFallbackStub_) {
for (ICStub *s = firstMonitorStub_; !s->isTypeMonitor_Fallback(); s = s->next())
s->trace(zone->barrierTracer());
}
for (ICStub *s = firstMonitorStub_; !s->isTypeMonitor_Fallback(); s = s->next())
s->trace(zone->barrierTracer());
}
firstMonitorStub_ = this;

View File

@ -3393,25 +3393,6 @@ JS_ForwardGetElementTo(JSContext *cx, JSObject *objArg, uint32_t index, JSObject
return JSObject::getElement(cx, obj, onBehalfOf, index, vp);
}
JS_PUBLIC_API(bool)
JS_GetElementIfPresent(JSContext *cx, JSObject *objArg, uint32_t index, JSObject *onBehalfOfArg,
MutableHandleValue vp, bool* present)
{
RootedObject obj(cx, objArg);
RootedObject onBehalfOf(cx, onBehalfOfArg);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
JSAutoResolveFlags rf(cx, 0);
bool isPresent;
if (!JSObject::getElementIfPresent(cx, obj, onBehalfOf, index, vp, &isPresent))
return false;
*present = isPresent;
return true;
}
JS_PUBLIC_API(bool)
JS_GetProperty(JSContext *cx, JSObject *objArg, const char *name, MutableHandleValue vp)
{

View File

@ -3040,15 +3040,6 @@ extern JS_PUBLIC_API(bool)
JS_ForwardGetElementTo(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf,
JS::MutableHandle<JS::Value> vp);
/*
* Get the property with name given by |index|, if it has one. If
* not, |*present| will be set to false and the value of |vp| must not
* be relied on.
*/
extern JS_PUBLIC_API(bool)
JS_GetElementIfPresent(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf,
JS::MutableHandle<JS::Value> vp, bool* present);
extern JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, JSObject *obj, uint32_t index, JS::MutableHandle<JS::Value> vp);

View File

@ -134,7 +134,7 @@ js::StringIsArrayIndex(JSLinearString *str, uint32_t *indexp)
}
static bool
DoubleIndexToId(JSContext *cx, double index, MutableHandleId id)
ToId(JSContext *cx, double index, MutableHandleId id)
{
if (index == uint32_t(index))
return IndexToId(cx, uint32_t(index), id.address());
@ -143,18 +143,26 @@ DoubleIndexToId(JSContext *cx, double index, MutableHandleId id)
return ValueToId<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp), id);
}
static bool
ToId(JSContext *cx, uint32_t index, MutableHandleId id)
{
return IndexToId(cx, index, id.address());
}
/*
* If the property at the given index exists, get its value into location
* pointed by vp and set *hole to false. Otherwise set *hole to true and *vp
* to JSVAL_VOID. This function assumes that the location pointed by vp is
* properly rooted and can be used as GC-protected storage for temporaries.
*/
template<typename IndexType>
static inline bool
DoGetElement(JSContext *cx, HandleObject obj, double index, bool *hole, MutableHandleValue vp)
DoGetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
IndexType index, bool *hole, MutableHandleValue vp)
{
RootedId id(cx);
if (!DoubleIndexToId(cx, index, &id))
if (!ToId(cx, index, &id))
return false;
RootedObject obj2(cx);
@ -166,27 +174,13 @@ DoGetElement(JSContext *cx, HandleObject obj, double index, bool *hole, MutableH
vp.setUndefined();
*hole = true;
} else {
if (!JSObject::getGeneric(cx, obj, obj, id, vp))
if (!JSObject::getGeneric(cx, obj, receiver, id, vp))
return false;
*hole = false;
}
return true;
}
static inline bool
DoGetElement(JSContext *cx, HandleObject obj, uint32_t index, bool *hole, MutableHandleValue vp)
{
bool present;
if (!JSObject::getElementIfPresent(cx, obj, obj, index, vp, &present))
return false;
*hole = !present;
if (*hole)
vp.setUndefined();
return true;
}
template<typename IndexType>
static void
AssertGreaterThanZero(IndexType index)
@ -203,7 +197,8 @@ AssertGreaterThanZero(uint32_t index)
template<typename IndexType>
static bool
GetElement(JSContext *cx, HandleObject obj, IndexType index, bool *hole, MutableHandleValue vp)
GetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
IndexType index, bool *hole, MutableHandleValue vp)
{
AssertGreaterThanZero(index);
if (obj->isNative() && index < obj->getDenseInitializedLength()) {
@ -220,7 +215,14 @@ GetElement(JSContext *cx, HandleObject obj, IndexType index, bool *hole, Mutable
}
}
return DoGetElement(cx, obj, index, hole, vp);
return DoGetElement(cx, obj, receiver, index, hole, vp);
}
template<typename IndexType>
static inline bool
GetElement(JSContext *cx, HandleObject obj, IndexType index, bool *hole, MutableHandleValue vp)
{
return GetElement(cx, obj, obj, index, hole, vp);
}
static bool
@ -296,7 +298,7 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
}
RootedId id(cx);
if (!DoubleIndexToId(cx, index, &id))
if (!ToId(cx, index, &id))
return false;
RootedValue tmp(cx, v);
@ -2680,20 +2682,18 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
static bool
array_slice(JSContext *cx, unsigned argc, Value *vp)
{
uint32_t length, begin, end, slot;
bool hole;
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject obj(cx, ToObject(cx, args.thisv()));
if (!obj)
return false;
uint32_t length;
if (!GetLengthProperty(cx, obj, &length))
return false;
begin = 0;
end = length;
uint32_t begin = 0;
uint32_t end = length;
if (args.length() > 0) {
double d;
if (!ToInteger(cx, args[0], &d))
@ -2741,20 +2741,50 @@ array_slice(JSContext *cx, unsigned argc, Value *vp)
return true;
}
RootedValue value(cx);
for (slot = begin; slot < end; slot++) {
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, obj, slot, &hole, &value)) {
return false;
if (js::SliceOp op = obj->getOps()->slice) {
// Ensure that we have dense elements, so that DOM can use js::UnsafeDefineElement.
JSObject::EnsureDenseResult result = narr->ensureDenseElements(cx, 0, end - begin);
if (result == JSObject::ED_FAILED)
return false;
if (result == JSObject::ED_OK) {
if (!op(cx, obj, begin, end, narr))
return false;
args.rval().setObject(*narr);
return true;
}
if (!hole && !SetArrayElement(cx, narr, slot - begin, value))
return false;
// Fallthrough
JS_ASSERT(result == JSObject::ED_SPARSE);
}
if (!SliceSlowly(cx, obj, obj, begin, end, narr))
return false;
args.rval().setObject(*narr);
return true;
}
JS_FRIEND_API(bool)
js::SliceSlowly(JSContext* cx, HandleObject obj, HandleObject receiver,
uint32_t begin, uint32_t end, HandleObject result)
{
RootedValue value(cx);
for (uint32_t slot = begin; slot < end; slot++) {
bool hole;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetElement(cx, obj, receiver, slot, &hole, &value))
{
return false;
}
if (!hole && !JSObject::defineElement(cx, result, slot - begin, value))
return false;
}
return true;
}
/* ES5 15.4.4.20. */
static bool
array_filter(JSContext *cx, unsigned argc, Value *vp)

View File

@ -1165,6 +1165,14 @@ js::GetObjectMetadata(JSObject *obj)
return obj->getMetadata();
}
JS_FRIEND_API(void)
js::UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value)
{
JS_ASSERT(obj->isNative());
JS_ASSERT(index < obj->getDenseInitializedLength());
obj->setDenseElementWithType(cx, index, value);
}
JS_FRIEND_API(bool)
js_DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg,
JS::Handle<js::PropertyDescriptor> descriptor, bool *bp)

View File

@ -1739,6 +1739,13 @@ SetObjectMetadata(JSContext *cx, JS::HandleObject obj, JS::HandleObject metadata
JS_FRIEND_API(JSObject *)
GetObjectMetadata(JSObject *obj);
JS_FRIEND_API(void)
UnsafeDefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value);
JS_FRIEND_API(bool)
SliceSlowly(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver,
uint32_t begin, uint32_t end, JS::HandleObject result);
/* ES5 8.12.8. */
extern JS_FRIEND_API(bool)
DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);

View File

@ -223,7 +223,7 @@ IdToTypeId(jsid id)
if (JSID_IS_STRING(id)) {
JSFlatString *str = JSID_TO_FLAT_STRING(id);
JS::TwoByteChars cp = str->range();
if (JS7_ISDEC(cp[0]) || cp[0] == '-') {
if (cp.length() > 0 && (JS7_ISDEC(cp[0]) || cp[0] == '-')) {
for (size_t i = 1; i < cp.length(); ++i) {
if (!JS7_ISDEC(cp[i]))
return id;

View File

@ -396,7 +396,11 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
return &obj->as<PropertyIteratorObject>();
}
return &NewBuiltinClassInstance(cx, &PropertyIteratorObject::class_)->as<PropertyIteratorObject>();
JSObject *obj = NewBuiltinClassInstance(cx, &PropertyIteratorObject::class_);
if (!obj)
return nullptr;
return &obj->as<PropertyIteratorObject>();
}
NativeIterator *

View File

@ -1030,12 +1030,6 @@ class JSObject : public js::ObjectImpl
static inline bool getElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver,
uint32_t index, js::Value *vp);
/* If element is not present (e.g. array hole) *present is set to
false and the contents of *vp are unusable garbage. */
static inline bool getElementIfPresent(JSContext *cx, js::HandleObject obj,
js::HandleObject receiver, uint32_t index,
js::MutableHandleValue vp, bool *present);
static bool getSpecial(JSContext *cx, js::HandleObject obj,
js::HandleObject receiver, js::SpecialId sid,
js::MutableHandleValue vp)

View File

@ -583,38 +583,6 @@ JSObject::getElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver,
return getGenericNoGC(cx, obj, receiver, id, vp);
}
/* static */ inline bool
JSObject::getElementIfPresent(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
uint32_t index, js::MutableHandleValue vp,
bool *present)
{
js::ElementIfPresentOp op = obj->getOps()->getElementIfPresent;
if (op)
return op(cx, obj, receiver, index, vp, present);
/*
* For now, do the index-to-id conversion just once, then use
* lookupGeneric/getGeneric. Once lookupElement and getElement stop both
* doing index-to-id conversions, we can use those here.
*/
JS::RootedId id(cx);
if (!js::IndexToId(cx, index, id.address()))
return false;
JS::RootedObject obj2(cx);
js::RootedShape prop(cx);
if (!lookupGeneric(cx, obj, id, &obj2, &prop))
return false;
if (!prop) {
*present = false;
return true;
}
*present = true;
return getGeneric(cx, obj, receiver, id, vp);
}
inline js::GlobalObject &
JSObject::global() const
{

View File

@ -151,27 +151,6 @@ BaseProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
return CallJSPropertyOp(cx, desc.getter(), receiver, id, vp);
}
bool
BaseProxyHandler::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present)
{
RootedId id(cx);
if (!IndexToId(cx, index, id.address()))
return false;
assertEnteredPolicy(cx, proxy, id);
if (!has(cx, proxy, id, present))
return false;
if (!*present) {
Debug_SetValueRangeToCrashOnTouch(vp.address(), 1);
return true;
}
return get(cx, proxy, receiver, id, vp);
}
bool
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, bool strict, MutableHandleValue vp)
@ -385,6 +364,34 @@ BaseProxyHandler::unwatch(JSContext *cx, HandleObject proxy, HandleId id)
return true;
}
bool
BaseProxyHandler::slice(JSContext *cx, HandleObject proxy, uint32_t begin, uint32_t end,
HandleObject result)
{
assertEnteredPolicy(cx, proxy, JSID_VOID);
RootedId id(cx);
RootedValue value(cx);
for (uint32_t index = begin; index < end; index++) {
if (!IndexToId(cx, index, id.address()))
return false;
bool present;
if (!Proxy::has(cx, proxy, id, &present))
return false;
if (present) {
if (!Proxy::get(cx, proxy, proxy, id, &value))
return false;
if (!JSObject::defineElement(cx, result, index - begin, value))
return false;
}
}
return true;
}
bool
DirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<PropertyDescriptor> desc, unsigned flags)
@ -2519,41 +2526,6 @@ Proxy::callProp(JSContext *cx, HandleObject proxy, HandleObject receiver, Handle
return true;
}
bool
Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver, uint32_t index,
MutableHandleValue vp, bool *present)
{
JS_CHECK_RECURSION(cx, return false);
RootedId id(cx);
if (!IndexToId(cx, index, id.address()))
return false;
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
if (!policy.allowed())
return policy.returnValue();
if (!handler->hasPrototype()) {
return handler->getElementIfPresent(cx, proxy, receiver, index,
vp, present);
}
bool hasOwn;
if (!handler->hasOwn(cx, proxy, id, &hasOwn))
return false;
if (hasOwn) {
*present = true;
return proxy->as<ProxyObject>().handler()->get(cx, proxy, receiver, id, vp);
}
*present = false;
INVOKE_ON_PROTOTYPE(cx, handler, proxy,
JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present));
}
bool
Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict,
MutableHandleValue vp)
@ -2776,6 +2748,18 @@ Proxy::unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id)
return proxy->as<ProxyObject>().handler()->unwatch(cx, proxy, id);
}
/* static */ bool
Proxy::slice(JSContext *cx, HandleObject proxy, uint32_t begin, uint32_t end,
HandleObject result)
{
JS_CHECK_RECURSION(cx, return false);
BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
if (!policy.allowed())
return policy.returnValue();
return handler->slice(cx, proxy, begin, end, result);
}
static JSObject *
proxy_innerObject(JSContext *cx, HandleObject obj)
{
@ -2891,13 +2875,6 @@ proxy_GetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_
return proxy_GetGeneric(cx, obj, receiver, id, vp);
}
static bool
proxy_GetElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp, bool *present)
{
return Proxy::getElementIfPresent(cx, obj, receiver, index, vp, present);
}
static bool
proxy_GetSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid,
MutableHandleValue vp)
@ -3076,17 +3053,24 @@ proxy_Construct(JSContext *cx, unsigned argc, Value *vp)
}
static bool
proxy_Watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable)
proxy_Watch(JSContext *cx, HandleObject obj, HandleId id, HandleObject callable)
{
return Proxy::watch(cx, obj, id, callable);
}
static bool
proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id)
proxy_Unwatch(JSContext *cx, HandleObject obj, HandleId id)
{
return Proxy::unwatch(cx, obj, id);
}
static bool
proxy_Slice(JSContext *cx, HandleObject proxy, uint32_t begin, uint32_t end,
HandleObject result)
{
return Proxy::slice(cx, proxy, begin, end, result);
}
#define PROXY_CLASS_EXT \
{ \
nullptr, /* outerObject */ \
@ -3128,7 +3112,6 @@ proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id)
proxy_GetGeneric, \
proxy_GetProperty, \
proxy_GetElement, \
proxy_GetElementIfPresent, \
proxy_GetSpecial, \
proxy_SetGeneric, \
proxy_SetProperty, \
@ -3140,6 +3123,7 @@ proxy_Unwatch(JSContext *cx, JS::HandleObject obj, JS::HandleId id)
proxy_DeleteElement, \
proxy_DeleteSpecial, \
proxy_Watch, proxy_Unwatch, \
proxy_Slice, \
nullptr, /* enumerate */ \
nullptr, /* thisObject */ \
} \
@ -3186,7 +3170,6 @@ const Class js::OuterWindowProxyObject::class_ = {
proxy_GetGeneric,
proxy_GetProperty,
proxy_GetElement,
proxy_GetElementIfPresent,
proxy_GetSpecial,
proxy_SetGeneric,
proxy_SetProperty,
@ -3198,6 +3181,7 @@ const Class js::OuterWindowProxyObject::class_ = {
proxy_DeleteElement,
proxy_DeleteSpecial,
proxy_Watch, proxy_Unwatch,
proxy_Slice,
nullptr, /* enumerate */
nullptr, /* thisObject */
}

View File

@ -166,8 +166,6 @@ class JS_FRIEND_API(BaseProxyHandler)
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g);
virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
virtual void finalize(JSFreeOp *fop, JSObject *proxy);
virtual bool getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present);
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop);
// These two hooks must be overridden, or not overridden, in tandem -- no
@ -176,6 +174,9 @@ class JS_FRIEND_API(BaseProxyHandler)
JS::HandleObject callable);
virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id);
virtual bool slice(JSContext *cx, HandleObject proxy, uint32_t begin, uint32_t end,
HandleObject result);
/* See comment for weakmapKeyDelegateOp in js/Class.h. */
virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
virtual bool isScripted() { return false; }
@ -276,8 +277,6 @@ class Proxy
static bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp);
static bool getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present);
static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
bool strict, MutableHandleValue vp);
static bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
@ -296,9 +295,11 @@ class Proxy
static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop);
static bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::HandleObject callable);
static bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id);
static bool watch(JSContext *cx, HandleObject proxy, HandleId id, HandleObject callable);
static bool unwatch(JSContext *cx, HandleObject proxy, HandleId id);
static bool slice(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end,
HandleObject result);
/* IC entry path for handling __noSuchMethod__ on access. */
static bool callProp(JSContext *cx, HandleObject proxy, HandleObject reveiver, HandleId id,

View File

@ -73,7 +73,7 @@ js::StartOffThreadAsmJSCompile(ExclusiveContext *cx, AsmJSParallelTask *asmData)
if (!state.asmJSWorklist.append(asmData))
return false;
state.notifyAll(WorkerThreadState::PRODUCER);
state.notifyOne(WorkerThreadState::PRODUCER);
return true;
}
@ -501,6 +501,13 @@ WorkerThreadState::notifyAll(CondVar which)
PR_NotifyAllCondVar((which == CONSUMER) ? consumerWakeup : producerWakeup);
}
void
WorkerThreadState::notifyOne(CondVar which)
{
JS_ASSERT(isLocked());
PR_NotifyCondVar((which == CONSUMER) ? consumerWakeup : producerWakeup);
}
bool
WorkerThreadState::canStartAsmJSCompile()
{

View File

@ -95,6 +95,7 @@ class WorkerThreadState
void wait(CondVar which, uint32_t timeoutMillis = 0);
void notifyAll(CondVar which);
void notifyOne(CondVar which);
bool canStartAsmJSCompile();
bool canStartIonCompile();

View File

@ -837,14 +837,6 @@ DeadObjectProxy::defaultValue(JSContext *cx, HandleObject obj, JSType hint, Muta
return false;
}
bool
DeadObjectProxy::getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present)
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;
}
bool
DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop)
{

View File

@ -208,9 +208,6 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
MutableHandleValue vp) MOZ_OVERRIDE;
virtual bool getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp,
bool *present) MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) MOZ_OVERRIDE;

View File

@ -556,7 +556,6 @@ const Class WithObject::class_ = {
with_GetGeneric,
with_GetProperty,
with_GetElement,
nullptr, /* getElementIfPresent */
with_GetSpecial,
with_SetGeneric,
with_SetProperty,
@ -567,7 +566,8 @@ const Class WithObject::class_ = {
with_DeleteProperty,
with_DeleteElement,
with_DeleteSpecial,
nullptr, nullptr, /* watch/unwatch */
nullptr, nullptr, /* watch/unwatch */
nullptr, /* slice */
with_Enumerate,
with_ThisObject,
}

View File

@ -1037,16 +1037,6 @@ ArrayBufferObject::obj_getElement(JSContext *cx, HandleObject obj,
return baseops::GetElement(cx, delegate, receiver, index, vp);
}
bool
ArrayBufferObject::obj_getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present)
{
RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
if (!delegate)
return false;
return JSObject::getElementIfPresent(cx, delegate, receiver, index, vp, present);
}
bool
ArrayBufferObject::obj_getSpecial(JSContext *cx, HandleObject obj,
HandleObject receiver, HandleSpecialId sid,
@ -1494,27 +1484,6 @@ class TypedArrayObjectTemplate : public TypedArrayObject
return obj_getProperty(cx, obj, receiver, name, vp);
}
static bool
obj_getElementIfPresent(JSContext *cx, HandleObject tarray, HandleObject receiver, uint32_t index,
MutableHandleValue vp, bool *present)
{
// Fast-path the common case of index < length
if (index < tarray->as<TypedArrayObject>().length()) {
// this inline function is specialized for each type
copyIndexToValue(tarray, index, vp);
*present = true;
return true;
}
RootedObject proto(cx, tarray->getProto());
if (!proto) {
vp.setUndefined();
return true;
}
return JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present);
}
static bool
setElementTail(JSContext *cx, HandleObject tarray, uint32_t index,
MutableHandleValue vp, bool strict)
@ -3480,7 +3449,6 @@ const Class ArrayBufferObject::class_ = {
ArrayBufferObject::obj_getGeneric,
ArrayBufferObject::obj_getProperty,
ArrayBufferObject::obj_getElement,
ArrayBufferObject::obj_getElementIfPresent,
ArrayBufferObject::obj_getSpecial,
ArrayBufferObject::obj_setGeneric,
ArrayBufferObject::obj_setProperty,
@ -3492,8 +3460,9 @@ const Class ArrayBufferObject::class_ = {
ArrayBufferObject::obj_deleteElement,
ArrayBufferObject::obj_deleteSpecial,
nullptr, nullptr, /* watch/unwatch */
nullptr, /* slice */
ArrayBufferObject::obj_enumerate,
nullptr, /* thisObject */
nullptr, /* thisObject */
}
};
@ -3643,7 +3612,6 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
_typedArray##Object::obj_getGeneric, \
_typedArray##Object::obj_getProperty, \
_typedArray##Object::obj_getElement, \
_typedArray##Object::obj_getElementIfPresent, \
_typedArray##Object::obj_getSpecial, \
_typedArray##Object::obj_setGeneric, \
_typedArray##Object::obj_setProperty, \
@ -3655,8 +3623,9 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double)
_typedArray##Object::obj_deleteElement, \
_typedArray##Object::obj_deleteSpecial, \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* slice */ \
_typedArray##Object::obj_enumerate, \
nullptr, /* thisObject */ \
nullptr, /* thisObject */ \
} \
}

View File

@ -107,8 +107,6 @@ class ArrayBufferObject : public JSObject
static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp);
static bool obj_getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp, bool *present);
static bool obj_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleSpecialId sid, MutableHandleValue vp);

View File

@ -120,7 +120,7 @@ interface ScheduledGCCallback : nsISupports
/**
* interface of Components.utils
*/
[scriptable, uuid(ef621cac-c818-464a-9fb1-9a35731a7f32)]
[scriptable, uuid(8dd4680f-4f06-4760-a147-292cb307662f)]
interface nsIXPCComponents_Utils : nsISupports
{
@ -338,12 +338,13 @@ interface nsIXPCComponents_Utils : nsISupports
* algorithm.
* The return value is the new forwarder function, wrapped into
* the caller's compartment.
* The 3rd argument is the name of the property that will
* be set on the target scope, with the forwarder function as
* the value.
* The 3rd argument is an optional options object:
* - defineAs: the name of the property that will
* be set on the target scope, with
* the forwarder function as the value.
*/
[implicit_jscontext]
jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname);
jsval exportFunction(in jsval vfunction, in jsval vscope, [optional] in jsval voptions);
/*
* To be called from JS only.

View File

@ -243,17 +243,20 @@ IsProxy(JSContext *cx, unsigned argc, jsval *vp)
namespace xpc {
bool
ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleValue vname,
ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleValue voptions,
MutableHandleValue rval)
{
if (!vscope.isObject() || !vfunction.isObject() || !vname.isString()) {
bool hasOptions = !voptions.isUndefined();
if (!vscope.isObject() || !vfunction.isObject() || (hasOptions && !voptions.isObject())) {
JS_ReportError(cx, "Invalid argument");
return false;
}
RootedObject funObj(cx, &vfunction.toObject());
RootedObject targetScope(cx, &vscope.toObject());
RootedString funName(cx, vname.toString());
ExportOptions options(cx, hasOptions ? &voptions.toObject() : nullptr);
if (hasOptions && !options.Parse())
return false;
// We can only export functions to scopes those are transparent for us,
// so if there is a security wrapper around targetScope we must throw.
@ -268,11 +271,6 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV
return false;
}
if (JS_GetStringLength(funName) == 0) {
JS_ReportError(cx, "3rd argument should be a non-empty string");
return false;
}
{
// We need to operate in the target scope from here on, let's enter
// its compartment.
@ -285,16 +283,28 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV
return false;
}
RootedId id(cx, options.defineAs);
if (JSID_IS_VOID(id)) {
// If there wasn't any function name specified,
// copy the name from the function being imported.
JSFunction *fun = JS_GetObjectFunction(funObj);
RootedString funName(cx, JS_GetFunctionId(fun));
if (!funName)
funName = JS_InternString(cx, "");
RootedValue vname(cx);
vname.setString(funName);
if (!JS_ValueToId(cx, vname, id.address()))
return false;
}
MOZ_ASSERT(JSID_IS_STRING(id));
// The function forwarder will live in the target compartment. Since
// this function will be referenced from its private slot, to avoid a
// GC hazard, we must wrap it to the same compartment.
if (!JS_WrapObject(cx, &funObj))
return false;
RootedId id(cx);
if (!JS_ValueToId(cx, vname, id.address()))
return false;
// And now, let's create the forwarder function in the target compartment
// for the function the be exported.
if (!NewFunctionForwarder(cx, id, funObj, /* doclone = */ true, rval)) {
@ -302,12 +312,16 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV
return false;
}
// We have the forwarder function in the target compartment, now
// we have to add it to the target scope as a property.
if (!JS_DefinePropertyById(cx, targetScope, id, rval,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE))
return false;
// We have the forwarder function in the target compartment. If
// defineAs was set, we also need to define it as a property on
// the target.
if (!JSID_IS_VOID(options.defineAs)) {
if (!JS_DefinePropertyById(cx, targetScope, id, rval,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE)) {
return false;
}
}
}
// Finally we have to re-wrap the exported function back to the caller compartment.
@ -321,19 +335,19 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV
* Expected type of the arguments and the return value:
* function exportFunction(function funToExport,
* object targetScope,
* string name)
* [optional] object options)
*/
static bool
ExportFunction(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 3) {
JS_ReportError(cx, "Function requires at least 3 arguments");
if (args.length() < 2) {
JS_ReportError(cx, "Function requires at least 2 arguments");
return false;
}
return ExportFunction(cx, args[0], args[1],
args[2], args.rval());
RootedValue options(cx, args.length() > 2 ? args[2] : UndefinedValue());
return ExportFunction(cx, args[0], args[1], options, args.rval());
}
} /* namespace xpc */

View File

@ -3094,13 +3094,13 @@ nsXPCComponents_Utils::EvalInWindow(const nsAString &source, const Value &window
/* jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname); */
NS_IMETHODIMP
nsXPCComponents_Utils::ExportFunction(const Value &vfunction, const Value &vscope,
const Value &vname, JSContext *cx, Value *rval)
const Value &voptions, JSContext *cx, Value *rval)
{
RootedValue rfunction(cx, vfunction);
RootedValue rscope(cx, vscope);
RootedValue rname(cx, vname);
RootedValue roptions(cx, voptions);
RootedValue res(cx);
if (!xpc::ExportFunction(cx, rfunction, rscope, rname, &res))
if (!xpc::ExportFunction(cx, rfunction, rscope, roptions, &res))
return NS_ERROR_FAILURE;
*rval = res;
return NS_OK;

View File

@ -1790,7 +1790,7 @@ private:
rtTotal += amount; \
} while (0)
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JSMallocSizeOf)
MOZ_DEFINE_MALLOC_SIZE_OF(JSMallocSizeOf)
namespace xpc {
@ -2394,10 +2394,10 @@ ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats &rtStats,
} // namespace xpc
class JSMainRuntimeCompartmentsReporter MOZ_FINAL : public MemoryMultiReporter
class JSMainRuntimeCompartmentsReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
JSMainRuntimeCompartmentsReporter() {}
NS_DECL_ISUPPORTS
typedef js::Vector<nsCString, 0, js::SystemAllocPolicy> Paths;
@ -2436,7 +2436,9 @@ class JSMainRuntimeCompartmentsReporter MOZ_FINAL : public MemoryMultiReporter
}
};
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
NS_IMPL_ISUPPORTS1(JSMainRuntimeCompartmentsReporter, nsIMemoryReporter)
MOZ_DEFINE_MALLOC_SIZE_OF(OrphanMallocSizeOf)
namespace xpc {

View File

@ -720,7 +720,6 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // getGeneric
nullptr, // getProperty
nullptr, // getElement
nullptr, // getElementIfPresent
nullptr, // getSpecial
nullptr, // setGeneric
nullptr, // setProperty
@ -732,6 +731,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // deleteElement
nullptr, // deleteSpecial
nullptr, nullptr, // watch/unwatch
nullptr, // slice
XPC_WN_JSOp_Enumerate,
XPC_WN_JSOp_ThisObject,
}

View File

@ -981,7 +981,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* getGeneric */ \
nullptr, /* getProperty */ \
nullptr, /* getElement */ \
nullptr, /* getElementIfPresent */ \
nullptr, /* getSpecial */ \
nullptr, /* setGeneric */ \
nullptr, /* setProperty */ \
@ -993,6 +992,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* deleteElement */ \
nullptr, /* deleteSpecial */ \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* slice */ \
XPC_WN_JSOp_Enumerate, \
XPC_WN_JSOp_ThisObject, \
}
@ -1010,7 +1010,6 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* getGeneric */ \
nullptr, /* getProperty */ \
nullptr, /* getElement */ \
nullptr, /* getElementIfPresent */ \
nullptr, /* getSpecial */ \
nullptr, /* setGeneric */ \
nullptr, /* setProperty */ \
@ -1022,6 +1021,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* deleteElement */ \
nullptr, /* deleteSpecial */ \
nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* slice */ \
XPC_WN_JSOp_Enumerate, \
XPC_WN_JSOp_ThisObject, \
}
@ -3461,6 +3461,19 @@ public:
JS::RootedId defineAs;
};
class MOZ_STACK_CLASS ExportOptions : public OptionsBase {
public:
ExportOptions(JSContext *cx = xpc_GetSafeJSContext(),
JSObject* options = nullptr)
: OptionsBase(cx, options)
, defineAs(cx, JSID_VOID)
{ }
virtual bool Parse() { return ParseId("defineAs", &defineAs); };
JS::RootedId defineAs;
};
JSObject *
CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
JS::CompartmentOptions& aOptions);

View File

@ -40,6 +40,7 @@ support-files =
# bug 929498
skip-if = os == 'android'
[test_asmjs2.html]
[test_asmjs3.html]
[test_bug384632.html]
[test_bug390488.html]
[test_bug393269.html]

View File

@ -0,0 +1,67 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=941830
-->
<head>
<meta charset="utf-8">
<title>asm.js browser tests</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=941830">asm.js browser tests</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script>
var jsFuns = SpecialPowers.Cu.getJSTestingFunctions();
ok(jsFuns.isAsmJSCompilationAvailable());
var asmjsCode = "function f() { 'use asm';";
for (var i = 0; i < 1000; i++)
asmjsCode += "function g" + i + "() { return " + i + "}";
asmjsCode += "return g42 }";
ok(asmjsCode.length > 10000);
var workerCode = asmjsCode;
workerCode += "if (f()() !== 42) postMessage('fail'); else postMessage('ok');";
workerCode = 'var code = "' + workerCode + '"; eval(code); eval(code)';
var workerBlob = new Blob([workerCode], {type:"application/javascript"});
var mainCode = asmjsCode;
mainCode += "ok(jsFuns.isAsmJSModuleLoadedFromCache(f), 'f is a cache hit')\n";
mainCode += "var g42 = f();\n";
mainCode += "ok(jsFuns.isAsmJSFunction(g42), 'g42 is an asm.js function');\n";
mainCode += "ok(g42() === 42, 'g42 returns the correct result');\n";
mainCode += "SimpleTest.finish();\n";
var mainBlob = new Blob([mainCode], {type:"application/javascript"});
var w = new Worker(URL.createObjectURL(workerBlob));
var received = 0;
w.onmessage = function(e) {
switch (received) {
case 0:
ok(e.data === "ok", "Received first message");
received = 1;
break;
case 1:
ok(e.data === "ok", "Received second message");
received = 2;
var script = document.createElement('script');
script.src = URL.createObjectURL(mainBlob);
document.body.appendChild(script);
break;
default:
throw "Huh?";
}
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View File

@ -1,9 +1,9 @@
function run_test() {
var Cu = Components.utils;
var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true });
subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
xorigsb = new Cu.Sandbox("http://test.com");
var subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
var subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
var xorigsb = new Cu.Sandbox("http://test.com");
epsb.subsb = subsb;
epsb.xorigsb = xorigsb;
@ -32,7 +32,7 @@ function run_test() {
do_check_true(wasCalled);
wasCalled = false;
}
exportFunction(funToExport, subsb, "imported");
exportFunction(funToExport, subsb, { defineAs: "imported" });
}.toSource() + ")()", epsb);
subsb.xrayed = Cu.evalInSandbox("(" + function () {
@ -64,7 +64,7 @@ function run_test() {
// not subsume the principal of the target.
Cu.evalInSandbox("(" + function() {
try{
exportFunction(function(){}, this.xorigsb, "denied");
exportFunction(function() {}, this.xorigsb, { defineAs: "denied" });
do_check_true(false);
} catch (e) {
do_check_true(e.toString().indexOf('Permission denied') > -1);
@ -74,8 +74,8 @@ function run_test() {
// Let's create an object in the target scope and add privileged
// function to it as a property.
Cu.evalInSandbox("(" + function() {
var newContentObject = createObjectIn(subsb, {defineAs:"importedObject"});
exportFunction(funToExport, newContentObject, "privMethod");
var newContentObject = createObjectIn(subsb, { defineAs: "importedObject" });
exportFunction(funToExport, newContentObject, { defineAs: "privMethod" });
}.toSource() + ")()", epsb);
Cu.evalInSandbox("(" + function () {
@ -87,13 +87,27 @@ function run_test() {
}.toSource() + ")()", epsb);
// exportFunction and createObjectIn should be available from Cu too.
var newContentObject = Cu.createObjectIn(subsb, {defineAs:"importedObject2"});
var newContentObject = Cu.createObjectIn(subsb, { defineAs: "importedObject2" });
var wasCalled = false;
Cu.exportFunction(function(arg){wasCalled = arg.wasCalled;}, newContentObject, "privMethod");
Cu.exportFunction(function(arg) { wasCalled = arg.wasCalled; },
newContentObject, { defineAs: "privMethod" });
Cu.evalInSandbox("(" + function () {
importedObject2.privMethod({wasCalled: true});
}.toSource() + ")()", subsb);
// 3rd argument of exportFunction should be optional.
Cu.evalInSandbox("(" + function() {
subsb.imported2 = exportFunction(funToExport, subsb);
}.toSource() + ")()", epsb);
Cu.evalInSandbox("(" + function () {
imported2(42, tobecloned, native, mixed);
}.toSource() + ")()", subsb);
Cu.evalInSandbox("(" + function() {
checkIfCalled();
}.toSource() + ")()", epsb);
do_check_true(wasCalled, true);
}

View File

@ -647,7 +647,8 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
// Perhaps the document containing this frame currently has no presentation?
if (lm && lm->GetBackendType() == LAYERS_CLIENT) {
*aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
*aTextureFactoryIdentifier =
static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
} else {
*aTextureFactoryIdentifier = TextureFactoryIdentifier();
}

View File

@ -130,6 +130,23 @@ struct IsPointer : FalseType {};
template<typename T>
struct IsPointer<T*> : TrueType {};
/**
* IsLvalueReference determines whether a type is an lvalue reference.
*
* mozilla::IsLvalueReference<struct S*>::value is false;
* mozilla::IsLvalueReference<int**>::value is false;
* mozilla::IsLvalueReference<void (*)(void)>::value is false;
* mozilla::IsLvalueReference<int>::value is false;
* mozilla::IsLvalueReference<struct S>::value is false;
* mozilla::IsLvalueReference<struct S*&>::value is true;
* mozilla::IsLvalueReference<struct S&&>::value is false.
*/
template<typename T>
struct IsLvalueReference : FalseType {};
template<typename T>
struct IsLvalueReference<T&> : TrueType {};
namespace detail {
// __is_enum is a supported extension across all of our supported compilers.
@ -424,16 +441,6 @@ struct IsConvertible
: IntegralConstant<bool, detail::ConvertibleTester<From, To>::value>
{};
/**
* Is IsLvalueReference<T> is true if its template param is T& and is false if
* its type is T or T&&.
*/
template<typename T>
struct IsLvalueReference : FalseType {};
template<typename T>
struct IsLvalueReference<T&> : TrueType {};
/* 20.9.7 Transformations between types [meta.trans] */
/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */

View File

@ -223,13 +223,11 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO
return n;
}
class PreferenceServiceReporter MOZ_FINAL : public MemoryMultiReporter
class PreferenceServiceReporter MOZ_FINAL : public nsIMemoryReporter
{
public:
PreferenceServiceReporter() {}
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
nsISupports* aData);
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
protected:
static const uint32_t kSuspectReferentCount = 1000;
@ -238,6 +236,8 @@ protected:
void* aClosure);
};
NS_IMPL_ISUPPORTS1(PreferenceServiceReporter, nsIMemoryReporter)
struct PreferencesReferentCount {
PreferencesReferentCount() : numStrong(0), numWeakAlive(0), numWeakDead(0) {}
size_t numStrong;
@ -285,6 +285,8 @@ PreferenceServiceReporter::CountReferents(PrefCallback* aKey,
return PL_DHASH_NEXT;
}
MOZ_DEFINE_MALLOC_SIZE_OF(PreferenceServiceMallocSizeOf)
NS_IMETHODIMP
PreferenceServiceReporter::CollectReports(nsIMemoryReporterCallback* aCb,
nsISupports* aClosure)
@ -300,7 +302,7 @@ PreferenceServiceReporter::CollectReports(nsIMemoryReporterCallback* aCb,
REPORT(NS_LITERAL_CSTRING("explicit/preferences"),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
Preferences::SizeOfIncludingThisAndOtherStuff(MallocSizeOf),
Preferences::SizeOfIncludingThisAndOtherStuff(PreferenceServiceMallocSizeOf),
"Memory used by the preferences system.");
nsPrefBranch* rootBranch =

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