merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-07-08 11:58:46 +02:00
Родитель 75e7b5bab2 7220b22c54
Коммит 838f21f656
179 изменённых файлов: 1169 добавлений и 9008 удалений

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

@ -306,7 +306,6 @@ def old_configure_options(*options):
'--with-nss-prefix', '--with-nss-prefix',
'--with-pthreads', '--with-pthreads',
'--with-qemu-exe', '--with-qemu-exe',
'--with-qtdir',
'--with-servo', '--with-servo',
'--with-sixgill', '--with-sixgill',
'--with-soft-float', '--with-soft-float',

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

@ -244,7 +244,7 @@ using mozilla::devtools::DeserializedNode;
using mozilla::devtools::DeserializedStackFrame; using mozilla::devtools::DeserializedStackFrame;
template<> template<>
struct Concrete<DeserializedNode> : public Base class Concrete<DeserializedNode> : public Base
{ {
protected: protected:
explicit Concrete(DeserializedNode* ptr) : Base(ptr) { } explicit Concrete(DeserializedNode* ptr) : Base(ptr) { }
@ -253,8 +253,6 @@ protected:
} }
public: public:
static const char16_t concreteTypeName[];
static void construct(void* storage, DeserializedNode* ptr) { static void construct(void* storage, DeserializedNode* ptr) {
new (storage) Concrete(ptr); new (storage) Concrete(ptr);
} }
@ -273,6 +271,8 @@ public:
// We ignore the `bool wantNames` parameter because we can't control whether // We ignore the `bool wantNames` parameter because we can't control whether
// the core dump was serialized with edge names or not. // the core dump was serialized with edge names or not.
js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override; js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override;
static const char16_t concreteTypeName[];
}; };
template<> template<>

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

@ -46,7 +46,7 @@ class HeapSnapshot final : public nsISupports
friend struct DeserializedNode; friend struct DeserializedNode;
friend struct DeserializedEdge; friend struct DeserializedEdge;
friend struct DeserializedStackFrame; friend struct DeserializedStackFrame;
friend struct JS::ubi::Concrete<JS::ubi::DeserializedNode>; friend class JS::ubi::Concrete<JS::ubi::DeserializedNode>;
explicit HeapSnapshot(JSContext* cx, nsISupports* aParent) explicit HeapSnapshot(JSContext* cx, nsISupports* aParent)
: timestamp(Nothing()) : timestamp(Nothing())

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

@ -23,6 +23,7 @@ using mozilla::dom::DOMRequestService;
using mozilla::dom::DOMCursor; using mozilla::dom::DOMCursor;
using mozilla::dom::Promise; using mozilla::dom::Promise;
using mozilla::dom::AutoJSAPI; using mozilla::dom::AutoJSAPI;
using mozilla::dom::GetJSRuntime;
DOMRequest::DOMRequest(nsPIDOMWindowInner* aWindow) DOMRequest::DOMRequest(nsPIDOMWindowInner* aWindow)
: DOMEventTargetHelper(aWindow) : DOMEventTargetHelper(aWindow)
@ -301,7 +302,7 @@ class FireSuccessAsyncTask : public mozilla::Runnable
FireSuccessAsyncTask(DOMRequest* aRequest, FireSuccessAsyncTask(DOMRequest* aRequest,
const JS::Value& aResult) : const JS::Value& aResult) :
mReq(aRequest), mReq(aRequest),
mResult(nsContentUtils::RootingCxForThread(), aResult) mResult(GetJSRuntime(), aResult)
{ {
} }

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

@ -7,6 +7,7 @@
#include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ThreadLocal.h" #include "mozilla/ThreadLocal.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "jsapi.h" #include "jsapi.h"
#include "xpcpublic.h" #include "xpcpublic.h"
@ -284,6 +285,20 @@ IsJSAPIActive()
return topEntry && !topEntry->NoJSAPI(); return topEntry && !topEntry->NoJSAPI();
} }
namespace danger {
JSContext*
GetJSContext()
{
return CycleCollectedJSRuntime::Get()->Context();
}
} // namespace danger
JSRuntime*
GetJSRuntime()
{
return CycleCollectedJSRuntime::Get()->Runtime();
}
AutoJSAPI::AutoJSAPI() AutoJSAPI::AutoJSAPI()
: ScriptSettingsStackEntry(nullptr, eJSAPI) : ScriptSettingsStackEntry(nullptr, eJSAPI)
, mCx(nullptr) , mCx(nullptr)
@ -325,6 +340,7 @@ AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
JSContext* aCx, bool aIsMainThread) JSContext* aCx, bool aIsMainThread)
{ {
MOZ_ASSERT(aCx); MOZ_ASSERT(aCx);
MOZ_ASSERT(aCx == danger::GetJSContext());
MOZ_ASSERT(aIsMainThread == NS_IsMainThread()); MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
MOZ_ASSERT(bool(aGlobalObject) == bool(aGlobal)); MOZ_ASSERT(bool(aGlobalObject) == bool(aGlobal));
MOZ_ASSERT_IF(aGlobalObject, aGlobalObject->GetGlobalJSObject() == aGlobal); MOZ_ASSERT_IF(aGlobalObject, aGlobalObject->GetGlobalJSObject() == aGlobal);
@ -418,18 +434,16 @@ AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject, AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
bool aIsMainThread, bool aIsMainThread,
JSContext* aCx,
Type aType) Type aType)
: ScriptSettingsStackEntry(aGlobalObject, aType) : ScriptSettingsStackEntry(aGlobalObject, aType)
, mIsMainThread(aIsMainThread) , mIsMainThread(aIsMainThread)
{ {
MOZ_ASSERT(aGlobalObject); MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global"); MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global");
MOZ_ASSERT(aCx);
MOZ_ASSERT(aIsMainThread == NS_IsMainThread()); MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(), aCx, InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(),
aIsMainThread); danger::GetJSContext(), aIsMainThread);
} }
void void
@ -438,8 +452,7 @@ AutoJSAPI::Init()
MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once"); MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
InitInternal(/* aGlobalObject */ nullptr, /* aGlobal */ nullptr, InitInternal(/* aGlobalObject */ nullptr, /* aGlobal */ nullptr,
nsContentUtils::GetDefaultJSContextForThread(), danger::GetJSContext(), NS_IsMainThread());
NS_IsMainThread());
} }
bool bool
@ -464,7 +477,7 @@ AutoJSAPI::Init(nsIGlobalObject* aGlobalObject, JSContext* aCx)
bool bool
AutoJSAPI::Init(nsIGlobalObject* aGlobalObject) AutoJSAPI::Init(nsIGlobalObject* aGlobalObject)
{ {
return Init(aGlobalObject, nsContentUtils::GetDefaultJSContextForThread()); return Init(aGlobalObject, danger::GetJSContext());
} }
bool bool
@ -634,16 +647,11 @@ AutoJSAPI::IsStackTop() const
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
const char *aReason, const char *aReason,
bool aIsMainThread, bool aIsMainThread)
JSContext* aCx) : AutoJSAPI(aGlobalObject, aIsMainThread, eEntryScript)
: AutoJSAPI(aGlobalObject, aIsMainThread,
aCx ? aCx : nsContentUtils::GetSafeJSContext(),
eEntryScript)
, mWebIDLCallerPrincipal(nullptr) , mWebIDLCallerPrincipal(nullptr)
{ {
MOZ_ASSERT(aGlobalObject); MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == nsContentUtils::GetSafeJSContext());
if (aIsMainThread && gRunToCompletionListeners > 0) { if (aIsMainThread && gRunToCompletionListeners > 0) {
mDocShellEntryMonitor.emplace(cx(), aReason); mDocShellEntryMonitor.emplace(cx(), aReason);
@ -652,9 +660,8 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
AutoEntryScript::AutoEntryScript(JSObject* aObject, AutoEntryScript::AutoEntryScript(JSObject* aObject,
const char *aReason, const char *aReason,
bool aIsMainThread, bool aIsMainThread)
JSContext* aCx) : AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread)
: AutoEntryScript(xpc::NativeGlobal(aObject), aReason, aIsMainThread, aCx)
{ {
} }
@ -776,7 +783,7 @@ AutoJSContext::AutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
if (IsJSAPIActive()) { if (IsJSAPIActive()) {
mCx = nsContentUtils::GetSafeJSContext(); mCx = danger::GetJSContext();
} else { } else {
mJSAPI.Init(); mJSAPI.Init();
mCx = mJSAPI.cx(); mCx = mJSAPI.cx();

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

@ -127,6 +127,17 @@ inline JSObject& IncumbentJSGlobal()
// AutoJSAPI or AutoEntryScript to get yourself a properly set up JSContext. // AutoJSAPI or AutoEntryScript to get yourself a properly set up JSContext.
bool IsJSAPIActive(); bool IsJSAPIActive();
namespace danger {
// Get the JSContext for this thread. This is in the "danger" namespace because
// we generally want people using AutoJSAPI instead, unless they really know
// what they're doing.
JSContext* GetJSContext();
} // namespace danger
JSRuntime* GetJSRuntime();
class ScriptSettingsStack; class ScriptSettingsStack;
class ScriptSettingsStackEntry { class ScriptSettingsStackEntry {
friend class ScriptSettingsStack; friend class ScriptSettingsStack;
@ -278,13 +289,9 @@ public:
} }
protected: protected:
// Protected constructor, allowing subclasses to specify a particular cx to // Protected constructor for subclasses. This constructor initialises the
// be used. This constructor initialises the AutoJSAPI, so Init must NOT be // AutoJSAPI, so Init must NOT be called on subclasses that use this.
// called on subclasses that use this. AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, Type aType);
// If aGlobalObject, its associated JS global or aCx are null this will cause
// an assertion, as will setting aIsMainThread incorrectly.
AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx,
Type aType);
private: private:
mozilla::Maybe<JSAutoRequest> mAutoRequest; mozilla::Maybe<JSAutoRequest> mAutoRequest;
@ -313,15 +320,11 @@ class MOZ_STACK_CLASS AutoEntryScript : public AutoJSAPI {
public: public:
AutoEntryScript(nsIGlobalObject* aGlobalObject, AutoEntryScript(nsIGlobalObject* aGlobalObject,
const char *aReason, const char *aReason,
bool aIsMainThread = NS_IsMainThread(), bool aIsMainThread = NS_IsMainThread());
// Note: aCx is mandatory off-main-thread.
JSContext* aCx = nullptr);
AutoEntryScript(JSObject* aObject, // Any object from the relevant global AutoEntryScript(JSObject* aObject, // Any object from the relevant global
const char *aReason, const char *aReason,
bool aIsMainThread = NS_IsMainThread(), bool aIsMainThread = NS_IsMainThread());
// Note: aCx is mandatory off-main-thread.
JSContext* aCx = nullptr);
~AutoEntryScript(); ~AutoEntryScript();

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

@ -5546,28 +5546,7 @@ nsContentUtils::GetCurrentJSContext()
if (!IsJSAPIActive()) { if (!IsJSAPIActive()) {
return nullptr; return nullptr;
} }
return GetSafeJSContext(); return danger::GetJSContext();
}
/* static */
JSContext *
nsContentUtils::GetSafeJSContext()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsInitialized());
return sXPConnect->GetSafeJSContext();
}
/* static */
JSContext *
nsContentUtils::GetDefaultJSContextForThread()
{
MOZ_ASSERT(IsInitialized());
if (MOZ_LIKELY(NS_IsMainThread())) {
return GetSafeJSContext();
} else {
return workers::GetCurrentThreadJSContext();
}
} }
/* static */ /* static */

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

