import changes from rmottola/Arctic-Fox:

- Bug 1129223 - Remove local mozAfterRemotePaint events (a9aec8f51)
- override -> MOZ_OVERRIDE (2de5b532c)
- Bug 1129223 - Introduce new, more efficient mozLayerTreeReady event (9a363c950)
- Bug 963921 - Clients of the JS API should use JS_DefineElement where appropriate (912f064c0)
- Bug 1133746. Allow DOMProxyShadows to communicate to the JIT whether the shadowing is done by the expando object or not. (dbe537f12)
This commit is contained in:
2019-02-25 11:46:05 +08:00
parent 2e31415af7
commit 301eae9eba
37 changed files with 397 additions and 147 deletions
+4
View File
@@ -1184,6 +1184,10 @@ FragmentOrElement::DestroyContent()
// The child can remove itself from the parent in BindToTree. // The child can remove itself from the parent in BindToTree.
mAttrsAndChildren.ChildAt(i)->DestroyContent(); mAttrsAndChildren.ChildAt(i)->DestroyContent();
} }
ShadowRoot* shadowRoot = GetShadowRoot();
if (shadowRoot) {
shadowRoot->DestroyContent();
}
} }
void void
+9
View File
@@ -711,6 +711,15 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
} }
} }
void
ShadowRoot::DestroyContent()
{
if (mOlderShadow) {
mOlderShadow->DestroyContent();
}
DocumentFragment::DestroyContent();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(ShadowRootStyleSheetList, StyleSheetList, NS_IMPL_CYCLE_COLLECTION_INHERITED(ShadowRootStyleSheetList, StyleSheetList,
mShadowRoot) mShadowRoot)
+2
View File
@@ -133,6 +133,8 @@ public:
{ {
mIsComposedDocParticipant = aIsComposedDocParticipant; mIsComposedDocParticipant = aIsComposedDocParticipant;
} }
virtual void DestroyContent() MOZ_OVERRIDE;
protected: protected:
virtual ~ShadowRoot(); virtual ~ShadowRoot();
+7 -3
View File
@@ -19,6 +19,13 @@ namespace dom {
static bool static bool
ShouldExposeChildWindow(nsString& aNameBeingResolved, nsIDOMWindow *aChild) ShouldExposeChildWindow(nsString& aNameBeingResolved, nsIDOMWindow *aChild)
{ {
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aChild);
NS_ENSURE_TRUE(piWin, false);
Element* e = piWin->GetFrameElementInternal();
if (e && e->IsInShadowTree()) {
return false;
}
// If we're same-origin with the child, go ahead and expose it. // If we're same-origin with the child, go ahead and expose it.
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aChild); nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aChild);
NS_ENSURE_TRUE(sop, false); NS_ENSURE_TRUE(sop, false);
@@ -63,9 +70,6 @@ ShouldExposeChildWindow(nsString& aNameBeingResolved, nsIDOMWindow *aChild)
// allow the child to arbitrarily pollute the parent namespace, and requires // allow the child to arbitrarily pollute the parent namespace, and requires
// cross-origin communication only in a limited set of cases that can be // cross-origin communication only in a limited set of cases that can be
// computed independently by the parent. // computed independently by the parent.
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aChild);
NS_ENSURE_TRUE(piWin, false);
Element* e = piWin->GetFrameElementInternal();
return e && e->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, return e && e->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
aNameBeingResolved, eCaseMatters); aNameBeingResolved, eCaseMatters);
} }
+39 -16
View File
@@ -194,7 +194,7 @@ nsFrameLoader::Create(Element* aOwner, bool aNetworkCreated)
NS_ENSURE_TRUE(aOwner, nullptr); NS_ENSURE_TRUE(aOwner, nullptr);
nsIDocument* doc = aOwner->OwnerDoc(); nsIDocument* doc = aOwner->OwnerDoc();
NS_ENSURE_TRUE(!doc->IsResourceDoc() && NS_ENSURE_TRUE(!doc->IsResourceDoc() &&
((!doc->IsLoadedAsData() && aOwner->GetUncomposedDoc()) || ((!doc->IsLoadedAsData() && aOwner->GetComposedDoc()) ||
doc->IsStaticDocument()), doc->IsStaticDocument()),
nullptr); nullptr);
@@ -349,7 +349,7 @@ private:
nsresult nsresult
nsFrameLoader::ReallyStartLoadingInternal() nsFrameLoader::ReallyStartLoadingInternal()
{ {
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc()); NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInComposedDoc());
PROFILER_LABEL("nsFrameLoader", "ReallyStartLoading", PROFILER_LABEL("nsFrameLoader", "ReallyStartLoading",
js::ProfileEntry::Category::OTHER); js::ProfileEntry::Category::OTHER);
@@ -876,12 +876,12 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size,
// want here. For now, hack. // want here. For now, hack.
if (!mRemoteBrowserShown) { if (!mRemoteBrowserShown) {
if (!mOwnerContent || if (!mOwnerContent ||
!mOwnerContent->GetUncomposedDoc()) { !mOwnerContent->GetComposedDoc()) {
return false; return false;
} }
nsRefPtr<layers::LayerManager> layerManager = nsRefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForDocument(mOwnerContent->GetUncomposedDoc()); nsContentUtils::LayerManagerForDocument(mOwnerContent->GetComposedDoc());
if (!layerManager) { if (!layerManager) {
// This is just not going to work. // This is just not going to work.
return false; return false;
@@ -972,8 +972,8 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
return NS_ERROR_DOM_SECURITY_ERR; return NS_ERROR_DOM_SECURITY_ERR;
} }
nsIDocument* ourDoc = ourContent->GetCurrentDoc(); nsIDocument* ourDoc = ourContent->GetComposedDoc();
nsIDocument* otherDoc = otherContent->GetCurrentDoc(); nsIDocument* otherDoc = otherContent->GetComposedDoc();
if (!ourDoc || !otherDoc) { if (!ourDoc || !otherDoc) {
// Again, how odd, given that we had docshells // Again, how odd, given that we had docshells
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
@@ -1191,8 +1191,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
otherChildDocument->GetParentDocument(); otherChildDocument->GetParentDocument();
// Make sure to swap docshells between the two frames. // Make sure to swap docshells between the two frames.
nsIDocument* ourDoc = ourContent->GetUncomposedDoc(); nsIDocument* ourDoc = ourContent->GetComposedDoc();
nsIDocument* otherDoc = otherContent->GetUncomposedDoc(); nsIDocument* otherDoc = otherContent->GetComposedDoc();
if (!ourDoc || !otherDoc) { if (!ourDoc || !otherDoc) {
// Again, how odd, given that we had docshells // Again, how odd, given that we had docshells
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
@@ -1612,7 +1612,7 @@ nsFrameLoader::MaybeCreateDocShell()
// XXXbz this is such a total hack.... We really need to have a // XXXbz this is such a total hack.... We really need to have a
// better setup for doing this. // better setup for doing this.
nsIDocument* doc = mOwnerContent->OwnerDoc(); nsIDocument* doc = mOwnerContent->OwnerDoc();
if (!(doc->IsStaticDocument() || mOwnerContent->IsInDoc())) { if (!(doc->IsStaticDocument() || mOwnerContent->IsInComposedDoc())) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
@@ -2674,17 +2674,40 @@ nsFrameLoader::RequestNotifyAfterRemotePaint()
// If remote browsing (e10s), handle this with the TabParent. // If remote browsing (e10s), handle this with the TabParent.
if (mRemoteBrowser) { if (mRemoteBrowser) {
unused << mRemoteBrowser->SendRequestNotifyAfterRemotePaint(); unused << mRemoteBrowser->SendRequestNotifyAfterRemotePaint();
return NS_OK;
} }
// If not remote browsing, directly use the document's window. return NS_OK;
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell); }
if (!window) {
NS_WARNING("Unable to get window for synchronous MozAfterRemotePaint event."); NS_IMETHODIMP
return NS_OK; nsFrameLoader::RequestNotifyLayerTreeReady()
{
if (mRemoteBrowser) {
return mRemoteBrowser->RequestNotifyLayerTreeReady() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
} }
window->SetRequestNotifyAfterRemotePaint(); nsRefPtr<AsyncEventDispatcher> event =
new AsyncEventDispatcher(mOwnerContent,
NS_LITERAL_STRING("MozLayerTreeReady"),
true, false);
event->PostDOMEvent();
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::RequestNotifyLayerTreeCleared()
{
if (mRemoteBrowser) {
return mRemoteBrowser->RequestNotifyLayerTreeCleared() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
nsRefPtr<AsyncEventDispatcher> event =
new AsyncEventDispatcher(mOwnerContent,
NS_LITERAL_STRING("MozLayerTreeCleared"),
true, false);
event->PostDOMEvent();
return NS_OK; return NS_OK;
} }
+2 -2
View File
@@ -514,7 +514,7 @@ nsFrameMessageManager::GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::V
pair = JS_NewArrayObject(aCx, pairElts); pair = JS_NewArrayObject(aCx, pairElts);
NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, pair), NS_ENSURE_TRUE(JS_DefineElement(aCx, array, i, pair, JSPROP_ENUMERATE),
NS_ERROR_OUT_OF_MEMORY); NS_ERROR_OUT_OF_MEMORY);
} }
@@ -696,7 +696,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
retval[i].Length(), &ret)) { retval[i].Length(), &ret)) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, ret), NS_ENSURE_TRUE(JS_DefineElement(aCx, dataArray, i, ret, JSPROP_ENUMERATE),
NS_ERROR_OUT_OF_MEMORY); NS_ERROR_OUT_OF_MEMORY);
} }
+1 -16
View File
@@ -587,7 +587,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
mInnerWindow(nullptr), mOuterWindow(aOuterWindow), mInnerWindow(nullptr), mOuterWindow(aOuterWindow),
// Make sure no actual window ends up with mWindowID == 0 // Make sure no actual window ends up with mWindowID == 0
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false), mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
mMarkedCCGeneration(0), mSendAfterRemotePaint(false) mMarkedCCGeneration(0)
{} {}
nsPIDOMWindow::~nsPIDOMWindow() {} nsPIDOMWindow::~nsPIDOMWindow() {}
@@ -3776,21 +3776,6 @@ nsPIDOMWindow::RefreshMediaElements()
service->RefreshAgentsVolume(this); service->RefreshAgentsVolume(this);
} }
void
nsPIDOMWindow::SendAfterRemotePaintIfRequested()
{
if (!mSendAfterRemotePaint) {
return;
}
mSendAfterRemotePaint = false;
nsContentUtils::DispatchChromeEvent(GetExtantDoc(),
GetParentTarget(),
NS_LITERAL_STRING("MozAfterRemotePaint"),
false, false);
}
// nsISpeechSynthesisGetter // nsISpeechSynthesisGetter
#ifdef MOZ_WEBSPEECH #ifdef MOZ_WEBSPEECH
+9 -1
View File
@@ -16,7 +16,7 @@ interface nsIDOMElement;
interface nsITabParent; interface nsITabParent;
interface nsILoadContext; interface nsILoadContext;
[scriptable, builtinclass, uuid(28b6b043-46ec-412f-9be9-db22938b0d6d)] [scriptable, builtinclass, uuid(d24f9330-ae4e-11e4-ab27-0800200c9a66)]
interface nsIFrameLoader : nsISupports interface nsIFrameLoader : nsISupports
{ {
/** /**
@@ -121,6 +121,14 @@ interface nsIFrameLoader : nsISupports
*/ */
void requestNotifyAfterRemotePaint(); void requestNotifyAfterRemotePaint();
/**
* Request an event when the layer tree from the remote tab becomes
* available or unavailable. When this happens, a mozLayerTreeReady
* or mozLayerTreeCleared event is fired.
*/
void requestNotifyLayerTreeReady();
void requestNotifyLayerTreeCleared();
/** /**
* The default event mode automatically forwards the events * The default event mode automatically forwards the events
* handled in EventStateManager::HandleCrossProcessEvent to * handled in EventStateManager::HandleCrossProcessEvent to
+2 -3
View File
@@ -131,7 +131,7 @@ IsJavaMIME(const nsACString & aMIMEType)
static bool static bool
InActiveDocument(nsIContent *aContent) InActiveDocument(nsIContent *aContent)
{ {
if (!aContent->IsInDoc()) { if (!aContent->IsInComposedDoc()) {
return false; return false;
} }
nsIDocument *doc = aContent->OwnerDoc(); nsIDocument *doc = aContent->OwnerDoc();
@@ -3333,11 +3333,10 @@ nsObjectLoadingContent::GetContentDocument()
nsCOMPtr<nsIContent> thisContent = nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this)); do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
if (!thisContent->IsInDoc()) { if (!thisContent->IsInComposedDoc()) {
return nullptr; return nullptr;
} }
// XXXbz should this use GetComposedDoc()? sXBL/XBL2 issue!
nsIDocument *sub_doc = thisContent->OwnerDoc()->GetSubDocumentFor(thisContent); nsIDocument *sub_doc = thisContent->OwnerDoc()->GetSubDocumentFor(thisContent);
if (!sub_doc) { if (!sub_doc) {
return nullptr; return nullptr;
-15
View File
@@ -769,17 +769,6 @@ public:
return mMarkedCCGeneration; return mMarkedCCGeneration;
} }
// Sets the condition that we send an NS_AFTER_REMOTE_PAINT message just before the next
// composite. Used in non-e10s implementations.
void SetRequestNotifyAfterRemotePaint()
{
mSendAfterRemotePaint = true;
}
// Sends an NS_AFTER_REMOTE_PAINT message if requested by
// SetRequestNotifyAfterRemotePaint().
void SendAfterRemotePaintIfRequested();
virtual already_AddRefed<nsPIDOMWindow> GetOpener() = 0; virtual already_AddRefed<nsPIDOMWindow> GetOpener() = 0;
// aLoadInfo will be passed on through to the windowwatcher. // aLoadInfo will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except // aForceNoOpener will act just like a "noopener" feature in aOptions except
@@ -885,10 +874,6 @@ protected:
bool mHasNotifiedGlobalCreated; bool mHasNotifiedGlobalCreated;
uint32_t mMarkedCCGeneration; uint32_t mMarkedCCGeneration;
// If true, send an NS_AFTER_REMOTE_PAINT message before compositing in a
// non-e10s implementation.
bool mSendAfterRemotePaint;
}; };
+1
View File
@@ -765,6 +765,7 @@ support-files = file_bug503473-frame.sjs
skip-if = buildapp == 'b2g' || e10s skip-if = buildapp == 'b2g' || e10s
support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs
[test_bug1025933.html] [test_bug1025933.html]
[test_bug1037687.html]
[test_element.matches.html] [test_element.matches.html]
[test_user_select.html] [test_user_select.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
+63
View File
@@ -0,0 +1,63 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1037687
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1037687</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1037687 **/
SimpleTest.waitForExplicitFinish();
var host;
var sr;
var embed;
var object;
var iframe;
var resourceLoadCount = 0;
function resourceLoaded(event) {
++resourceLoadCount;
ok(true, event.target + " got " + event.load);
if (resourceLoadCount == 3) {
SimpleTest.finish();
}
}
function createResource(sr, type) {
var el = document.createElement(type);
var attrName = type == "object" ? "data" : "src";
el.setAttribute(attrName, "file_mozfiledataurl_img.jpg");
el.onload = resourceLoaded;
var info = document.createElement("div");
info.textContent = type;
sr.appendChild(info);
sr.appendChild(el);
}
function test() {
host = document.getElementById("host");
sr = host.createShadowRoot();
embed = createResource(sr, "embed");
object = createResource(sr, "object");
iframe = createResource(sr, "iframe");
}
</script>
</head>
<body onload="test()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037687">Mozilla Bug 1037687</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<div id="host"></div>
</body>
</html>
+10 -5
View File
@@ -33,17 +33,22 @@ const char DOMProxyHandler::family = 0;
js::DOMProxyShadowsResult js::DOMProxyShadowsResult
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
{ {
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO); JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
if (v.isObject()) { bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
if (expando) {
bool hasOwn; bool hasOwn;
Rooted<JSObject*> object(cx, &v.toObject()); if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
if (!JS_AlreadyHasOwnPropertyById(cx, object, id, &hasOwn))
return js::ShadowCheckFailed; return js::ShadowCheckFailed;
return hasOwn ? js::Shadows : js::DoesntShadow; if (hasOwn) {
return isOverrideBuiltins ?
js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
}
} }
if (v.isUndefined()) { if (!isOverrideBuiltins) {
// Our expando, if any, didn't shadow, so we're not shadowing at all.
return js::DoesntShadow; return js::DoesntShadow;
} }
+4 -4
View File
@@ -72,7 +72,7 @@ HTMLObjectElement::DoneAddingChildren(bool aHaveNotified)
// If we're already in a document, we need to trigger the load // If we're already in a document, we need to trigger the load
// Otherwise, BindToTree takes care of that. // Otherwise, BindToTree takes care of that.
if (IsInDoc()) { if (IsInComposedDoc()) {
StartObjectLoad(aHaveNotified); StartObjectLoad(aHaveNotified);
} }
} }
@@ -312,7 +312,7 @@ HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
// We also don't want to start loading the object when we're not yet in // We also don't want to start loading the object when we're not yet in
// a document, just in case that the caller wants to set additional // a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document. // attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren && if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) { aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
return LoadObject(aNotify, true); return LoadObject(aNotify, true);
} }
@@ -329,7 +329,7 @@ HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// See comment in SetAttr // See comment in SetAttr
if (aNotify && IsInDoc() && mIsDoneAddingChildren && if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) { aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
return LoadObject(aNotify, true); return LoadObject(aNotify, true);
} }
@@ -541,7 +541,7 @@ HTMLObjectElement::StartObjectLoad(bool aNotify)
{ {
// BindToTree can call us asynchronously, and we may be removed from the tree // BindToTree can call us asynchronously, and we may be removed from the tree
// in the interim // in the interim
if (!IsInDoc() || !OwnerDoc()->IsActive()) { if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
return; return;
} }
+3 -3
View File
@@ -83,7 +83,7 @@ HTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
// If we're already in a document, we need to trigger the load // If we're already in a document, we need to trigger the load
// Otherwise, BindToTree takes care of that. // Otherwise, BindToTree takes care of that.
if (IsInDoc()) { if (IsInComposedDoc()) {
StartObjectLoad(aHaveNotified); StartObjectLoad(aHaveNotified);
} }
} }
@@ -191,7 +191,7 @@ HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
// We also don't want to start loading the object when we're not yet in // We also don't want to start loading the object when we're not yet in
// a document, just in case that the caller wants to set additional // a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document. // attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren && if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) { aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
return LoadObject(aNotify, true); return LoadObject(aNotify, true);
} }
@@ -324,7 +324,7 @@ HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
{ {
// BindToTree can call us asynchronously, and we may be removed from the tree // BindToTree can call us asynchronously, and we may be removed from the tree
// in the interim // in the interim
if (!IsInDoc() || !OwnerDoc()->IsActive()) { if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
return; return;
} }
+2 -2
View File
@@ -131,7 +131,7 @@ nsGenericHTMLFrameElement::GetContentWindow()
void void
nsGenericHTMLFrameElement::EnsureFrameLoader() nsGenericHTMLFrameElement::EnsureFrameLoader()
{ {
if (!IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) { if (!IsInComposedDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
// If frame loader is there, we just keep it around, cached // If frame loader is there, we just keep it around, cached
return; return;
} }
@@ -221,7 +221,7 @@ nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument,
aCompileEventHandlers); aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) { if (IsInComposedDoc()) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Missing a script blocker!"); "Missing a script blocker!");
+5 -3
View File
@@ -458,7 +458,8 @@ private:
return rv; return rv;
} }
if (NS_WARN_IF(!JS_SetElement(aCx, array, index, value))) { if (NS_WARN_IF(!JS_DefineElement(aCx, array, index, value,
JSPROP_ENUMERATE))) {
IDB_REPORT_INTERNAL_ERR(); IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
} }
@@ -511,7 +512,8 @@ private:
return rv; return rv;
} }
if (NS_WARN_IF(!JS_SetElement(aCx, array, index, value))) { if (NS_WARN_IF(!JS_DefineElement(aCx, array, index, value,
JSPROP_ENUMERATE))) {
IDB_REPORT_INTERNAL_ERR(); IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
} }
@@ -1100,7 +1102,7 @@ BackgroundFactoryRequestChild::Recv__delete__(
IDBOpenDBRequest* request = GetOpenDBRequest(); IDBOpenDBRequest* request = GetOpenDBRequest();
MOZ_ASSERT(request); MOZ_ASSERT(request);
request->NoteComplete(); request->NoteComplete();
if (NS_WARN_IF(!result)) { if (NS_WARN_IF(!result)) {
+1 -1
View File
@@ -218,7 +218,7 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
aTypeOffset = 0; aTypeOffset = 0;
if (!JS_SetElement(aCx, array, index++, val)) { if (!JS_DefineElement(aCx, array, index++, val, JSPROP_ENUMERATE)) {
NS_WARNING("Failed to set array element!"); NS_WARNING("Failed to set array element!");
IDB_REPORT_INTERNAL_ERR(); IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+2 -2
View File
@@ -359,7 +359,7 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
return rv; return rv;
} }
if (!JS_SetElement(aCx, arrayObj, i, value)) { if (!JS_DefineElement(aCx, arrayObj, i, value, JSPROP_ENUMERATE)) {
IDB_REPORT_INTERNAL_ERR(); IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
} }
@@ -471,7 +471,7 @@ KeyPath::ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aValue) const
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
} }
if (!JS_SetElement(aCx, array, i, val)) { if (!JS_DefineElement(aCx, array, i, val, JSPROP_ENUMERATE)) {
IDB_REPORT_INTERNAL_ERR(); IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
} }
+80
View File
@@ -2645,6 +2645,86 @@ TabParent::GetTabId(uint64_t* aId)
return NS_OK; return NS_OK;
} }
class LayerTreeUpdateRunnable MOZ_FINAL
: public nsRunnable
{
uint64_t mLayersId;
bool mActive;
public:
explicit LayerTreeUpdateRunnable(uint64_t aLayersId, bool aActive)
: mLayersId(aLayersId), mActive(aActive) {}
private:
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
TabParent* tabParent = TabParent::GetTabParentFromLayersId(mLayersId);
if (tabParent) {
tabParent->LayerTreeUpdate(mActive);
}
return NS_OK;
}
};
// This observer runs on the compositor thread, so we dispatch a runnable to the
// main thread to actually dispatch the event.
class LayerTreeUpdateObserver : public CompositorUpdateObserver
{
virtual void ObserveUpdate(uint64_t aLayersId, bool aActive) {
nsRefPtr<LayerTreeUpdateRunnable> runnable = new LayerTreeUpdateRunnable(aLayersId, aActive);
NS_DispatchToMainThread(runnable);
}
};
bool
TabParent::RequestNotifyLayerTreeReady()
{
RenderFrameParent* frame = GetRenderFrame();
if (!frame) {
return false;
}
CompositorParent::RequestNotifyLayerTreeReady(frame->GetLayersId(),
new LayerTreeUpdateObserver());
return true;
}
bool
TabParent::RequestNotifyLayerTreeCleared()
{
RenderFrameParent* frame = GetRenderFrame();
if (!frame) {
return false;
}
CompositorParent::RequestNotifyLayerTreeCleared(frame->GetLayersId(),
new LayerTreeUpdateObserver());
return true;
}
bool
TabParent::LayerTreeUpdate(bool aActive)
{
nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
if (!target) {
NS_WARNING("Could not locate target for layer tree message.");
return true;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMEvent(getter_AddRefs(event), mFrameElement, nullptr, nullptr);
if (aActive) {
event->InitEvent(NS_LITERAL_STRING("MozLayerTreeReady"), true, false);
} else {
event->InitEvent(NS_LITERAL_STRING("MozLayerTreeCleared"), true, false);
}
event->SetTrusted(true);
event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
bool dummy;
mFrameElement->DispatchEvent(event, &dummy);
return true;
}
bool bool
TabParent::RecvRemotePaintIsReady() TabParent::RecvRemotePaintIsReady()
{ {
+5
View File
@@ -376,6 +376,11 @@ public:
bool SendLoadRemoteScript(const nsString& aURL, bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope); const bool& aRunInGlobalScope);
// See nsIFrameLoader requestNotifyLayerTreeReady.
bool RequestNotifyLayerTreeReady();
bool RequestNotifyLayerTreeCleared();
bool LayerTreeUpdate(bool aActive);
protected: protected:
bool ReceiveMessage(const nsString& aMessage, bool ReceiveMessage(const nsString& aMessage,
bool aSync, bool aSync,
+1 -1
View File
@@ -587,7 +587,7 @@ MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachm
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!JS_SetElement(aCx, attachments, i, attachmentObj)) { if (!JS_DefineElement(aCx, attachments, i, attachmentObj, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }
+1 -1
View File
@@ -197,7 +197,7 @@ MobileMessageCallback::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
JS::Rooted<JSObject*> deleteArrayObj(cx, JS_NewArrayObject(cx, aSize)); JS::Rooted<JSObject*> deleteArrayObj(cx, JS_NewArrayObject(cx, aSize));
for (uint32_t i = 0; i < aSize; i++) { for (uint32_t i = 0; i < aSize; i++) {
JS_SetElement(cx, deleteArrayObj, i, aDeleted[i]); JS_DefineElement(cx, deleteArrayObj, i, aDeleted[i], JSPROP_ENUMERATE);
} }
JS::Rooted<JS::Value> deleteArrayVal(cx, JS::ObjectValue(*deleteArrayObj)); JS::Rooted<JS::Value> deleteArrayVal(cx, JS::ObjectValue(*deleteArrayObj));
+1 -1
View File
@@ -120,7 +120,7 @@ GetParamsFromSendMmsMessageRequest(JSContext* aCx,
JS::Rooted<JSObject*> obj(aCx, JS::Rooted<JSObject*> obj(aCx,
MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i))); MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
NS_ENSURE_TRUE(obj, false); NS_ENSURE_TRUE(obj, false);
if (!JS_SetElement(aCx, attachmentArray, i, obj)) { if (!JS_DefineElement(aCx, attachmentArray, i, obj, JSPROP_ENUMERATE)) {
return false; return false;
} }
} }
+64 -24
View File
@@ -1426,6 +1426,22 @@ CompositorParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
} }
} }
/* static */ void
CompositorParent::RequestNotifyLayerTreeReady(uint64_t aLayersId, CompositorUpdateObserver* aObserver)
{
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aLayersId].mLayerTreeReadyObserver = aObserver;
}
/* static */ void
CompositorParent::RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver)
{
EnsureLayerTreeMapReady();
MonitorAutoLock lock(*sIndirectLayerTreesLock);
sIndirectLayerTrees[aLayersId].mLayerTreeClearedObserver = aObserver;
}
/** /**
* This class handles layer updates pushed directly from child * This class handles layer updates pushed directly from child
* processes to the compositor thread. It's associated with a * processes to the compositor thread. It's associated with a
@@ -1455,26 +1471,26 @@ public:
virtual IToplevelProtocol* virtual IToplevelProtocol*
CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds, CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
base::ProcessHandle aPeerProcess, base::ProcessHandle aPeerProcess,
mozilla::ipc::ProtocolCloneContext* aCtx) override; mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason aWhy) override; virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
// FIXME/bug 774388: work out what shutdown protocol we need. // FIXME/bug 774388: work out what shutdown protocol we need.
virtual bool RecvRequestOverfill() override { return true; } virtual bool RecvRequestOverfill() MOZ_OVERRIDE { return true; }
virtual bool RecvWillStop() override { return true; } virtual bool RecvWillStop() MOZ_OVERRIDE { return true; }
virtual bool RecvStop() override { return true; } virtual bool RecvStop() MOZ_OVERRIDE { return true; }
virtual bool RecvPause() override { return true; } virtual bool RecvPause() MOZ_OVERRIDE { return true; }
virtual bool RecvResume() override { return true; } virtual bool RecvResume() MOZ_OVERRIDE { return true; }
virtual bool RecvNotifyChildCreated(const uint64_t& child) override; virtual bool RecvNotifyChildCreated(const uint64_t& child) MOZ_OVERRIDE;
virtual bool RecvAdoptChild(const uint64_t& child) override { return false; } virtual bool RecvAdoptChild(const uint64_t& child) MOZ_OVERRIDE { return false; }
virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot, virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
const nsIntRect& aRect) override const nsIntRect& aRect) MOZ_OVERRIDE
{ return true; } { return true; }
virtual bool RecvFlushRendering() override { return true; } virtual bool RecvFlushRendering() MOZ_OVERRIDE { return true; }
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override { return true; } virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) MOZ_OVERRIDE { return true; }
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return true; } virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) MOZ_OVERRIDE { return true; }
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return true; } virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) MOZ_OVERRIDE { return true; }
virtual bool RecvGetTileSize(int32_t* aWidth, int32_t* aHeight) override virtual bool RecvGetTileSize(int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE
{ {
*aWidth = gfxPlatform::GetPlatform()->GetTileWidth(); *aWidth = gfxPlatform::GetPlatform()->GetTileWidth();
*aHeight = gfxPlatform::GetPlatform()->GetTileHeight(); *aHeight = gfxPlatform::GetPlatform()->GetTileHeight();
@@ -1485,15 +1501,15 @@ public:
/** /**
* Tells this CompositorParent to send a message when the compositor has received the transaction. * Tells this CompositorParent to send a message when the compositor has received the transaction.
*/ */
virtual bool RecvRequestNotifyAfterRemotePaint() override; virtual bool RecvRequestNotifyAfterRemotePaint() MOZ_OVERRIDE;
virtual PLayerTransactionParent* virtual PLayerTransactionParent*
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints, AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId, const uint64_t& aId,
TextureFactoryIdentifier* aTextureFactoryIdentifier, TextureFactoryIdentifier* aTextureFactoryIdentifier,
bool *aSuccess) override; bool *aSuccess) MOZ_OVERRIDE;
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) override; virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
const uint64_t& aTransactionId, const uint64_t& aTransactionId,
@@ -1502,15 +1518,16 @@ public:
bool aIsFirstPaint, bool aIsFirstPaint,
bool aScheduleComposite, bool aScheduleComposite,
uint32_t aPaintSequenceNumber, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction) override; bool aIsRepeatTransaction) MOZ_OVERRIDE;
virtual void ForceComposite(LayerTransactionParent* aLayerTree) override; virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) override; const TimeStamp& aTime) MOZ_OVERRIDE;
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override; virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree, virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
APZTestData* aOutData) override; APZTestData* aOutData) MOZ_OVERRIDE;
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override; virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) MOZ_OVERRIDE;
void DidComposite(uint64_t aId); void DidComposite(uint64_t aId);
@@ -1737,6 +1754,12 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
mNotifyAfterRemotePaint = false; mNotifyAfterRemotePaint = false;
} }
if (state->mLayerTreeReadyObserver) {
nsRefPtr<CompositorUpdateObserver> observer = state->mLayerTreeReadyObserver;
state->mLayerTreeReadyObserver = nullptr;
observer->ObserveUpdate(id, true);
}
aLayerTree->SetPendingTransactionId(aTransactionId); aLayerTree->SetPendingTransactionId(aTransactionId);
} }
@@ -1823,6 +1846,23 @@ CrossProcessCompositorParent::ForceComposite(LayerTransactionParent* aLayerTree)
} }
} }
void
CrossProcessCompositorParent::NotifyClearCachedResources(LayerTransactionParent* aLayerTree)
{
uint64_t id = aLayerTree->GetId();
MOZ_ASSERT(id != 0);
nsRefPtr<CompositorUpdateObserver> observer;
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
observer = sIndirectLayerTrees[id].mLayerTreeClearedObserver;
sIndirectLayerTrees[id].mLayerTreeClearedObserver = nullptr;
}
if (observer) {
observer->ObserveUpdate(id, false);
}
}
bool bool
CrossProcessCompositorParent::SetTestSampleTime( CrossProcessCompositorParent::SetTestSampleTime(
LayerTransactionParent* aLayerTree, const TimeStamp& aTime) LayerTransactionParent* aLayerTree, const TimeStamp& aTime)
+17 -1
View File
@@ -130,7 +130,18 @@ private:
CancelableTask* mSetNeedsCompositeTask; CancelableTask* mSetNeedsCompositeTask;
}; };
class CompositorParent final : public PCompositorParent, class CompositorUpdateObserver
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorUpdateObserver);
virtual void ObserveUpdate(uint64_t aLayersId, bool aActive) = 0;
protected:
virtual ~CompositorUpdateObserver() {}
};
class CompositorParent MOZ_FINAL : public PCompositorParent,
public ShadowLayersManager public ShadowLayersManager
{ {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent) NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
@@ -305,6 +316,8 @@ public:
LayerTransactionParent* mLayerTree; LayerTransactionParent* mLayerTree;
nsTArray<PluginWindowData> mPluginData; nsTArray<PluginWindowData> mPluginData;
bool mUpdatedPluginDataAvailable; bool mUpdatedPluginDataAvailable;
nsRefPtr<CompositorUpdateObserver> mLayerTreeReadyObserver;
nsRefPtr<CompositorUpdateObserver> mLayerTreeClearedObserver;
}; };
/** /**
@@ -319,6 +332,9 @@ public:
*/ */
static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp); static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
static void RequestNotifyLayerTreeReady(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
static void RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
float ComputeRenderIntegrity(); float ComputeRenderIntegrity();
/** /**
@@ -843,6 +843,8 @@ LayerTransactionParent::RecvClearCachedResources()
// context, it's just a subtree root. We need to scope the clear // context, it's just a subtree root. We need to scope the clear
// of resources to exactly that subtree, so we specify it here. // of resources to exactly that subtree, so we specify it here.
mLayerManager->ClearCachedResources(mRoot); mLayerManager->ClearCachedResources(mRoot);
mShadowLayersManager->NotifyClearCachedResources(this);
} }
return true; return true;
} }
+2
View File
@@ -29,6 +29,8 @@ public:
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; } virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; }
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) { }
virtual void ForceComposite(LayerTransactionParent* aLayerTree) { } virtual void ForceComposite(LayerTransactionParent* aLayerTree) { }
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) { return true; } const TimeStamp& aTime) { return true; }
+2 -2
View File
@@ -3294,7 +3294,7 @@ EffectlesslyLookupProperty(JSContext* cx, HandleObject obj, HandlePropertyName n
if (*shadowsResult == ShadowCheckFailed) if (*shadowsResult == ShadowCheckFailed)
return false; return false;
if (*shadowsResult == Shadows) { if (DOMProxyIsShadowing(*shadowsResult)) {
holder.set(obj); holder.set(obj);
return true; return true;
} }
@@ -6604,7 +6604,7 @@ TryAttachNativeGetPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
} }
// If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead. // If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
if (isDOMProxy && domProxyShadowsResult == Shadows) { if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
MOZ_ASSERT(obj == holder); MOZ_ASSERT(obj == holder);
#if JS_HAS_NO_SUCH_METHOD #if JS_HAS_NO_SUCH_METHOD
if (isCallProp) if (isCallProp)
+3 -2
View File
@@ -1711,9 +1711,10 @@ GetPropertyIC::tryAttachProxy(JSContext* cx, HandleScript outerScript, IonScript
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id); DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed) if (shadows == ShadowCheckFailed)
return false; return false;
if (shadows == Shadows) if (DOMProxyIsShadowing(shadows))
return tryAttachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr, emitted); return tryAttachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr, emitted);
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
return tryAttachDOMProxyUnshadowed(cx, outerScript, ion, obj, name, return tryAttachDOMProxyUnshadowed(cx, outerScript, ion, obj, name,
shadows == DoesntShadowUnique, returnAddr, emitted); shadows == DoesntShadowUnique, returnAddr, emitted);
} }
@@ -3078,7 +3079,7 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id); DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed) if (shadows == ShadowCheckFailed)
return false; return false;
if (shadows == Shadows) { if (DOMProxyIsShadowing(shadows)) {
if (!cache.attachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr)) if (!cache.attachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr))
return false; return false;
addedSetterStub = true; addedSetterStub = true;
+25 -9
View File
@@ -1138,14 +1138,23 @@ NukeCrossCompartmentWrappers(JSContext* cx,
* The DOMProxyShadowsCheck function will be called to check if the property for * The DOMProxyShadowsCheck function will be called to check if the property for
* id should be gotten from the prototype, or if there is an own property that * id should be gotten from the prototype, or if there is an own property that
* shadows it. * shadows it.
* If DoesntShadow is returned then the slot at listBaseExpandoSlot should * * If ShadowsViaDirectExpando is returned, then the slot at
* either be undefined or point to an expando object that would contain the own * listBaseExpandoSlot contains an expando object which has the property in
* property. * question.
* If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot should * * If ShadowsViaIndirectExpando is returned, then the slot at
* contain a private pointer to a ExpandoAndGeneration, which contains a * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
* JS::Value that should either be undefined or point to an expando object, and * and the expando object in the ExpandoAndGeneration has the property in
* a uint32 value. If that value changes then the IC for getting a property will * question.
* be invalidated. * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
* either be undefined or point to an expando object that would contain the
* own property.
* * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
* should contain a private pointer to a ExpandoAndGeneration, which contains
* a JS::Value that should either be undefined or point to an expando object,
* and a uint32 value. If that value changes then the IC for getting a
* property will be invalidated.
* * If Shadows is returned, that means the property is an own property of the
* proxy but doesn't live on the expando object.
*/ */
struct ExpandoAndGeneration { struct ExpandoAndGeneration {
@@ -1178,7 +1187,9 @@ typedef enum DOMProxyShadowsResult {
ShadowCheckFailed, ShadowCheckFailed,
Shadows, Shadows,
DoesntShadow, DoesntShadow,
DoesntShadowUnique DoesntShadowUnique,
ShadowsViaDirectExpando,
ShadowsViaIndirectExpando
} DOMProxyShadowsResult; } DOMProxyShadowsResult;
typedef DOMProxyShadowsResult typedef DOMProxyShadowsResult
(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id); (* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id);
@@ -1189,6 +1200,11 @@ SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpan
const void* GetDOMProxyHandlerFamily(); const void* GetDOMProxyHandlerFamily();
uint32_t GetDOMProxyExpandoSlot(); uint32_t GetDOMProxyExpandoSlot();
DOMProxyShadowsCheck GetDOMProxyShadowsCheck(); DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
return result == Shadows ||
result == ShadowsViaDirectExpando ||
result == ShadowsViaIndirectExpando;
}
/* Implemented in jsdate.cpp. */ /* Implemented in jsdate.cpp. */
+4 -4
View File
@@ -34,8 +34,8 @@ nsTArrayToJSArray(JSContext* aCx, const nsTArray<T>& aSourceArray,
rv = nsContentUtils::WrapNative(aCx, obj, &wrappedVal); rv = nsContentUtils::WrapNative(aCx, obj, &wrappedVal);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!JS_SetElement(aCx, arrayObj, index, wrappedVal)) { if (!JS_DefineElement(aCx, arrayObj, index, wrappedVal, JSPROP_ENUMERATE)) {
NS_WARNING("JS_SetElement failed!"); NS_WARNING("JS_DefineElement failed!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }
@@ -74,8 +74,8 @@ nsTArrayToJSArray<nsString>(JSContext* aCx,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
if (!JS_SetElement(aCx, arrayObj, index, s)) { if (!JS_DefineElement(aCx, arrayObj, index, s, JSPROP_ENUMERATE)) {
NS_WARNING("JS_SetElement failed!"); NS_WARNING("JS_DefineElement failed!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }
+1 -1
View File
@@ -1280,7 +1280,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
for (i = 0; i < count; i++) { \ for (i = 0; i < count; i++) { \
if (!NativeData2JS(&current, ((_t*)*s)+i, type, iid, pErr) || \ if (!NativeData2JS(&current, ((_t*)*s)+i, type, iid, pErr) || \
!JS_SetElement(cx, array, i, current)) \ !JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) \
goto failure; \ goto failure; \
} \ } \
PR_END_MACRO PR_END_MACRO
-7
View File
@@ -8986,13 +8986,6 @@ PresShell::WillPaintWindow()
void void
PresShell::DidPaintWindow() PresShell::DidPaintWindow()
{ {
if (mDocument) {
nsCOMPtr<nsPIDOMWindow> window = mDocument->GetWindow();
if (window) {
window->SendAfterRemotePaintIfRequested();
}
}
nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext(); nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
if (rootPresContext != mPresContext) { if (rootPresContext != mPresContext) {
// This could be a popup's presshell. No point in notifying XPConnect // This could be a popup's presshell. No point in notifying XPConnect
+1 -1
View File
@@ -95,7 +95,7 @@ StatementRow::GetProperty(nsIXPConnectWrappedNative *aWrapper,
// Copy the blob over to the JS array. // Copy the blob over to the JS array.
for (uint32_t i = 0; i < length; i++) { for (uint32_t i = 0; i < length; i++) {
if (!::JS_SetElement(aCtx, scope, i, blob[i])) { if (!::JS_DefineElement(aCtx, scope, i, blob[i], JSPROP_ENUMERATE)) {
*_retval = false; *_retval = false;
return NS_OK; return NS_OK;
} }
+1 -1
View File
@@ -119,7 +119,7 @@ PlaceInfo::GetVisits(JSContext* aContext,
JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject()); JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject());
NS_ENSURE_STATE(jsobj); NS_ENSURE_STATE(jsobj);
bool rc = JS_SetElement(aContext, visits, idx, jsobj); bool rc = JS_DefineElement(aContext, visits, idx, jsobj, JSPROP_ENUMERATE);
NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
} }
+21 -16
View File
@@ -1739,8 +1739,8 @@ TelemetryImpl::ReflectSQL(const SlowSQLEntryType *entry,
if (!arrayObj) { if (!arrayObj) {
return false; return false;
} }
return (JS_SetElement(cx, arrayObj, 0, stat->hitCount) return (JS_DefineElement(cx, arrayObj, 0, stat->hitCount, JSPROP_ENUMERATE)
&& JS_SetElement(cx, arrayObj, 1, stat->totalTime) && JS_DefineElement(cx, arrayObj, 1, stat->totalTime, JSPROP_ENUMERATE)
&& JS_DefineProperty(cx, obj, sql.BeginReading(), arrayObj, && JS_DefineProperty(cx, obj, sql.BeginReading(), arrayObj,
JSPROP_ENUMERATE)); JSPROP_ENUMERATE));
} }
@@ -2328,13 +2328,16 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
const size_t length = stacks.GetStackCount(); const size_t length = stacks.GetStackCount();
for (size_t i = 0; i < length; ++i) { for (size_t i = 0; i < length; ++i) {
if (!JS_SetElement(cx, durationArray, i, mHangReports.GetDuration(i))) { if (!JS_DefineElement(cx, durationArray, i, mHangReports.GetDuration(i),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!JS_SetElement(cx, systemUptimeArray, i, mHangReports.GetSystemUptime(i))) { if (!JS_DefineElement(cx, systemUptimeArray, i, mHangReports.GetSystemUptime(i),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!JS_SetElement(cx, firefoxUptimeArray, i, mHangReports.GetFirefoxUptime(i))) { if (!JS_DefineElement(cx, firefoxUptimeArray, i, mHangReports.GetFirefoxUptime(i),
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
const nsTArray<HangReports::AnnotationInfo>& annotationInfo = const nsTArray<HangReports::AnnotationInfo>& annotationInfo =
@@ -2347,7 +2350,7 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
} }
JS::RootedValue indexValue(cx); JS::RootedValue indexValue(cx);
indexValue.setNumber(annotationInfo[iterIndex].mHangIndex); indexValue.setNumber(annotationInfo[iterIndex].mHangIndex);
if (!JS_SetElement(cx, keyValueArray, 0, indexValue)) { if (!JS_DefineElement(cx, keyValueArray, 0, indexValue, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
JS::Rooted<JSObject*> jsAnnotation(cx, JS_NewPlainObject(cx)); JS::Rooted<JSObject*> jsAnnotation(cx, JS_NewPlainObject(cx));
@@ -2369,11 +2372,11 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }
if (!JS_SetElement(cx, keyValueArray, 1, jsAnnotation)) { if (!JS_DefineElement(cx, keyValueArray, 1, jsAnnotation, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!JS_SetElement(cx, annotationsArray, iterIndex, if (!JS_DefineElement(cx, annotationsArray, iterIndex,
keyValueArray)) { keyValueArray, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }
@@ -2409,7 +2412,8 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!moduleInfoArray) { if (!moduleInfoArray) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, moduleArray, moduleIndex, moduleInfoArray)) { if (!JS_DefineElement(cx, moduleArray, moduleIndex, moduleInfoArray,
JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
@@ -2420,7 +2424,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!str) { if (!str) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, moduleInfoArray, index++, str)) { if (!JS_DefineElement(cx, moduleInfoArray, index++, str, JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
@@ -2429,7 +2433,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!id) { if (!id) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, moduleInfoArray, index++, id)) { if (!JS_DefineElement(cx, moduleInfoArray, index++, id, JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
} }
@@ -2451,7 +2455,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, reportArray, i, pcArray)) { if (!JS_DefineElement(cx, reportArray, i, pcArray, JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
@@ -2465,13 +2469,14 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
} }
int modIndex = (std::numeric_limits<uint16_t>::max() == frame.mModIndex) ? int modIndex = (std::numeric_limits<uint16_t>::max() == frame.mModIndex) ?
-1 : frame.mModIndex; -1 : frame.mModIndex;
if (!JS_SetElement(cx, framePair, 0, modIndex)) { if (!JS_DefineElement(cx, framePair, 0, modIndex, JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, framePair, 1, static_cast<double>(frame.mOffset))) { if (!JS_DefineElement(cx, framePair, 1, static_cast<double>(frame.mOffset),
JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
if (!JS_SetElement(cx, pcArray, pcIndex, framePair)) { if (!JS_DefineElement(cx, pcArray, pcIndex, framePair, JSPROP_ENUMERATE)) {
return nullptr; return nullptr;
} }
} }