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.
mAttrsAndChildren.ChildAt(i)->DestroyContent();
}
ShadowRoot* shadowRoot = GetShadowRoot();
if (shadowRoot) {
shadowRoot->DestroyContent();
}
}
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,
mShadowRoot)
+2
View File
@@ -133,6 +133,8 @@ public:
{
mIsComposedDocParticipant = aIsComposedDocParticipant;
}
virtual void DestroyContent() MOZ_OVERRIDE;
protected:
virtual ~ShadowRoot();
+7 -3
View File
@@ -19,6 +19,13 @@ namespace dom {
static bool
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.
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aChild);
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
// cross-origin communication only in a limited set of cases that can be
// 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,
aNameBeingResolved, eCaseMatters);
}
+39 -16
View File
@@ -194,7 +194,7 @@ nsFrameLoader::Create(Element* aOwner, bool aNetworkCreated)
NS_ENSURE_TRUE(aOwner, nullptr);
nsIDocument* doc = aOwner->OwnerDoc();
NS_ENSURE_TRUE(!doc->IsResourceDoc() &&
((!doc->IsLoadedAsData() && aOwner->GetUncomposedDoc()) ||
((!doc->IsLoadedAsData() && aOwner->GetComposedDoc()) ||
doc->IsStaticDocument()),
nullptr);
@@ -349,7 +349,7 @@ private:
nsresult
nsFrameLoader::ReallyStartLoadingInternal()
{
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInDoc());
NS_ENSURE_STATE(mURIToLoad && mOwnerContent && mOwnerContent->IsInComposedDoc());
PROFILER_LABEL("nsFrameLoader", "ReallyStartLoading",
js::ProfileEntry::Category::OTHER);
@@ -876,12 +876,12 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size,
// want here. For now, hack.
if (!mRemoteBrowserShown) {
if (!mOwnerContent ||
!mOwnerContent->GetUncomposedDoc()) {
!mOwnerContent->GetComposedDoc()) {
return false;
}
nsRefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForDocument(mOwnerContent->GetUncomposedDoc());
nsContentUtils::LayerManagerForDocument(mOwnerContent->GetComposedDoc());
if (!layerManager) {
// This is just not going to work.
return false;
@@ -972,8 +972,8 @@ nsFrameLoader::SwapWithOtherRemoteLoader(nsFrameLoader* aOther,
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIDocument* ourDoc = ourContent->GetCurrentDoc();
nsIDocument* otherDoc = otherContent->GetCurrentDoc();
nsIDocument* ourDoc = ourContent->GetComposedDoc();
nsIDocument* otherDoc = otherContent->GetComposedDoc();
if (!ourDoc || !otherDoc) {
// Again, how odd, given that we had docshells
return NS_ERROR_NOT_IMPLEMENTED;
@@ -1191,8 +1191,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
otherChildDocument->GetParentDocument();
// Make sure to swap docshells between the two frames.
nsIDocument* ourDoc = ourContent->GetUncomposedDoc();
nsIDocument* otherDoc = otherContent->GetUncomposedDoc();
nsIDocument* ourDoc = ourContent->GetComposedDoc();
nsIDocument* otherDoc = otherContent->GetComposedDoc();
if (!ourDoc || !otherDoc) {
// Again, how odd, given that we had docshells
return NS_ERROR_NOT_IMPLEMENTED;
@@ -1612,7 +1612,7 @@ nsFrameLoader::MaybeCreateDocShell()
// XXXbz this is such a total hack.... We really need to have a
// better setup for doing this.
nsIDocument* doc = mOwnerContent->OwnerDoc();
if (!(doc->IsStaticDocument() || mOwnerContent->IsInDoc())) {
if (!(doc->IsStaticDocument() || mOwnerContent->IsInComposedDoc())) {
return NS_ERROR_UNEXPECTED;
}
@@ -2674,17 +2674,40 @@ nsFrameLoader::RequestNotifyAfterRemotePaint()
// If remote browsing (e10s), handle this with the TabParent.
if (mRemoteBrowser) {
unused << mRemoteBrowser->SendRequestNotifyAfterRemotePaint();
return NS_OK;
}
// If not remote browsing, directly use the document's window.
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
if (!window) {
NS_WARNING("Unable to get window for synchronous MozAfterRemotePaint event.");
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
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;
}
+2 -2
View File
@@ -514,7 +514,7 @@ nsFrameMessageManager::GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::V
pair = JS_NewArrayObject(aCx, pairElts);
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);
}
@@ -696,7 +696,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
retval[i].Length(), &ret)) {
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);
}
+1 -16
View File
@@ -587,7 +587,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
mInnerWindow(nullptr), mOuterWindow(aOuterWindow),
// Make sure no actual window ends up with mWindowID == 0
mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
mMarkedCCGeneration(0), mSendAfterRemotePaint(false)
mMarkedCCGeneration(0)
{}
nsPIDOMWindow::~nsPIDOMWindow() {}
@@ -3776,21 +3776,6 @@ nsPIDOMWindow::RefreshMediaElements()
service->RefreshAgentsVolume(this);
}
void
nsPIDOMWindow::SendAfterRemotePaintIfRequested()
{
if (!mSendAfterRemotePaint) {
return;
}
mSendAfterRemotePaint = false;
nsContentUtils::DispatchChromeEvent(GetExtantDoc(),
GetParentTarget(),
NS_LITERAL_STRING("MozAfterRemotePaint"),
false, false);
}
// nsISpeechSynthesisGetter
#ifdef MOZ_WEBSPEECH
+9 -1
View File
@@ -16,7 +16,7 @@ interface nsIDOMElement;
interface nsITabParent;
interface nsILoadContext;
[scriptable, builtinclass, uuid(28b6b043-46ec-412f-9be9-db22938b0d6d)]
[scriptable, builtinclass, uuid(d24f9330-ae4e-11e4-ab27-0800200c9a66)]
interface nsIFrameLoader : nsISupports
{
/**
@@ -121,6 +121,14 @@ interface nsIFrameLoader : nsISupports
*/
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
* handled in EventStateManager::HandleCrossProcessEvent to
+2 -3
View File
@@ -131,7 +131,7 @@ IsJavaMIME(const nsACString & aMIMEType)
static bool
InActiveDocument(nsIContent *aContent)
{
if (!aContent->IsInDoc()) {
if (!aContent->IsInComposedDoc()) {
return false;
}
nsIDocument *doc = aContent->OwnerDoc();
@@ -3333,11 +3333,10 @@ nsObjectLoadingContent::GetContentDocument()
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
if (!thisContent->IsInDoc()) {
if (!thisContent->IsInComposedDoc()) {
return nullptr;
}
// XXXbz should this use GetComposedDoc()? sXBL/XBL2 issue!
nsIDocument *sub_doc = thisContent->OwnerDoc()->GetSubDocumentFor(thisContent);
if (!sub_doc) {
return nullptr;
-15
View File
@@ -769,17 +769,6 @@ public:
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;
// aLoadInfo will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except
@@ -885,10 +874,6 @@ protected:
bool mHasNotifiedGlobalCreated;
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
support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs
[test_bug1025933.html]
[test_bug1037687.html]
[test_element.matches.html]
[test_user_select.html]
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
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);
if (v.isObject()) {
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
if (expando) {
bool hasOwn;
Rooted<JSObject*> object(cx, &v.toObject());
if (!JS_AlreadyHasOwnPropertyById(cx, object, id, &hasOwn))
if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
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;
}
+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
// Otherwise, BindToTree takes care of that.
if (IsInDoc()) {
if (IsInComposedDoc()) {
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
// a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
return LoadObject(aNotify, true);
}
@@ -329,7 +329,7 @@ HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
NS_ENSURE_SUCCESS(rv, rv);
// See comment in SetAttr
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
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
// in the interim
if (!IsInDoc() || !OwnerDoc()->IsActive()) {
if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
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
// Otherwise, BindToTree takes care of that.
if (IsInDoc()) {
if (IsInComposedDoc()) {
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
// a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
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
// in the interim
if (!IsInDoc() || !OwnerDoc()->IsActive()) {
if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
return;
}
+2 -2
View File
@@ -131,7 +131,7 @@ nsGenericHTMLFrameElement::GetContentWindow()
void
nsGenericHTMLFrameElement::EnsureFrameLoader()
{
if (!IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
if (!IsInComposedDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
// If frame loader is there, we just keep it around, cached
return;
}
@@ -221,7 +221,7 @@ nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
if (IsInComposedDoc()) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Missing a script blocker!");
+5 -3
View File
@@ -458,7 +458,8 @@ private:
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();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@@ -511,7 +512,8 @@ private:
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();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
@@ -1100,7 +1102,7 @@ BackgroundFactoryRequestChild::Recv__delete__(
IDBOpenDBRequest* request = GetOpenDBRequest();
MOZ_ASSERT(request);
request->NoteComplete();
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;
if (!JS_SetElement(aCx, array, index++, val)) {
if (!JS_DefineElement(aCx, array, index++, val, JSPROP_ENUMERATE)) {
NS_WARNING("Failed to set array element!");
IDB_REPORT_INTERNAL_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;
}
if (!JS_SetElement(aCx, arrayObj, i, value)) {
if (!JS_DefineElement(aCx, arrayObj, i, value, JSPROP_ENUMERATE)) {
IDB_REPORT_INTERNAL_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;
}
if (!JS_SetElement(aCx, array, i, val)) {
if (!JS_DefineElement(aCx, array, i, val, JSPROP_ENUMERATE)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
+80
View File
@@ -2645,6 +2645,86 @@ TabParent::GetTabId(uint64_t* aId)
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
TabParent::RecvRemotePaintIsReady()
{
+5
View File
@@ -376,6 +376,11 @@ public:
bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope);
// See nsIFrameLoader requestNotifyLayerTreeReady.
bool RequestNotifyLayerTreeReady();
bool RequestNotifyLayerTreeCleared();
bool LayerTreeUpdate(bool aActive);
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
+1 -1
View File
@@ -587,7 +587,7 @@ MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachm
return NS_ERROR_FAILURE;
}
if (!JS_SetElement(aCx, attachments, i, attachmentObj)) {
if (!JS_DefineElement(aCx, attachments, i, attachmentObj, JSPROP_ENUMERATE)) {
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));
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));
+1 -1
View File
@@ -120,7 +120,7 @@ GetParamsFromSendMmsMessageRequest(JSContext* aCx,
JS::Rooted<JSObject*> obj(aCx,
MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
NS_ENSURE_TRUE(obj, false);
if (!JS_SetElement(aCx, attachmentArray, i, obj)) {
if (!JS_DefineElement(aCx, attachmentArray, i, obj, JSPROP_ENUMERATE)) {
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
* processes to the compositor thread. It's associated with a
@@ -1455,26 +1471,26 @@ public:
virtual IToplevelProtocol*
CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
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.
virtual bool RecvRequestOverfill() override { return true; }
virtual bool RecvWillStop() override { return true; }
virtual bool RecvStop() override { return true; }
virtual bool RecvPause() override { return true; }
virtual bool RecvResume() override { return true; }
virtual bool RecvNotifyChildCreated(const uint64_t& child) override;
virtual bool RecvAdoptChild(const uint64_t& child) override { return false; }
virtual bool RecvRequestOverfill() MOZ_OVERRIDE { return true; }
virtual bool RecvWillStop() MOZ_OVERRIDE { return true; }
virtual bool RecvStop() MOZ_OVERRIDE { return true; }
virtual bool RecvPause() MOZ_OVERRIDE { return true; }
virtual bool RecvResume() MOZ_OVERRIDE { return true; }
virtual bool RecvNotifyChildCreated(const uint64_t& child) MOZ_OVERRIDE;
virtual bool RecvAdoptChild(const uint64_t& child) MOZ_OVERRIDE { return false; }
virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
const nsIntRect& aRect) override
const nsIntRect& aRect) MOZ_OVERRIDE
{ return true; }
virtual bool RecvFlushRendering() override { return true; }
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) override { return true; }
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return true; }
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return true; }
virtual bool RecvGetTileSize(int32_t* aWidth, int32_t* aHeight) override
virtual bool RecvFlushRendering() MOZ_OVERRIDE { return true; }
virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) MOZ_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) MOZ_OVERRIDE { return true; }
virtual bool RecvGetTileSize(int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE
{
*aWidth = gfxPlatform::GetPlatform()->GetTileWidth();
*aHeight = gfxPlatform::GetPlatform()->GetTileHeight();
@@ -1485,15 +1501,15 @@ public:
/**
* 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*
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,
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,
const uint64_t& aTransactionId,
@@ -1502,15 +1518,16 @@ public:
bool aIsFirstPaint,
bool aScheduleComposite,
uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction) override;
virtual void ForceComposite(LayerTransactionParent* aLayerTree) override;
bool aIsRepeatTransaction) MOZ_OVERRIDE;
virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) override;
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
const TimeStamp& aTime) MOZ_OVERRIDE;
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE;
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);
@@ -1737,6 +1754,12 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
mNotifyAfterRemotePaint = false;
}
if (state->mLayerTreeReadyObserver) {
nsRefPtr<CompositorUpdateObserver> observer = state->mLayerTreeReadyObserver;
state->mLayerTreeReadyObserver = nullptr;
observer->ObserveUpdate(id, true);
}
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
CrossProcessCompositorParent::SetTestSampleTime(
LayerTransactionParent* aLayerTree, const TimeStamp& aTime)
+17 -1
View File
@@ -130,7 +130,18 @@ private:
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
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
@@ -305,6 +316,8 @@ public:
LayerTransactionParent* mLayerTree;
nsTArray<PluginWindowData> mPluginData;
bool mUpdatedPluginDataAvailable;
nsRefPtr<CompositorUpdateObserver> mLayerTreeReadyObserver;
nsRefPtr<CompositorUpdateObserver> mLayerTreeClearedObserver;
};
/**
@@ -319,6 +332,9 @@ public:
*/
static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
static void RequestNotifyLayerTreeReady(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
static void RequestNotifyLayerTreeCleared(uint64_t aLayersId, CompositorUpdateObserver* aObserver);
float ComputeRenderIntegrity();
/**
@@ -843,6 +843,8 @@ LayerTransactionParent::RecvClearCachedResources()
// context, it's just a subtree root. We need to scope the clear
// of resources to exactly that subtree, so we specify it here.
mLayerManager->ClearCachedResources(mRoot);
mShadowLayersManager->NotifyClearCachedResources(this);
}
return true;
}
+2
View File
@@ -29,6 +29,8 @@ public:
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; }
virtual void NotifyClearCachedResources(LayerTransactionParent* aLayerTree) { }
virtual void ForceComposite(LayerTransactionParent* aLayerTree) { }
virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree,
const TimeStamp& aTime) { return true; }
+2 -2
View File
@@ -3294,7 +3294,7 @@ EffectlesslyLookupProperty(JSContext* cx, HandleObject obj, HandlePropertyName n
if (*shadowsResult == ShadowCheckFailed)
return false;
if (*shadowsResult == Shadows) {
if (DOMProxyIsShadowing(*shadowsResult)) {
holder.set(obj);
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 (isDOMProxy && domProxyShadowsResult == Shadows) {
if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
MOZ_ASSERT(obj == holder);
#if JS_HAS_NO_SUCH_METHOD
if (isCallProp)
+3 -2
View File
@@ -1711,9 +1711,10 @@ GetPropertyIC::tryAttachProxy(JSContext* cx, HandleScript outerScript, IonScript
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows)
if (DOMProxyIsShadowing(shadows))
return tryAttachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr, emitted);
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
return tryAttachDOMProxyUnshadowed(cx, outerScript, ion, obj, name,
shadows == DoesntShadowUnique, returnAddr, emitted);
}
@@ -3078,7 +3079,7 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows) {
if (DOMProxyIsShadowing(shadows)) {
if (!cache.attachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr))
return false;
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
* id should be gotten from the prototype, or if there is an own property that
* shadows it.
* 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 ShadowsViaDirectExpando is returned, then the slot at
* listBaseExpandoSlot contains an expando object which has the property in
* question.
* * If ShadowsViaIndirectExpando is returned, then the slot at
* listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
* and the expando object in the ExpandoAndGeneration has the property in
* question.
* * 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 {
@@ -1178,7 +1187,9 @@ typedef enum DOMProxyShadowsResult {
ShadowCheckFailed,
Shadows,
DoesntShadow,
DoesntShadowUnique
DoesntShadowUnique,
ShadowsViaDirectExpando,
ShadowsViaIndirectExpando
} DOMProxyShadowsResult;
typedef DOMProxyShadowsResult
(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id);
@@ -1189,6 +1200,11 @@ SetDOMProxyInformation(const void* domProxyHandlerFamily, uint32_t domProxyExpan
const void* GetDOMProxyHandlerFamily();
uint32_t GetDOMProxyExpandoSlot();
DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
return result == Shadows ||
result == ShadowsViaDirectExpando ||
result == ShadowsViaIndirectExpando;
}
/* 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);
NS_ENSURE_SUCCESS(rv, rv);
if (!JS_SetElement(aCx, arrayObj, index, wrappedVal)) {
NS_WARNING("JS_SetElement failed!");
if (!JS_DefineElement(aCx, arrayObj, index, wrappedVal, JSPROP_ENUMERATE)) {
NS_WARNING("JS_DefineElement failed!");
return NS_ERROR_FAILURE;
}
}
@@ -74,8 +74,8 @@ nsTArrayToJSArray<nsString>(JSContext* aCx,
return NS_ERROR_OUT_OF_MEMORY;
}
if (!JS_SetElement(aCx, arrayObj, index, s)) {
NS_WARNING("JS_SetElement failed!");
if (!JS_DefineElement(aCx, arrayObj, index, s, JSPROP_ENUMERATE)) {
NS_WARNING("JS_DefineElement failed!");
return NS_ERROR_FAILURE;
}
}
+1 -1
View File
@@ -1280,7 +1280,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s,
PR_BEGIN_MACRO \
for (i = 0; i < count; i++) { \
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; \
} \
PR_END_MACRO
-7
View File
@@ -8986,13 +8986,6 @@ PresShell::WillPaintWindow()
void
PresShell::DidPaintWindow()
{
if (mDocument) {
nsCOMPtr<nsPIDOMWindow> window = mDocument->GetWindow();
if (window) {
window->SendAfterRemotePaintIfRequested();
}
}
nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
if (rootPresContext != mPresContext) {
// 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.
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;
return NS_OK;
}
+1 -1
View File
@@ -119,7 +119,7 @@ PlaceInfo::GetVisits(JSContext* aContext,
JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject());
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);
}
+21 -16
View File
@@ -1739,8 +1739,8 @@ TelemetryImpl::ReflectSQL(const SlowSQLEntryType *entry,
if (!arrayObj) {
return false;
}
return (JS_SetElement(cx, arrayObj, 0, stat->hitCount)
&& JS_SetElement(cx, arrayObj, 1, stat->totalTime)
return (JS_DefineElement(cx, arrayObj, 0, stat->hitCount, JSPROP_ENUMERATE)
&& JS_DefineElement(cx, arrayObj, 1, stat->totalTime, JSPROP_ENUMERATE)
&& JS_DefineProperty(cx, obj, sql.BeginReading(), arrayObj,
JSPROP_ENUMERATE));
}
@@ -2328,13 +2328,16 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
const size_t length = stacks.GetStackCount();
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;
}
if (!JS_SetElement(cx, systemUptimeArray, i, mHangReports.GetSystemUptime(i))) {
if (!JS_DefineElement(cx, systemUptimeArray, i, mHangReports.GetSystemUptime(i),
JSPROP_ENUMERATE)) {
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;
}
const nsTArray<HangReports::AnnotationInfo>& annotationInfo =
@@ -2347,7 +2350,7 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
}
JS::RootedValue indexValue(cx);
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;
}
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;
}
}
if (!JS_SetElement(cx, keyValueArray, 1, jsAnnotation)) {
if (!JS_DefineElement(cx, keyValueArray, 1, jsAnnotation, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
if (!JS_SetElement(cx, annotationsArray, iterIndex,
keyValueArray)) {
if (!JS_DefineElement(cx, annotationsArray, iterIndex,
keyValueArray, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
}
@@ -2409,7 +2412,8 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!moduleInfoArray) {
return nullptr;
}
if (!JS_SetElement(cx, moduleArray, moduleIndex, moduleInfoArray)) {
if (!JS_DefineElement(cx, moduleArray, moduleIndex, moduleInfoArray,
JSPROP_ENUMERATE)) {
return nullptr;
}
@@ -2420,7 +2424,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!str) {
return nullptr;
}
if (!JS_SetElement(cx, moduleInfoArray, index++, str)) {
if (!JS_DefineElement(cx, moduleInfoArray, index++, str, JSPROP_ENUMERATE)) {
return nullptr;
}
@@ -2429,7 +2433,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
if (!id) {
return nullptr;
}
if (!JS_SetElement(cx, moduleInfoArray, index++, id)) {
if (!JS_DefineElement(cx, moduleInfoArray, index++, id, JSPROP_ENUMERATE)) {
return nullptr;
}
}
@@ -2451,7 +2455,7 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
return nullptr;
}
if (!JS_SetElement(cx, reportArray, i, pcArray)) {
if (!JS_DefineElement(cx, reportArray, i, pcArray, JSPROP_ENUMERATE)) {
return nullptr;
}
@@ -2465,13 +2469,14 @@ CreateJSStackObject(JSContext *cx, const CombinedStacks &stacks) {
}
int modIndex = (std::numeric_limits<uint16_t>::max() == frame.mModIndex) ?
-1 : frame.mModIndex;
if (!JS_SetElement(cx, framePair, 0, modIndex)) {
if (!JS_DefineElement(cx, framePair, 0, modIndex, JSPROP_ENUMERATE)) {
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;
}
if (!JS_SetElement(cx, pcArray, pcIndex, framePair)) {
if (!JS_DefineElement(cx, pcArray, pcIndex, framePair, JSPROP_ENUMERATE)) {
return nullptr;
}
}