@ -1722,11 +1722,10 @@ public:
nsresult* aRv); nsresult* aRv);
static JSContext *GetCurrentJSContext(); static JSContext *GetCurrentJSContext();
static JSContext *GetSafeJSContext();
static JSContext *GetCurrentJSContextForThread(); static JSContext *GetCurrentJSContextForThread();
static JSContext *GetDefaultJSContextForThread(); inline static JSContext *RootingCx() {
inline static JSContext *RootingCx() { return GetSafeJSContext(); } return mozilla::dom::danger::GetJSContext();
inline static JSContext *RootingCxForThread() { return GetDefaultJSContextForThread(); } }
/** /**
* Case insensitive comparison between two strings. However it only ignores * Case insensitive comparison between two strings. However it only ignores

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

@ -2093,11 +2093,8 @@ nsFrameLoader::MaybeCreateDocShell()
} }
DocShellOriginAttributes attrs; DocShellOriginAttributes attrs;
if (docShell->ItemType() == mDocShell->ItemType()) {
if (!mOwnerContent->IsXULElement(nsGkAtoms::browser)) { attrs = nsDocShell::Cast(docShell)->GetOriginAttributes();
nsCOMPtr<nsIPrincipal> parentPrin = doc->NodePrincipal();
PrincipalOriginAttributes poa = BasePrincipal::Cast(parentPrin)->OriginAttributesRef();
attrs.InheritFromDocToChildDocShell(poa);
} }
if (OwnerIsAppFrame()) { if (OwnerIsAppFrame()) {

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

@ -3300,12 +3300,6 @@ nsGlobalWindow::WillHandleEvent(EventChainPostVisitor& aVisitor)
return NS_OK; return NS_OK;
} }
JSContext*
nsGlobalWindow::GetJSContextForEventHandlers()
{
return nullptr;
}
nsresult nsresult
nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor) nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
{ {

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

@ -117,7 +117,6 @@ public:
} }
using mozilla::DOMEventTargetHelper::AddEventListener; using mozilla::DOMEventTargetHelper::AddEventListener;
virtual JSContext* GetJSContextForEventHandlers() override { return nsContentUtils::GetSafeJSContext(); }
virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; } virtual nsIPrincipal* GetPrincipal() override { return mPrincipal; }
void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope); void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
void FireUnloadEvent(); void FireUnloadEvent();

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

@ -247,8 +247,8 @@ FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win,
return nullptr; return nullptr;
} }
JSContext* cx = nsContentUtils::RootingCxForThread(); JSRuntime* rt = GetJSRuntime();
JS::RootedObject exceptionObject(cx, &exceptionValue.toObject()); JS::RootedObject exceptionObject(rt, &exceptionValue.toObject());
JSObject* stackObject = ExceptionStackOrNull(exceptionObject); JSObject* stackObject = ExceptionStackOrNull(exceptionObject);
if (stackObject) { if (stackObject) {
return stackObject; return stackObject;
@ -269,7 +269,7 @@ FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win,
if (!stack) { if (!stack) {
return nullptr; return nullptr;
} }
JS::RootedValue value(cx); JS::RootedValue value(rt);
stack->GetNativeSavedFrame(&value); stack->GetNativeSavedFrame(&value);
if (value.isObject()) { if (value.isObject()) {
return &value.toObject(); return &value.toObject();

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

@ -367,8 +367,8 @@ nsJSUtils::ResetTimeZone()
bool nsAutoJSString::init(const JS::Value &v) bool nsAutoJSString::init(const JS::Value &v)
{ {
JSContext* cx = nsContentUtils::RootingCxForThread(); JSContext* cx = nsContentUtils::RootingCx();
if (!init(nsContentUtils::RootingCxForThread(), v)) { if (!init(cx, v)) {
JS_ClearPendingException(cx); JS_ClearPendingException(cx);
return false; return false;
} }

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

@ -359,7 +359,7 @@ void
ErrorResult::ClearUnionData() ErrorResult::ClearUnionData()
{ {
if (IsJSException()) { if (IsJSException()) {
JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); JSContext* cx = nsContentUtils::RootingCx();
MOZ_ASSERT(cx); MOZ_ASSERT(cx);
mJSException.setUndefined(); mJSException.setUndefined();
js::RemoveRawValueRoot(cx, &mJSException); js::RemoveRawValueRoot(cx, &mJSException);
@ -398,7 +398,7 @@ ErrorResult::operator=(ErrorResult&& aRHS)
mMessage = aRHS.mMessage; mMessage = aRHS.mMessage;
aRHS.mMessage = nullptr; aRHS.mMessage = nullptr;
} else if (aRHS.IsJSException()) { } else if (aRHS.IsJSException()) {
JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); JSContext* cx = nsContentUtils::RootingCx();
MOZ_ASSERT(cx); MOZ_ASSERT(cx);
mJSException.setUndefined(); mJSException.setUndefined();
if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) { if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) {
@ -453,7 +453,7 @@ ErrorResult::CloneTo(ErrorResult& aRv) const
#ifdef DEBUG #ifdef DEBUG
aRv.mUnionState = HasJSException; aRv.mUnionState = HasJSException;
#endif #endif
JSContext* cx = nsContentUtils::RootingCxForThread(); JSContext* cx = nsContentUtils::RootingCx();
JS::Rooted<JS::Value> exception(cx, mJSException); JS::Rooted<JS::Value> exception(cx, mJSException);
aRv.ThrowJSException(cx, exception); aRv.ThrowJSException(cx, exception);
} }
@ -2350,7 +2350,7 @@ ConstructJSImplementation(const char* aContractId,
do_QueryInterface(implISupports); do_QueryInterface(implISupports);
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal); nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
if (gpi) { if (gpi) {
JS::Rooted<JS::Value> initReturn(nsContentUtils::RootingCxForThread()); JS::Rooted<JS::Value> initReturn(GetJSRuntime());
rv = gpi->Init(window, &initReturn); rv = gpi->Init(window, &initReturn);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
aRv.Throw(rv); aRv.Throw(rv);

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

@ -8,26 +8,20 @@
# #
# The WebIDL interfaces are defined in dom/webidl. For interfaces requiring # The WebIDL interfaces are defined in dom/webidl. For interfaces requiring
# special handling, there are corresponding entries in the configuration table # special handling, there are corresponding entries in the configuration table
# below. The configuration table maps each interface name to a |descriptor| or # below. The configuration table maps each interface name to a |descriptor|.
# list of |descriptor|s.
# #
# Valid fields for all descriptors: # Valid fields for all descriptors:
# * nativeType - The native type (concrete class or XPCOM interface) that # * nativeType - The native type (concrete class or XPCOM interface) that
# instances of this interface will unwrap to. If not # instances of this interface will unwrap to. If not
# specified, defaults to 'nsIDOM' followed by the interface # specified, defaults to 'nsIDOM' followed by the interface
# name for external interfaces, # name for external interfaces and
# 'mozilla::dom::workers::InterfaceName' for worker # 'mozilla::dom::InterfaceName' for everything else.
# non-callback interfaces, and 'mozilla::dom::InterfaceName'
# for everything else.
# * headerFile - The file in which the nativeType is declared (defaults # * headerFile - The file in which the nativeType is declared (defaults
# to an educated guess). # to an educated guess).
# * concrete - Indicates whether there exist JS objects with this interface as # * concrete - Indicates whether there exist JS objects with this interface as
# their primary interface (and hence whose prototype is this # their primary interface (and hence whose prototype is this
# interface's prototype object). Always False for callback # interface's prototype object). Always False for callback
# interfaces. Defaults to True otherwise. # interfaces. Defaults to True otherwise.
# * workers - Indicates whether the descriptor is intended to be used solely
# for worker threads (defaults to false). If true the interface
# will not be made available on the main thread.
# * notflattened - The native type does not have nsIClassInfo, so when # * notflattened - The native type does not have nsIClassInfo, so when
# wrapping it the right IID needs to be passed in. # wrapping it the right IID needs to be passed in.
# Only relevant for callback interfaces. # Only relevant for callback interfaces.
@ -41,13 +35,7 @@
# not can only be returned from a limited set of methods, # not can only be returned from a limited set of methods,
# cannot be prefable, and must ensure that they disallow # cannot be prefable, and must ensure that they disallow
# XPConnect wrapping. Always false for callback interfaces. # XPConnect wrapping. Always false for callback interfaces.
# Always true for worker descriptors for non-callback # Defaults to true for non-callback descriptors.
# interfaces. Defaults to true for non-worker non-callback
# descriptors.
#
# A non-worker descriptor can have 'wantsXrays': False specified if it
# should not have Xray hooks generated. Make sure to have someone
# familiar with Xrays review any use of this!
# #
# The following fields are either a string, an array (defaults to an empty # The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and # array) or a dictionary with three possible keys (all, getterOnly and
@ -56,24 +44,8 @@
# * implicitJSContext - attributes and methods specified in the .webidl file # * implicitJSContext - attributes and methods specified in the .webidl file
# that require a JSContext as the first argument # that require a JSContext as the first argument
# #
# A descriptor can also have 'skipGen': True specified if it should be skipped # The value for an interface is a dictionary which specifies the
# when deciding what header includes to generate and should never have an # descriptor to use when generating that interface's binding.
# implementation generated for it. This is only needed in special cases like
# worker descriptors for objects that will never actually appear in workers.
#
# The value for an interface can be a list or a dictionary, which affects which
# bindings are generated for that interface.
# - If the value for the interface is just a record, then a single binding for
# will be generated using those settings.
# - If it is a list with a single record which has 'workers':True, then that
# record will be used to generate bindings for workers, plus the default
# settings will be used to generate bindings for the main thread.
# - If it is a list with two records, then one should have 'workers':True,
# and the other should have 'workers':False (or left unset). These will
# be used to generate bindings for workers and for mainthread, as you would
# expect.
# Nothing else is allowed. If you have a list with a single 'workers':False
# entry, just make it not a list.
DOMInterfaces = { DOMInterfaces = {
@ -425,11 +397,6 @@ DOMInterfaces = {
'nativeType': 'nsDOMTokenList', 'nativeType': 'nsDOMTokenList',
}, },
'DummyInterface': {
'skipGen': True,
'register': False,
},
'DynamicsCompressorNode': { 'DynamicsCompressorNode': {
'binaryNames': { 'binaryNames': {
'release': 'getRelease' 'release': 'getRelease'

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

@ -134,10 +134,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
return; return;
} }
// Off the main thread, AutoEntryScript expects us to pass a JSContext. mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread);
mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread,
mIsMainThread ? nullptr
: workers::GetCurrentThreadJSContext());
mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal); mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull(); nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
if (incumbent) { if (incumbent) {

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

@ -41,7 +41,7 @@ def toStringBool(arg):
def toBindingNamespace(arg): def toBindingNamespace(arg):
return re.sub("((_workers)?$)", "Binding\\1", arg) return arg + "Binding"
def isTypeCopyConstructible(type): def isTypeCopyConstructible(type):
@ -533,8 +533,6 @@ def PrototypeIDAndDepth(descriptor):
prototypeID = "prototypes::id::" prototypeID = "prototypes::id::"
if descriptor.interface.hasInterfacePrototypeObject(): if descriptor.interface.hasInterfacePrototypeObject():
prototypeID += descriptor.interface.identifier.name prototypeID += descriptor.interface.identifier.name
if descriptor.workers:
prototypeID += "_workers"
depth = "PrototypeTraits<%s>::Depth" % prototypeID depth = "PrototypeTraits<%s>::Depth" % prototypeID
else: else:
prototypeID += "_ID_Count" prototypeID += "_ID_Count"
@ -980,16 +978,6 @@ class CGIncludeGuard(CGWrapper):
declarePost='\n#endif // %s\n' % define) declarePost='\n#endif // %s\n' % define)
def getRelevantProviders(descriptor, config):
if descriptor is not None:
return [descriptor]
# Do both the non-worker and worker versions
return [
config.getDescriptorProvider(False),
config.getDescriptorProvider(True)
]
class CGHeaders(CGWrapper): class CGHeaders(CGWrapper):
""" """
Generates the appropriate include statements. Generates the appropriate include statements.
@ -1052,12 +1040,11 @@ class CGHeaders(CGWrapper):
bindingHeaders = set() bindingHeaders = set()
declareIncludes = set(declareIncludes) declareIncludes = set(declareIncludes)
def addHeadersForType((t, descriptor, dictionary)): def addHeadersForType((t, dictionary)):
""" """
Add the relevant headers for this type. We use descriptor and Add the relevant headers for this type. We use dictionary, if
dictionary, if passed, to decide what to do with interface types. passed, to decide what to do with interface types.
""" """
assert not descriptor or not dictionary
# Dictionaries have members that need to be actually # Dictionaries have members that need to be actually
# declared, not just forward-declared. # declared, not just forward-declared.
if dictionary: if dictionary:
@ -1088,22 +1075,20 @@ class CGHeaders(CGWrapper):
headerSet = declareIncludes headerSet = declareIncludes
headerSet.add("mozilla/dom/TypedArray.h") headerSet.add("mozilla/dom/TypedArray.h")
else: else:
providers = getRelevantProviders(descriptor, config) try:
for p in providers: typeDesc = config.getDescriptor(unrolled.inner.identifier.name)
try: except NoSuchDescriptorError:
typeDesc = p.getDescriptor(unrolled.inner.identifier.name) return
except NoSuchDescriptorError: # Dictionaries with interface members rely on the
continue # actual class definition of that interface member
# Dictionaries with interface members rely on the # being visible in the binding header, because they
# actual class definition of that interface member # store them in RefPtr and have inline
# being visible in the binding header, because they # constructors/destructors.
# store them in RefPtr and have inline #
# constructors/destructors. # XXXbz maybe dictionaries with interface members
# # should just have out-of-line constructors and
# XXXbz maybe dictionaries with interface members # destructors?
# should just have out-of-line constructors and headerSet.add(typeDesc.headerFile)
# destructors?
headerSet.add(typeDesc.headerFile)
elif unrolled.isDictionary(): elif unrolled.isDictionary():
headerSet.add(self.getDeclarationFilename(unrolled.inner)) headerSet.add(self.getDeclarationFilename(unrolled.inner))
elif unrolled.isCallback(): elif unrolled.isCallback():
@ -1124,7 +1109,7 @@ class CGHeaders(CGWrapper):
bindingHeaders.add("mozilla/dom/MozMap.h") bindingHeaders.add("mozilla/dom/MozMap.h")
# Also add headers for the type the MozMap is # Also add headers for the type the MozMap is
# parametrized over, if needed. # parametrized over, if needed.
addHeadersForType((t.inner, descriptor, dictionary)) addHeadersForType((t.inner, dictionary))
map(addHeadersForType, map(addHeadersForType,
getAllTypes(descriptors + callbackDescriptors, dictionaries, getAllTypes(descriptors + callbackDescriptors, dictionaries,
@ -1174,10 +1159,10 @@ class CGHeaders(CGWrapper):
# convenience functions # convenience functions
if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType(): if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType, addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None)) None))
if desc.interface.maplikeOrSetlikeOrIterable.hasValueType(): if desc.interface.maplikeOrSetlikeOrIterable.hasValueType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType, addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
desc, None)) None))
for d in dictionaries: for d in dictionaries:
if d.parent: if d.parent:
@ -1258,19 +1243,17 @@ def SortedDictValues(d):
def UnionsForFile(config, webIDLFile): def UnionsForFile(config, webIDLFile):
""" """
Returns a list of tuples each containing two elements (type and descriptor) Returns a list of union types for all union types that are only used in
for all union types that are only used in webIDLFile. If webIDLFile is None webIDLFile. If webIDLFile is None this will return the list of tuples for
this will return the list of tuples for union types that are used in more union types that are used in more than one WebIDL file.
than one WebIDL file.
""" """
return config.unionsPerFilename.get(webIDLFile, []) return config.unionsPerFilename.get(webIDLFile, [])
def UnionTypes(unionTypes, config): def UnionTypes(unionTypes, config):
""" """
The unionTypes argument should be a list of tuples, each containing two The unionTypes argument should be a list of union types. This is typically
elements: a union type and a descriptor. This is typically the list the list generated by UnionsForFile.
generated by UnionsForFile.
Returns a tuple containing a set of header filenames to include in Returns a tuple containing a set of header filenames to include in
the header for the types in unionTypes, a set of header filenames to the header for the types in unionTypes, a set of header filenames to
@ -1288,10 +1271,9 @@ def UnionTypes(unionTypes, config):
traverseMethods = dict() traverseMethods = dict()
unlinkMethods = dict() unlinkMethods = dict()
for (t, descriptor) in unionTypes: for t in unionTypes:
name = str(t) name = str(t)
if name not in unionStructs: if name not in unionStructs:
providers = getRelevantProviders(descriptor, config)
unionStructs[name] = t unionStructs[name] = t
def addHeadersForType(f): def addHeadersForType(f):
@ -1304,23 +1286,22 @@ def UnionTypes(unionTypes, config):
headers.add("jsfriendapi.h") headers.add("jsfriendapi.h")
headers.add("mozilla/dom/TypedArray.h") headers.add("mozilla/dom/TypedArray.h")
else: else:
for p in providers: try:
try: typeDesc = config.getDescriptor(f.inner.identifier.name)
typeDesc = p.getDescriptor(f.inner.identifier.name) except NoSuchDescriptorError:
except NoSuchDescriptorError: return
continue if typeDesc.interface.isCallback() or isSequence:
if typeDesc.interface.isCallback() or isSequence: # Callback interfaces always use strong refs, so
# Callback interfaces always use strong refs, so # we need to include the right header to be able
# we need to include the right header to be able # to Release() in our inlined code.
# to Release() in our inlined code. #
# # Similarly, sequences always contain strong
# Similarly, sequences always contain strong # refs, so we'll need the header to handler
# refs, so we'll need the header to handler # those.
# those. headers.add(typeDesc.headerFile)
headers.add(typeDesc.headerFile) else:
else: declarations.add((typeDesc.nativeType, False))
declarations.add((typeDesc.nativeType, False)) implheaders.add(typeDesc.headerFile)
implheaders.add(typeDesc.headerFile)
elif f.isDictionary(): elif f.isDictionary():
# For a dictionary, we need to see its declaration in # For a dictionary, we need to see its declaration in
# UnionTypes.h so we have its sizeof and know how big to # UnionTypes.h so we have its sizeof and know how big to
@ -1375,26 +1356,23 @@ def UnionConversions(unionTypes, config):
headers = set() headers = set()
unionConversions = dict() unionConversions = dict()
for (t, descriptor) in unionTypes: for t in unionTypes:
name = str(t) name = str(t)
if name not in unionConversions: if name not in unionConversions:
providers = getRelevantProviders(descriptor, config) unionConversions[name] = CGUnionConversionStruct(t, config)
unionConversions[name] = CGUnionConversionStruct(t, providers[0])
def addHeadersForType(f, providers): def addHeadersForType(f):
f = f.unroll() f = f.unroll()
if f.isInterface(): if f.isInterface():
if f.isSpiderMonkeyInterface(): if f.isSpiderMonkeyInterface():
headers.add("jsfriendapi.h") headers.add("jsfriendapi.h")
headers.add("mozilla/dom/TypedArray.h") headers.add("mozilla/dom/TypedArray.h")
elif f.inner.isExternal(): elif f.inner.isExternal():
providers = getRelevantProviders(descriptor, config) try:
for p in providers: typeDesc = config.getDescriptor(f.inner.identifier.name)
try: except NoSuchDescriptorError:
typeDesc = p.getDescriptor(f.inner.identifier.name) return
except NoSuchDescriptorError: headers.add(typeDesc.headerFile)
continue
headers.add(typeDesc.headerFile)
else: else:
headers.add(CGHeaders.getDeclarationFilename(f.inner)) headers.add(CGHeaders.getDeclarationFilename(f.inner))
elif f.isDictionary(): elif f.isDictionary():
@ -1404,14 +1382,14 @@ def UnionConversions(unionTypes, config):
elif f.isMozMap(): elif f.isMozMap():
headers.add("mozilla/dom/MozMap.h") headers.add("mozilla/dom/MozMap.h")
# And the internal type of the MozMap # And the internal type of the MozMap
addHeadersForType(f.inner, providers) addHeadersForType(f.inner)
# We plan to include UnionTypes.h no matter what, so it's # We plan to include UnionTypes.h no matter what, so it's
# OK if we throw it into the set here. # OK if we throw it into the set here.
headers.add(CGHeaders.getUnionDeclarationFilename(config, t)) headers.add(CGHeaders.getUnionDeclarationFilename(config, t))
for f in t.flatMemberTypes: for f in t.flatMemberTypes:
addHeadersForType(f, providers) addHeadersForType(f)
return (headers, return (headers,
CGWrapper(CGList(SortedDictValues(unionConversions), "\n"), CGWrapper(CGList(SortedDictValues(unionConversions), "\n"),
@ -2032,24 +2010,8 @@ class PropertyDefiner:
@staticmethod @staticmethod
def getControllingCondition(interfaceMember, descriptor): def getControllingCondition(interfaceMember, descriptor):
# We do a slightly complicated thing for exposure sets to deal nicely
# with the situation of an [Exposed=Window] thing on an interface
# exposed in workers that has a worker-specific descriptor. In that
# situation, we already skip generation of the member entirely in the
# worker binding, and shouldn't need to check for the various worker
# scopes in the non-worker binding.
interface = descriptor.interface interface = descriptor.interface
nonExposureSet = interface.exposureSet - interfaceMember.exposureSet nonExposureSet = interface.exposureSet - interfaceMember.exposureSet
# Skip getting the descriptor if we're just exposed everywhere or not
# looking at the non-worker descriptor.
if len(nonExposureSet) and not descriptor.workers:
workerProvider = descriptor.config.getDescriptorProvider(True)
workerDesc = workerProvider.getDescriptor(interface.identifier.name)
if workerDesc.workers:
# Just drop all the worker interface names from the
# nonExposureSet, since we know we'll have a mainthread global
# of some sort.
nonExposureSet.difference_update(interface.getWorkerExposureSet())
return MemberCondition( return MemberCondition(
PropertyDefiner.getStringAttr(interfaceMember, PropertyDefiner.getStringAttr(interfaceMember,
@ -2186,12 +2148,6 @@ def methodLength(method):
return min(overloadLength(arguments) for retType, arguments in signatures) return min(overloadLength(arguments) for retType, arguments in signatures)
def isMaybeExposedIn(member, descriptor):
# All we can say for sure is that if this is a worker descriptor
# and member is not exposed in any worker, then it's not exposed.
return not descriptor.workers or member.isExposedInAnyWorker()
def clearableCachedAttrs(descriptor): def clearableCachedAttrs(descriptor):
return (m for m in descriptor.interface.members if return (m for m in descriptor.interface.members if
m.isAttr() and m.isAttr() and
@ -2229,16 +2185,13 @@ class MethodDefiner(PropertyDefiner):
methods = [m for m in descriptor.interface.members if methods = [m for m in descriptor.interface.members if
m.isMethod() and m.isStatic() == static and m.isMethod() and m.isStatic() == static and
MemberIsUnforgeable(m, descriptor) == unforgeable and MemberIsUnforgeable(m, descriptor) == unforgeable and
not m.isIdentifierLess() and not m.isIdentifierLess()]
isMaybeExposedIn(m, descriptor)]
else: else:
methods = [] methods = []
self.chrome = [] self.chrome = []
self.regular = [] self.regular = []
for m in methods: for m in methods:
if m.identifier.name == 'queryInterface': if m.identifier.name == 'queryInterface':
if self.descriptor.workers:
continue
if m.isStatic(): if m.isStatic():
raise TypeError("Legacy queryInterface member shouldn't be static") raise TypeError("Legacy queryInterface member shouldn't be static")
signatures = m.signatures() signatures = m.signatures()
@ -2315,8 +2268,7 @@ class MethodDefiner(PropertyDefiner):
# neither. # neither.
if (not static and if (not static and
not unforgeable and not unforgeable and
descriptor.supportsIndexedProperties() and descriptor.supportsIndexedProperties()):
isMaybeExposedIn(descriptor.operations['IndexedGetter'], descriptor)):
if hasIterator(methods, self.regular): if hasIterator(methods, self.regular):
raise TypeError("Cannot have indexed getter/attr on " raise TypeError("Cannot have indexed getter/attr on "
"interface %s with other members " "interface %s with other members "
@ -2379,8 +2331,7 @@ class MethodDefiner(PropertyDefiner):
if not static: if not static:
stringifier = descriptor.operations['Stringifier'] stringifier = descriptor.operations['Stringifier']
if (stringifier and if (stringifier and
unforgeable == MemberIsUnforgeable(stringifier, descriptor) and unforgeable == MemberIsUnforgeable(stringifier, descriptor)):
isMaybeExposedIn(stringifier, descriptor)):
toStringDesc = { toStringDesc = {
"name": "toString", "name": "toString",
"nativeName": stringifier.identifier.name, "nativeName": stringifier.identifier.name,
@ -2394,8 +2345,7 @@ class MethodDefiner(PropertyDefiner):
self.regular.append(toStringDesc) self.regular.append(toStringDesc)
jsonifier = descriptor.operations['Jsonifier'] jsonifier = descriptor.operations['Jsonifier']
if (jsonifier and if (jsonifier and
unforgeable == MemberIsUnforgeable(jsonifier, descriptor) and unforgeable == MemberIsUnforgeable(jsonifier, descriptor)):
isMaybeExposedIn(jsonifier, descriptor)):
toJSONDesc = { toJSONDesc = {
"name": "toJSON", "name": "toJSON",
"nativeName": jsonifier.identifier.name, "nativeName": jsonifier.identifier.name,
@ -2548,7 +2498,6 @@ class AttrDefiner(PropertyDefiner):
attributes = [m for m in descriptor.interface.members if attributes = [m for m in descriptor.interface.members if
m.isAttr() and m.isStatic() == static and m.isAttr() and m.isStatic() == static and
MemberIsUnforgeable(m, descriptor) == unforgeable and MemberIsUnforgeable(m, descriptor) == unforgeable and
isMaybeExposedIn(m, descriptor) and
not isNonExposedNavigatorObjectGetter(m, descriptor)] not isNonExposedNavigatorObjectGetter(m, descriptor)]
else: else:
attributes = [] attributes = []
@ -2636,8 +2585,7 @@ class ConstDefiner(PropertyDefiner):
def __init__(self, descriptor, name): def __init__(self, descriptor, name):
PropertyDefiner.__init__(self, descriptor, name) PropertyDefiner.__init__(self, descriptor, name)
self.name = name self.name = name
constants = [m for m in descriptor.interface.members if m.isConst() and constants = [m for m in descriptor.interface.members if m.isConst()]
isMaybeExposedIn(m, descriptor)]
self.chrome = [m for m in constants if isChromeOnly(m)] self.chrome = [m for m in constants if isChromeOnly(m)]
self.regular = [m for m in constants if not isChromeOnly(m)] self.regular = [m for m in constants if not isChromeOnly(m)]
@ -3299,16 +3247,6 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
Argument('bool', 'aDefineOnGlobal')] Argument('bool', 'aDefineOnGlobal')]
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'JSObject*', args) CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'JSObject*', args)
def declare(self):
if self.descriptor.workers:
return ''
return CGAbstractMethod.declare(self)
def define(self):
if self.descriptor.workers:
return ''
return CGAbstractMethod.define(self)
def definition_body(self): def definition_body(self):
if len(self.descriptor.interface.namedConstructors) > 0: if len(self.descriptor.interface.namedConstructors) > 0:
getConstructor = dedent(""" getConstructor = dedent("""
@ -3829,13 +3767,6 @@ class CGWrapGlobalMethod(CGAbstractMethod):
else: else:
chromeProperties = "nullptr" chromeProperties = "nullptr"
if self.descriptor.workers:
fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
// JS_FireOnNewGlobalObject(aCx, aReflector);
"""
else:
fireOnNewGlobal = ""
if self.descriptor.hasUnforgeableMembers: if self.descriptor.hasUnforgeableMembers:
declareProto = "JS::Handle<JSObject*> canonicalProto =\n" declareProto = "JS::Handle<JSObject*> canonicalProto =\n"
assertProto = ( assertProto = (
@ -3875,7 +3806,6 @@ class CGWrapGlobalMethod(CGAbstractMethod):
$*{unforgeable} $*{unforgeable}
$*{slots} $*{slots}
$*{fireOnNewGlobal}
return true; return true;
""", """,
@ -3886,8 +3816,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
properties=properties, properties=properties,
chromeProperties=chromeProperties, chromeProperties=chromeProperties,
unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True), unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
slots=InitMemberSlots(self.descriptor, True), slots=InitMemberSlots(self.descriptor, True))
fireOnNewGlobal=fireOnNewGlobal)
class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod): class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
@ -5386,7 +5315,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
""", """,
getPromiseGlobal=getPromiseGlobal, getPromiseGlobal=getPromiseGlobal,
exceptionCode=exceptionCode) exceptionCode=exceptionCode)
elif not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal(): elif not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
if failureCode is not None: if failureCode is not None:
templateBody += str(CastableObjectUnwrapper( templateBody += str(CastableObjectUnwrapper(
descriptor, descriptor,
@ -5402,9 +5331,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
isCallbackReturnValue, isCallbackReturnValue,
firstCap(sourceDescription))) firstCap(sourceDescription)))
else: else:
# Worker descriptors can't end up here, because all of our
# "external" stuff is not exposed in workers.
assert not descriptor.workers
# Either external, or new-binding non-castable. We always have a # Either external, or new-binding non-castable. We always have a
# holder for these, because we don't actually know whether we have # holder for these, because we don't actually know whether we have
# to addref when unwrapping or not. So we just pass an # to addref when unwrapping or not. So we just pass an
@ -6497,7 +6423,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
else: else:
wrappingCode = "" wrappingCode = ""
if not descriptor.interface.isExternal() and not descriptor.skipGen: if not descriptor.interface.isExternal():
if descriptor.wrapperCache: if descriptor.wrapperCache:
wrapMethod = "GetOrCreateDOMReflector" wrapMethod = "GetOrCreateDOMReflector"
wrapArgs = "cx, %s, ${jsvalHandle}" % result wrapArgs = "cx, %s, ${jsvalHandle}" % result
@ -7691,31 +7617,7 @@ class CGMethodCall(CGThing):
isConstructor=isConstructor, isConstructor=isConstructor,
useCounterName=useCounterName) useCounterName=useCounterName)
def filteredSignatures(signatures, descriptor): signatures = method.signatures()
def typeExposedInWorkers(type):
return (not type.isGeckoInterface() or
type.inner.isExposedInAnyWorker())
if descriptor.workers:
# Filter out the signatures that should not be exposed in a
# worker. The IDL parser enforces the return value being
# exposed correctly, but we have to check the argument types.
#
# If this code changes, adjust the self._deps
# computation in CGDDescriptor.__init__ as needed.
assert all(typeExposedInWorkers(sig[0]) for sig in signatures)
signatures = filter(
lambda sig: all(typeExposedInWorkers(arg.type)
for arg in sig[1]),
signatures)
if len(signatures) == 0:
raise TypeError("%s.%s has a worker binding with no "
"signatures that take arguments exposed in "
"workers." %
(descriptor.interface.identifier.name,
method.identifier.name))
return signatures
signatures = filteredSignatures(method.signatures(), descriptor)
if len(signatures) == 1: if len(signatures) == 1:
# Special case: we can just do a per-signature method call # Special case: we can just do a per-signature method call
# here for our one signature and not worry about switching # here for our one signature and not worry about switching
@ -7745,17 +7647,13 @@ class CGMethodCall(CGThing):
argCountCases = [] argCountCases = []
for argCountIdx, argCount in enumerate(allowedArgCounts): for argCountIdx, argCount in enumerate(allowedArgCounts):
possibleSignatures = filteredSignatures( possibleSignatures = method.signaturesForArgCount(argCount)
method.signaturesForArgCount(argCount),
descriptor)
# Try to optimize away cases when the next argCount in the list # Try to optimize away cases when the next argCount in the list
# will have the same code as us; if it does, we can fall through to # will have the same code as us; if it does, we can fall through to
# that case. # that case.
if argCountIdx+1 < len(allowedArgCounts): if argCountIdx+1 < len(allowedArgCounts):
nextPossibleSignatures = filteredSignatures( nextPossibleSignatures = method.signaturesForArgCount(allowedArgCounts[argCountIdx+1])
method.signaturesForArgCount(allowedArgCounts[argCountIdx+1]),
descriptor)
else: else:
nextPossibleSignatures = None nextPossibleSignatures = None
if possibleSignatures == nextPossibleSignatures: if possibleSignatures == nextPossibleSignatures:
@ -11981,21 +11879,6 @@ class CGDescriptor(CGThing):
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject() assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
self._deps = descriptor.interface.getDeps() self._deps = descriptor.interface.getDeps()
# If we have a worker descriptor, add dependencies on interface types we
# have as method arguments to overloaded methods. See the
# filteredSignatures() bit in CGMethodCall. Note that we have to add
# both interfaces that _are_ exposed in workers and ones that aren't;
# the idea is that we have to notice when the exposure set changes.
if descriptor.workers:
methods = (m for m in descriptor.interface.members if
m.isMethod() and isMaybeExposedIn(m, descriptor) and
len(m.signatures()) != 1)
for m in methods:
for sig in m.signatures():
for arg in sig[1]:
if (arg.type.isGeckoInterface() and
not arg.type.inner.isExternal()):
self._deps.add(arg.type.inner.filename())
cgThings = [] cgThings = []
cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" % cgThings.append(CGGeneric(declare="typedef %s NativeType;\n" %
@ -12019,8 +11902,6 @@ class CGDescriptor(CGThing):
for m in descriptor.interface.members: for m in descriptor.interface.members:
if m.isMethod() and m.identifier.name == 'queryInterface': if m.isMethod() and m.identifier.name == 'queryInterface':
continue continue
if not isMaybeExposedIn(m, descriptor):
continue
props = memberProperties(m, descriptor) props = memberProperties(m, descriptor)
@ -13070,25 +12951,9 @@ class CGRegisterWorkerBindings(CGAbstractMethod):
self.config = config self.config = config
def definition_body(self): def definition_body(self):
# We have to be a bit careful: Some of the interfaces we want to expose
# in workers only have one descriptor, while others have both a worker
# and a non-worker descriptor. When both are present we want the worker
# descriptor, but otherwise we want whatever descriptor we've got.
descriptors = self.config.getDescriptors(hasInterfaceObject=True, descriptors = self.config.getDescriptors(hasInterfaceObject=True,
isExposedInAnyWorker=True, isExposedInAnyWorker=True,
register=True, register=True)
skipGen=False,
workers=True)
workerDescriptorIfaceNames = set(d.interface.identifier.name for
d in descriptors)
descriptors.extend(
filter(
lambda d: d.interface.identifier.name not in workerDescriptorIfaceNames,
self.config.getDescriptors(hasInterfaceObject=True,
isExposedInAnyWorker=True,
register=True,
skipGen=False,
workers=False)))
conditions = [] conditions = []
for desc in descriptors: for desc in descriptors:
bindingNS = toBindingNamespace(desc.name) bindingNS = toBindingNamespace(desc.name)
@ -13111,25 +12976,9 @@ class CGRegisterWorkerDebuggerBindings(CGAbstractMethod):
self.config = config self.config = config
def definition_body(self): def definition_body(self):
# We have to be a bit careful: Some of the interfaces we want to expose
# in workers only have one descriptor, while others have both a worker
# and a non-worker descriptor. When both are present we want the worker
# descriptor, but otherwise we want whatever descriptor we've got.
descriptors = self.config.getDescriptors(hasInterfaceObject=True, descriptors = self.config.getDescriptors(hasInterfaceObject=True,
isExposedInWorkerDebugger=True, isExposedInWorkerDebugger=True,
register=True, register=True)
skipGen=False,
workers=True)
workerDescriptorIfaceNames = set(d.interface.identifier.name for
d in descriptors)
descriptors.extend(
filter(
lambda d: d.interface.identifier.name not in workerDescriptorIfaceNames,
self.config.getDescriptors(hasInterfaceObject=True,
isExposedInWorkerDebugger=True,
register=True,
skipGen=False,
workers=False)))
conditions = [] conditions = []
for desc in descriptors: for desc in descriptors:
bindingNS = toBindingNamespace(desc.name) bindingNS = toBindingNamespace(desc.name)
@ -13156,9 +13005,7 @@ class CGResolveSystemBinding(CGAbstractMethod):
def definition_body(self): def definition_body(self):
descriptors = self.config.getDescriptors(hasInterfaceObject=True, descriptors = self.config.getDescriptors(hasInterfaceObject=True,
isExposedInSystemGlobals=True, isExposedInSystemGlobals=True,
workers=False, register=True)
register=True,
skipGen=False)
def descNameToId(name): def descNameToId(name):
return "s%s_id" % name return "s%s_id" % name
@ -13343,24 +13190,16 @@ class ForwardDeclarationBuilder:
def build(self): def build(self):
return self._build(atTopLevel=True) return self._build(atTopLevel=True)
def forwardDeclareForType(self, t, config, workerness='both'): def forwardDeclareForType(self, t, config):
t = t.unroll() t = t.unroll()
if t.isGeckoInterface(): if t.isGeckoInterface():
name = t.inner.identifier.name name = t.inner.identifier.name
# Find and add the non-worker implementation, if any. try:
if workerness != 'workeronly': desc = config.getDescriptor(name)
try: self.add(desc.nativeType)
desc = config.getDescriptor(name, False) except NoSuchDescriptorError:
self.add(desc.nativeType) pass
except NoSuchDescriptorError:
pass
# Find and add the worker implementation, if any.
if workerness != 'mainthreadonly':
try:
desc = config.getDescriptor(name, True)
self.add(desc.nativeType)
except NoSuchDescriptorError:
pass
# Note: Spidermonkey interfaces are typedefs, so can't be # Note: Spidermonkey interfaces are typedefs, so can't be
# forward-declared # forward-declared
elif t.isCallback(): elif t.isCallback():
@ -13375,7 +13214,7 @@ class ForwardDeclarationBuilder:
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, False)) self.addInMozillaDom(CGUnionStruct.unionTypeName(t, False))
self.addInMozillaDom(CGUnionStruct.unionTypeName(t, True)) self.addInMozillaDom(CGUnionStruct.unionTypeName(t, True))
elif t.isMozMap(): elif t.isMozMap():
self.forwardDeclareForType(t.inner, config, workerness) self.forwardDeclareForType(t.inner, config)
# Don't need to do anything for void, primitive, string, any or object. # Don't need to do anything for void, primitive, string, any or object.
# There may be some other cases we are missing. # There may be some other cases we are missing.
@ -13387,7 +13226,7 @@ class CGForwardDeclarations(CGWrapper):
boolean. If the boolean is true we will declare a struct, otherwise we'll boolean. If the boolean is true we will declare a struct, otherwise we'll
declare a class. declare a class.
""" """
def __init__(self, config, descriptors, mainCallbacks, workerCallbacks, def __init__(self, config, descriptors, callbacks,
dictionaries, callbackInterfaces, additionalDeclarations=[]): dictionaries, callbackInterfaces, additionalDeclarations=[]):
builder = ForwardDeclarationBuilder() builder = ForwardDeclarationBuilder()
@ -13424,16 +13263,10 @@ class CGForwardDeclarations(CGWrapper):
continue continue
builder.add(d.nativeType + "Atoms", isStruct=True) builder.add(d.nativeType + "Atoms", isStruct=True)
for callback in mainCallbacks: for callback in callbacks:
builder.addInMozillaDom(callback.identifier.name) builder.addInMozillaDom(callback.identifier.name)
for t in getTypesFromCallback(callback): for t in getTypesFromCallback(callback):
builder.forwardDeclareForType(t, config, builder.forwardDeclareForType(t, config)
workerness='mainthreadonly')
for callback in workerCallbacks:
builder.addInMozillaDom(callback.identifier.name)
for t in getTypesFromCallback(callback):
builder.forwardDeclareForType(t, config, workerness='workeronly')
for d in callbackInterfaces: for d in callbackInterfaces:
builder.add(d.nativeType) builder.add(d.nativeType)
@ -13471,8 +13304,7 @@ class CGBindingRoot(CGThing):
True) True)
descriptors = config.getDescriptors(webIDLFile=webIDLFile, descriptors = config.getDescriptors(webIDLFile=webIDLFile,
hasInterfaceOrInterfacePrototypeObject=True, hasInterfaceOrInterfacePrototypeObject=True)
skipGen=False)
unionTypes = UnionsForFile(config, webIDLFile) unionTypes = UnionsForFile(config, webIDLFile)
@ -13533,14 +13365,11 @@ class CGBindingRoot(CGThing):
# XXXkhuey ugly hack but this is going away soon. # XXXkhuey ugly hack but this is going away soon.
bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl") bindingHeaders['xpcprivate.h'] = webIDLFile.endswith("EventTarget.webidl")
hasWorkerStuff = len(config.getDescriptors(webIDLFile=webIDLFile,
workers=True)) != 0
bindingHeaders["WorkerPrivate.h"] = hasWorkerStuff
hasThreadChecks = hasWorkerStuff or any(d.hasThreadChecks() for d in descriptors) hasThreadChecks = any(d.hasThreadChecks() for d in descriptors)
bindingHeaders["nsThreadUtils.h"] = hasThreadChecks bindingHeaders["nsThreadUtils.h"] = hasThreadChecks
dictionaries = config.getDictionaries(webIDLFile=webIDLFile) dictionaries = config.getDictionaries(webIDLFile)
def dictionaryHasChromeOnly(dictionary): def dictionaryHasChromeOnly(dictionary):
while dictionary: while dictionary:
@ -13554,10 +13383,7 @@ class CGBindingRoot(CGThing):
any(dictionaryHasChromeOnly(d) for d in dictionaries)) any(dictionaryHasChromeOnly(d) for d in dictionaries))
hasNonEmptyDictionaries = any( hasNonEmptyDictionaries = any(
len(dict.members) > 0 for dict in dictionaries) len(dict.members) > 0 for dict in dictionaries)
mainCallbacks = config.getCallbacks(webIDLFile=webIDLFile, callbacks = config.getCallbacks(webIDLFile)
workers=False)
workerCallbacks = config.getCallbacks(webIDLFile=webIDLFile,
workers=True)
callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile, callbackDescriptors = config.getDescriptors(webIDLFile=webIDLFile,
isCallback=True) isCallback=True)
jsImplemented = config.getDescriptors(webIDLFile=webIDLFile, jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
@ -13566,9 +13392,6 @@ class CGBindingRoot(CGThing):
bindingHeaders["nsIGlobalObject.h"] = jsImplemented bindingHeaders["nsIGlobalObject.h"] = jsImplemented
bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
# Only mainthread things can have hasXPConnectImpls
provider = config.getDescriptorProvider(False)
def descriptorClearsPropsInSlots(descriptor): def descriptorClearsPropsInSlots(descriptor):
if not descriptor.wrapperCache: if not descriptor.wrapperCache:
return False return False
@ -13581,7 +13404,7 @@ class CGBindingRoot(CGThing):
cgthings = [CGEnum(e) for e in enums] cgthings = [CGEnum(e) for e in enums]
hasCode = (descriptors or callbackDescriptors or dictionaries or hasCode = (descriptors or callbackDescriptors or dictionaries or
mainCallbacks or workerCallbacks) callbacks)
bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode
bindingHeaders["mozilla/OwningNonNull.h"] = hasCode bindingHeaders["mozilla/OwningNonNull.h"] = hasCode
bindingHeaders["mozilla/dom/BindingDeclarations.h"] = ( bindingHeaders["mozilla/dom/BindingDeclarations.h"] = (
@ -13646,36 +13469,27 @@ class CGBindingRoot(CGThing):
for t in dependencySortObjects(dictionaries + unionStructs, getDependencies, getName): for t in dependencySortObjects(dictionaries + unionStructs, getDependencies, getName):
if t.isDictionary(): if t.isDictionary():
cgthings.append(CGDictionary(t, config.getDescriptorProvider(False))) cgthings.append(CGDictionary(t, config))
else: else:
assert t.isUnion() assert t.isUnion()
# FIXME: Unions are broken in workers. See bug 809899. cgthings.append(CGUnionStruct(t, config))
cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False))) cgthings.append(CGUnionStruct(t, config, True))
cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False), True))
# Do codegen for all the callbacks. # Do codegen for all the callbacks.
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False)) cgthings.extend(CGCallbackFunction(c, config) for c in callbacks)
for c in mainCallbacks)
cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c)) cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c))
for c in mainCallbacks]) for c in callbacks])
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True))
for c in workerCallbacks if c not in mainCallbacks)
cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c))
for c in workerCallbacks if c not in mainCallbacks])
# Do codegen for all the descriptors # Do codegen for all the descriptors
cgthings.extend([CGDescriptor(x) for x in descriptors]) cgthings.extend([CGDescriptor(x) for x in descriptors])
# Do codegen for all the callback interfaces. Skip worker callbacks. # Do codegen for all the callback interfaces.
cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors])
not x.workers])
cgthings.extend([CGNamespace('binding_detail', cgthings.extend([CGNamespace('binding_detail',
CGFastCallback(x.interface)) CGFastCallback(x.interface))
for x in callbackDescriptors if not x.workers]) for x in callbackDescriptors])
# Do codegen for JS implemented classes # Do codegen for JS implemented classes
def getParentDescriptor(desc): def getParentDescriptor(desc):
@ -13695,7 +13509,7 @@ class CGBindingRoot(CGThing):
CGWrapper(curr, pre="\n")) CGWrapper(curr, pre="\n"))
curr = CGList([CGForwardDeclarations(config, descriptors, curr = CGList([CGForwardDeclarations(config, descriptors,
mainCallbacks, workerCallbacks, callbacks,
dictionaries, dictionaries,
callbackDescriptors + jsImplemented, callbackDescriptors + jsImplemented,
additionalDeclarations=unionDeclarations), additionalDeclarations=unionDeclarations),
@ -13712,7 +13526,7 @@ class CGBindingRoot(CGThing):
curr = CGHeaders(descriptors, curr = CGHeaders(descriptors,
dictionaries, dictionaries,
mainCallbacks + workerCallbacks, callbacks,
callbackDescriptors, callbackDescriptors,
bindingDeclareHeaders, bindingDeclareHeaders,
bindingHeaders, bindingHeaders,
@ -14474,8 +14288,7 @@ class CGExampleRoot(CGThing):
respectively. respectively.
""" """
def __init__(self, config, interfaceName): def __init__(self, config, interfaceName):
# Let's assume we're not doing workers stuff descriptor = config.getDescriptor(interfaceName)
descriptor = config.getDescriptor(interfaceName, False)
self.root = CGWrapper(CGExampleClass(descriptor), self.root = CGWrapper(CGExampleClass(descriptor),
pre="\n", post="\n") pre="\n", post="\n")
@ -16441,13 +16254,11 @@ class GlobalGenRoots():
# Add the includes # Add the includes
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface) defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True, for desc in config.getDescriptors(hasInterfaceObject=True,
workers=False,
isExposedInWindow=True, isExposedInWindow=True,
register=True)] register=True)]
defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h') defineIncludes.append('mozilla/dom/WebIDLGlobalNameHash.h')
defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface) defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(isNavigatorProperty=True, for desc in config.getDescriptors(isNavigatorProperty=True,
workers=False,
register=True)]) register=True)])
curr = CGHeaders([], [], [], [], [], defineIncludes, 'RegisterBindings', curr = CGHeaders([], [], [], [], [], defineIncludes, 'RegisterBindings',
curr) curr)
@ -16472,8 +16283,7 @@ class GlobalGenRoots():
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface) defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True, for desc in config.getDescriptors(hasInterfaceObject=True,
register=True, register=True,
isExposedInAnyWorker=True, isExposedInAnyWorker=True)]
skipGen=False)]
curr = CGHeaders([], [], [], [], [], defineIncludes, curr = CGHeaders([], [], [], [], [], defineIncludes,
'RegisterWorkerBindings', curr) 'RegisterWorkerBindings', curr)
@ -16498,8 +16308,7 @@ class GlobalGenRoots():
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface) defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True, for desc in config.getDescriptors(hasInterfaceObject=True,
register=True, register=True,
isExposedInWorkerDebugger=True, isExposedInWorkerDebugger=True)]
skipGen=False)]
curr = CGHeaders([], [], [], [], [], defineIncludes, curr = CGHeaders([], [], [], [], [], defineIncludes,
'RegisterWorkerDebuggerBindings', curr) 'RegisterWorkerDebuggerBindings', curr)
@ -16524,8 +16333,7 @@ class GlobalGenRoots():
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface) defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True, for desc in config.getDescriptors(hasInterfaceObject=True,
register=True, register=True,
isExposedInSystemGlobals=True, isExposedInSystemGlobals=True)]
skipGen=False)]
defineIncludes.append("nsThreadUtils.h") # For NS_IsMainThread defineIncludes.append("nsThreadUtils.h") # For NS_IsMainThread
defineIncludes.append("js/Id.h") # For jsid defineIncludes.append("js/Id.h") # For jsid
defineIncludes.append("mozilla/dom/BindingUtils.h") # AtomizeAndPinJSString defineIncludes.append("mozilla/dom/BindingUtils.h") # AtomizeAndPinJSString
@ -16548,8 +16356,8 @@ class GlobalGenRoots():
unions = CGList(traverseMethods + unions = CGList(traverseMethods +
unlinkMethods + unlinkMethods +
[CGUnionStruct(t, config.getDescriptorProvider(False)) for t in unionStructs] + [CGUnionStruct(t, config) for t in unionStructs] +
[CGUnionStruct(t, config.getDescriptorProvider(False), True) for t in unionStructs], [CGUnionStruct(t, config, True) for t in unionStructs],
"\n") "\n")
includes.add("mozilla/OwningNonNull.h") includes.add("mozilla/OwningNonNull.h")
@ -16584,7 +16392,7 @@ class GlobalGenRoots():
unionTypes = [] unionTypes = []
for l in config.unionsPerFilename.itervalues(): for l in config.unionsPerFilename.itervalues():
unionTypes.extend(l) unionTypes.extend(l)
unionTypes.sort(key=lambda u: u[0].name) unionTypes.sort(key=lambda u: u.name)
headers, unions = UnionConversions(unionTypes, headers, unions = UnionConversions(unionTypes,
config) config)
@ -17112,8 +16920,7 @@ class CGEventClass(CGBindingImplClass):
class CGEventRoot(CGThing): class CGEventRoot(CGThing):
def __init__(self, config, interfaceName): def __init__(self, config, interfaceName):
# Let's assume we're not doing workers stuff, for now descriptor = config.getDescriptor(interfaceName)
descriptor = config.getDescriptor(interfaceName, False)
self.root = CGWrapper(CGEventClass(descriptor), self.root = CGWrapper(CGEventClass(descriptor),
pre="\n", post="\n") pre="\n", post="\n")
@ -17132,7 +16939,7 @@ class CGEventRoot(CGThing):
[], [],
[], [],
[ [
config.getDescriptor(parent, False).headerFile, config.getDescriptor(parent).headerFile,
"mozilla/Attributes.h", "mozilla/Attributes.h",
"mozilla/ErrorResult.h", "mozilla/ErrorResult.h",
"mozilla/dom/%sBinding.h" % interfaceName, "mozilla/dom/%sBinding.h" % interfaceName,

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

@ -9,12 +9,22 @@ from collections import defaultdict
autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n" autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
class Configuration: class DescriptorProvider:
"""
A way of getting descriptors for interface names. Subclasses must
have a getDescriptor method callable with the interface name only.
"""
def __init__(self):
pass
class Configuration(DescriptorProvider):
""" """
Represents global configuration state based on IDL parse data and Represents global configuration state based on IDL parse data and
the configuration file. the configuration file.
""" """
def __init__(self, filename, parseData, generatedEvents=[]): def __init__(self, filename, parseData, generatedEvents=[]):
DescriptorProvider.__init__(self)
# Read the configuration file. # Read the configuration file.
glbl = {} glbl = {}
@ -67,34 +77,14 @@ class Configuration:
entry = {} entry = {}
else: else:
entry = config[iface.identifier.name] entry = config[iface.identifier.name]
if not isinstance(entry, list): assert not isinstance(entry, list)
assert isinstance(entry, dict) desc = Descriptor(self, iface, entry)
entry = [entry] self.descriptors.append(desc)
elif len(entry) == 1:
if entry[0].get("workers", False):
# List with only a workers descriptor means we should
# infer a mainthread descriptor. If you want only
# workers bindings, don't use a list here.
entry.append({})
else:
raise TypeError("Don't use a single-element list for "
"non-worker-only interface " + iface.identifier.name +
" in Bindings.conf")
elif len(entry) == 2:
if entry[0].get("workers", False) == entry[1].get("workers", False):
raise TypeError("The two entries for interface " + iface.identifier.name +
" in Bindings.conf should not have the same value for 'workers'")
else:
raise TypeError("Interface " + iface.identifier.name +
" should have no more than two entries in Bindings.conf")
descs = [Descriptor(self, iface, x) for x in entry]
self.descriptors.extend(descs)
# Setting up descriptorsByName while iterating through interfaces # Setting up descriptorsByName while iterating through interfaces
# means we can get the nativeType of iterable interfaces without # means we can get the nativeType of iterable interfaces without
# having to do multiple loops. # having to do multiple loops.
for d in descs: assert desc.interface.identifier.name not in self.descriptorsByName
self.descriptorsByName.setdefault(d.interface.identifier.name, self.descriptorsByName[desc.interface.identifier.name] = desc
[]).append(d)
# Keep the descriptor list sorted for determinism. # Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x, y: cmp(x.name, y.name)) self.descriptors.sort(lambda x, y: cmp(x.name, y.name))
@ -107,19 +97,6 @@ class Configuration:
self.enums = [e for e in parseData if e.isEnum()] self.enums = [e for e in parseData if e.isEnum()]
# Figure out what our main-thread and worker dictionaries and callbacks
# are.
mainTypes = set()
for descriptor in ([self.getDescriptor("DummyInterface", workers=False)] +
self.getDescriptors(workers=False, isExternal=False, skipGen=False)):
mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
(mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
workerTypes = set()
for descriptor in (self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
(workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
self.dictionaries = [d for d in parseData if d.isDictionary()] self.dictionaries = [d for d in parseData if d.isDictionary()]
self.callbacks = [c for c in parseData if self.callbacks = [c for c in parseData if
c.isCallback() and not c.isInterface()] c.isCallback() and not c.isInterface()]
@ -128,15 +105,15 @@ class Configuration:
# union types with that name are used. # union types with that name are used.
self.filenamesPerUnion = defaultdict(set) self.filenamesPerUnion = defaultdict(set)
# Dictionary mapping from a filename to a list of tuples containing a # Dictionary mapping from a filename to a list of types for
# type and descriptor for the union types used in that file. If a union # the union types used in that file. If a union type is used
# type is used in multiple files then it will be added to the list # in multiple files then it will be added to the list for the
# for the None key. Note that the list contains a tuple for every use of # None key. Note that the list contains a type for every use
# a union type, so there can be multiple tuples with union types that # of a union type, so there can be multiple entries with union
# have the same name. # types that have the same name.
self.unionsPerFilename = defaultdict(list) self.unionsPerFilename = defaultdict(list)
for (t, descriptor, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks): for (t, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
while True: while True:
if t.isMozMap(): if t.isMozMap():
t = t.inner t = t.inner
@ -172,7 +149,7 @@ class Configuration:
# unions for the file where we previously found # unions for the file where we previously found
# them. # them.
unionsForFilename = self.unionsPerFilename[f] unionsForFilename = self.unionsPerFilename[f]
unionsForFilename = filter(lambda u: u[0].name != t.name, unionsForFilename = filter(lambda u: u.name != t.name,
unionsForFilename) unionsForFilename)
if len(unionsForFilename) == 0: if len(unionsForFilename) == 0:
del self.unionsPerFilename[f] del self.unionsPerFilename[f]
@ -181,17 +158,9 @@ class Configuration:
# Unions with this name appear in multiple files, record # Unions with this name appear in multiple files, record
# the filename as None, so that we can detect that. # the filename as None, so that we can detect that.
uniqueFilenameForUnion = None uniqueFilenameForUnion = None
self.unionsPerFilename[uniqueFilenameForUnion].append((t, descriptor)) self.unionsPerFilename[uniqueFilenameForUnion].append(t)
filenamesForUnion.add(t.filename()) filenamesForUnion.add(t.filename())
def flagWorkerOrMainThread(items, main, worker):
for item in items:
if item in main:
item.setUserData("mainThread", True)
if item in worker:
item.setUserData("workers", True)
flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks)
def getInterface(self, ifname): def getInterface(self, ifname):
return self.interfaces[ifname] return self.interfaces[ifname]
@ -245,43 +214,23 @@ class Configuration:
def getEnums(self, webIDLFile): def getEnums(self, webIDLFile):
return filter(lambda e: e.filename() == webIDLFile, self.enums) return filter(lambda e: e.filename() == webIDLFile, self.enums)
@staticmethod def getDictionaries(self, webIDLFile):
def _filterForFileAndWorkers(items, filters): return filter(lambda d: d.filename() == webIDLFile, self.dictionaries)
"""Gets the items that match the given filters."""
for key, val in filters.iteritems():
if key == 'webIDLFile':
items = filter(lambda x: x.filename() == val, items)
elif key == 'workers':
if val:
items = filter(lambda x: x.getUserData("workers", False), items)
else:
items = filter(lambda x: x.getUserData("mainThread", False), items)
else:
assert(0) # Unknown key
return items
def getDictionaries(self, **filters): def getCallbacks(self, webIDLFile):
return self._filterForFileAndWorkers(self.dictionaries, filters) return filter(lambda c: c.filename() == webIDLFile, self.callbacks)
def getCallbacks(self, **filters): def getDescriptor(self, interfaceName):
return self._filterForFileAndWorkers(self.callbacks, filters)
def getDescriptor(self, interfaceName, workers):
""" """
Gets the appropriate descriptor for the given interface name Gets the appropriate descriptor for the given interface name.
and the given workers boolean.
""" """
# We may have optimized out this descriptor, but the chances of anyone # We may have optimized out this descriptor, but the chances of anyone
# asking about it are then slim. Put the check for that _after_ we've # asking about it are then slim. Put the check for that _after_ we've
# done our normal lookups. But that means we have to do our normal # done our normal lookup. But that means we have to do our normal
# lookups in a way that will not throw if they fail. # lookup in a way that will not throw if it fails.
for d in self.descriptorsByName.get(interfaceName, []): d = self.descriptorsByName.get(interfaceName, None)
if d.workers == workers: if d:
return d return d
if workers:
for d in self.descriptorsByName.get(interfaceName, []):
return d
if interfaceName in self.optimizedOutDescriptorNames: if interfaceName in self.optimizedOutDescriptorNames:
raise NoSuchDescriptorError( raise NoSuchDescriptorError(
@ -291,36 +240,12 @@ class Configuration:
raise NoSuchDescriptorError("For " + interfaceName + " found no matches") raise NoSuchDescriptorError("For " + interfaceName + " found no matches")
def getDescriptorProvider(self, workers):
"""
Gets a descriptor provider that can provide descriptors as needed,
for the given workers boolean
"""
return DescriptorProvider(self, workers)
class NoSuchDescriptorError(TypeError): class NoSuchDescriptorError(TypeError):
def __init__(self, str): def __init__(self, str):
TypeError.__init__(self, str) TypeError.__init__(self, str)
class DescriptorProvider:
"""
A way of getting descriptors for interface names
"""
def __init__(self, config, workers):
self.config = config
self.workers = workers
def getDescriptor(self, interfaceName):
"""
Gets the appropriate descriptor for the given interface name given the
context of the current descriptor. This selects the appropriate
implementation for cases like workers.
"""
return self.config.getDescriptor(interfaceName, self.workers)
def methodReturnsJSObject(method): def methodReturnsJSObject(method):
assert method.isMethod() assert method.isMethod()
if method.returnsPromise(): if method.returnsPromise():
@ -350,14 +275,11 @@ class Descriptor(DescriptorProvider):
Represents a single descriptor for an interface. See Bindings.conf. Represents a single descriptor for an interface. See Bindings.conf.
""" """
def __init__(self, config, interface, desc): def __init__(self, config, interface, desc):
DescriptorProvider.__init__(self, config, desc.get('workers', False)) DescriptorProvider.__init__(self)
self.config = config
self.interface = interface self.interface = interface
if self.workers: self.wantsXrays = interface.isExposedInWindow()
assert 'wantsXrays' not in desc
self.wantsXrays = False
else:
self.wantsXrays = desc.get('wantsXrays', True)
# Read the desc, and fill in the relevant defaults. # Read the desc, and fill in the relevant defaults.
ifaceName = self.interface.identifier.name ifaceName = self.interface.identifier.name
@ -372,15 +294,9 @@ class Descriptor(DescriptorProvider):
nativeTypeDefault = iteratorNativeType(itrDesc) nativeTypeDefault = iteratorNativeType(itrDesc)
elif self.interface.isExternal(): elif self.interface.isExternal():
assert not self.workers
nativeTypeDefault = "nsIDOM" + ifaceName nativeTypeDefault = "nsIDOM" + ifaceName
elif self.interface.isCallback():
nativeTypeDefault = "mozilla::dom::" + ifaceName
else: else:
if self.workers: nativeTypeDefault = "mozilla::dom::" + ifaceName
nativeTypeDefault = "mozilla::dom::workers::" + ifaceName
else:
nativeTypeDefault = "mozilla::dom::" + ifaceName
self.nativeType = desc.get('nativeType', nativeTypeDefault) self.nativeType = desc.get('nativeType', nativeTypeDefault)
# Now create a version of nativeType that doesn't have extra # Now create a version of nativeType that doesn't have extra
@ -405,9 +321,7 @@ class Descriptor(DescriptorProvider):
basename = os.path.basename(self.interface.filename()) basename = os.path.basename(self.interface.filename())
headerDefault = basename.replace('.webidl', 'Binding.h') headerDefault = basename.replace('.webidl', 'Binding.h')
else: else:
if self.workers: if not self.interface.isExternal() and self.interface.getExtendedAttribute("HeaderFile"):
headerDefault = "mozilla/dom/workers/bindings/%s.h" % ifaceName
elif not self.interface.isExternal() and self.interface.getExtendedAttribute("HeaderFile"):
headerDefault = self.interface.getExtendedAttribute("HeaderFile")[0] headerDefault = self.interface.getExtendedAttribute("HeaderFile")[0]
elif self.interface.isIteratorInterface(): elif self.interface.isIteratorInterface():
headerDefault = "mozilla/dom/IterableIterator.h" headerDefault = "mozilla/dom/IterableIterator.h"
@ -421,8 +335,6 @@ class Descriptor(DescriptorProvider):
else: else:
self.jsImplParentHeader = self.jsImplParent.replace("::", "/") + ".h" self.jsImplParentHeader = self.jsImplParent.replace("::", "/") + ".h"
self.skipGen = desc.get('skipGen', False)
self.notflattened = desc.get('notflattened', False) self.notflattened = desc.get('notflattened', False)
self.register = desc.get('register', True) self.register = desc.get('register', True)
@ -551,9 +463,7 @@ class Descriptor(DescriptorProvider):
# object (that is, when we're not using SpiderMonkey promises). # object (that is, when we're not using SpiderMonkey promises).
self.wrapperCache = self.interface.hasInterfaceObject() self.wrapperCache = self.interface.hasInterfaceObject()
def make_name(name): self.name = interface.identifier.name
return name + "_workers" if self.workers else name
self.name = make_name(interface.identifier.name)
# self.extendedAttributes is a dict of dicts, keyed on # self.extendedAttributes is a dict of dicts, keyed on
# all/getterOnly/setterOnly and then on member name. Values are an # all/getterOnly/setterOnly and then on member name. Values are an
@ -691,8 +601,7 @@ class Descriptor(DescriptorProvider):
def hasInterfaceOrInterfacePrototypeObject(self): def hasInterfaceOrInterfacePrototypeObject(self):
# Forward-declared interfaces don't need either interface object or # Forward-declared interfaces don't need either interface object or
# interface prototype object as they're going to use QI (on main thread) # interface prototype object as they're going to use QI.
# or be passed as a JSObject (on worker threads).
if self.interface.isExternal(): if self.interface.isExternal():
return False return False
@ -707,17 +616,12 @@ class Descriptor(DescriptorProvider):
def getExtendedAttributes(self, member, getter=False, setter=False): def getExtendedAttributes(self, member, getter=False, setter=False):
def ensureValidThrowsExtendedAttribute(attr): def ensureValidThrowsExtendedAttribute(attr):
assert(attr is None or attr is True or len(attr) == 1) if (attr is not None and attr is not True):
if (attr is not None and attr is not True and
'Workers' not in attr and 'MainThread' not in attr):
raise TypeError("Unknown value for 'Throws': " + attr[0]) raise TypeError("Unknown value for 'Throws': " + attr[0])
def maybeAppendInfallibleToAttrs(attrs, throws): def maybeAppendInfallibleToAttrs(attrs, throws):
ensureValidThrowsExtendedAttribute(throws) ensureValidThrowsExtendedAttribute(throws)
if (throws is None or if throws is None:
(throws is not True and
('Workers' not in throws or not self.workers) and
('MainThread' not in throws or self.workers))):
attrs.append("infallible") attrs.append("infallible")
name = member.identifier.name name = member.identifier.name
@ -832,10 +736,15 @@ class Descriptor(DescriptorProvider):
def registersGlobalNamesOnWindow(self): def registersGlobalNamesOnWindow(self):
return (not self.interface.isExternal() and return (not self.interface.isExternal() and
self.interface.hasInterfaceObject() and self.interface.hasInterfaceObject() and
not self.workers and
self.interface.isExposedInWindow() and self.interface.isExposedInWindow() and
self.register) self.register)
def getDescriptor(self, interfaceName):
"""
Gets the appropriate descriptor for the given interface name.
"""
return self.config.getDescriptor(interfaceName)
# Some utility methods # Some utility methods
def getTypesFromDescriptor(descriptor): def getTypesFromDescriptor(descriptor):
@ -892,54 +801,23 @@ def getTypesFromCallback(callback):
return types return types
def findCallbacksAndDictionaries(inputTypes):
"""
Ensure that all callbacks and dictionaries reachable from types end up in
the returned callbacks and dictionaries sets.
Note that we assume that our initial invocation already includes all types
reachable via descriptors in "types", so we only have to deal with things
that are themeselves reachable via callbacks and dictionaries.
"""
def doFindCallbacksAndDictionaries(types, callbacks, dictionaries):
unhandledTypes = set()
for type in types:
if type.isCallback() and type.callback not in callbacks:
unhandledTypes |= getFlatTypes(getTypesFromCallback(type.callback))
callbacks.add(type.callback)
elif type.isDictionary() and type.inner not in dictionaries:
d = type.inner
unhandledTypes |= getFlatTypes(getTypesFromDictionary(d))
while d:
dictionaries.add(d)
d = d.parent
if len(unhandledTypes) != 0:
doFindCallbacksAndDictionaries(unhandledTypes, callbacks, dictionaries)
retCallbacks = set()
retDictionaries = set()
doFindCallbacksAndDictionaries(inputTypes, retCallbacks, retDictionaries)
return (retCallbacks, retDictionaries)
def getAllTypes(descriptors, dictionaries, callbacks): def getAllTypes(descriptors, dictionaries, callbacks):
""" """
Generate all the types we're dealing with. For each type, a tuple Generate all the types we're dealing with. For each type, a tuple
containing type, descriptor, dictionary is yielded. The containing type, dictionary is yielded. The dictionary can be None if the
descriptor and dictionary can be None if the type does not come type does not come from a dictionary.
from a descriptor or dictionary; they will never both be non-None.
""" """
for d in descriptors: for d in descriptors:
if d.interface.isExternal(): if d.interface.isExternal():
continue continue
for t in getTypesFromDescriptor(d): for t in getTypesFromDescriptor(d):
yield (t, d, None) yield (t, None)
for dictionary in dictionaries: for dictionary in dictionaries:
for t in getTypesFromDictionary(dictionary): for t in getTypesFromDictionary(dictionary):
yield (t, None, dictionary) yield (t, dictionary)
for callback in callbacks: for callback in callbacks:
for t in getTypesFromCallback(callback): for t in getTypesFromCallback(callback):
yield (t, None, None) yield (t, None)
def iteratorNativeType(descriptor): def iteratorNativeType(descriptor):
assert descriptor.interface.isIterable() assert descriptor.interface.isIterable()

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

@ -9,13 +9,15 @@
#include "jsapi.h" #include "jsapi.h"
#include "js/Class.h" #include "js/Class.h"
#include "nsContentUtils.h"
#include "nsJSPrincipals.h" #include "nsJSPrincipals.h"
#include "nsNullPrincipal.h" #include "nsNullPrincipal.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsContentUtils.h"
#include "xpcprivate.h" #include "xpcprivate.h"
#include "mozilla/dom/ScriptSettings.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -90,60 +92,67 @@ const js::Class SimpleGlobalClass = {
JSObject* JSObject*
SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto) SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto)
{ {
JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); // We can't root our return value with our AutoJSAPI because the rooting
JSAutoRequest ar(cx); // analysis thinks ~AutoJSAPI can GC. So we need to root in a scope outside
// the lifetime of the AutoJSAPI.
JS::Rooted<JSObject*> global(nsContentUtils::RootingCx());
JS::CompartmentOptions options; { // Scope to ensure the AutoJSAPI destructor runs before we end up returning
options.creationOptions().setInvisibleToDebugger(true); AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> global(cx); JS::CompartmentOptions options;
options.creationOptions().setInvisibleToDebugger(true);
if (NS_IsMainThread()) { if (NS_IsMainThread()) {
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create(); nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
options.creationOptions().setTrace(xpc::TraceXPCGlobal); options.creationOptions().setTrace(xpc::TraceXPCGlobal);
global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
nsJSPrincipals::get(principal), nsJSPrincipals::get(principal),
options); options);
} else { } else {
global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
nullptr, nullptr,
JS::DontFireOnNewGlobalHook, options); JS::DontFireOnNewGlobalHook, options);
} }
if (!global) { if (!global) {
JS_ClearPendingException(cx); jsapi.ClearException();
return nullptr;
}
JSAutoCompartment ac(cx, global);
// It's important to create the nsIGlobalObject for our new global before we
// start trying to wrap things like the prototype into its compartment,
// because the wrap operation relies on the global having its nsIGlobalObject
// already.
RefPtr<SimpleGlobalObject> globalObject =
new SimpleGlobalObject(global, globalType);
// Pass on ownership of globalObject to |global|.
JS_SetPrivate(global, globalObject.forget().take());
if (proto.isObjectOrNull()) {
JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
if (!JS_WrapObject(cx, &protoObj)) {
JS_ClearPendingException(cx);
return nullptr; return nullptr;
} }
if (!JS_SplicePrototype(cx, global, protoObj)) { JSAutoCompartment ac(cx, global);
JS_ClearPendingException(cx);
// It's important to create the nsIGlobalObject for our new global before we
// start trying to wrap things like the prototype into its compartment,
// because the wrap operation relies on the global having its
// nsIGlobalObject already.
RefPtr<SimpleGlobalObject> globalObject =
new SimpleGlobalObject(global, globalType);
// Pass on ownership of globalObject to |global|.
JS_SetPrivate(global, globalObject.forget().take());
if (proto.isObjectOrNull()) {
JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
if (!JS_WrapObject(cx, &protoObj)) {
jsapi.ClearException();
return nullptr;
}
if (!JS_SplicePrototype(cx, global, protoObj)) {
jsapi.ClearException();
return nullptr;
}
} else if (!proto.isUndefined()) {
// Bogus proto.
return nullptr; return nullptr;
} }
} else if (!proto.isUndefined()) {
// Bogus proto. JS_FireOnNewGlobalObject(cx, global);
return nullptr;
} }
JS_FireOnNewGlobalObject(cx, global);
return global; return global;
} }

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

@ -1 +0,0 @@
interface DummyInterface {};

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

@ -105,7 +105,7 @@ class TestWebIDLCodegenManager(unittest.TestCase):
"""generate_build_files() does the right thing from empty.""" """generate_build_files() does the right thing from empty."""
manager = self._get_manager() manager = self._get_manager()
result = manager.generate_build_files() result = manager.generate_build_files()
self.assertEqual(len(result.inputs), 5) self.assertEqual(len(result.inputs), 4)
output = manager.expected_build_output_files() output = manager.expected_build_output_files()
self.assertEqual(result.created, output) self.assertEqual(result.created, output)

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

@ -751,7 +751,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
mService = service; mService = service;
// Signal // Signal
JS::Rooted<JS::Value> value(nsContentUtils::RootingCxForThread()); JS::Rooted<JS::Value> value(dom::GetJSRuntime());
voiceInfo->GetRelSignalStrength(&value); voiceInfo->GetRelSignalStrength(&value);
if (value.isNumber()) { if (value.isNumber()) {
mSignal = (int)ceil(value.toNumber() / 20.0); mSignal = (int)ceil(value.toNumber() / 20.0);

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

@ -641,7 +641,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
} }
UpdateCIND(CINDType::SERVICE, service); UpdateCIND(CINDType::SERVICE, service);
JS::Rooted<JS::Value> value(nsContentUtils::RootingCxForThread()); JS::Rooted<JS::Value> value(dom::GetJSRuntime());
voiceInfo->GetRelSignalStrength(&value); voiceInfo->GetRelSignalStrength(&value);
if (value.isNumber()) { if (value.isNumber()) {
uint8_t signal = ceil(value.toNumber() / 20.0); uint8_t signal = ceil(value.toNumber() / 20.0);

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

@ -5539,7 +5539,7 @@ void
CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx, CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
double aDy, ErrorResult& aError) double aDy, ErrorResult& aError)
{ {
RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread()); RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCx());
DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject()); DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
MOZ_ASSERT(inited); MOZ_ASSERT(inited);
@ -5555,7 +5555,7 @@ CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
double aDirtyHeight, double aDirtyHeight,
ErrorResult& aError) ErrorResult& aError)
{ {
RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread()); RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCx());
DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject()); DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
MOZ_ASSERT(inited); MOZ_ASSERT(inited);

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

@ -974,112 +974,117 @@ WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName)
// Cool! We've checked out ok. Just need to initialize. // Cool! We've checked out ok. Just need to initialize.
//////
// Check if we need to initialize anything // Check if we need to initialize anything
{
bool hasUninitializedAttachments = false;
if (mColorAttachment0.HasImage() && IsDrawBuffer(0)) std::vector<WebGLFBAttachPoint*> tex3DToClear;
hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData();
size_t i = 1; const auto fnGatherIf3D = [&](WebGLFBAttachPoint& attach) {
for (const auto& cur : mMoreColorAttachments) { if (!attach.Texture())
if (cur.HasImage() && IsDrawBuffer(i)) return false;
hasUninitializedAttachments |= cur.HasUninitializedImageData();
++i; const auto& info = attach.Texture()->ImageInfoAt(attach.ImageTarget(),
} attach.MipLevel());
if (info.mDepth == 1)
return false;
if (mDepthAttachment.HasImage()) tex3DToClear.push_back(&attach);
hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData(); return true;
if (mStencilAttachment.HasImage()) };
hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData();
if (mDepthStencilAttachment.HasImage())
hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData();
if (!hasUninitializedAttachments) //////
return true;
}
// Get buffer-bit-mask and color-attachment-mask-list
uint32_t clearBits = 0; uint32_t clearBits = 0;
std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE); std::vector<GLenum> drawBuffersForClear(1 + mMoreColorAttachments.Size(),
LOCAL_GL_NONE);
std::vector<WebGLFBAttachPoint*> attachmentsToClear;
attachmentsToClear.reserve(1 + mMoreColorAttachments.Size() + 3);
const auto fnGatherColor = [&](WebGLFBAttachPoint& attach, uint32_t colorAttachNum) {
if (!IsDrawBuffer(colorAttachNum) || !attach.HasUninitializedImageData())
return;
if (fnGatherIf3D(attach))
return;
attachmentsToClear.push_back(&attach);
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT; clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0; drawBuffersForClear[colorAttachNum] = LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachNum;
};
const auto fnGatherOther = [&](WebGLFBAttachPoint& attach, GLenum attachClearBits) {
if (!attach.HasUninitializedImageData())
return;
if (fnGatherIf3D(attach))
return;
attachmentsToClear.push_back(&attach);
clearBits |= attachClearBits;
};
//////
fnGatherColor(mColorAttachment0, 0);
size_t colorAttachNum = 1;
for (auto& cur : mMoreColorAttachments) {
fnGatherColor(cur, colorAttachNum);
++colorAttachNum;
} }
size_t i = 1; fnGatherOther(mDepthAttachment, LOCAL_GL_DEPTH_BUFFER_BIT);
for (const auto& cur : mMoreColorAttachments) { fnGatherOther(mStencilAttachment, LOCAL_GL_STENCIL_BUFFER_BIT);
if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) { fnGatherOther(mDepthStencilAttachment,
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT; LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
tempDrawBuffers[i] = LOCAL_GL_COLOR_ATTACHMENT0 + i;
}
++i; //////
}
if (mDepthAttachment.HasUninitializedImageData() ||
mDepthStencilAttachment.HasUninitializedImageData())
{
clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
}
if (mStencilAttachment.HasUninitializedImageData() ||
mDepthStencilAttachment.HasUninitializedImageData())
{
clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
}
mContext->MakeContextCurrent(); mContext->MakeContextCurrent();
const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) { if (clearBits) {
const GLenum* ptr = nullptr; const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
if (list.size()) { this->mContext->gl->fDrawBuffers(list.size(), list.data());
ptr = &(list[0]); };
const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
const bool hasDrawBuffers = (mContext->IsWebGL2() ||
mContext->IsExtensionEnabled(drawBufferExt));
if (hasDrawBuffers) {
fnDrawBuffers(drawBuffersForClear);
} }
this->mContext->gl->fDrawBuffers(list.size(), ptr);
};
const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers; ////////////
const bool hasDrawBuffers = (mContext->IsWebGL2() ||
mContext->IsExtensionEnabled(drawBufferExt));
if (hasDrawBuffers) { // Clear!
fnDrawBuffers(tempDrawBuffers); {
gl::ScopedBindFramebuffer autoBind(mContext->gl, mGLName);
mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
}
if (hasDrawBuffers) {
fnDrawBuffers(mDrawBuffers);
}
for (auto* cur : attachmentsToClear) {
cur->SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
}
} }
// Clear! //////
{
// This FB maybe bind to GL_READ_FRAMEBUFFER and glClear only
// clear GL_DRAW_FRAMEBUFFER. So bind FB to GL_DRAW_FRAMEBUFFER
// here.
gl::ScopedBindFramebuffer autoFB(mContext->gl, mGLName);
mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);
}
if (hasDrawBuffers) { for (auto* attach : tex3DToClear) {
fnDrawBuffers(mDrawBuffers); auto* tex = attach->Texture();
} if (!tex->InitializeImageData(funcName, attach->ImageTarget(),
attach->MipLevel()))
// Mark all the uninitialized images as initialized. {
if (mDepthAttachment.HasUninitializedImageData()) return false;
mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); }
if (mStencilAttachment.HasUninitializedImageData())
mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
if (mDepthStencilAttachment.HasUninitializedImageData())
mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
}
i = 1;
for (auto& cur : mMoreColorAttachments) {
if (cur.HasUninitializedImageData() && IsDrawBuffer(i))
cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
++i;
} }
return true; return true;

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

@ -370,7 +370,7 @@ WebGLTexture::TexOrSubImage(bool isSubImage, const char* funcName, TexImageTarge
} }
dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr( dom::RootedTypedArray<dom::Uint8ClampedArray> scopedArr(
nsContentUtils::RootingCxForThread()); nsContentUtils::RootingCx());
const RefPtr<gfx::SourceSurface> surf = FromImageData(mContext, funcName, unpackType, const RefPtr<gfx::SourceSurface> surf = FromImageData(mContext, funcName, unpackType,
imageData, &scopedArr); imageData, &scopedArr);
if (!surf) if (!surf)

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

@ -3975,8 +3975,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, uint64_t aValue,
return NS_OK; return NS_OK;
} }
JS::RootedValue value(nsContentUtils::RootingCxForThread(), JS::RootedValue value(GetJSRuntime(), JS_NumberValue((double)aValue));
JS_NumberValue((double)aValue));
return ResolveInternal(i, value); return ResolveInternal(i, value);
} }

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

@ -292,9 +292,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTargetHelper,
} \ } \
virtual nsIScriptContext * GetContextForEventHandlers(nsresult *aRv) { \ virtual nsIScriptContext * GetContextForEventHandlers(nsresult *aRv) { \
return _to GetContextForEventHandlers(aRv); \ return _to GetContextForEventHandlers(aRv); \
} \
virtual JSContext * GetJSContextForEventHandlers(void) { \
return _to GetJSContextForEventHandlers(); \
} }
#define NS_REALLY_FORWARD_NSIDOMEVENTTARGET(_class) \ #define NS_REALLY_FORWARD_NSIDOMEVENTTARGET(_class) \

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

@ -154,7 +154,7 @@ JSEventHandler::HandleEvent(nsIDOMEvent* aEvent)
columnNumber.Construct(); columnNumber.Construct();
columnNumber.Value() = scriptEvent->Colno(); columnNumber.Value() = scriptEvent->Colno();
error.Construct(nsContentUtils::RootingCxForThread()); error.Construct(GetJSRuntime());
scriptEvent->GetError(&error.Value()); scriptEvent->GetError(&error.Value());
} else { } else {
msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent(); msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();

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

@ -7,3 +7,4 @@ support-files =
[test_basic.html] [test_basic.html]
[test_webkitdirectory.html] [test_webkitdirectory.html]
[test_worker_basic.html] [test_worker_basic.html]
skip-if = true # bug 1283344

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

@ -26,12 +26,6 @@ LOCAL_INCLUDES += [
'/dom/ipc', '/dom/ipc',
] ]
if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
LOCAL_INCLUDES += [
'/dom/system/qt',
]
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'/dom/system/android', '/dom/system/android',

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

@ -35,10 +35,6 @@
class nsIPrincipal; class nsIPrincipal;
#ifdef MOZ_ENABLE_QT5GEOPOSITION
#include "QTMLocationProvider.h"
#endif
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
#include "AndroidLocationProvider.h" #include "AndroidLocationProvider.h"
#endif #endif
@ -698,10 +694,6 @@ nsresult nsGeolocationService::Init()
obs->AddObserver(this, "xpcom-shutdown", false); obs->AddObserver(this, "xpcom-shutdown", false);
#ifdef MOZ_ENABLE_QT5GEOPOSITION
mProvider = new QTMLocationProvider();
#endif
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
mProvider = new AndroidLocationProvider(); mProvider = new AndroidLocationProvider();
#endif #endif

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

@ -94,7 +94,7 @@ Icc::NotifyEvent(const nsAString& aName)
nsresult nsresult
Icc::NotifyStkEvent(const nsAString& aName, nsIStkProactiveCmd* aStkProactiveCmd) Icc::NotifyStkEvent(const nsAString& aName, nsIStkProactiveCmd* aStkProactiveCmd)
{ {
JSContext* cx = nsContentUtils::RootingCxForThread(); JSContext* cx = nsContentUtils::RootingCx();
JS::Rooted<JS::Value> value(cx); JS::Rooted<JS::Value> value(cx);
nsCOMPtr<nsIStkCmdFactory> cmdFactory = nsCOMPtr<nsIStkCmdFactory> cmdFactory =

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

@ -485,7 +485,7 @@ IndexedDatabaseManager::CommonPostHandleEvent(EventChainPostVisitor& aVisitor,
error->GetName(errorName); error->GetName(errorName);
} }
RootedDictionary<ErrorEventInit> init(nsContentUtils::RootingCxForThread()); RootedDictionary<ErrorEventInit> init(nsContentUtils::RootingCx());
request->GetCallerLocation(init.mFilename, &init.mLineno, &init.mColno); request->GetCallerLocation(init.mFilename, &init.mLineno, &init.mColno);
init.mMessage = errorName; init.mMessage = errorName;

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

@ -274,12 +274,6 @@ interface nsIDOMEventTarget : nsISupports
*/ */
[notxpcom, nostdcall] [notxpcom, nostdcall]
nsIScriptContext GetContextForEventHandlers(out nsresult aRv); nsIScriptContext GetContextForEventHandlers(out nsresult aRv);
/**
* If the method above returns null, but a success code, this method
* is called.
*/
[notxpcom, nostdcall] JSContextPtr GetJSContextForEventHandlers();
}; };
%{C++ %{C++
@ -287,8 +281,7 @@ interface nsIDOMEventTarget : nsISupports
#define NS_IMPL_DOMTARGET_DEFAULTS(_class) \ #define NS_IMPL_DOMTARGET_DEFAULTS(_class) \
mozilla::dom::EventTarget* _class::GetTargetForDOMEvent() { return this; } \ mozilla::dom::EventTarget* _class::GetTargetForDOMEvent() { return this; } \
mozilla::dom::EventTarget* _class::GetTargetForEventTargetChain() { return this; } \ mozilla::dom::EventTarget* _class::GetTargetForEventTargetChain() { return this; } \
nsresult _class::WillHandleEvent(mozilla::EventChainPostVisitor& aVisitor) { return NS_OK; } \ nsresult _class::WillHandleEvent(mozilla::EventChainPostVisitor& aVisitor) { return NS_OK; }
JSContext* _class::GetJSContextForEventHandlers() { return nullptr; }
#define NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(aClass) \ #define NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(aClass) \
NS_IMETHODIMP \ NS_IMETHODIMP \

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

@ -3339,12 +3339,6 @@ TabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
return NS_OK; return NS_OK;
} }
JSContext*
TabChildGlobal::GetJSContextForEventHandlers()
{
return nsContentUtils::GetSafeJSContext();
}
nsIPrincipal* nsIPrincipal*
TabChildGlobal::GetPrincipal() TabChildGlobal::GetPrincipal()
{ {

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

@ -138,7 +138,6 @@ public:
return NS_OK; return NS_OK;
} }
virtual JSContext* GetJSContextForEventHandlers() override;
virtual nsIPrincipal* GetPrincipal() override; virtual nsIPrincipal* GetPrincipal() override;
virtual JSObject* GetGlobalJSObject() override; virtual JSObject* GetGlobalJSObject() override;

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

