mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central
This commit is contained in:
commit
de91ddd9df
@ -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.
|
||||
|
@ -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 };
|
||||
}
|
||||
|
27
configure.in
27
configure.in
@ -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 ========================================================
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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]
|
||||
|
77
content/svg/content/test/test_lengthParsing.html
Normal file
77
content/svg/content/test/test_lengthParsing.html
Normal 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>
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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!");
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -60,4 +60,6 @@ LOCAL_INCLUDES += [
|
||||
'/xpcom/build',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'gklayout'
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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',
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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() +
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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!");
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
37
js/src/jit-test/tests/arrays/slice.js
Normal file
37
js/src/jit-test/tests/arrays/slice.js
Normal 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);
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 *
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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 */ \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
|
67
js/xpconnect/tests/mochitest/test_asmjs3.html
Normal file
67
js/xpconnect/tests/mochitest/test_asmjs3.html
Normal 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>
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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] */
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user