@ -1073,7 +1073,7 @@ Notification::ConstructFromFields(
{ {
MOZ_ASSERT(aGlobal); MOZ_ASSERT(aGlobal);
RootedDictionary<NotificationOptions> options(nsContentUtils::RootingCxForThread()); RootedDictionary<NotificationOptions> options(nsContentUtils::RootingCx());
options.mDir = Notification::StringToDirection(nsString(aDir)); options.mDir = Notification::StringToDirection(nsString(aDir));
options.mLang = aLang; options.mLang = aLang;
options.mBody = aBody; options.mBody = aBody;

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

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* 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 <QtCore/QTimer>
#include "NestedLoopTimer.h"
#include "mozilla/plugins/PluginModuleChild.h"
namespace mozilla {
namespace plugins {
NestedLoopTimer::NestedLoopTimer(PluginModuleChild *pmc):
QObject(), mModule(pmc), mQTimer(nullptr)
{
}
NestedLoopTimer::~NestedLoopTimer()
{
if (mQTimer) {
mQTimer->stop();
delete mQTimer;
mQTimer = nullptr;
}
}
void NestedLoopTimer::timeOut()
{
// just detected a nested loop; start a timer that will
// periodically rpc-call back into the browser and process some
// events
mQTimer = new QTimer(this);
QObject::connect(mQTimer, SIGNAL(timeout()), this,
SLOT(processSomeEvents()));
mQTimer->setInterval(kNestedLoopDetectorIntervalMs);
mQTimer->start();
}
void NestedLoopTimer::processSomeEvents()
{
if (mModule)
mModule->CallProcessSomeEvents();
}
} /* namespace plugins */
} /* namespace mozilla */

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

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* 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 NESTEDLOOPTIMER_H
#define NESTEDLOOPTIMER_H
#include <QtCore/QObject>
class QTimer;
namespace mozilla {
namespace plugins {
class PluginModuleChild;
class NestedLoopTimer: public QObject
{
Q_OBJECT
public:
NestedLoopTimer(PluginModuleChild *pmc);
virtual ~NestedLoopTimer();
public Q_SLOTS:
virtual void timeOut();
virtual void processSomeEvents();
private:
PluginModuleChild *mModule;
QTimer *mQTimer;
};
} /* namespace plugins */
} /* namespace mozilla */
#undef slots
#endif

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

@ -1,18 +0,0 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginHelperQt.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
static const int kMaxtimeToProcessEvents = 30;
bool
PluginHelperQt::AnswerProcessSomeEvents()
{
QCoreApplication::processEvents(QEventLoop::AllEvents, kMaxtimeToProcessEvents);
return true;
}

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

@ -67,13 +67,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
'PluginInterposeOSX.h', 'PluginInterposeOSX.h',
] ]
if CONFIG['MOZ_ENABLE_QT']:
SOURCES += [
'!moc_NestedLoopTimer.cpp',
'NestedLoopTimer.cpp',
'PluginHelperQt.cpp',
]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'BrowserStreamChild.cpp', 'BrowserStreamChild.cpp',
'BrowserStreamParent.cpp', 'BrowserStreamParent.cpp',

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

@ -1,103 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
*
* Copyright (c) 2008, Mozilla Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the Mozilla Corporation nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributor(s):
* Josh Aas <josh@mozilla.com>
*
* ***** END LICENSE BLOCK ***** */
#include "nptest_platform.h"
#include "npapi.h"
using namespace std;
bool
pluginSupportsWindowMode()
{
return false;
}
bool
pluginSupportsWindowlessMode()
{
return true;
}
NPError
pluginInstanceInit(InstanceData* instanceData)
{
printf("NPERR_INCOMPATIBLE_VERSION_ERROR\n");
return NPERR_INCOMPATIBLE_VERSION_ERROR;
}
void
pluginInstanceShutdown(InstanceData* instanceData)
{
NPN_MemFree(instanceData->platformData);
instanceData->platformData = 0;
}
void
pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
{
instanceData->window = *newWindow;
}
void
pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
{
// XXX nothing here yet since we don't support windowed plugins
}
int16_t
pluginHandleEvent(InstanceData* instanceData, void* event)
{
return 0;
}
int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
int32_t pluginGetClipRegionRectCount(InstanceData* instanceData)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData,
int32_t rectIndex, RectEdge edge)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
{
}

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

@ -26,10 +26,6 @@ elif toolkit == 'android':
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nptest_droid.cpp', 'nptest_droid.cpp',
] ]
elif toolkit == 'qt':
UNIFIED_SOURCES += [
'nptest_qt.cpp',
]
elif toolkit == 'windows': elif toolkit == 'windows':
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nptest_windows.cpp', 'nptest_windows.cpp',
@ -61,13 +57,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
OS_LIBS += CONFIG['XLIBS'] OS_LIBS += CONFIG['XLIBS']
OS_LIBS += CONFIG['XEXT_LIBS'] OS_LIBS += CONFIG['XEXT_LIBS']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
CFLAGS += CONFIG['MOZ_QT_CFLAGS']
OS_LIBS += CONFIG['MOZ_QT_LIBS']
OS_LIBS += CONFIG['XLDFLAGS']
OS_LIBS += CONFIG['XLIBS']
if CONFIG['_MSC_VER']: if CONFIG['_MSC_VER']:
# This is intended as a temporary hack to support building with VS2015. # This is intended as a temporary hack to support building with VS2015.
# conversion from 'X' to 'Y' requires a narrowing conversion # conversion from 'X' to 'Y' requires a narrowing conversion

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

@ -430,11 +430,8 @@ private:
void MaybeSomething(T& aArgument, MaybeFunc aFunc) { void MaybeSomething(T& aArgument, MaybeFunc aFunc) {
MOZ_ASSERT(PromiseObj()); // It was preserved! MOZ_ASSERT(PromiseObj()); // It was preserved!
AutoJSAPI jsapi; AutoEntryScript aes(mGlobal, "Promise resolution or rejection");
if (!jsapi.Init(mGlobal)) { JSContext* cx = aes.cx();
return;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> val(cx);
if (!ToJSValue(cx, aArgument, &val)) { if (!ToJSValue(cx, aArgument, &val)) {

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

@ -324,6 +324,15 @@ SRICheckDataVerifier::VerifyHash(const SRIMetadata& aMetadata,
return NS_ERROR_SRI_CORRUPT; return NS_ERROR_SRI_CORRUPT;
} }
if (MOZ_LOG_TEST(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug)) {
nsAutoCString encodedHash;
nsresult rv = Base64Encode(mComputedHash, encodedHash);
if (NS_SUCCEEDED(rv)) {
SRILOG(("SRICheckDataVerifier::VerifyHash, mComputedHash=%s",
encodedHash.get()));
}
}
if (!binaryHash.Equals(mComputedHash)) { if (!binaryHash.Equals(mComputedHash)) {
SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] did not match", aHashIndex)); SRILOG(("SRICheckDataVerifier::VerifyHash, hash[%u] did not match", aHashIndex));
return NS_ERROR_SRI_CORRUPT; return NS_ERROR_SRI_CORRUPT;

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

@ -61,6 +61,25 @@
function bad_invalidBlobLoaded() { function bad_invalidBlobLoaded() {
ok(false, "We should not load stylesheets using blob: URLs when they have the wrong hash!"); ok(false, "We should not load stylesheets using blob: URLs when they have the wrong hash!");
} }
function good_correctUTF8HashLoaded() {
ok(true, "A UTF8 stylesheet was correctly loaded when integrity matched");
}
function bad_correctUTF8HashBlocked() {
ok(false, "We should load UTF8 stylesheets with hashes that match!");
}
function good_correctUTF8BOMHashLoaded() {
ok(true, "A UTF8 stylesheet (with BOM) was correctly loaded when integrity matched");
}
function bad_correctUTF8BOMHashBlocked() {
todo(false, "We should load UTF8 (with BOM) stylesheets with hashes that match!");
}
function good_correctUTF8ishHashLoaded() {
ok(true, "A UTF8ish stylesheet was correctly loaded when integrity matched");
}
function bad_correctUTF8ishHashBlocked() {
todo(false, "We should load UTF8ish stylesheets with hashes that match!");
}
</script> </script>
<!-- valid sha256 hash. should trigger onload --> <!-- valid sha256 hash. should trigger onload -->
@ -80,6 +99,24 @@
integrity="sha256-bogus" integrity="sha256-bogus"
onerror="good_incorrectHashBlocked()" onerror="good_incorrectHashBlocked()"
onload="bad_incorrectHashLoaded()"> onload="bad_incorrectHashLoaded()">
<!-- valid sha384 hash of a utf8 file. should trigger onload -->
<link rel="stylesheet" href="style4.css"
integrity="sha384-13rt+j7xMDLhohLukb7AZx8lDGS3hkahp0IoeuyvxSNVPyc1QQmTDcwXGhQZjoMH"
onerror="bad_correctUTF8HashBlocked()"
onload="good_correctUTF8HashLoaded()">
<!-- valid sha384 hash of a utf8 file with a BOM. should trigger onload -->
<link rel="stylesheet" href="style5.css"
integrity="sha384-udAqVKPIHf/OD1isAYKrgzsog/3Q6lSEL2nKhtLSTmHryiae0+y6x1akeTzEF446"
onerror="bad_correctUTF8BOMHashBlocked()"
onload="good_correctUTF8BOMHashLoaded()">
<!-- valid sha384 hash of a utf8 file with the wrong charset. should trigger onload -->
<link rel="stylesheet" href="style6.css"
integrity="sha384-Xli4ROFoVGCiRgXyl7y8jv5Vm2yuqj+8tkNL3cUI7AHaCocna75JLs5xID437W6C"
onerror="bad_correctUTF8ishHashBlocked()"
onload="good_correctUTF8ishHashLoaded()">
</head> </head>
<body> <body>
@ -109,7 +146,10 @@
document.body.appendChild(link); document.body.appendChild(link);
</script> </script>
<p><span id="red-text">This should be red </span> and <p><span id="red-text">This should be red </span>,
<span id="purple-text">this should be purple</span>,
<span id="brown-text">this should be brown</span>,
<span id="orange-text">this should be orange</span>, and
<span class="blue-text" id="blue-text-element">this should be blue.</span> <span class="blue-text" id="blue-text-element">this should be blue.</span>
However, <span id="black-text">this should stay black</span> and However, <span id="black-text">this should stay black</span> and
<span class="black-text" id="black-text-2">this should also stay black.</span> <span class="black-text" id="black-text-2">this should also stay black.</span>

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

@ -28,6 +28,11 @@ support-files =
style1.css^headers^ style1.css^headers^
style2.css style2.css
style3.css style3.css
style4.css
style4.css^headers^
style5.css
style6.css
style6.css^headers^
style_301.css style_301.css
style_301.css^headers^ style_301.css^headers^

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

@ -0,0 +1,4 @@
/* François was here. */
#purple-text {
color: purple;
}

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

@ -0,0 +1 @@
Content-Type: text/css; charset=utf-8

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

@ -0,0 +1,4 @@
/* François was here. */
#orange-text {
color: orange;
}

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

@ -0,0 +1,4 @@
/* François was here. */
#brown-text {
color: brown;
}

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

@ -0,0 +1 @@
Content-Type: text/css; charset=iso-8859-8

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

@ -596,7 +596,7 @@ AudioManager::Observe(nsISupports* aSubject,
// To process the volume control on each volume categories according to // To process the volume control on each volume categories according to
// change of settings // change of settings
else if (!strcmp(aTopic, MOZ_SETTINGS_CHANGE_ID)) { else if (!strcmp(aTopic, MOZ_SETTINGS_CHANGE_ID)) {
RootedDictionary<dom::SettingChangeNotification> setting(nsContentUtils::RootingCxForThread()); RootedDictionary<dom::SettingChangeNotification> setting(nsContentUtils::RootingCx());
if (!WrappedJSToDictionary(aSubject, setting)) { if (!WrappedJSToDictionary(aSubject, setting)) {
return NS_OK; return NS_OK;
} }

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

@ -247,7 +247,7 @@ AutoMounterSetting::Observe(nsISupports* aSubject,
// The string that we're interested in will be a JSON string that looks like: // The string that we're interested in will be a JSON string that looks like:
// {"key":"ums.autoMount","value":true} // {"key":"ums.autoMount","value":true}
RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCxForThread()); RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCx());
if (!WrappedJSToDictionary(aSubject, setting)) { if (!WrappedJSToDictionary(aSubject, setting)) {
return NS_OK; return NS_OK;
} }

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

@ -1,101 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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 "QTMLocationProvider.h"
#include "nsGeoPosition.h"
using namespace mozilla;
NS_IMPL_ISUPPORTS(QTMLocationProvider, nsIGeolocationProvider)
QTMLocationProvider::QTMLocationProvider()
{
if (QMetaType::type("QGeoPositionInfo") == QMetaType::UnknownType) {
qRegisterMetaType<QGeoPositionInfo>("QGeoPositionInfo");
}
mLocation = QGeoPositionInfoSource::createDefaultSource(this);
if (mLocation)
connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
}
QTMLocationProvider::~QTMLocationProvider()
{
delete mLocation;
}
void
QTMLocationProvider::positionUpdated(const QGeoPositionInfo &geoPosition)
{
if (!geoPosition.isValid()) {
NS_WARNING("Invalida geoposition received");
return;
}
QGeoCoordinate coord = geoPosition.coordinate();
double latitude = coord.latitude();
double longitude = coord.longitude();
double altitude = coord.altitude();
double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy);
double heading = geoPosition.attribute(QGeoPositionInfo::Direction);
bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed);
double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed);
RefPtr<nsGeoPosition> p =
new nsGeoPosition(latitude, longitude,
altitude, accuracy,
altitudeAccuracy, heading,
speed, geoPosition.timestamp().toTime_t());
if (mCallback) {
mCallback->Update(p);
}
}
NS_IMETHODIMP
QTMLocationProvider::Startup()
{
if (!mLocation)
return NS_ERROR_NOT_IMPLEMENTED;
// Not all versions of qt5positioning set default prefered method
// thus this workaround initializing QGeoPositionSource explicitly
SetHighAccuracy(false);
mLocation->startUpdates();
return NS_OK;
}
NS_IMETHODIMP
QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
mCallback = aCallback;
return NS_OK;
}
NS_IMETHODIMP
QTMLocationProvider::Shutdown()
{
if (!mLocation)
return NS_ERROR_NOT_IMPLEMENTED;
mLocation->stopUpdates();
mCallback = nullptr;
return NS_OK;
}
NS_IMETHODIMP
QTMLocationProvider::SetHighAccuracy(bool aHigh)
{
if (!mLocation)
return NS_ERROR_NOT_IMPLEMENTED;
mLocation->setPreferredPositioningMethods(aHigh ?
QGeoPositionInfoSource::SatellitePositioningMethods :
QGeoPositionInfoSource::AllPositioningMethods);
return NS_OK;
}

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

@ -1,35 +0,0 @@
/* 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 QTMLocationProvider_h
#define QTMLocationProvider_h
#include <QGeoPositionInfoSource>
#include "nsGeolocation.h"
#include "nsIGeolocationProvider.h"
#include "nsCOMPtr.h"
class QTMLocationProvider : public QObject,
public nsIGeolocationProvider
{
Q_OBJECT
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONPROVIDER
QTMLocationProvider();
public Q_SLOTS:
// QGeoPositionInfoSource
void positionUpdated(const QGeoPositionInfo&);
private:
~QTMLocationProvider();
QGeoPositionInfoSource* mLocation;
nsCOMPtr<nsIGeolocationUpdate> mCallback;
};
#endif /* QTMLocationProvider_h */

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

@ -1,20 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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 <QFeedbackEffect>
#include "QtHapticFeedback.h"
NS_IMPL_ISUPPORTS(QtHapticFeedback, nsIHapticFeedback)
NS_IMETHODIMP
QtHapticFeedback::PerformSimpleAction(int32_t aType)
{
if (aType == ShortPress)
QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressWeak);
if (aType == LongPress)
QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressStrong);
return NS_OK;
}

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

@ -1,15 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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 "nsIHapticFeedback.h"
class QtHapticFeedback : public nsIHapticFeedback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIHAPTICFEEDBACK
protected:
virtual ~QtHapticFeedback() {}
};

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

@ -1,26 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
SOURCES += [
'!moc_QTMLocationProvider.cpp',
'QTMLocationProvider.cpp',
]
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
LOCAL_INCLUDES += [
'/dom/geolocation',
]
if CONFIG['MOZ_ENABLE_QT5FEEDBACK']:
SOURCES += [
'QtHapticFeedback.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

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

@ -489,8 +489,6 @@ dictionary CameraDetectedFaceInit
DOMPointInit mouth; DOMPointInit mouth;
}; };
callback CameraFaceDetectionCallback = void (sequence<CameraDetectedFace> faces);
partial interface CameraControl partial interface CameraControl
{ {
/* Starts the face detection. This should be called after the preview is /* Starts the face detection. This should be called after the preview is

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

@ -1,13 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Dummy bindings that we need to force generation of things that
// aren't actually referenced anywhere in IDL yet but are used in C++.
interface DummyInterface {
void lifecycleCallbacks(optional LifecycleCallbacks arg);
void promiseJobCallback(PromiseJobCallback arg);
};

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

@ -10,8 +10,6 @@
* liability, trademark and document use rules apply. * liability, trademark and document use rules apply.
*/ */
callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)] [Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)]
interface OfflineAudioContext : AudioContext { interface OfflineAudioContext : AudioContext {

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

@ -13,24 +13,17 @@
[Exposed=(Window,DedicatedWorker,SharedWorker)] [Exposed=(Window,DedicatedWorker,SharedWorker)]
interface XMLHttpRequestEventTarget : EventTarget { interface XMLHttpRequestEventTarget : EventTarget {
// event handlers // event handlers
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onloadstart; attribute EventHandler onloadstart;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onprogress; attribute EventHandler onprogress;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onabort; attribute EventHandler onabort;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onerror; attribute EventHandler onerror;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onload; attribute EventHandler onload;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler ontimeout; attribute EventHandler ontimeout;
[SetterThrows=Workers, GetterThrows=Workers]
attribute EventHandler onloadend; attribute EventHandler onloadend;
}; };

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

@ -144,7 +144,6 @@ WEBIDL_FILES = [
'DOMTransaction.webidl', 'DOMTransaction.webidl',
'Downloads.webidl', 'Downloads.webidl',
'DragEvent.webidl', 'DragEvent.webidl',
'DummyBinding.webidl',
'DynamicsCompressorNode.webidl', 'DynamicsCompressorNode.webidl',
'Element.webidl', 'Element.webidl',
'Event.webidl', 'Event.webidl',

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

@ -6184,7 +6184,7 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
{ // scope for the AutoEntryScript, so it comes off the stack before we do { // scope for the AutoEntryScript, so it comes off the stack before we do
// Promise::PerformMicroTaskCheckpoint. // Promise::PerformMicroTaskCheckpoint.
AutoEntryScript aes(global, reason, false, aCx); AutoEntryScript aes(global, reason, false);
if (!info->mTimeoutCallable.isUndefined()) { if (!info->mTimeoutCallable.isUndefined()) {
JS::Rooted<JS::Value> rval(aCx); JS::Rooted<JS::Value> rval(aCx);
JS::HandleValueArray args = JS::HandleValueArray args =

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

@ -318,9 +318,7 @@ WorkerRunnable::Run()
JSContext* cx; JSContext* cx;
AutoJSAPI* jsapi; AutoJSAPI* jsapi;
if (globalObject) { if (globalObject) {
aes.emplace(globalObject, "Worker runnable", aes.emplace(globalObject, "Worker runnable", isMainThread);
isMainThread,
isMainThread ? nullptr : GetCurrentThreadJSContext());
jsapi = aes.ptr(); jsapi = aes.ptr();
cx = aes->cx(); cx = aes->cx();
} else { } else {

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

@ -507,7 +507,7 @@ public:
mReadyState(0), mUploadEvent(aUploadEvent), mProgressEvent(true), mReadyState(0), mUploadEvent(aUploadEvent), mProgressEvent(true),
mLengthComputable(aLengthComputable), mUseCachedArrayBufferResponse(false), mLengthComputable(aLengthComputable), mUseCachedArrayBufferResponse(false),
mResponseTextResult(NS_OK), mStatusResult(NS_OK), mResponseResult(NS_OK), mResponseTextResult(NS_OK), mStatusResult(NS_OK), mResponseResult(NS_OK),
mScopeObj(nsContentUtils::RootingCxForThread(), aScopeObj) mScopeObj(GetJSRuntime(), aScopeObj)
{ } { }
EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType, EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType,
@ -520,7 +520,7 @@ public:
mUploadEvent(aUploadEvent), mProgressEvent(false), mLengthComputable(0), mUploadEvent(aUploadEvent), mProgressEvent(false), mLengthComputable(0),
mUseCachedArrayBufferResponse(false), mResponseTextResult(NS_OK), mUseCachedArrayBufferResponse(false), mResponseTextResult(NS_OK),
mStatusResult(NS_OK), mResponseResult(NS_OK), mStatusResult(NS_OK), mResponseResult(NS_OK),
mScopeObj(nsContentUtils::RootingCxForThread(), aScopeObj) mScopeObj(GetJSRuntime(), aScopeObj)
{ } { }
private: private:

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

@ -18,7 +18,7 @@
#include "txXPathObjectAdaptor.h" #include "txXPathObjectAdaptor.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "nsContentUtils.h" #include "mozilla/dom/ScriptSettings.h"
#include "nsIClassInfo.h" #include "nsIClassInfo.h"
#include "nsIInterfaceInfo.h" #include "nsIInterfaceInfo.h"
#include "js/RootingAPI.h" #include "js/RootingAPI.h"
@ -384,7 +384,7 @@ txXPCOMExtensionFunctionCall::evaluate(txIEvalContext* aContext,
uint8_t paramCount = methodInfo->GetParamCount(); uint8_t paramCount = methodInfo->GetParamCount();
uint8_t inArgs = paramCount - 1; uint8_t inArgs = paramCount - 1;
JS::Rooted<txParamArrayHolder> invokeParams(nsContentUtils::RootingCxForThread()); JS::Rooted<txParamArrayHolder> invokeParams(mozilla::dom::GetJSRuntime());
if (!invokeParams.get().Init(paramCount)) { if (!invokeParams.get().Init(paramCount)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }

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

@ -476,6 +476,12 @@ CheckUserContextCompatibility(nsIDocShell* aDocShell)
return false; return false;
} }
// DocShell can have UsercontextID set but loading a document with system
// principal. In this case, we consider everything ok.
if (nsContentUtils::IsSystemPrincipal(subjectPrincipal)) {
return true;
}
uint32_t principalUserContextId; uint32_t principalUserContextId;
nsresult rv = subjectPrincipal->GetUserContextId(&principalUserContextId); nsresult rv = subjectPrincipal->GetUserContextId(&principalUserContextId);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, false);

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

@ -81,13 +81,6 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
SOURCES += [ SOURCES += [
'cairo-ps-surface.c', 'cairo-ps-surface.c',
] ]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
EXPORTS.cairo += [
'cairo-qt.h',
]
SOURCES += [
'cairo-qt-surface.cpp',
]
if CONFIG['MOZ_X11']: if CONFIG['MOZ_X11']:
EXPORTS.cairo += [ EXPORTS.cairo += [
@ -249,10 +242,6 @@ if CONFIG['GNU_CC'] and CONFIG['OS_TARGET'] == 'Android' and CONFIG['MOZ_OPTIMIZ
CFLAGS += ['-O2'] CFLAGS += ['-O2']
CXXFLAGS += ['-O2'] CXXFLAGS += ['-O2']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
CFLAGS += CONFIG['MOZ_QT_CFLAGS']
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']
if CONFIG['MOZ_X11']: if CONFIG['MOZ_X11']:
CFLAGS += CONFIG['XCFLAGS'] CFLAGS += CONFIG['XCFLAGS']

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

@ -91,6 +91,3 @@ CXXFLAGS += CONFIG['TK_CFLAGS']
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS'] CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']

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

@ -70,6 +70,9 @@ Decoder::Init()
// No re-initializing // No re-initializing
MOZ_ASSERT(!mInitialized, "Can't re-initialize a decoder!"); MOZ_ASSERT(!mInitialized, "Can't re-initialize a decoder!");
// All decoders must have a SourceBufferIterator.
MOZ_ASSERT(mIterator);
// It doesn't make sense to decode anything but the first frame if we can't // It doesn't make sense to decode anything but the first frame if we can't
// store anything in the SurfaceCache, since only the last frame we decode // store anything in the SurfaceCache, since only the last frame we decode
// will be retrievable. // will be retrievable.
@ -240,6 +243,12 @@ Decoder::SetTargetSize(const nsIntSize& aSize)
return NS_OK; return NS_OK;
} }
Maybe<IntSize>
Decoder::GetTargetSize()
{
return mDownscaler ? Some(mDownscaler->TargetSize()) : Nothing();
}
nsresult nsresult
Decoder::AllocateFrame(uint32_t aFrameNum, Decoder::AllocateFrame(uint32_t aFrameNum,
const nsIntSize& aTargetSize, const nsIntSize& aTargetSize,

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

@ -114,7 +114,14 @@ public:
* *
* This must be called before Init() is called. * This must be called before Init() is called.
*/ */
nsresult SetTargetSize(const nsIntSize& aSize); nsresult SetTargetSize(const gfx::IntSize& aSize);
/**
* If this decoder supports downscale-during-decode and is configured to
* downscale, returns the target size that the output size will be decoded to.
* Otherwise, returns Nothing().
*/
Maybe<gfx::IntSize> GetTargetSize();
/** /**
* Set the requested sample size for this decoder. Used to implement the * Set the requested sample size for this decoder. Used to implement the
@ -126,12 +133,10 @@ public:
/** /**
* Set an iterator to the SourceBuffer which will feed data to this decoder. * Set an iterator to the SourceBuffer which will feed data to this decoder.
* This must always be called before calling Init(). (And only before Init().)
* *
* This should be called for almost all decoders; the exceptions are the * XXX(seth): We should eliminate this method and pass a SourceBufferIterator
* contained decoders of an nsICODecoder, which will be fed manually via Write * to the various decoder constructors instead.
* instead.
*
* This must be called before Init() is called.
*/ */
void SetIterator(SourceBufferIterator&& aIterator) void SetIterator(SourceBufferIterator&& aIterator)
{ {
@ -247,27 +252,24 @@ public:
ImageMetadata& GetImageMetadata() { return mImageMetadata; } ImageMetadata& GetImageMetadata() { return mImageMetadata; }
/** /**
* Returns a weak pointer to the image associated with this decoder. * @return a weak pointer to the image associated with this decoder. Illegal
* to call if this decoder is not associated with an image.
*/ */
RasterImage* GetImage() const { MOZ_ASSERT(mImage); return mImage.get(); } RasterImage* GetImage() const { MOZ_ASSERT(mImage); return mImage.get(); }
/**
* @return a possibly-null weak pointer to the image associated with this
* decoder. May be called even if this decoder is not associated with an
* image.
*/
RasterImage* GetImageMaybeNull() const { return mImage.get(); }
RawAccessFrameRef GetCurrentFrameRef() RawAccessFrameRef GetCurrentFrameRef()
{ {
return mCurrentFrame ? mCurrentFrame->RawAccessRef() return mCurrentFrame ? mCurrentFrame->RawAccessRef()
: RawAccessFrameRef(); : RawAccessFrameRef();
} }
/**
* Writes data to the decoder. Only public for the benefit of nsICODecoder;
* other callers should use Decode().
*
* @param aBuffer buffer containing the data to be written
* @param aCount the number of bytes to write
*
* Any errors are reported by setting the appropriate state on the decoder.
*/
void Write(const char* aBuffer, uint32_t aCount);
protected: protected:
friend class nsICODecoder; friend class nsICODecoder;
@ -357,6 +359,16 @@ protected:
void PostDataError(); void PostDataError();
void PostDecoderError(nsresult aFailCode); void PostDecoderError(nsresult aFailCode);
/**
* Called by Decode() to write data to the decoder.
*
* @param aBuffer A buffer containing the data to be written.
* @param aCount The number of bytes to write.
*
* Any errors are reported by setting the appropriate state on the decoder.
*/
void Write(const char* aBuffer, uint32_t aCount);
/** /**
* CompleteDecode() finishes up the decoding process after Decode() determines * CompleteDecode() finishes up the decoding process after Decode() determines
* that we're finished. It records final progress and does all the cleanup * that we're finished. It records final progress and does all the cleanup

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

@ -227,6 +227,54 @@ DecoderFactory::CreateMetadataDecoder(DecoderType aType,
return task.forget(); return task.forget();
} }
/* static */ already_AddRefed<Decoder>
DecoderFactory::CreateDecoderForICOResource(DecoderType aType,
NotNull<SourceBuffer*> aSourceBuffer,
NotNull<nsICODecoder*> aICODecoder,
const Maybe<uint32_t>& aDataOffset
/* = Nothing() */)
{
// Create the decoder.
RefPtr<Decoder> decoder;
switch (aType) {
case DecoderType::BMP:
MOZ_ASSERT(aDataOffset);
decoder = new nsBMPDecoder(aICODecoder->GetImageMaybeNull(), *aDataOffset);
break;
case DecoderType::PNG:
MOZ_ASSERT(!aDataOffset);
decoder = new nsPNGDecoder(aICODecoder->GetImageMaybeNull());
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ICO resource decoder type");
return nullptr;
}
MOZ_ASSERT(decoder);
// Initialize the decoder, copying settings from @aICODecoder.
decoder->SetMetadataDecode(aICODecoder->IsMetadataDecode());
decoder->SetIterator(aSourceBuffer->Iterator());
decoder->SetDecoderFlags(aICODecoder->GetDecoderFlags());
decoder->SetSurfaceFlags(aICODecoder->GetSurfaceFlags());
// Set a target size for downscale-during-decode if applicable.
const Maybe<IntSize> targetSize = aICODecoder->GetTargetSize();
if (targetSize) {
DebugOnly<nsresult> rv = decoder->SetTargetSize(*targetSize);
MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
}
decoder->Init();
if (NS_FAILED(decoder->GetDecoderError())) {
return nullptr;
}
return decoder.forget();
}
/* static */ already_AddRefed<Decoder> /* static */ already_AddRefed<Decoder>
DecoderFactory::CreateAnonymousDecoder(DecoderType aType, DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
NotNull<SourceBuffer*> aSourceBuffer, NotNull<SourceBuffer*> aSourceBuffer,

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

@ -20,6 +20,7 @@ namespace image {
class Decoder; class Decoder;
class IDecodingTask; class IDecodingTask;
class nsICODecoder;
class RasterImage; class RasterImage;
class SourceBuffer; class SourceBuffer;
@ -119,6 +120,29 @@ public:
NotNull<SourceBuffer*> aSourceBuffer, NotNull<SourceBuffer*> aSourceBuffer,
int aSampleSize); int aSampleSize);
/**
* Creates and initializes a decoder for an ICO resource, which may be either
* a BMP or PNG image.
*
* @param aType Which type of decoder to create. This must be either BMP or
* PNG.
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
* from.
* @param aICODecoder The ICO decoder which is controlling this resource
* decoder. @aICODecoder's settings will be copied to the
* resource decoder, so the two decoders will have the
* same decoder flags, surface flags, target size, and
* other parameters.
* @param aDataOffset If @aType is BMP, specifies the offset at which data
* begins in the BMP resource. Must be Some() if and only
* if @aType is BMP.
*/
static already_AddRefed<Decoder>
CreateDecoderForICOResource(DecoderType aType,
NotNull<SourceBuffer*> aSourceBuffer,
NotNull<nsICODecoder*> aICODecoder,
const Maybe<uint32_t>& aDataOffset = Nothing());
/** /**
* Creates and initializes an anonymous decoder (one which isn't associated * Creates and initializes an anonymous decoder (one which isn't associated
* with an Image object). Only the first frame of the image will be decoded. * with an Image object). Only the first frame of the image will be decoded.

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

@ -138,6 +138,13 @@ SourceBuffer::Compact()
length += mChunks[i].Length(); length += mChunks[i].Length();
} }
// If our total length is zero (which means ExpectLength() got called, but no
// data ever actually got written) then just empty our chunk list.
if (MOZ_UNLIKELY(length == 0)) {
mChunks.Clear();
return NS_OK;
}
Maybe<Chunk> newChunk = CreateChunk(length, /* aRoundUp = */ false); Maybe<Chunk> newChunk = CreateChunk(length, /* aRoundUp = */ false);
if (MOZ_UNLIKELY(!newChunk || newChunk->AllocationFailed())) { if (MOZ_UNLIKELY(!newChunk || newChunk->AllocationFailed())) {
NS_WARNING("Failed to allocate chunk for SourceBuffer compacting - OOM?"); NS_WARNING("Failed to allocate chunk for SourceBuffer compacting - OOM?");

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

@ -1,141 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 cin et: */
/* 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/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function GtkQtIconsConverter()
{ };
GtkQtIconsConverter.prototype =
{
classID: Components.ID("{c0783c34-a831-40c6-8c03-98c9f74cca45}"),
QueryInterface: XPCOMUtils.generateQI(
[Components.interfaces.nsIGtkQtIconsConverter]),
convert: function(icon) { return this._gtk_qt_icons_table[icon]; },
_gtk_qt_icons_table:
{
'about':
0,
'add':
0,
'apply':
44, // QStyle::SP_DialogApplyButton
'cancel':
39, // QStyle::SP_DialogCancelButton
'clear':
45, // QStyle::SP_DialogResetButton
'color-picker':
0,
'copy':
0,
'close':
43, // QStyle::SP_DialogCloseButton
'cut':
0,
'delete':
0,
'dialog-error':
0,
'dialog-info':
0,
'dialog-question':
12, // QStyle::SP_MessageBoxQuestion
'dialog-warning':
10, // QStyle::SP_MessageBoxWarning
'directory':
37, // QStyle::SP_DirIcon
'file':
24, // QStyle::SP_FileIcon
'find':
0,
'go-back-ltr':
53, // QStyle::SP_ArrowBack
'go-back-rtl':
53, // QStyle::SP_ArrowBack
'go-back':
53, // QStyle::SP_ArrowBack
'go-forward-ltr':
54, // QStyle::SP_ArrowForward
'go-forward-rtl':
54, // QStyle::SP_ArrowForward
'go-forward':
54, // QStyle::SP_ArrowForward
'go-up':
49, // QStyle::SP_ArrowUp
'goto-first':
0,
'goto-last':
0,
'help':
7, // QStyle::SP_TitleBarContextHelpButton
'home':
55, // QStyle::SP_DirHomeIcon
'info':
9, // QStyle::SP_MessageBoxInformation
'jump-to':
0,
'media-pause':
0,
'media-play':
0,
'network':
20, // QStyle::SP_DriveNetIcon
'no':
48, // QStyle::SP_DialogNoButton
'ok':
38, // QStyle::SP_DialogOkButton
'open':
21, // QStyle::SP_DirOpenIcon
'orientation-landscape':
0,
'orientation-portrait':
0,
'paste':
0,
'preferences':
34, // QStyle::SP_FileDialogContentsView
'print-preview':
0,
'print':
0,
'properties':
0,
'quit':
0,
'redo':
0,
'refresh':
58, // QStyle::SP_BrowserReload
'remove':
0,
'revert-to-saved':
0,
'save-as':
42, // QStyle::SP_DialogSaveButton
'save':
42, // QStyle::SP_DialogSaveButton
'select-all':
0,
'select-font':
0,
'stop':
59, // QStyle::SP_BrowserStop
'undelete':
0,
'undo':
0,
'yes':
47, // QStyle::SP_DialogYesButton
'zoom-100':
0,
'zoom-in':
0,
'zoom-out':
0
},
}
var components = [GtkQtIconsConverter];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

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

@ -1,2 +0,0 @@
component {c0783c34-a831-40c6-8c03-98c9f74cca45} gtkqticonsconverter.js
contract @mozilla.org/gtkqticonsconverter;1 {c0783c34-a831-40c6-8c03-98c9f74cca45}

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

@ -1,27 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
'nsGtkQtIconsConverter.idl',
]
XPIDL_MODULE = 'gtkqticonsconverter'
SOURCES += [
'nsIconChannel.cpp',
]
EXTRA_COMPONENTS += [
'gtkqticonsconverter.manifest',
]
EXTRA_PP_COMPONENTS += [
'gtkqticonsconverter.js',
]
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']

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

@ -1,12 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 cin et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(c0783c34-a831-40c6-8c03-98c9f74cca45)]
interface nsIGtkQtIconsConverter : nsISupports
{
long convert(in string icon);
};

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

@ -1,133 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 cin et: */
/* 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 <QIcon>
#include <stdlib.h>
#include <unistd.h>
#include "mozilla/EndianUtils.h"
#include "nsMimeTypes.h"
#include "nsIMIMEService.h"
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsNullPrincipal.h"
#include "nsIURL.h"
#include "nsIconChannel.h"
#include "nsGtkQtIconsConverter.h"
NS_IMPL_ISUPPORTS(nsIconChannel,
nsIRequest,
nsIChannel)
static nsresult
moz_qicon_to_channel(QImage* image, nsIURI* aURI,
nsIChannel** aChannel)
{
NS_ENSURE_ARG_POINTER(image);
int width = image->width();
int height = image->height();
NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0,
NS_ERROR_UNEXPECTED);
const int n_channels = 4;
long int buf_size = 2 + n_channels * height * width;
uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size);
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint8_t* out = buf;
*(out++) = width;
*(out++) = height;
const uchar* const pixels = image->bits();
int rowextra = image->bytesPerLine() - width * n_channels;
// encode the RGB data and the A data
const uchar* in = pixels;
for (int y = 0; y < height; ++y, in += rowextra) {
for (int x = 0; x < width; ++x) {
uint8_t r = *(in++);
uint8_t g = *(in++);
uint8_t b = *(in++);
uint8_t a = *(in++);
#define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
#if MOZ_LITTLE_ENDIAN
*(out++) = DO_PREMULTIPLY(b);
*(out++) = DO_PREMULTIPLY(g);
*(out++) = DO_PREMULTIPLY(r);
*(out++) = a;
#else
*(out++) = a;
*(out++) = DO_PREMULTIPLY(r);
*(out++) = DO_PREMULTIPLY(g);
*(out++) = DO_PREMULTIPLY(b);
#endif
#undef DO_PREMULTIPLY
}
}
NS_ASSERTION(out == buf + buf_size, "size miscalculation");
nsresult rv;
nsCOMPtr<nsIStringInputStream> stream =
do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = stream->AdoptData((char*)buf, buf_size);
NS_ENSURE_SUCCESS(rv, rv);
// nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
// this iconChannel. Use the most restrictive security settings for the
// temporary loadInfo to make sure the channel can not be openend.
nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
return NS_NewInputStreamChannel(aChannel,
aURI,
stream,
nullPrincipal,
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
nsIContentPolicy::TYPE_INTERNAL_IMAGE,
NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}
nsresult
nsIconChannel::Init(nsIURI* aURI)
{
nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
nsAutoCString stockIcon;
iconURI->GetStockIcon(stockIcon);
nsAutoCString iconSizeString;
iconURI->GetIconSize(iconSizeString);
uint32_t desiredImageSize;
iconURI->GetImageSize(&desiredImageSize);
nsAutoCString iconStateString;
iconURI->GetIconState(iconStateString);
bool disabled = iconStateString.EqualsLiteral("disabled");
// This is a workaround for
// https://bugzilla.mozilla.org/show_bug.cgi?id=662299
// Try to find corresponding freedesktop icon and fallback to empty QIcon
// if failed.
QIcon icon = QIcon::fromTheme(QString(stockIcon.get()).replace("gtk-",
"edit-"));
QPixmap pixmap = icon.pixmap(desiredImageSize, desiredImageSize,
disabled ? QIcon::Disabled : QIcon::Normal);
QImage image = pixmap.toImage();
return moz_qicon_to_channel(&image, iconURI,
getter_AddRefs(mRealChannel));
}

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

@ -1,40 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 cin et: */
/* 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_image_encoders_icon_qt_nsIconChannel_h
#define mozilla_image_encoders_icon_qt_nsIconChannel_h
#include "mozilla/Attributes.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
#include "nsIIconURI.h"
#include "nsCOMPtr.h"
/// This class is the gnome implementation of nsIconChannel. It basically asks
/// qt for an icon, and creates a new channel for
/// that file to which all calls will be proxied.
class nsIconChannel final : public nsIChannel {
public:
NS_DECL_ISUPPORTS
NS_FORWARD_NSIREQUEST(mRealChannel->)
NS_FORWARD_NSICHANNEL(mRealChannel->)
nsIconChannel() { };
/// Called by nsIconProtocolHandler after it creates this channel.
/// Must be called before calling any other function on this object.
/// If this method fails, no other function must be called on this object.
nsresult Init(nsIURI* aURI);
private:
~nsIconChannel() { };
/// The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html).
/// Will always be non-null after a successful Init.
nsCOMPtr<nsIChannel> mRealChannel;
};
#endif // mozilla_image_encoders_icon_qt_nsIconChannel_h

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

@ -10,8 +10,6 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
# fix that another time. # fix that another time.
if 'gtk' in toolkit: if 'gtk' in toolkit:
DIRS += ['icon/gtk', 'icon'] DIRS += ['icon/gtk', 'icon']
elif toolkit == 'qt':
DIRS += ['icon/qt', 'icon']
if CONFIG['OS_ARCH'] == 'WINNT': if CONFIG['OS_ARCH'] == 'WINNT':
DIRS += ['icon/win', 'icon'] DIRS += ['icon/win', 'icon']

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

@ -156,7 +156,6 @@ public:
private: private:
friend class DecoderFactory; friend class DecoderFactory;
friend class nsICODecoder;
enum class State { enum class State {
FILE_HEADER, FILE_HEADER,
@ -172,12 +171,10 @@ private:
RLE_ABSOLUTE RLE_ABSOLUTE
}; };
// This is the constructor used by DecoderFactory. // This is the constructor used for normal BMP images.
explicit nsBMPDecoder(RasterImage* aImage); explicit nsBMPDecoder(RasterImage* aImage);
// This is the constructor used by nsICODecoder. // This is the constructor used for BMP resources in ICO images.
// XXX(seth): nsICODecoder is temporarily an exception to the rule that
// decoders should only be instantiated via DecoderFactory.
nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset); nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
// Helper constructor called by the other two. // Helper constructor called by the other two.

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

@ -54,6 +54,7 @@ nsICODecoder::GetNumColors()
nsICODecoder::nsICODecoder(RasterImage* aImage) nsICODecoder::nsICODecoder(RasterImage* aImage)
: Decoder(aImage) : Decoder(aImage)
, mLexer(Transition::To(ICOState::HEADER, ICOHEADERSIZE)) , mLexer(Transition::To(ICOState::HEADER, ICOHEADERSIZE))
, mDoNotResume(WrapNotNull(new DoNotResume))
, mBiggestResourceColorDepth(0) , mBiggestResourceColorDepth(0)
, mBestResourceDelta(INT_MIN) , mBestResourceDelta(INT_MIN)
, mBestResourceColorDepth(0) , mBestResourceColorDepth(0)
@ -88,9 +89,18 @@ nsICODecoder::GetFinalStateFromContainedDecoder()
return; return;
} }
// Finish the internally used decoder. MOZ_ASSERT(mContainedSourceBuffer,
mContainedDecoder->CompleteDecode(); "Should have a SourceBuffer if we have a decoder");
// Let the contained decoder finish up if necessary.
if (!mContainedSourceBuffer->IsComplete()) {
mContainedSourceBuffer->Complete(NS_OK);
if (NS_FAILED(mContainedDecoder->Decode(mDoNotResume))) {
PostDataError();
}
}
// Make our state the same as the state of the contained decoder.
mDecodeDone = mContainedDecoder->GetDecodeDone(); mDecodeDone = mContainedDecoder->GetDecodeDone();
mDataError = mDataError || mContainedDecoder->HasDataError(); mDataError = mDataError || mContainedDecoder->HasDataError();
mFailCode = NS_SUCCEEDED(mFailCode) ? mContainedDecoder->GetDecoderError() mFailCode = NS_SUCCEEDED(mFailCode) ? mContainedDecoder->GetDecoderError()
@ -291,14 +301,12 @@ nsICODecoder::SniffResource(const char* aData)
PNGSIGNATURESIZE); PNGSIGNATURESIZE);
if (isPNG) { if (isPNG) {
// Create a PNG decoder which will do the rest of the work for us. // Create a PNG decoder which will do the rest of the work for us.
mContainedDecoder = new nsPNGDecoder(mImage); mContainedSourceBuffer = new SourceBuffer();
mContainedDecoder->SetMetadataDecode(IsMetadataDecode()); mContainedSourceBuffer->ExpectLength(mDirEntry.mBytesInRes);
mContainedDecoder->SetDecoderFlags(GetDecoderFlags()); mContainedDecoder =
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags()); DecoderFactory::CreateDecoderForICOResource(DecoderType::PNG,
if (mDownscaler) { WrapNotNull(mContainedSourceBuffer),
mContainedDecoder->SetTargetSize(mDownscaler->TargetSize()); WrapNotNull(this));
}
mContainedDecoder->Init();
if (!WriteToContainedDecoder(aData, PNGSIGNATURESIZE)) { if (!WriteToContainedDecoder(aData, PNGSIGNATURESIZE)) {
return Transition::TerminateFailure(); return Transition::TerminateFailure();
@ -371,15 +379,15 @@ nsICODecoder::ReadBIH(const char* aData)
// Create a BMP decoder which will do most of the work for us; the exception // Create a BMP decoder which will do most of the work for us; the exception
// is the AND mask, which isn't present in standalone BMPs. // is the AND mask, which isn't present in standalone BMPs.
RefPtr<nsBMPDecoder> bmpDecoder = new nsBMPDecoder(mImage, dataOffset); mContainedSourceBuffer = new SourceBuffer();
mContainedDecoder = bmpDecoder; mContainedSourceBuffer->ExpectLength(mDirEntry.mBytesInRes);
mContainedDecoder->SetMetadataDecode(IsMetadataDecode()); mContainedDecoder =
mContainedDecoder->SetDecoderFlags(GetDecoderFlags()); DecoderFactory::CreateDecoderForICOResource(DecoderType::BMP,
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags()); WrapNotNull(mContainedSourceBuffer),
if (mDownscaler) { WrapNotNull(this),
mContainedDecoder->SetTargetSize(mDownscaler->TargetSize()); Some(dataOffset));
} RefPtr<nsBMPDecoder> bmpDecoder =
mContainedDecoder->Init(); static_cast<nsBMPDecoder*>(mContainedDecoder.get());
// Verify that the BIH width and height values match the ICO directory entry, // Verify that the BIH width and height values match the ICO directory entry,
// and fix the BIH height value to compensate for the fact that the underlying // and fix the BIH height value to compensate for the fact that the underlying
@ -639,7 +647,22 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
bool bool
nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount) nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount)
{ {
mContainedDecoder->Write(aBuffer, aCount); MOZ_ASSERT(mContainedDecoder);
MOZ_ASSERT(mContainedSourceBuffer);
// Append the provided data to the SourceBuffer that the contained decoder is
// reading from.
mContainedSourceBuffer->Append(aBuffer, aCount);
// Write to the contained decoder. If we run out of data, the ICO decoder will
// get resumed when there's more data available, as usual, so we don't need
// the contained decoder to get resumed too. To avoid that, we provide an
// IResumable which just does nothing.
if (NS_FAILED(mContainedDecoder->Decode(mDoNotResume))) {
PostDataError();
}
// Make our state the same as the state of the contained decoder.
mProgress |= mContainedDecoder->TakeProgress(); mProgress |= mContainedDecoder->TakeProgress();
mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect()); mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
if (mContainedDecoder->HasDataError()) { if (mContainedDecoder->HasDataError()) {
@ -648,6 +671,7 @@ nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount)
if (mContainedDecoder->HasDecoderError()) { if (mContainedDecoder->HasDecoderError()) {
PostDecoderError(mContainedDecoder->GetDecoderError()); PostDecoderError(mContainedDecoder->GetDecoderError());
} }
return !HasError(); return !HasError();
} }

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

@ -10,10 +10,11 @@
#include "StreamingLexer.h" #include "StreamingLexer.h"
#include "Decoder.h" #include "Decoder.h"
#include "imgFrame.h" #include "imgFrame.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/NotNull.h"
#include "nsBMPDecoder.h" #include "nsBMPDecoder.h"
#include "nsPNGDecoder.h" #include "nsPNGDecoder.h"
#include "ICOFileHeaders.h" #include "ICOFileHeaders.h"
#include "mozilla/gfx/2D.h"
namespace mozilla { namespace mozilla {
namespace image { namespace image {
@ -110,8 +111,22 @@ private:
LexerTransition<ICOState> FinishMask(); LexerTransition<ICOState> FinishMask();
LexerTransition<ICOState> FinishResource(); LexerTransition<ICOState> FinishResource();
// A helper implementation of IResumable which just does nothing; see
// WriteToContainedDecoder() for more details.
class DoNotResume final : public IResumable
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DoNotResume, override)
void Resume() override { }
private:
virtual ~DoNotResume() { }
};
StreamingLexer<ICOState, 32> mLexer; // The lexer. StreamingLexer<ICOState, 32> mLexer; // The lexer.
RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder. RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
RefPtr<SourceBuffer> mContainedSourceBuffer; // SourceBuffer for mContainedDecoder.
NotNull<RefPtr<IResumable>> mDoNotResume; // IResumable helper for SourceBuffer.
UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask. UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header. char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
IconDirEntry mDirEntry; // The dir entry for the selected resource. IconDirEntry mDirEntry; // The dir entry for the selected resource.

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

@ -998,6 +998,38 @@ nsPNGDecoder::SpeedHistogram()
return Telemetry::IMAGE_DECODE_SPEED_PNG; return Telemetry::IMAGE_DECODE_SPEED_PNG;
} }
bool
nsPNGDecoder::IsValidICO() const
{
// Only 32-bit RGBA PNGs are valid ICO resources; see here:
// http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
// If there are errors in the call to png_get_IHDR, the error_callback in
// nsPNGDecoder.cpp is called. In this error callback we do a longjmp, so
// we need to save the jump buffer here. Oterwise we'll end up without a
// proper callstack.
if (setjmp(png_jmpbuf(mPNG))) {
// We got here from a longjmp call indirectly from png_get_IHDR
return false;
}
png_uint_32
png_width, // Unused
png_height; // Unused
int png_bit_depth,
png_color_type;
if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
&png_color_type, nullptr, nullptr, nullptr)) {
return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_color_type == PNG_COLOR_TYPE_RGB) &&
png_bit_depth == 8);
} else {
return false;
}
}
} // namespace image } // namespace image
} // namespace mozilla } // namespace mozilla

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

@ -26,12 +26,13 @@ public:
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override; virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
virtual Telemetry::ID SpeedHistogram() override; virtual Telemetry::ID SpeedHistogram() override;
/// @return true if this PNG is a valid ICO resource.
bool IsValidICO() const;
private: private:
friend class DecoderFactory; friend class DecoderFactory;
friend class nsICODecoder;
// Decoders should only be instantiated via DecoderFactory. // Decoders should only be instantiated via DecoderFactory.
// XXX(seth): nsICODecoder is temporarily an exception to this rule.
explicit nsPNGDecoder(RasterImage* aImage); explicit nsPNGDecoder(RasterImage* aImage);
nsresult CreateFrame(gfx::SurfaceFormat aFormat, nsresult CreateFrame(gfx::SurfaceFormat aFormat,
@ -54,37 +55,6 @@ private:
void WriteRow(uint8_t* aRow); void WriteRow(uint8_t* aRow);
// Check if PNG is valid ICO (32bpp RGBA)
// http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
bool IsValidICO() const
{
// If there are errors in the call to png_get_IHDR, the error_callback in
// nsPNGDecoder.cpp is called. In this error callback we do a longjmp, so
// we need to save the jump buffer here. Oterwise we'll end up without a
// proper callstack.
if (setjmp(png_jmpbuf(mPNG))) {
// We got here from a longjmp call indirectly from png_get_IHDR
return false;
}
png_uint_32
png_width, // Unused
png_height; // Unused
int png_bit_depth,
png_color_type;
if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
&png_color_type, nullptr, nullptr, nullptr)) {
return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_color_type == PNG_COLOR_TYPE_RGB) &&
png_bit_depth == 8);
} else {
return false;
}
}
enum class State enum class State
{ {
PNG_DATA, PNG_DATA,

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

@ -66,6 +66,3 @@ GENERATED_FILES += [
langgroups = GENERATED_FILES['langGroups.properties.h'] langgroups = GENERATED_FILES['langGroups.properties.h']
langgroups.script = 'props2arrays.py' langgroups.script = 'props2arrays.py'
langgroups.inputs = ['langGroups.properties'] langgroups.inputs = ['langGroups.properties']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']

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

@ -10,7 +10,3 @@ RESOURCE_FILES.entityTables = [
'html40Symbols.properties', 'html40Symbols.properties',
'mathml20.properties', 'mathml20.properties',
] ]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
CFLAGS += CONFIG['MOZ_QT_CFLAGS']
CXXFLAGS += CONFIG['MOZ_QT_CFLAGS']

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

@ -139,11 +139,6 @@ if os_bsd or os_linux:
SOURCES += [ SOURCES += [
'src/base/message_pump_glib.cc', 'src/base/message_pump_glib.cc',
] ]
if CONFIG['MOZ_ENABLE_QT']:
SOURCES += [
'!moc_message_pump_qt.cc',
'src/base/message_pump_qt.cc',
]
ost = CONFIG['OS_TEST'] ost = CONFIG['OS_TEST']
if '86' not in ost and 'arm' not in ost and 'aarch64' != ost and 'mips' not in ost: if '86' not in ost and 'arm' not in ost and 'aarch64' != ost and 'mips' not in ost:

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

@ -578,6 +578,11 @@ class Base {
// node owns exclusively that are not exposed as their own ubi::Nodes. // node owns exclusively that are not exposed as their own ubi::Nodes.
// |mallocSizeOf| should be a malloc block sizing function; see // |mallocSizeOf| should be a malloc block sizing function; see
// |mfbt/MemoryReporting.h|. // |mfbt/MemoryReporting.h|.
//
// Because we can use |JS::ubi::Node|s backed by a snapshot that was taken
// on a 64-bit platform when we are currently on a 32-bit platform, we
// cannot rely on |size_t| for node sizes. Instead, |Size| is uint64_t on
// all platforms.
using Size = uint64_t; using Size = uint64_t;
virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; } virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; }
@ -641,28 +646,28 @@ class Base {
}; };
// A traits template with a specialization for each referent type that // A traits template with a specialization for each referent type that
// ubi::Node supports. The specialization must be the concrete subclass of // ubi::Node supports. The specialization must be the concrete subclass of Base
// Base that represents a pointer to the referent type. It must also // that represents a pointer to the referent type. It must include these
// include the members described here. // members:
//
// // The specific char16_t array returned by Concrete<T>::typeName().
// static const char16_t concreteTypeName[];
//
// // Construct an instance of this concrete class in |storage| referring
// // to |referent|. Implementations typically use a placement 'new'.
// //
// // In some cases, |referent| will contain dynamic type information that
// // identifies it a some more specific subclass of |Referent|. For
// // example, when |Referent| is |JSObject|, then |referent->getClass()|
// // could tell us that it's actually a JSFunction. Similarly, if
// // |Referent| is |nsISupports|, we would like a ubi::Node that knows its
// // final implementation type.
// //
// // So we delegate the actual construction to this specialization, which
// // knows Referent's details.
// static void construct(void* storage, Referent* referent);
template<typename Referent> template<typename Referent>
struct Concrete { class Concrete;
// The specific char16_t array returned by Concrete<T>::typeName.
static const char16_t concreteTypeName[];
// Construct an instance of this concrete class in |storage| referring
// to |referent|. Implementations typically use a placement 'new'.
//
// In some cases, |referent| will contain dynamic type information that
// identifies it a some more specific subclass of |Referent|. For example,
// when |Referent| is |JSObject|, then |referent->getClass()| could tell us
// that it's actually a JSFunction. Similarly, if |Referent| is
// |nsISupports|, we would like a ubi::Node that knows its final
// implementation type.
//
// So, we delegate the actual construction to this specialization, which
// knows Referent's details.
static void construct(void* storage, Referent* referent);
};
// A container for a Base instance; all members simply forward to the contained // A container for a Base instance; all members simply forward to the contained
// instance. This container allows us to pass ubi::Node instances by value. // instance. This container allows us to pass ubi::Node instances by value.
@ -994,24 +999,24 @@ class MOZ_STACK_CLASS RootList {
/*** Concrete classes for ubi::Node referent types ************************************************/ /*** Concrete classes for ubi::Node referent types ************************************************/
template<> template<>
struct Concrete<RootList> : public Base { class Concrete<RootList> : public Base {
js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
const char16_t* typeName() const override { return concreteTypeName; }
protected: protected:
explicit Concrete(RootList* ptr) : Base(ptr) { } explicit Concrete(RootList* ptr) : Base(ptr) { }
RootList& get() const { return *static_cast<RootList*>(ptr); } RootList& get() const { return *static_cast<RootList*>(ptr); }
public: public:
static const char16_t concreteTypeName[];
static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); } static void construct(void* storage, RootList* ptr) { new (storage) Concrete(ptr); }
js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
const char16_t* typeName() const override { return concreteTypeName; }
static const char16_t concreteTypeName[];
}; };
// A reusable ubi::Concrete specialization base class for types supported by // A reusable ubi::Concrete specialization base class for types supported by
// JS::TraceChildren. // JS::TraceChildren.
template<typename Referent> template<typename Referent>
class TracerConcrete : public Base { class TracerConcrete : public Base {
const char16_t* typeName() const override { return concreteTypeName; }
js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override; js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override;
JS::Zone* zone() const override; JS::Zone* zone() const override;
@ -1020,7 +1025,6 @@ class TracerConcrete : public Base {
Referent& get() const { return *static_cast<Referent*>(ptr); } Referent& get() const { return *static_cast<Referent*>(ptr); }
public: public:
static const char16_t concreteTypeName[];
static void construct(void* storage, Referent* ptr) { new (storage) TracerConcrete(ptr); } static void construct(void* storage, Referent* ptr) { new (storage) TracerConcrete(ptr); }
}; };
@ -1042,9 +1046,7 @@ class TracerConcreteWithCompartment : public TracerConcrete<Referent> {
// Define specializations for some commonly-used public JSAPI types. // Define specializations for some commonly-used public JSAPI types.
// These can use the generic templates above. // These can use the generic templates above.
template<> template<>
struct Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> { class Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> {
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
protected: protected:
explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { } explicit Concrete(JS::Symbol* ptr) : TracerConcrete(ptr) { }
@ -1052,23 +1054,40 @@ struct Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> {
static void construct(void* storage, JS::Symbol* ptr) { static void construct(void* storage, JS::Symbol* ptr) {
new (storage) Concrete(ptr); new (storage) Concrete(ptr);
} }
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
const char16_t* typeName() const override { return concreteTypeName; }
static const char16_t concreteTypeName[];
}; };
template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> { template<>
CoarseType coarseType() const final { return CoarseType::Script; } class Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
const char* scriptFilename() const final;
protected: protected:
explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { } explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { }
public: public:
static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); } static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); }
CoarseType coarseType() const final { return CoarseType::Script; }
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
const char* scriptFilename() const final;
const char16_t* typeName() const override { return concreteTypeName; }
static const char16_t concreteTypeName[];
}; };
// The JSObject specialization. // The JSObject specialization.
template<> template<>
class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> { class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
protected:
explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { }
public:
static void construct(void* storage, JSObject* ptr) {
new (storage) Concrete(ptr);
}
const char* jsObjectClassName() const override; const char* jsObjectClassName() const override;
MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName)
const override; const override;
@ -1079,26 +1098,25 @@ class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
CoarseType coarseType() const final { return CoarseType::Object; } CoarseType coarseType() const final { return CoarseType::Object; }
protected: const char16_t* typeName() const override { return concreteTypeName; }
explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { } static const char16_t concreteTypeName[];
public:
static void construct(void* storage, JSObject* ptr) {
new (storage) Concrete(ptr);
}
}; };
// For JSString, we extend the generic template with a 'size' implementation. // For JSString, we extend the generic template with a 'size' implementation.
template<> struct Concrete<JSString> : TracerConcrete<JSString> { template<>
Size size(mozilla::MallocSizeOf mallocSizeOf) const override; class Concrete<JSString> : TracerConcrete<JSString> {
CoarseType coarseType() const final { return CoarseType::String; }
protected: protected:
explicit Concrete(JSString *ptr) : TracerConcrete<JSString>(ptr) { } explicit Concrete(JSString *ptr) : TracerConcrete<JSString>(ptr) { }
public: public:
static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); } static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); }
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
CoarseType coarseType() const final { return CoarseType::String; }
const char16_t* typeName() const override { return concreteTypeName; }
static const char16_t concreteTypeName[];
}; };
// The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts. // The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts.
@ -1115,7 +1133,6 @@ class Concrete<void> : public Base {
public: public:
static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); } static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); }
static const char16_t concreteTypeName[];
}; };

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

@ -546,7 +546,7 @@ static inline jsval_layout
OBJECT_TO_JSVAL_IMPL(JSObject* obj) OBJECT_TO_JSVAL_IMPL(JSObject* obj)
{ {
jsval_layout l; jsval_layout l;
MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42); MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x48);
l.s.tag = JSVAL_TAG_OBJECT; l.s.tag = JSVAL_TAG_OBJECT;
l.s.payload.obj = obj; l.s.payload.obj = obj;
return l; return l;
@ -828,7 +828,7 @@ OBJECT_TO_JSVAL_IMPL(JSObject* obj)
{ {
jsval_layout l; jsval_layout l;
uint64_t objBits = (uint64_t)obj; uint64_t objBits = (uint64_t)obj;
MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x42); MOZ_ASSERT(uintptr_t(obj) > 0x1000 || uintptr_t(obj) == 0x48);
MOZ_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0); MOZ_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT; l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;
return l; return l;
@ -1552,7 +1552,7 @@ static inline Value
ObjectValueCrashOnTouch() ObjectValueCrashOnTouch()
{ {
Value v; Value v;
v.setObject(*reinterpret_cast<JSObject*>(0x42)); v.setObject(*reinterpret_cast<JSObject*>(0x48));
return v; return v;
} }

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

@ -296,6 +296,11 @@ class ExecutableAllocator
: "r" (code), "r" (reinterpret_cast<char*>(code) + size) : "r" (code), "r" (reinterpret_cast<char*>(code) + size)
: "r0", "r1", "r2"); : "r0", "r1", "r2");
} }
#elif defined(JS_CODEGEN_ARM64) && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
static void cacheFlush(void* code, size_t size)
{
__clear_cache(code, (void *)((size_t)code + size));
}
#elif JS_CPU_SPARC #elif JS_CPU_SPARC
static void cacheFlush(void* code, size_t size) static void cacheFlush(void* code, size_t size)
{ {

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

@ -3333,7 +3333,7 @@ PerThreadData::setAutoFlushICache(AutoFlushICache* afc)
void void
AutoFlushICache::setRange(uintptr_t start, size_t len) AutoFlushICache::setRange(uintptr_t start, size_t len)
{ {
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
AutoFlushICache* afc = TlsPerThreadData.get()->PerThreadData::autoFlushICache(); AutoFlushICache* afc = TlsPerThreadData.get()->PerThreadData::autoFlushICache();
MOZ_ASSERT(afc); MOZ_ASSERT(afc);
MOZ_ASSERT(!afc->start_); MOZ_ASSERT(!afc->start_);
@ -3420,14 +3420,14 @@ AutoFlushICache::setInhibit()
// the respective AutoFlushICache dynamic context. // the respective AutoFlushICache dynamic context.
// //
AutoFlushICache::AutoFlushICache(const char* nonce, bool inhibit) AutoFlushICache::AutoFlushICache(const char* nonce, bool inhibit)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
: start_(0), : start_(0),
stop_(0), stop_(0),
name_(nonce), name_(nonce),
inhibit_(inhibit) inhibit_(inhibit)
#endif #endif
{ {
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
PerThreadData* pt = TlsPerThreadData.get(); PerThreadData* pt = TlsPerThreadData.get();
AutoFlushICache* afc = pt->PerThreadData::autoFlushICache(); AutoFlushICache* afc = pt->PerThreadData::autoFlushICache();
if (afc) if (afc)
@ -3442,7 +3442,7 @@ AutoFlushICache::AutoFlushICache(const char* nonce, bool inhibit)
AutoFlushICache::~AutoFlushICache() AutoFlushICache::~AutoFlushICache()
{ {
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
PerThreadData* pt = TlsPerThreadData.get(); PerThreadData* pt = TlsPerThreadData.get();
MOZ_ASSERT(pt->PerThreadData::autoFlushICache() == this); MOZ_ASSERT(pt->PerThreadData::autoFlushICache() == this);

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

@ -751,7 +751,7 @@ struct VMFunction;
struct AutoFlushICache struct AutoFlushICache
{ {
private: private:
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
uintptr_t start_; uintptr_t start_;
uintptr_t stop_; uintptr_t stop_;
const char* name_; const char* name_;
@ -788,7 +788,13 @@ IsMarked(const jit::VMFunction*)
namespace JS { namespace JS {
namespace ubi { namespace ubi {
template<> template<>
struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> { class Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
protected:
explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { }
public:
static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
CoarseType coarseType() const final { return CoarseType::Script; } CoarseType coarseType() const final { return CoarseType::Script; }
Size size(mozilla::MallocSizeOf mallocSizeOf) const override { Size size(mozilla::MallocSizeOf mallocSizeOf) const override {
@ -798,11 +804,8 @@ struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
return size; return size;
} }
protected: const char16_t* typeName() const override { return concreteTypeName; }
explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { } static const char16_t concreteTypeName[];
public:
static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
}; };
} // namespace ubi } // namespace ubi

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

@ -272,6 +272,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
masm.abiret(); masm.abiret();
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("EnterJIT");
JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
#ifdef JS_ION_PERF #ifdef JS_ION_PERF
@ -313,6 +314,7 @@ JitRuntime::generateInvalidator(JSContext* cx)
masm.branch(bailoutTail); masm.branch(bailoutTail);
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("Invalidator");
return linker.newCode<NoGC>(cx, OTHER_CODE); return linker.newCode<NoGC>(cx, OTHER_CODE);
} }
@ -420,6 +422,7 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
masm.ret(); masm.ret();
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("ArgumentsRectifier");
JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
if (returnAddrOut) if (returnAddrOut)
@ -527,6 +530,7 @@ JitRuntime::generateBailoutTable(JSContext* cx, uint32_t frameClass)
MacroAssembler masm; MacroAssembler masm;
masm.breakpoint(); masm.breakpoint();
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("BailoutTable");
return linker.newCode<NoGC>(cx, OTHER_CODE); return linker.newCode<NoGC>(cx, OTHER_CODE);
} }
@ -541,6 +545,7 @@ JitRuntime::generateBailoutHandler(JSContext* cx)
#endif #endif
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("BailoutHandler");
return linker.newCode<NoGC>(cx, OTHER_CODE); return linker.newCode<NoGC>(cx, OTHER_CODE);
} }
@ -727,6 +732,7 @@ JitRuntime::generateVMWrapper(JSContext* cx, const VMFunction& f)
f.extraValuesToPop * sizeof(Value))); f.extraValuesToPop * sizeof(Value)));
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("VMWrapper");
JitCode* wrapper = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* wrapper = linker.newCode<NoGC>(cx, OTHER_CODE);
if (!wrapper) if (!wrapper)
return nullptr; return nullptr;
@ -770,6 +776,7 @@ JitRuntime::generatePreBarrier(JSContext* cx, MIRType type)
masm.abiret(); masm.abiret();
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("PreBarrier");
return linker.newCode<NoGC>(cx, OTHER_CODE); return linker.newCode<NoGC>(cx, OTHER_CODE);
} }
@ -824,6 +831,7 @@ JitRuntime::generateDebugTrapHandler(JSContext* cx)
masm.abiret(); masm.abiret();
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("DebugTrapHandler");
JitCode* codeDbg = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* codeDbg = linker.newCode<NoGC>(cx, OTHER_CODE);
#ifdef JS_ION_PERF #ifdef JS_ION_PERF
@ -841,6 +849,7 @@ JitRuntime::generateExceptionTailStub(JSContext* cx, void* handler)
masm.handleFailureWithHandlerTail(handler); masm.handleFailureWithHandlerTail(handler);
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("ExceptionTailStub");
JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
#ifdef JS_ION_PERF #ifdef JS_ION_PERF
@ -858,6 +867,7 @@ JitRuntime::generateBailoutTailStub(JSContext* cx)
masm.generateBailoutTail(r1, r2); masm.generateBailoutTail(r1, r2);
Linker linker(masm); Linker linker(masm);
AutoFlushICache afc("BailoutTailStub");
JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE); JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
#ifdef JS_ION_PERF #ifdef JS_ION_PERF

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

@ -41,10 +41,14 @@ namespace JS {
namespace ubi { namespace ubi {
template<> template<>
struct Concrete<FakeNode> : public Base class Concrete<FakeNode> : public Base
{ {
static const char16_t concreteTypeName[]; protected:
const char16_t* typeName() const override { return concreteTypeName; } explicit Concrete(FakeNode* ptr) : Base(ptr) { }
FakeNode& get() const { return *static_cast<FakeNode*>(ptr); }
public:
static void construct(void* storage, FakeNode* ptr) { new (storage) Concrete(ptr); }
UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override { UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames) const override {
return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges)); return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
@ -54,11 +58,8 @@ struct Concrete<FakeNode> : public Base
return 1; return 1;
} }
static void construct(void* storage, FakeNode* ptr) { new (storage) Concrete(ptr); } static const char16_t concreteTypeName[];
const char16_t* typeName() const override { return concreteTypeName; }
protected:
explicit Concrete(FakeNode* ptr) : Base(ptr) { }
FakeNode& get() const { return *static_cast<FakeNode*>(ptr); }
}; };
const char16_t Concrete<FakeNode>::concreteTypeName[] = MOZ_UTF16("FakeNode"); const char16_t Concrete<FakeNode>::concreteTypeName[] = MOZ_UTF16("FakeNode");

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

@ -1836,15 +1836,19 @@ JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global)
{ {
MOZ_ASSERT(global->is<GlobalObject>()); MOZ_ASSERT(global->is<GlobalObject>());
// Off thread parsing and compilation tasks create a dummy global which is then // Off thread parsing and compilation tasks create a dummy global which is
// merged back into the host compartment. Since it used to be a global, it will still // then merged back into the host compartment. Since it used to be a
// have this trace hook, but it does not have a meaning relative to its new compartment. // global, it will still have this trace hook, but it does not have a
// We can safely skip it. // meaning relative to its new compartment. We can safely skip it.
if (!global->isOwnGlobal()) //
// Similarly, if we GC when creating the global, we may not have set that
// global's compartment's global pointer yet. In this case, the compartment
// will not yet contain anything that needs to be traced.
if (!global->isOwnGlobal(trc))
return; return;
// Trace the compartment for any GC things that should only stick around if we know the // Trace the compartment for any GC things that should only stick around if
// compartment is live. // we know the compartment is live.
global->compartment()->trace(trc); global->compartment()->trace(trc);
if (JSTraceOp trace = global->compartment()->creationOptions().getTrace()) if (JSTraceOp trace = global->compartment()->creationOptions().getTrace())

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше