mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Merge inbound to mozilla-central. a=merge
This commit is contained in:
commit
199c24a789
@ -702,10 +702,10 @@ NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(DocAccessible)
|
||||
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(DocAccessible)
|
||||
|
||||
void
|
||||
DocAccessible::AttributeWillChange(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
DocAccessible::AttributeWillChange(dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute, int32_t aModType,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aNewValue)
|
||||
{
|
||||
Accessible* accessible = GetAccessible(aElement);
|
||||
@ -748,15 +748,13 @@ DocAccessible::AttributeWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
DocAccessible::NativeAnonymousChildListChange(nsIContent* aContent,
|
||||
bool aIsRemove)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::AttributeChanged(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
DocAccessible::AttributeChanged(dom::Element* aElement,
|
||||
int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
@ -1086,9 +1084,7 @@ DocAccessible::ARIAActiveDescendantChanged(Accessible* aAccessible)
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
DocAccessible::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1139,35 +1135,30 @@ DocAccessible::DocumentStatesChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
DocAccessible::CharacterDataWillChange(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
DocAccessible::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::ContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
DocAccessible::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainerNode,
|
||||
nsIContent* aChildNode,
|
||||
DocAccessible::ContentRemoved(nsIContent* aChildNode,
|
||||
nsIContent* aPreviousSiblingNode)
|
||||
{
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "DOM content removed; doc: %p", this);
|
||||
logging::Node("container node", aContainerNode);
|
||||
logging::Node("container node", aChildNode->GetParent());
|
||||
logging::Node("content node", aChildNode);
|
||||
logging::MsgEnd();
|
||||
}
|
||||
|
@ -9,6 +9,10 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%
|
||||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 28800); // 8 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=192 hours
|
||||
pref("app.update.promptWaitTime", 691200);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
@ -7,6 +7,10 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/projects/firefox/%
|
||||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 7200); // 2 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=12 hours
|
||||
pref("app.update.promptWaitTime", 43200);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
@ -7,6 +7,10 @@ pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%
|
||||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// Interval: Time between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 43200); // 12 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
// 0 means "download everything at once"
|
||||
pref("app.update.download.backgroundInterval", 0);
|
||||
// Give the user x seconds to react before showing the big UI. default=192 hours
|
||||
pref("app.update.promptWaitTime", 691200);
|
||||
// app.update.url.manual: URL user can browse to manually if for some reason
|
||||
|
@ -7,6 +7,9 @@ pref("startup.homepage_welcome_url", "");
|
||||
pref("startup.homepage_welcome_url.additional", "");
|
||||
// The time interval between checks for a new version (in seconds)
|
||||
pref("app.update.interval", 86400); // 24 hours
|
||||
// The time interval between the downloading of mar file chunks in the
|
||||
// background (in seconds)
|
||||
pref("app.update.download.backgroundInterval", 60);
|
||||
// Give the user x seconds to react before showing the big UI. default=24 hours
|
||||
pref("app.update.promptWaitTime", 86400);
|
||||
// URL user can browse to manually if for some reason all update installation
|
||||
|
@ -248,9 +248,6 @@ src:*/xpcom/ds/PLDHashTable.cpp
|
||||
# Hash/Cache function in Skia
|
||||
fun:*GradientShaderCache*Build32bitCache*
|
||||
|
||||
# Hash function in js/public/Utility.h
|
||||
fun:ScrambleHashCode*
|
||||
|
||||
# Hashing functions in Cairo
|
||||
fun:*_hash_matrix_fnv*
|
||||
fun:*_hash_mix_bits*
|
||||
|
@ -255,9 +255,6 @@ src:*/xpcom/ds/PLDHashTable.cpp
|
||||
# Hash/Cache function in Skia
|
||||
fun:*GradientShaderCache*Build32bitCache*
|
||||
|
||||
# Hash function in js/public/Utility.h
|
||||
fun:ScrambleHashCode*
|
||||
|
||||
# Hashing functions in Cairo
|
||||
fun:*_hash_matrix_fnv*
|
||||
fun:*_hash_mix_bits*
|
||||
|
@ -253,23 +253,20 @@ nsSHEntryShared::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsSHEntryShared::CharacterDataWillChange(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsSHEntryShared::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument,
|
||||
dom::Element* aContent,
|
||||
nsSHEntryShared::AttributeWillChange(dom::Element* aContent,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -278,15 +275,13 @@ nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsSHEntryShared::NativeAnonymousChildListChange(nsIContent* aContent,
|
||||
bool aIsRemove)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::AttributeChanged(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
nsSHEntryShared::AttributeChanged(dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -296,25 +291,19 @@ nsSHEntryShared::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsSHEntryShared::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsSHEntryShared::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsSHEntryShared::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
|
@ -653,5 +653,94 @@ ChromeUtils::ClearRecentJSDevError(GlobalObject&)
|
||||
}
|
||||
#endif // NIGHTLY_BUILD
|
||||
|
||||
constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude;
|
||||
|
||||
/* static */ void
|
||||
ChromeUtils::GetCallerLocation(const GlobalObject& aGlobal, nsIPrincipal* aPrincipal,
|
||||
JS::MutableHandle<JSObject*> aRetval)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
auto* principals = nsJSPrincipals::get(aPrincipal);
|
||||
|
||||
JS::StackCapture captureMode(JS::FirstSubsumedFrame(cx, principals));
|
||||
|
||||
JS::RootedObject frame(cx);
|
||||
if (!JS::CaptureCurrentStack(cx, &frame, mozilla::Move(captureMode))) {
|
||||
JS_ClearPendingException(cx);
|
||||
aRetval.set(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// FirstSubsumedFrame gets us a stack which stops at the first principal which
|
||||
// is subsumed by the given principal. That means that we may have a lot of
|
||||
// privileged frames that we don't care about at the top of the stack, though.
|
||||
// We need to filter those out to get the frame we actually want.
|
||||
aRetval.set(js::GetFirstSubsumedSavedFrame(cx, principals, frame, kSkipSelfHosted));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ChromeUtils::CreateError(const GlobalObject& aGlobal, const nsAString& aMessage,
|
||||
JS::Handle<JSObject*> aStack,
|
||||
JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv)
|
||||
{
|
||||
if (aStack && !JS::IsSavedFrame(aStack)) {
|
||||
aRv.Throw(NS_ERROR_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
|
||||
JSContext* cx = aGlobal.Context();
|
||||
|
||||
auto cleanup = MakeScopeExit([&]() {
|
||||
aRv.NoteJSContextException(cx);
|
||||
});
|
||||
|
||||
JS::RootedObject retVal(cx);
|
||||
{
|
||||
JS::RootedString fileName(cx, JS_GetEmptyString(cx));
|
||||
uint32_t line = 0;
|
||||
uint32_t column = 0;
|
||||
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
JS::RootedObject stack(cx);
|
||||
if (aStack) {
|
||||
stack = UncheckedUnwrap(aStack);
|
||||
ac.emplace(cx, stack);
|
||||
|
||||
if (JS::GetSavedFrameLine(cx, stack, &line) != JS::SavedFrameResult::Ok ||
|
||||
JS::GetSavedFrameColumn(cx, stack, &column) != JS::SavedFrameResult::Ok ||
|
||||
JS::GetSavedFrameSource(cx, stack, &fileName) != JS::SavedFrameResult::Ok) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JS::RootedString message(cx);
|
||||
{
|
||||
JS::RootedValue msgVal(cx);
|
||||
if (!xpc::NonVoidStringToJsval(cx, aMessage, &msgVal)) {
|
||||
return;
|
||||
}
|
||||
message = msgVal.toString();
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> err(cx);
|
||||
if (!JS::CreateError(cx, JSEXN_ERR, stack,
|
||||
fileName, line, column,
|
||||
nullptr, message, &err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(err.isObject());
|
||||
retVal = &err.toObject();
|
||||
}
|
||||
|
||||
if (aStack && !JS_WrapObject(cx, &retVal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cleanup.release();
|
||||
aRetVal.set(retVal);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -166,6 +166,15 @@ public:
|
||||
const nsAString& id,
|
||||
const nsAString& resourceURI,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static void
|
||||
GetCallerLocation(const GlobalObject& global, nsIPrincipal* principal,
|
||||
JS::MutableHandle<JSObject*> aRetval);
|
||||
|
||||
static void
|
||||
CreateError(const GlobalObject& global, const nsAString& message,
|
||||
JS::Handle<JSObject*> stack,
|
||||
JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -224,12 +224,10 @@ NodeIterator::Detach()
|
||||
* nsIMutationObserver interface
|
||||
*/
|
||||
|
||||
void NodeIterator::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
nsIContent *aPreviousSibling)
|
||||
void NodeIterator::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
nsINode *container = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* container = aChild->GetParentNode();
|
||||
|
||||
mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
|
@ -438,8 +438,7 @@ ShadowRoot::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError)
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
ShadowRoot::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -468,26 +467,22 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
ShadowRoot::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
for (nsIContent* content = aFirstNewContent;
|
||||
content;
|
||||
content = content->GetNextSibling()) {
|
||||
ContentInserted(aDocument, aContainer, content);
|
||||
ContentInserted(content);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
ShadowRoot::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
// Check to ensure that the content is in the same anonymous tree
|
||||
// as the container because anonymous content may report its container
|
||||
// as the host but it may not be in the host's child list.
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(aContainer, aChild)) {
|
||||
// Check to ensure that the child not an anonymous subtree root because
|
||||
// even though its parent could be the host it may not be in the host's child
|
||||
// list.
|
||||
if (aChild->IsRootOfAnonymousSubtree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -495,7 +490,7 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aContainer && aContainer == GetHost()) {
|
||||
if (aChild->GetParent() == GetHost()) {
|
||||
if (const HTMLSlotElement* slot = AssignSlotFor(aChild)) {
|
||||
slot->EnqueueSlotChangeEvent();
|
||||
}
|
||||
@ -504,7 +499,7 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
|
||||
|
||||
// If parent's root is a shadow root, and parent is a slot whose assigned
|
||||
// nodes is the empty list, then run signal a slot change for parent.
|
||||
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aContainer);
|
||||
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aChild->GetParent());
|
||||
if (slot && slot->GetContainingShadow() == this &&
|
||||
slot->AssignedNodes().IsEmpty()) {
|
||||
slot->EnqueueSlotChangeEvent();
|
||||
@ -512,15 +507,12 @@ ShadowRoot::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
ShadowRoot::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
|
||||
{
|
||||
// Check to ensure that the content is in the same anonymous tree
|
||||
// as the container because anonymous content may report its container
|
||||
// as the host but it may not be in the host's child list.
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(aContainer, aChild)) {
|
||||
// Check to ensure that the child not an anonymous subtree root because
|
||||
// even though its parent could be the host it may not be in the host's child
|
||||
// list.
|
||||
if (aChild->IsRootOfAnonymousSubtree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -528,7 +520,7 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aContainer && aContainer == GetHost()) {
|
||||
if (aChild->GetParent() == GetHost()) {
|
||||
nsAutoString slotName;
|
||||
if (aChild->IsElement()) {
|
||||
aChild->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::slot, slotName);
|
||||
@ -541,7 +533,7 @@ ShadowRoot::ContentRemoved(nsIDocument* aDocument,
|
||||
|
||||
// If parent's root is a shadow root, and parent is a slot whose assigned
|
||||
// nodes is the empty list, then run signal a slot change for parent.
|
||||
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aContainer);
|
||||
HTMLSlotElement* slot = HTMLSlotElement::FromContentOrNull(aChild->GetParent());
|
||||
if (slot && slot->GetContainingShadow() == this &&
|
||||
slot->AssignedNodes().IsEmpty()) {
|
||||
slot->EnqueueSlotChangeEvent();
|
||||
|
@ -681,8 +681,7 @@ nsContentList::Item(uint32_t aIndex)
|
||||
}
|
||||
|
||||
void
|
||||
nsContentList::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
nsContentList::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -715,25 +714,24 @@ nsContentList::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsContentList::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsContentList::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
NS_PRECONDITION(aContainer, "Can't get at the new content if no container!");
|
||||
nsIContent* container = aFirstNewContent->GetParent();
|
||||
NS_PRECONDITION(container, "Can't get at the new content if no container!");
|
||||
|
||||
/*
|
||||
* If the state is LIST_DIRTY then we have no useful information in our list
|
||||
* and we want to put off doing work as much as possible.
|
||||
*
|
||||
* Also, if aContainer is anonymous from our point of view, we know that we
|
||||
* Also, if container is anonymous from our point of view, we know that we
|
||||
* can't possibly be matching any of the kids.
|
||||
*
|
||||
* Optimize out also the common case when just one new node is appended and
|
||||
* it doesn't match us.
|
||||
*/
|
||||
if (mState == LIST_DIRTY ||
|
||||
!nsContentUtils::IsInSameAnonymousTree(mRootNode, aContainer) ||
|
||||
!MayContainRelevantNodes(aContainer) ||
|
||||
!nsContentUtils::IsInSameAnonymousTree(mRootNode, container) ||
|
||||
!MayContainRelevantNodes(container) ||
|
||||
(!aFirstNewContent->HasChildren() &&
|
||||
!aFirstNewContent->GetNextSibling() &&
|
||||
!MatchSelf(aFirstNewContent))) {
|
||||
@ -749,7 +747,7 @@ nsContentList::ContentAppended(nsIDocument* aDocument,
|
||||
* already have.
|
||||
*/
|
||||
|
||||
int32_t count = aContainer->GetChildCount();
|
||||
int32_t count = container->GetChildCount();
|
||||
|
||||
if (count > 0) {
|
||||
uint32_t ourCount = mElements.Length();
|
||||
@ -800,7 +798,7 @@ nsContentList::ContentAppended(nsIDocument* aDocument,
|
||||
if (mDeep) {
|
||||
for (nsIContent* cur = aFirstNewContent;
|
||||
cur;
|
||||
cur = cur->GetNextNode(aContainer)) {
|
||||
cur = cur->GetNextNode(container)) {
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
mElements.AppendElement(cur);
|
||||
}
|
||||
@ -818,15 +816,13 @@ nsContentList::ContentAppended(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsContentList::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
// Note that aContainer can be null here if we are inserting into
|
||||
// the document itself; any attempted optimizations to this method
|
||||
// should deal with that.
|
||||
// Note that aChild->GetParentNode() can be null here if we are inserting into
|
||||
// the document itself; any attempted optimizations to this method should deal
|
||||
// with that.
|
||||
if (mState != LIST_DIRTY &&
|
||||
MayContainRelevantNodes(NODE_FROM(aContainer, aDocument)) &&
|
||||
MayContainRelevantNodes(aChild->GetParentNode()) &&
|
||||
nsContentUtils::IsInSameAnonymousTree(mRootNode, aChild) &&
|
||||
MatchSelf(aChild)) {
|
||||
SetDirty();
|
||||
@ -836,16 +832,11 @@ nsContentList::ContentInserted(nsIDocument *aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsContentList::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
// Note that aContainer can be null here if we are removing from
|
||||
// the document itself; any attempted optimizations to this method
|
||||
// should deal with that.
|
||||
if (mState != LIST_DIRTY &&
|
||||
MayContainRelevantNodes(NODE_FROM(aContainer, aDocument)) &&
|
||||
MayContainRelevantNodes(aChild->GetParentNode()) &&
|
||||
nsContentUtils::IsInSameAnonymousTree(mRootNode, aChild) &&
|
||||
MatchSelf(aChild)) {
|
||||
SetDirty();
|
||||
@ -1113,8 +1104,7 @@ nsCachableElementsByNameNodeList::WrapObject(JSContext *cx, JS::Handle<JSObject*
|
||||
}
|
||||
|
||||
void
|
||||
nsCachableElementsByNameNodeList::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
nsCachableElementsByNameNodeList::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -1126,7 +1116,7 @@ nsCachableElementsByNameNodeList::AttributeChanged(nsIDocument* aDocument,
|
||||
return;
|
||||
}
|
||||
|
||||
nsCacheableFuncStringContentList::AttributeChanged(aDocument, aElement,
|
||||
nsCacheableFuncStringContentList::AttributeChanged(aElement,
|
||||
aNameSpaceID, aAttribute,
|
||||
aModType, aOldValue);
|
||||
}
|
||||
@ -1150,7 +1140,7 @@ nsLabelsNodeList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
|
||||
}
|
||||
|
||||
void
|
||||
nsLabelsNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement,
|
||||
nsLabelsNodeList::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
@ -1170,24 +1160,21 @@ nsLabelsNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement,
|
||||
}
|
||||
|
||||
void
|
||||
nsLabelsNodeList::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsLabelsNodeList::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
nsIContent* container = aFirstNewContent->GetParent();
|
||||
// If a labelable element is moved to outside or inside of
|
||||
// nested associated labels, we're gonna have to modify
|
||||
// the content list.
|
||||
if (mState != LIST_DIRTY ||
|
||||
nsContentUtils::IsInSameAnonymousTree(mRootNode, aContainer)) {
|
||||
nsContentUtils::IsInSameAnonymousTree(mRootNode, container)) {
|
||||
SetDirty();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsLabelsNodeList::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsLabelsNodeList::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
// If a labelable element is moved to outside or inside of
|
||||
// nested associated labels, we're gonna have to modify
|
||||
@ -1200,9 +1187,7 @@ nsLabelsNodeList::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsLabelsNodeList::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsLabelsNodeList::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
// If a labelable element is removed, we're gonna have to clean
|
||||
|
@ -120,8 +120,7 @@ nsMutationReceiver::Disconnect(bool aRemoveFromObserver)
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsMutationReceiver::NativeAnonymousChildListChange(nsIContent* aContent,
|
||||
bool aIsRemove) {
|
||||
if (!NativeAnonymousChildList()) {
|
||||
return;
|
||||
@ -152,8 +151,7 @@ nsMutationReceiver::NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::AttributeWillChange(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
nsMutationReceiver::AttributeWillChange(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -190,8 +188,7 @@ nsMutationReceiver::AttributeWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsMutationReceiver::CharacterDataWillChange(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
if (nsAutoMutationBatch::IsBatching() ||
|
||||
@ -217,11 +214,9 @@ nsMutationReceiver::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsMutationReceiver::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
nsINode* parent = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* parent = aFirstNewContent->GetParentNode();
|
||||
bool wantsChildList =
|
||||
ChildList() &&
|
||||
((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) ||
|
||||
@ -257,11 +252,9 @@ nsMutationReceiver::ContentAppended(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsMutationReceiver::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
nsINode* parent = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* parent = aChild->GetParentNode();
|
||||
bool wantsChildList =
|
||||
ChildList() &&
|
||||
((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) ||
|
||||
@ -291,16 +284,14 @@ nsMutationReceiver::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsMutationReceiver::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsMutationReceiver::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!IsObservable(aChild)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsINode* parent = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* parent = aChild->GetParentNode();
|
||||
if (Subtree() && parent->SubtreeRoot() != RegisterTarget()->SubtreeRoot()) {
|
||||
return;
|
||||
}
|
||||
|
@ -404,13 +404,12 @@ public:
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
|
||||
|
||||
virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
virtual void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute) override
|
||||
{
|
||||
// We can reuse AttributeWillChange implementation.
|
||||
AttributeWillChange(aDocument, aElement, aNameSpaceID, aAttribute,
|
||||
AttributeWillChange(aElement, aNameSpaceID, aAttribute,
|
||||
mozilla::dom::MutationEventBinding::MODIFICATION, nullptr);
|
||||
}
|
||||
|
||||
|
@ -3216,11 +3216,10 @@ nsFrameLoader::ApplySandboxFlags(uint32_t sandboxFlags)
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
nsFrameLoader::AttributeChanged(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
{
|
||||
MOZ_ASSERT(mObservingOwnerContent);
|
||||
|
@ -279,7 +279,7 @@ public:
|
||||
// nsWrapperCache
|
||||
virtual JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return GetWrapper();
|
||||
MOZ_CRASH("We should never get here!");
|
||||
}
|
||||
|
||||
// nsIGlobalJSObjectHolder
|
||||
|
@ -108,7 +108,6 @@ public:
|
||||
* added/removed from the document (the other notifications are used
|
||||
* for that).
|
||||
*
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContent The piece of content that changed. Is never null.
|
||||
* @param aInfo The structure with information details about the change.
|
||||
*
|
||||
@ -118,8 +117,7 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
virtual void CharacterDataWillChange(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&) = 0;
|
||||
|
||||
/**
|
||||
@ -130,7 +128,6 @@ public:
|
||||
* added/removed from the document (the other notifications are used
|
||||
* for that).
|
||||
*
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContent The piece of content that changed. Is never null.
|
||||
* @param aInfo The structure with information details about the change.
|
||||
*
|
||||
@ -140,8 +137,7 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
virtual void CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&) = 0;
|
||||
|
||||
/**
|
||||
@ -151,7 +147,6 @@ public:
|
||||
* attribute doesn't actually change there will be no corresponding
|
||||
* AttributeChanged).
|
||||
*
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContent The element whose attribute will change
|
||||
* @param aNameSpaceID The namespace id of the changing attribute
|
||||
* @param aAttribute The name of the changing attribute
|
||||
@ -167,17 +162,15 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void AttributeWillChange(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
virtual void AttributeWillChange(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aNewValue) = 0;
|
||||
|
||||
/**
|
||||
* Notification that an attribute of an element has changed.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aElement The element whose attribute changed
|
||||
* @param aNameSpaceID The namespace id of the changed attribute
|
||||
* @param aAttribute The name of the changed attribute
|
||||
@ -193,36 +186,31 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void AttributeChanged(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
virtual void AttributeChanged(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue) = 0;
|
||||
|
||||
/**
|
||||
* Notification that the root of a native anonymous has been added
|
||||
* or removed.
|
||||
*
|
||||
* @param aDocument Owner doc of aContent
|
||||
* @param aContent Anonymous node that's been added or removed
|
||||
* @param aIsRemove True if it's a removal, false if an addition
|
||||
*/
|
||||
virtual void NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
virtual void NativeAnonymousChildListChange(nsIContent* aContent,
|
||||
bool aIsRemove) {}
|
||||
|
||||
/**
|
||||
* Notification that an attribute of an element has been
|
||||
* set to the value it already had.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent.
|
||||
* @param aElement The element whose attribute changed
|
||||
* @param aNameSpaceID The namespace id of the changed attribute
|
||||
* @param aAttribute The name of the changed attribute
|
||||
*/
|
||||
virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
virtual void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute) {}
|
||||
|
||||
@ -230,10 +218,7 @@ public:
|
||||
* Notification that one or more content nodes have been appended to the
|
||||
* child list of another node in the tree.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContainer The container that had new children appended. Is never
|
||||
* null.
|
||||
* @param aFirstNewContent the node at aIndexInContainer in aContainer.
|
||||
* @param aFirstNewContent the first node appended.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
@ -241,22 +226,13 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent) = 0;
|
||||
virtual void ContentAppended(nsIContent* aFirstNewContent) = 0;
|
||||
|
||||
/**
|
||||
* Notification that a content node has been inserted as child to another
|
||||
* node in the tree.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent, or, when aContainer
|
||||
* is null, the container that had the child inserted.
|
||||
* Can be null.
|
||||
* @param aContainer The container that had new a child inserted. Can be
|
||||
* null to indicate that the child was inserted into
|
||||
* aDocument
|
||||
* @param aChild The newly inserted child.
|
||||
* @param aIndexInContainer The index in the container of the new child.
|
||||
* @param aChild The newly inserted child.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
@ -264,23 +240,13 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild) = 0;
|
||||
virtual void ContentInserted(nsIContent* aChild) = 0;
|
||||
|
||||
/**
|
||||
* Notification that a content node has been removed from the child list of
|
||||
* another node in the tree.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent, or, when aContainer
|
||||
* is null, the container that had the child removed.
|
||||
* Can be null.
|
||||
* @param aContainer The container that had new a child removed. Can be
|
||||
* null to indicate that the child was removed from
|
||||
* aDocument.
|
||||
* @param aChild The child that was removed.
|
||||
* @param aIndexInContainer The index in the container which the child used
|
||||
* to have.
|
||||
* @param aPreviousSibling The previous sibling to the child that was removed.
|
||||
* Can be null if there was no previous sibling.
|
||||
*
|
||||
@ -290,9 +256,7 @@ public:
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
virtual void ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling) = 0;
|
||||
|
||||
/**
|
||||
@ -336,50 +300,39 @@ public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
|
||||
virtual void CharacterDataWillChange(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
virtual void CharacterDataWillChange(nsIContent* aContent, \
|
||||
const CharacterDataChangeInfo& aInfo) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
|
||||
virtual void CharacterDataChanged(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
virtual void CharacterDataChanged(nsIContent* aContent, \
|
||||
const CharacterDataChangeInfo& aInfo) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
|
||||
virtual void AttributeWillChange(nsIDocument* aDocument, \
|
||||
mozilla::dom::Element* aElement, \
|
||||
virtual void AttributeWillChange(mozilla::dom::Element* aElement, \
|
||||
int32_t aNameSpaceID, \
|
||||
nsAtom* aAttribute, \
|
||||
int32_t aModType, \
|
||||
const nsAttrValue* aNewValue) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_NATIVEANONYMOUSCHILDLISTCHANGE \
|
||||
virtual void NativeAnonymousChildListChange(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
virtual void NativeAnonymousChildListChange(nsIContent* aContent, \
|
||||
bool aIsRemove) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
|
||||
virtual void AttributeChanged(nsIDocument* aDocument, \
|
||||
mozilla::dom::Element* aElement, \
|
||||
virtual void AttributeChanged(mozilla::dom::Element* aElement, \
|
||||
int32_t aNameSpaceID, \
|
||||
nsAtom* aAttribute, \
|
||||
nsAtom* aAttribute, \
|
||||
int32_t aModType, \
|
||||
const nsAttrValue* aOldValue) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
|
||||
virtual void ContentAppended(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aFirstNewContent) override;
|
||||
virtual void ContentAppended(nsIContent* aFirstNewContent) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
|
||||
virtual void ContentInserted(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild) override;
|
||||
virtual void ContentInserted(nsIContent* aChild) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED \
|
||||
virtual void ContentRemoved(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild, \
|
||||
virtual void ContentRemoved(nsIContent* aChild, \
|
||||
nsIContent* aPreviousSibling) override;
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
|
||||
@ -402,26 +355,23 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
|
||||
|
||||
#define NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(_class) \
|
||||
void \
|
||||
_class::NodeWillBeDestroyed(const nsINode* aNode) \
|
||||
_class::NodeWillBeDestroyed(const nsINode* aNode) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) \
|
||||
void \
|
||||
_class::CharacterDataWillChange(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
_class::CharacterDataWillChange(nsIContent* aContent, \
|
||||
const CharacterDataChangeInfo& aInfo) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::CharacterDataChanged(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
_class::CharacterDataChanged(nsIContent* aContent, \
|
||||
const CharacterDataChangeInfo& aInfo) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::AttributeWillChange(nsIDocument* aDocument, \
|
||||
mozilla::dom::Element* aElement, \
|
||||
_class::AttributeWillChange(mozilla::dom::Element* aElement, \
|
||||
int32_t aNameSpaceID, \
|
||||
nsAtom* aAttribute, \
|
||||
int32_t aModType, \
|
||||
@ -429,14 +379,12 @@ _class::AttributeWillChange(nsIDocument* aDocument, \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::NativeAnonymousChildListChange(nsIDocument* aDocument, \
|
||||
nsIContent* aContent, \
|
||||
_class::NativeAnonymousChildListChange(nsIContent* aContent, \
|
||||
bool aIsRemove) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::AttributeChanged(nsIDocument* aDocument, \
|
||||
mozilla::dom::Element* aElement, \
|
||||
_class::AttributeChanged(mozilla::dom::Element* aElement, \
|
||||
int32_t aNameSpaceID, \
|
||||
nsAtom* aAttribute, \
|
||||
int32_t aModType, \
|
||||
@ -444,22 +392,15 @@ _class::AttributeChanged(nsIDocument* aDocument, \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::ContentAppended(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aFirstNewContent) \
|
||||
_class::ContentAppended(nsIContent* aFirstNewContent) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::ContentInserted(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild) \
|
||||
_class::ContentInserted(nsIContent* aChild) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::ContentRemoved(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild, \
|
||||
nsIContent* aPreviousSibling) \
|
||||
_class::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
|
@ -134,7 +134,7 @@ nsNodeUtils::CharacterDataWillChange(nsIContent* aContent,
|
||||
{
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(CharacterDataWillChange, aContent,
|
||||
(doc, aContent, aInfo), IsRemoveNotification::No);
|
||||
(aContent, aInfo), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
@ -143,7 +143,7 @@ nsNodeUtils::CharacterDataChanged(nsIContent* aContent,
|
||||
{
|
||||
nsIDocument* doc = aContent->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(CharacterDataChanged, aContent,
|
||||
(doc, aContent, aInfo), IsRemoveNotification::No);
|
||||
(aContent, aInfo), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
void
|
||||
@ -155,7 +155,7 @@ nsNodeUtils::AttributeWillChange(Element* aElement,
|
||||
{
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeWillChange, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute,
|
||||
(aElement, aNameSpaceID, aAttribute,
|
||||
aModType, aNewValue), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ nsNodeUtils::AttributeChanged(Element* aElement,
|
||||
{
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeChanged, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute,
|
||||
(aElement, aNameSpaceID, aAttribute,
|
||||
aModType, aOldValue), IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ nsNodeUtils::AttributeSetToCurrentValue(Element* aElement,
|
||||
{
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeSetToCurrentValue, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute),
|
||||
(aElement, aNameSpaceID, aAttribute),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ nsNodeUtils::ContentAppended(nsIContent* aContainer,
|
||||
nsIDocument* doc = aContainer->OwnerDoc();
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentAppended, aContainer,
|
||||
(doc, aContainer, aFirstNewContent),
|
||||
(aFirstNewContent),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ nsNodeUtils::NativeAnonymousChildListChange(nsIContent* aContent,
|
||||
auto isRemove = aIsRemove
|
||||
? IsRemoveNotification::Yes : IsRemoveNotification::No;
|
||||
IMPL_MUTATION_NOTIFICATION(NativeAnonymousChildListChange, aContent,
|
||||
(doc, aContent, aIsRemove),
|
||||
(aContent, aIsRemove),
|
||||
isRemove);
|
||||
}
|
||||
|
||||
@ -213,19 +213,8 @@ nsNodeUtils::ContentInserted(nsINode* aContainer,
|
||||
NS_PRECONDITION(aContainer->IsContent() ||
|
||||
aContainer->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
"container must be an nsIContent or an nsIDocument");
|
||||
nsIContent* container;
|
||||
nsIDocument* doc = aContainer->OwnerDoc();
|
||||
nsIDocument* document;
|
||||
if (aContainer->IsContent()) {
|
||||
container = aContainer->AsContent();
|
||||
document = doc;
|
||||
} else {
|
||||
container = nullptr;
|
||||
document = static_cast<nsIDocument*>(aContainer);
|
||||
}
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer,
|
||||
(document, container, aChild),
|
||||
IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer, (aChild),
|
||||
IsRemoveNotification::No);
|
||||
}
|
||||
|
||||
@ -237,19 +226,11 @@ nsNodeUtils::ContentRemoved(nsINode* aContainer,
|
||||
NS_PRECONDITION(aContainer->IsContent() ||
|
||||
aContainer->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
"container must be an nsIContent or an nsIDocument");
|
||||
nsIContent* container;
|
||||
nsIDocument* doc = aContainer->OwnerDoc();
|
||||
nsIDocument* document;
|
||||
if (aContainer->IsContent()) {
|
||||
container = static_cast<nsIContent*>(aContainer);
|
||||
document = doc;
|
||||
} else {
|
||||
container = nullptr;
|
||||
document = static_cast<nsIDocument*>(aContainer);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aChild->GetParentNode() == aContainer,
|
||||
"We expect the parent link to be still around at this point");
|
||||
IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
|
||||
(document, container, aChild, aPreviousSibling),
|
||||
(aChild, aPreviousSibling),
|
||||
IsRemoveNotification::Yes);
|
||||
}
|
||||
|
||||
|
@ -517,8 +517,7 @@ nsRange::UnregisterCommonAncestor(nsINode* aNode, bool aIsUnlinking)
|
||||
* nsIMutationObserver implementation
|
||||
******************************************************/
|
||||
void
|
||||
nsRange::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
nsRange::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo& aInfo)
|
||||
{
|
||||
MOZ_ASSERT(!mNextEndRef);
|
||||
@ -673,15 +672,12 @@ nsRange::CharacterDataChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsRange::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsRange::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* container = aFirstNewContent->GetParentNode();
|
||||
MOZ_ASSERT(container);
|
||||
MOZ_ASSERT(aFirstNewContent->GetParentNode() == container);
|
||||
if (container->IsSelectionDescendant() && IsInSelection()) {
|
||||
nsINode* child = aFirstNewContent;
|
||||
while (child) {
|
||||
@ -711,14 +707,12 @@ nsRange::ContentAppended(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsRange::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsRange::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
|
||||
bool updateBoundaries = false;
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* container = aChild->GetParentNode();
|
||||
MOZ_ASSERT(container);
|
||||
RawRangeBoundary newStart(mStart);
|
||||
RawRangeBoundary newEnd(mEnd);
|
||||
@ -763,13 +757,12 @@ nsRange::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsRange::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
nsRange::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
|
||||
{
|
||||
MOZ_ASSERT(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* container = aChild->GetParentNode();
|
||||
MOZ_ASSERT(container);
|
||||
|
||||
RawRangeBoundary newStart;
|
||||
RawRangeBoundary newEnd;
|
||||
Maybe<bool> gravitateStart;
|
||||
|
@ -273,8 +273,7 @@ nsAttributeTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
}
|
||||
|
||||
void
|
||||
nsAttributeTextNode::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
nsAttributeTextNode::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
|
@ -925,8 +925,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
IMEContentObserver::CharacterDataWillChange(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo& aInfo)
|
||||
{
|
||||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||
@ -958,8 +957,7 @@ IMEContentObserver::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
IMEContentObserver::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo& aInfo)
|
||||
{
|
||||
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
|
||||
@ -1107,28 +1105,22 @@ IMEContentObserver::NotifyContentAdded(nsINode* aContainer,
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
IMEContentObserver::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
NotifyContentAdded(NODE_FROM(aContainer, aDocument),
|
||||
aFirstNewContent, aContainer->GetLastChild());
|
||||
nsIContent* parent = aFirstNewContent->GetParent();
|
||||
MOZ_ASSERT(parent);
|
||||
NotifyContentAdded(parent, aFirstNewContent, parent->GetLastChild());
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
IMEContentObserver::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
MOZ_ASSERT(aChild);
|
||||
NotifyContentAdded(NODE_FROM(aContainer, aDocument),
|
||||
aChild, aChild);
|
||||
NotifyContentAdded(aChild->GetParentNode(), aChild, aChild);
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
IMEContentObserver::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!NeedsTextChangeNotification() ||
|
||||
@ -1139,8 +1131,7 @@ IMEContentObserver::ContentRemoved(nsIDocument* aDocument,
|
||||
mEndOfAddedTextCache.Clear();
|
||||
MaybeNotifyIMEOfAddedTextDuringDocumentChange();
|
||||
|
||||
nsINode* containerNode = NODE_FROM(aContainer, aDocument);
|
||||
|
||||
nsINode* containerNode = aChild->GetParentNode();
|
||||
MOZ_ASSERT(containerNode);
|
||||
|
||||
uint32_t offset = 0;
|
||||
@ -1191,8 +1182,7 @@ IMEContentObserver::ContentRemoved(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::AttributeWillChange(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
IMEContentObserver::AttributeWillChange(dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -1207,8 +1197,7 @@ IMEContentObserver::AttributeWillChange(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::AttributeChanged(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
IMEContentObserver::AttributeChanged(dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
|
@ -1531,9 +1531,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLMediaElement, nsGenericHTMLElement)
|
||||
|
||||
void
|
||||
HTMLMediaElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
HTMLMediaElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (aChild == mSourcePointer) {
|
||||
|
@ -179,30 +179,23 @@ void HTMLOutputElement::DescendantsChanged()
|
||||
|
||||
// nsIMutationObserver
|
||||
|
||||
void HTMLOutputElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
void HTMLOutputElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
DescendantsChanged();
|
||||
}
|
||||
|
||||
void HTMLOutputElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
void HTMLOutputElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
DescendantsChanged();
|
||||
}
|
||||
|
||||
void HTMLOutputElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
void HTMLOutputElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
DescendantsChanged();
|
||||
}
|
||||
|
||||
void HTMLOutputElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
void HTMLOutputElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
DescendantsChanged();
|
||||
|
@ -64,33 +64,26 @@ HTMLStyleElement::SetDisabled(bool aDisabled)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLStyleElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
HTMLStyleElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
ContentChanged(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLStyleElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
HTMLStyleElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
ContentChanged(aContainer);
|
||||
ContentChanged(aFirstNewContent->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
HTMLStyleElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
HTMLStyleElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLStyleElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
HTMLStyleElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
|
@ -447,12 +447,11 @@ TableRowsCollection::HandleInsert(nsIContent* aContainer,
|
||||
// nsIMutationObserver
|
||||
|
||||
void
|
||||
TableRowsCollection::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
TableRowsCollection::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
nsIContent* container = aFirstNewContent->GetParent();
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(mParent, aFirstNewContent) ||
|
||||
!InterestingContainer(aContainer)) {
|
||||
!InterestingContainer(container)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -460,37 +459,33 @@ TableRowsCollection::ContentAppended(nsIDocument* aDocument,
|
||||
// appending into mParent, in which case we can provide the guess that we
|
||||
// should insert at the end of the body, which can help us avoid potentially
|
||||
// expensive work in the common case.
|
||||
int32_t indexGuess = mParent == aContainer ? mFootStart : -1;
|
||||
int32_t indexGuess = mParent == container ? mFootStart : -1;
|
||||
|
||||
// Insert each of the newly added content one at a time. The indexGuess should
|
||||
// make insertions of a large number of elements cheaper.
|
||||
for (nsIContent* content = aFirstNewContent;
|
||||
content; content = content->GetNextSibling()) {
|
||||
indexGuess = HandleInsert(aContainer, content, indexGuess);
|
||||
indexGuess = HandleInsert(container, content, indexGuess);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TableRowsCollection::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
TableRowsCollection::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(mParent, aChild) ||
|
||||
!InterestingContainer(aContainer)) {
|
||||
!InterestingContainer(aChild->GetParent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
HandleInsert(aContainer, aChild);
|
||||
HandleInsert(aChild->GetParent(), aChild);
|
||||
}
|
||||
|
||||
void
|
||||
TableRowsCollection::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
TableRowsCollection::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!nsContentUtils::IsInSameAnonymousTree(mParent, aChild) ||
|
||||
!InterestingContainer(aContainer)) {
|
||||
!InterestingContainer(aChild->GetParent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -988,33 +988,26 @@ HTMLTextAreaElement::BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTextAreaElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
HTMLTextAreaElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
ContentChanged(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTextAreaElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
HTMLTextAreaElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
ContentChanged(aFirstNewContent);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTextAreaElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
HTMLTextAreaElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTextAreaElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
HTMLTextAreaElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
|
@ -54,34 +54,27 @@ HTMLTitleElement::SetText(const nsAString& aText, ErrorResult& aError)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTitleElement::CharacterDataChanged(nsIDocument *aDocument,
|
||||
nsIContent *aContent,
|
||||
HTMLTitleElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTitleElement::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aFirstNewContent)
|
||||
HTMLTitleElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTitleElement::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild)
|
||||
HTMLTitleElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTitleElement::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
nsIContent *aPreviousSibling)
|
||||
HTMLTitleElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
@ -251,8 +251,9 @@ bool nsDOMStringMap::AttrToDataProp(const nsAString& aAttr,
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMStringMap::AttributeChanged(nsIDocument *aDocument, Element* aElement,
|
||||
int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||
nsDOMStringMap::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
{
|
||||
|
@ -620,6 +620,9 @@ OmxDataDecoder::FillCodecConfigDataToOmx()
|
||||
|
||||
// Some codecs like h264, its codec specific data is at the first packet, not in container.
|
||||
if (csc->Length()) {
|
||||
// Buffer size should large enough for raw data.
|
||||
MOZ_RELEASE_ASSERT(inbuf->mBuffer->nAllocLen >= csc->Length());
|
||||
|
||||
memcpy(inbuf->mBuffer->pBuffer,
|
||||
csc->Elements(),
|
||||
csc->Length());
|
||||
|
@ -1,9 +1,7 @@
|
||||
function playAndPostResult(test_case, parent_window) {
|
||||
log("runTest " + test_case.name);
|
||||
|
||||
function playAndPostResult(muted, parent_window) {
|
||||
let element = document.createElement("video");
|
||||
element.preload = "auto";
|
||||
element.muted = test_case.muted;
|
||||
element.muted = muted;
|
||||
element.src = "short.mp4";
|
||||
element.id = "video";
|
||||
document.body.appendChild(element);
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<title>Autoplay policy frame</title>
|
||||
<script type="text/javascript" src="AutoplayTestUtils.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<style>
|
||||
video {
|
||||
width: 50%;
|
||||
@ -12,10 +13,16 @@
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
nextWindowMessage().then(
|
||||
window.addEventListener("message",
|
||||
(event) => {
|
||||
playAndPostResult(event.data, event.source);
|
||||
});
|
||||
if (event.data == "click") {
|
||||
synthesizeMouseAtCenter(document.body, {});
|
||||
} else if (event.data == "play-audible") {
|
||||
playAndPostResult(false, event.source);
|
||||
} else if (event.data == "play-muted") {
|
||||
playAndPostResult(true, event.source);
|
||||
}
|
||||
}, false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
function testAutoplayInWindow(test_case, parent_window) {
|
||||
log("testAutoplayInWindow: " + test_case.name);
|
||||
playAndPostResult(test_case, parent_window);
|
||||
playAndPostResult(test_case.muted, parent_window);
|
||||
}
|
||||
|
||||
async function testAutoplayInChildFrame(test_case, parent_window) {
|
||||
@ -34,10 +34,11 @@
|
||||
await once(frame, "load");
|
||||
// Click the iframe to activate if appropriate.
|
||||
if (test_case.activated_child) {
|
||||
synthesizeMouseAtCenter(frame, {});
|
||||
frame.contentWindow.postMessage("click", "*");
|
||||
}
|
||||
// Ask the child iframe to try to play video.
|
||||
frame.contentWindow.postMessage(test_case, "*");
|
||||
let play_message = test_case.muted ? "play-muted" : "play-audible";
|
||||
frame.contentWindow.postMessage(play_message, "*");
|
||||
// Wait for the iframe to tell us whether it could play video.
|
||||
let result = await nextWindowMessage();
|
||||
// Report whether the iframe could play to the parent.
|
||||
|
@ -688,8 +688,7 @@ skip-if = android_version == '15' || android_version == '17' || android_version
|
||||
[test_autoplay_policy.html]
|
||||
skip-if = android_version == '23' # bug 1424903
|
||||
[test_autoplay_policy_activation.html]
|
||||
#skip-if = android_version == '23' # bug 1424903
|
||||
skip-if = true # bug 1441424 - temporarily disabled to land bug 1193394
|
||||
skip-if = android_version == '23' # bug 1424903
|
||||
[test_buffered.html]
|
||||
skip-if = android_version == '15' || android_version == '22' # bug 1308388, android(bug 1232305)
|
||||
[test_bug448534.html]
|
||||
|
@ -76,15 +76,14 @@
|
||||
should_play: true,
|
||||
},
|
||||
|
||||
// TODO: This case fails, Firefox's behaviour needs to be fixed.
|
||||
// {
|
||||
// name: "audible playback in unactivated cross-origin iframe in activated parent blocked",
|
||||
// muted: false,
|
||||
// same_origin_child: false,
|
||||
// activated_child: false,
|
||||
// activated_parent: true,
|
||||
// should_play: false,
|
||||
// },
|
||||
{
|
||||
name: "audible playback in unactivated cross-origin iframe in activated parent blocked",
|
||||
muted: false,
|
||||
same_origin_child: false,
|
||||
activated_child: false,
|
||||
activated_parent: true,
|
||||
should_play: false,
|
||||
},
|
||||
|
||||
{
|
||||
name: "audible playback in unactivated cross-origin iframe in unactivated parent blocked",
|
||||
|
@ -78,16 +78,14 @@ ScriptElement::ScriptEvaluated(nsresult aResult,
|
||||
}
|
||||
|
||||
void
|
||||
ScriptElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
ScriptElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
||||
void
|
||||
ScriptElement::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
ScriptElement::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -97,17 +95,13 @@ ScriptElement::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
ScriptElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
ScriptElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
||||
void
|
||||
ScriptElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
ScriptElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
@ -188,8 +188,7 @@ SVGMPathElement::GetStringInfo()
|
||||
// nsIMutationObserver methods
|
||||
|
||||
void
|
||||
SVGMPathElement::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
SVGMPathElement::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
|
@ -133,33 +133,26 @@ SVGStyleElement::ParseAttribute(int32_t aNamespaceID,
|
||||
// nsIMutationObserver methods
|
||||
|
||||
void
|
||||
SVGStyleElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
SVGStyleElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
ContentChanged(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
SVGStyleElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
SVGStyleElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
ContentChanged(aContainer);
|
||||
ContentChanged(aFirstNewContent->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
SVGStyleElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
SVGStyleElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
}
|
||||
|
||||
void
|
||||
SVGStyleElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
SVGStyleElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
ContentChanged(aChild);
|
||||
|
@ -39,34 +39,27 @@ SVGTitleElement::~SVGTitleElement()
|
||||
}
|
||||
|
||||
void
|
||||
SVGTitleElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
SVGTitleElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
SVGTitleElement::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aFirstNewContent)
|
||||
SVGTitleElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
SVGTitleElement::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild)
|
||||
SVGTitleElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
||||
void
|
||||
SVGTitleElement::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
nsIContent *aPreviousSibling)
|
||||
SVGTitleElement::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
SendTitleChangeEvent(false);
|
||||
}
|
||||
|
@ -147,8 +147,7 @@ SVGUseElement::Height()
|
||||
// nsIMutationObserver methods
|
||||
|
||||
void
|
||||
SVGUseElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
SVGUseElement::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
||||
@ -157,8 +156,7 @@ SVGUseElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
SVGUseElement::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
SVGUseElement::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -170,30 +168,27 @@ SVGUseElement::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
SVGUseElement::ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aFirstNewContent)
|
||||
SVGUseElement::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
if (nsContentUtils::IsInSameAnonymousTree(this, aContainer)) {
|
||||
// FIXME(emilio, bug 1442336): Why does this check the parent but
|
||||
// ContentInserted the child?
|
||||
if (nsContentUtils::IsInSameAnonymousTree(this, aFirstNewContent->GetParent())) {
|
||||
TriggerReclone();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVGUseElement::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild)
|
||||
SVGUseElement::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
// FIXME(emilio, bug 1442336): Why does this check the child but
|
||||
// ContentAppended the parent?
|
||||
if (nsContentUtils::IsInSameAnonymousTree(this, aChild)) {
|
||||
TriggerReclone();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVGUseElement::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
nsIContent *aPreviousSibling)
|
||||
SVGUseElement::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (nsContentUtils::IsInSameAnonymousTree(this, aChild)) {
|
||||
TriggerReclone();
|
||||
|
@ -294,6 +294,22 @@ partial namespace ChromeUtils {
|
||||
*/
|
||||
[Throws]
|
||||
void defineModuleGetter(object target, DOMString id, DOMString resourceURI);
|
||||
|
||||
/**
|
||||
* Returns the scripted location of the first ancestor stack frame with a
|
||||
* principal which is subsumed by the given principal. If no such frame
|
||||
* exists on the call stack, returns null.
|
||||
*/
|
||||
object? getCallerLocation(Principal principal);
|
||||
|
||||
/**
|
||||
* Creates a JS Error object with the given message and stack.
|
||||
*
|
||||
* If a stack object is provided, the error object is created in the global
|
||||
* that it belongs to.
|
||||
*/
|
||||
[Throws]
|
||||
object createError(DOMString message, optional object? stack = null);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -43,4 +43,7 @@ partial interface WorkerGlobalScope {
|
||||
// XXXbz no spec for this yet, because the webperf WG is a bit dysfunctional
|
||||
[Constant, Cached]
|
||||
readonly attribute Performance performance;
|
||||
|
||||
[Func="WorkerGlobalScope::IsInAutomation", Throws]
|
||||
object getJSTestingFunctions();
|
||||
};
|
||||
|
@ -2617,6 +2617,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
, mParentFrozen(false)
|
||||
, mIsSecureContext(false)
|
||||
, mDebuggerRegistered(false)
|
||||
, mIsInAutomation(false)
|
||||
{
|
||||
MOZ_ASSERT_IF(!IsDedicatedWorker(), NS_IsMainThread());
|
||||
mLoadInfo.StealFrom(aLoadInfo);
|
||||
@ -2632,6 +2633,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
mIsSecureContext = aParent->IsSecureContext();
|
||||
MOZ_ASSERT_IF(mIsChromeWorker, mIsSecureContext);
|
||||
|
||||
mIsInAutomation = aParent->IsInAutomation();
|
||||
|
||||
MOZ_ASSERT(IsDedicatedWorker());
|
||||
|
||||
if (aParent->mParentFrozen) {
|
||||
@ -2665,6 +2668,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||
.creationOptions().setSecureContext(true);
|
||||
}
|
||||
|
||||
mIsInAutomation = xpc::IsInAutomation();
|
||||
|
||||
// Our parent can get suspended after it initiates the async creation
|
||||
// of a new worker thread. In this case suspend the new worker as well.
|
||||
if (mLoadInfo.mWindow && mLoadInfo.mWindow->IsSuspended()) {
|
||||
|
@ -633,6 +633,12 @@ public:
|
||||
return mIsSecureContext;
|
||||
}
|
||||
|
||||
// Check whether we're running in automation.
|
||||
bool IsInAutomation() const
|
||||
{
|
||||
return mIsInAutomation;
|
||||
}
|
||||
|
||||
TimeStamp CreationTimeStamp() const
|
||||
{
|
||||
return mCreationTimeStamp;
|
||||
@ -1479,6 +1485,10 @@ private:
|
||||
bool mIsSecureContext;
|
||||
|
||||
bool mDebuggerRegistered;
|
||||
|
||||
// mIsInAutomation is true when we're running in test automation.
|
||||
// We expose some extra testing functions in that case.
|
||||
bool mIsInAutomation;
|
||||
};
|
||||
|
||||
class AutoSyncLoopHolder
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "WorkerScope.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Clients.h"
|
||||
@ -400,6 +401,26 @@ WorkerGlobalScope::GetPerformance()
|
||||
return mPerformance;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerGlobalScope::IsInAutomation(JSContext* aCx, JSObject* /* unused */)
|
||||
{
|
||||
return GetWorkerPrivateFromContext(aCx)->IsInAutomation();
|
||||
}
|
||||
|
||||
void
|
||||
WorkerGlobalScope::GetJSTestingFunctions(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aFunctions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
JSObject* obj = js::GetTestingFunctions(aCx);
|
||||
if (!obj) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
aFunctions.set(obj);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
WorkerGlobalScope::Fetch(const RequestOrUSVString& aInput,
|
||||
const RequestInit& aInit,
|
||||
|
@ -161,6 +161,11 @@ public:
|
||||
return mPerformance;
|
||||
}
|
||||
|
||||
static bool IsInAutomation(JSContext* aCx, JSObject* /* unused */);
|
||||
void GetJSTestingFunctions(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aFunctions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Fetch(const RequestOrUSVString& aInput, const RequestInit& aInit,
|
||||
CallerType aCallerType, ErrorResult& aRv);
|
||||
|
@ -76,11 +76,7 @@ var ecmaGlobals =
|
||||
{name: "URIError", insecureContext: true},
|
||||
{name: "WeakMap", insecureContext: true},
|
||||
{name: "WeakSet", insecureContext: true},
|
||||
// WebAssembly is not supported on some hardware configurations,
|
||||
// but we have no way to check that from here. Just give up for
|
||||
// now and don't check for it at all. Do NOT add any other uses
|
||||
// of "optional"!
|
||||
{name: "WebAssembly", insecureContext: true, optional: true},
|
||||
{name: "WebAssembly", insecureContext: true, disabled: !getJSTestingFunctions().wasmIsSupportedByHardware()},
|
||||
];
|
||||
// IMPORTANT: Do not change the list above without review from
|
||||
// a JavaScript Engine peer!
|
||||
@ -291,8 +287,6 @@ function createInterfaceMap(version, userAgent) {
|
||||
(isInsecureContext && !Boolean(entry.insecureContext)) ||
|
||||
entry.disabled) {
|
||||
interfaceMap[entry.name] = false;
|
||||
} else if (entry.optional) {
|
||||
interfaceMap[entry.name] = "optional";
|
||||
} else {
|
||||
interfaceMap[entry.name] = true;
|
||||
}
|
||||
@ -313,21 +307,17 @@ function runTest(version, userAgent) {
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
continue;
|
||||
}
|
||||
ok(interfaceMap[name] === "optional" || interfaceMap[name],
|
||||
ok(interfaceMap[name],
|
||||
"If this is failing: DANGER, are you sure you want to expose the new interface " + name +
|
||||
" to all webpages as a property on the worker? Do not make a change to this file without a " +
|
||||
" review from a DOM peer for that specific change!!! (or a JS peer for changes to ecmaGlobals)");
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
for (var name of Object.keys(interfaceMap)) {
|
||||
if (interfaceMap[name] === "optional") {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
} else {
|
||||
ok(name in self === interfaceMap[name],
|
||||
name + " should " + (interfaceMap[name] ? "" : " NOT") + " be defined on the global scope");
|
||||
if (!interfaceMap[name]) {
|
||||
delete interfaceMap[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
is(Object.keys(interfaceMap).length, 0,
|
||||
|
@ -828,13 +828,12 @@ InsertAppendedContent(XBLChildrenElement* aPoint,
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsBindingManager::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
// Try to find insertion points for all the new kids.
|
||||
XBLChildrenElement* point = nullptr;
|
||||
nsIContent* parent = aContainer;
|
||||
nsIContent* container = aFirstNewContent->GetParent();
|
||||
nsIContent* parent = container;
|
||||
|
||||
// Handle appending of default content.
|
||||
if (parent && parent->IsActiveChildrenElement()) {
|
||||
@ -863,7 +862,7 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
|
||||
// points.
|
||||
for (nsIContent* currentChild = aFirstNewContent; currentChild;
|
||||
currentChild = currentChild->GetNextSibling()) {
|
||||
HandleChildInsertion(aContainer, currentChild, true);
|
||||
HandleChildInsertion(container, currentChild, true);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -896,23 +895,19 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsBindingManager::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
HandleChildInsertion(aContainer, aChild, false);
|
||||
HandleChildInsertion(aChild->GetParent(), aChild, false);
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsBindingManager::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
aChild->SetXBLInsertionPoint(nullptr);
|
||||
|
||||
XBLChildrenElement* point = nullptr;
|
||||
nsIContent* parent = aContainer;
|
||||
nsIContent* parent = aChild->GetParent();
|
||||
|
||||
// Handle appending of default content.
|
||||
if (parent && parent->IsActiveChildrenElement()) {
|
||||
|
@ -221,8 +221,7 @@ nsXMLPrettyPrinter::Unhook()
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
nsXMLPrettyPrinter::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -232,28 +231,22 @@ nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLPrettyPrinter::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
nsXMLPrettyPrinter::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
MaybeUnhook(aContainer);
|
||||
MaybeUnhook(aFirstNewContent->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLPrettyPrinter::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
nsXMLPrettyPrinter::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
MaybeUnhook(aContainer);
|
||||
MaybeUnhook(aChild->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLPrettyPrinter::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsXMLPrettyPrinter::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
MaybeUnhook(aContainer);
|
||||
MaybeUnhook(aChild->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -122,16 +122,14 @@ XPathResult::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
}
|
||||
|
||||
void
|
||||
XPathResult::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
XPathResult::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
Invalidate(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
XPathResult::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
XPathResult::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -141,28 +139,21 @@ XPathResult::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
XPathResult::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
XPathResult::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
Invalidate(aContainer);
|
||||
Invalidate(aFirstNewContent->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
XPathResult::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
XPathResult::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
Invalidate(aContainer);
|
||||
Invalidate(aChild->GetParent());
|
||||
}
|
||||
|
||||
void
|
||||
XPathResult::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
XPathResult::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
|
||||
{
|
||||
Invalidate(aContainer);
|
||||
Invalidate(aChild->GetParent());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1235,16 +1235,14 @@ txMozillaXSLTProcessor::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
}
|
||||
|
||||
void
|
||||
txMozillaXSLTProcessor::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
txMozillaXSLTProcessor::CharacterDataChanged(nsIContent* aContent,
|
||||
const CharacterDataChangeInfo&)
|
||||
{
|
||||
mStylesheet = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
txMozillaXSLTProcessor::AttributeChanged(Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
@ -1254,25 +1252,19 @@ txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
txMozillaXSLTProcessor::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
txMozillaXSLTProcessor::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
mStylesheet = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
txMozillaXSLTProcessor::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
txMozillaXSLTProcessor::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
mStylesheet = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
txMozillaXSLTProcessor::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
txMozillaXSLTProcessor::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
mStylesheet = nullptr;
|
||||
|
@ -855,12 +855,11 @@ ShouldPersistAttribute(Element* aElement, nsAtom* aAttribute)
|
||||
}
|
||||
|
||||
void
|
||||
XULDocument::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement, int32_t aNameSpaceID,
|
||||
XULDocument::AttributeChanged(Element* aElement, int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute, int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
{
|
||||
NS_ASSERTION(aDocument == this, "unexpected doc");
|
||||
NS_ASSERTION(aElement->OwnerDoc() == this, "unexpected doc");
|
||||
|
||||
// Might not need this, but be safe for now.
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
@ -943,11 +942,9 @@ XULDocument::AttributeChanged(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
XULDocument::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
XULDocument::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
NS_ASSERTION(aDocument == this, "unexpected doc");
|
||||
NS_ASSERTION(aFirstNewContent->OwnerDoc() == this, "unexpected doc");
|
||||
|
||||
// Might not need this, but be safe for now.
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
@ -961,11 +958,9 @@ XULDocument::ContentAppended(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
XULDocument::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
XULDocument::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
NS_ASSERTION(aDocument == this, "unexpected doc");
|
||||
NS_ASSERTION(aChild->OwnerDoc() == this, "unexpected doc");
|
||||
|
||||
// Might not need this, but be safe for now.
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
@ -974,12 +969,9 @@ XULDocument::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
XULDocument::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
XULDocument::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling)
|
||||
{
|
||||
NS_ASSERTION(aDocument == this, "unexpected doc");
|
||||
NS_ASSERTION(aChild->OwnerDoc() == this, "unexpected doc");
|
||||
|
||||
// Might not need this, but be safe for now.
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
@ -314,8 +314,7 @@ HTMLEditor::DeleteRefToAnonymousNode(ManualNACPtr aContent,
|
||||
|
||||
// FIXME(emilio): This is the only caller to PresShell::ContentRemoved that
|
||||
// passes NAC into it. This is not great!
|
||||
aShell->ContentRemoved(
|
||||
aContent->GetComposedDoc(), parentContent, aContent, nullptr);
|
||||
aShell->ContentRemoved(aContent, nullptr);
|
||||
|
||||
if (document) {
|
||||
aShell->EndUpdate(document, UPDATE_CONTENT_MODEL);
|
||||
|
@ -3136,25 +3136,19 @@ HTMLEditor::InsertTextImpl(nsIDocument& aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
HTMLEditor::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent)
|
||||
HTMLEditor::ContentAppended(nsIContent* aFirstNewContent)
|
||||
{
|
||||
DoContentInserted(aDocument, aContainer, aFirstNewContent, eAppended);
|
||||
DoContentInserted(aFirstNewContent, eAppended);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLEditor::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
HTMLEditor::ContentInserted(nsIContent* aChild)
|
||||
{
|
||||
DoContentInserted(aDocument, aContainer, aChild, eInserted);
|
||||
DoContentInserted(aChild, eInserted);
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLEditor::IsInObservedSubtree(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
HTMLEditor::IsInObservedSubtree(nsIContent* aChild)
|
||||
{
|
||||
if (!aChild) {
|
||||
return false;
|
||||
@ -3173,16 +3167,14 @@ HTMLEditor::IsInObservedSubtree(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
HTMLEditor::DoContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
HTMLEditor::DoContentInserted(nsIContent* aChild,
|
||||
InsertedOrAppended aInsertedOrAppended)
|
||||
{
|
||||
MOZ_ASSERT(aChild);
|
||||
nsINode* container = NODE_FROM(aContainer, aDocument);
|
||||
nsINode* container = aChild->GetParentNode();
|
||||
MOZ_ASSERT(container);
|
||||
|
||||
if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
|
||||
if (!IsInObservedSubtree(aChild)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3223,12 +3215,10 @@ HTMLEditor::DoContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
HTMLEditor::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
HTMLEditor::ContentRemoved(nsIContent* aChild,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
|
||||
if (!IsInObservedSubtree(aChild)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3243,9 +3233,8 @@ HTMLEditor::ContentRemoved(nsIDocument* aDocument,
|
||||
NewRunnableMethod("HTMLEditor::NotifyRootChanged",
|
||||
this,
|
||||
&HTMLEditor::NotifyRootChanged));
|
||||
}
|
||||
// We don't need to handle our own modifications
|
||||
else if (!mAction && (aContainer ? aContainer->IsEditable() : aDocument->IsEditable())) {
|
||||
} else if (!mAction && aChild->GetParentNode()->IsEditable()) {
|
||||
if (aChild && IsMozEditorBogusNode(aChild)) {
|
||||
// Ignore removal of the bogus node
|
||||
return;
|
||||
|
@ -1163,9 +1163,7 @@ protected:
|
||||
int32_t& aMarginLeft,
|
||||
int32_t& aMarginTop);
|
||||
|
||||
bool IsInObservedSubtree(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild);
|
||||
bool IsInObservedSubtree(nsIContent* aChild);
|
||||
|
||||
void UpdateRootElement();
|
||||
|
||||
@ -1359,9 +1357,7 @@ private:
|
||||
nsAtom* aAttribute,
|
||||
const nsAString& aValue);
|
||||
typedef enum { eInserted, eAppended } InsertedOrAppended;
|
||||
void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
InsertedOrAppended aInsertedOrAppended);
|
||||
void DoContentInserted(nsIContent* aChild, InsertedOrAppended);
|
||||
already_AddRefed<Element> GetElementOrParentByTagName(
|
||||
const nsAString& aTagName, nsINode* aNode);
|
||||
already_AddRefed<Element> CreateElementWithDefaults(
|
||||
|
@ -229,10 +229,16 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
|
||||
DecoderFactory::CloneAnimationDecoder(Decoder* aDecoder)
|
||||
{
|
||||
MOZ_ASSERT(aDecoder);
|
||||
MOZ_ASSERT(aDecoder->HasAnimation());
|
||||
|
||||
RefPtr<Decoder> decoder = GetDecoder(aDecoder->GetType(), nullptr,
|
||||
/* aIsRedecode = */ true);
|
||||
// In an ideal world, we would assert aDecoder->HasAnimation() but we cannot.
|
||||
// The decoder may not have detected it is animated yet (e.g. it did not even
|
||||
// get scheduled yet, or it has only decoded the first frame and has yet to
|
||||
// rediscover it is animated).
|
||||
DecoderType type = aDecoder->GetType();
|
||||
MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG,
|
||||
"Calling CloneAnimationDecoder for non-animating DecoderType");
|
||||
|
||||
RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true);
|
||||
MOZ_ASSERT(decoder, "Should have a decoder now");
|
||||
|
||||
// Initialize the decoder.
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/WrappingOperations.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WrappingOperations.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -697,7 +698,7 @@ ScrambleHashCode(HashNumber h)
|
||||
* are stored in a hash table; see Knuth for details.
|
||||
*/
|
||||
static const HashNumber goldenRatio = 0x9E3779B9U;
|
||||
return h * goldenRatio;
|
||||
return mozilla::WrappingMultiply(h, goldenRatio);
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
|
@ -120,7 +120,7 @@ CreateRegExpSearchResult(const MatchPairs& matches)
|
||||
*/
|
||||
static RegExpRunStatus
|
||||
ExecuteRegExpImpl(JSContext* cx, RegExpStatics* res, MutableHandleRegExpShared re,
|
||||
HandleLinearString input, size_t searchIndex, MatchPairs* matches,
|
||||
HandleLinearString input, size_t searchIndex, VectorMatchPairs* matches,
|
||||
size_t* endIndex)
|
||||
{
|
||||
RegExpRunStatus status = RegExpShared::execute(cx, re, input, searchIndex, matches, endIndex);
|
||||
@ -147,7 +147,7 @@ js::ExecuteRegExpLegacy(JSContext* cx, RegExpStatics* res, Handle<RegExpObject*>
|
||||
if (!shared)
|
||||
return false;
|
||||
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
RegExpRunStatus status = ExecuteRegExpImpl(cx, res, &shared, input, *lastIndex,
|
||||
&matches, nullptr);
|
||||
@ -904,7 +904,7 @@ IsTrailSurrogateWithLeadSurrogate(HandleLinearString input, int32_t index)
|
||||
*/
|
||||
static RegExpRunStatus
|
||||
ExecuteRegExp(JSContext* cx, HandleObject regexp, HandleString string, int32_t lastIndex,
|
||||
MatchPairs* matches, size_t* endIndex)
|
||||
VectorMatchPairs* matches, size_t* endIndex)
|
||||
{
|
||||
/*
|
||||
* WARNING: Despite the presence of spec step comment numbers, this
|
||||
@ -979,7 +979,7 @@ RegExpMatcherImpl(JSContext* cx, HandleObject regexp, HandleString string, int32
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
/* Execute regular expression and gather matches. */
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
/* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr);
|
||||
@ -1048,7 +1048,7 @@ RegExpSearcherImpl(JSContext* cx, HandleObject regexp, HandleString string, int3
|
||||
int32_t* result)
|
||||
{
|
||||
/* Execute regular expression and gather matches. */
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
VectorMatchPairs matches;
|
||||
|
||||
/* Steps 3, 9-14, except 12.a.i, 12.c.i.1. */
|
||||
RegExpRunStatus status = ExecuteRegExp(cx, regexp, string, lastIndex, &matches, nullptr);
|
||||
|
@ -689,6 +689,12 @@ class FullParseHandler
|
||||
!node->pn_funbox->isArrow();
|
||||
}
|
||||
|
||||
void noteExpressionClosure(Node* funcNode) const {
|
||||
// No need to do anything: |funcNode->pn_funbox| modifications
|
||||
// performed elsewhere in the relevant code path will assure
|
||||
// |isExpressionClosure| above tests true on |*funcNode|.
|
||||
}
|
||||
|
||||
ParseNode* newObjectMethodOrPropertyDefinition(ParseNode* key, ParseNode* fn, AccessorType atype) {
|
||||
MOZ_ASSERT(isUsableAsObjectPropertyName(key));
|
||||
|
||||
|
@ -2599,7 +2599,7 @@ Parser<FullParseHandler, CharT>::standaloneFunction(HandleFunction fun,
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
|
||||
AutoAwaitIsKeyword<FullParseHandler, CharT> awaitIsKeyword(this, awaitHandling);
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, fn, Statement,
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &fn, Statement,
|
||||
parameterListEnd, /* isStandaloneFunction = */ true))
|
||||
{
|
||||
return null();
|
||||
@ -3414,7 +3414,7 @@ GeneralParser<ParseHandler, CharT>::functionDefinition(Node funcNode, uint32_t t
|
||||
// reparse a function due to failed syntax parsing and encountering new
|
||||
// "use foo" directives.
|
||||
while (true) {
|
||||
if (trySyntaxParseInnerFunction(funcNode, fun, toStringStart, inHandling, yieldHandling,
|
||||
if (trySyntaxParseInnerFunction(&funcNode, fun, toStringStart, inHandling, yieldHandling,
|
||||
kind, generatorKind, asyncKind, tryAnnexB, directives,
|
||||
&newDirectives))
|
||||
{
|
||||
@ -3442,7 +3442,7 @@ GeneralParser<ParseHandler, CharT>::functionDefinition(Node funcNode, uint32_t t
|
||||
|
||||
template <typename CharT>
|
||||
bool
|
||||
Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode* funcNode,
|
||||
Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode** funcNode,
|
||||
HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
@ -3460,7 +3460,7 @@ Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode* funcNode
|
||||
// parse to avoid the overhead of a lazy syntax-only parse. Although
|
||||
// the prediction may be incorrect, IIFEs are common enough that it
|
||||
// pays off for lots of code.
|
||||
if (funcNode->isLikelyIIFE() &&
|
||||
if ((*funcNode)->isLikelyIIFE() &&
|
||||
generatorKind == GeneratorKind::NotGenerator &&
|
||||
asyncKind == FunctionAsyncKind::SyncFunction)
|
||||
{
|
||||
@ -3482,16 +3482,17 @@ Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode* funcNode
|
||||
// Make a FunctionBox before we enter the syntax parser, because |pn|
|
||||
// still expects a FunctionBox to be attached to it during BCE, and
|
||||
// the syntax parser cannot attach one to it.
|
||||
FunctionBox* funbox = newFunctionBox(funcNode, fun, toStringStart, inheritedDirectives,
|
||||
FunctionBox* funbox = newFunctionBox(*funcNode, fun, toStringStart, inheritedDirectives,
|
||||
generatorKind, asyncKind);
|
||||
if (!funbox)
|
||||
return false;
|
||||
funbox->initWithEnclosingParseContext(pc, kind);
|
||||
|
||||
if (!syntaxParser->innerFunctionForFunctionBox(SyntaxParseHandler::NodeGeneric,
|
||||
pc, funbox, inHandling, yieldHandling,
|
||||
kind, newDirectives))
|
||||
{
|
||||
SyntaxParseHandler::Node syntaxNode =
|
||||
syntaxParser->innerFunctionForFunctionBox(SyntaxParseHandler::NodeGeneric, pc, funbox,
|
||||
inHandling, yieldHandling, kind,
|
||||
newDirectives);
|
||||
if (!syntaxNode) {
|
||||
if (syntaxParser->hadAbortedSyntaxParse()) {
|
||||
// Try again with a full parse. UsedNameTracker needs to be
|
||||
// rewound to just before we tried the syntax parse for
|
||||
@ -3511,7 +3512,7 @@ Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode* funcNode
|
||||
return false;
|
||||
|
||||
// Update the end position of the parse node.
|
||||
funcNode->pn_pos.end = anyChars.currentToken().pos.end;
|
||||
(*funcNode)->pn_pos.end = anyChars.currentToken().pos.end;
|
||||
|
||||
// Append possible Annex B function box only upon successfully parsing.
|
||||
if (tryAnnexB) {
|
||||
@ -3523,13 +3524,19 @@ Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode* funcNode
|
||||
} while (false);
|
||||
|
||||
// We failed to do a syntax parse above, so do the full parse.
|
||||
return innerFunction(funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
Node innerFunc =
|
||||
innerFunction(*funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
if (!innerFunc)
|
||||
return false;
|
||||
|
||||
*funcNode = innerFunc;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool
|
||||
Parser<SyntaxParseHandler, CharT>::trySyntaxParseInnerFunction(Node funcNode, HandleFunction fun,
|
||||
Parser<SyntaxParseHandler, CharT>::trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
@ -3541,13 +3548,20 @@ Parser<SyntaxParseHandler, CharT>::trySyntaxParseInnerFunction(Node funcNode, Ha
|
||||
Directives* newDirectives)
|
||||
{
|
||||
// This is already a syntax parser, so just parse the inner function.
|
||||
return innerFunction(funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
Node innerFunc =
|
||||
innerFunction(*funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
|
||||
if (!innerFunc)
|
||||
return false;
|
||||
|
||||
*funcNode = innerFunc;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
inline bool
|
||||
GeneralParser<ParseHandler, CharT>::trySyntaxParseInnerFunction(Node funcNode, HandleFunction fun,
|
||||
GeneralParser<ParseHandler, CharT>::trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
@ -3565,7 +3579,7 @@ GeneralParser<ParseHandler, CharT>::trySyntaxParseInnerFunction(Node funcNode, H
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
bool
|
||||
typename ParseHandler::Node
|
||||
GeneralParser<ParseHandler, CharT>::innerFunctionForFunctionBox(Node funcNode,
|
||||
ParseContext* outerpc,
|
||||
FunctionBox* funbox,
|
||||
@ -3582,16 +3596,19 @@ GeneralParser<ParseHandler, CharT>::innerFunctionForFunctionBox(Node funcNode,
|
||||
// Push a new ParseContext.
|
||||
SourceParseContext funpc(this, funbox, newDirectives);
|
||||
if (!funpc.init())
|
||||
return false;
|
||||
return null();
|
||||
|
||||
if (!functionFormalParametersAndBody(inHandling, yieldHandling, funcNode, kind))
|
||||
return false;
|
||||
if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funcNode, kind))
|
||||
return null();
|
||||
|
||||
return leaveInnerFunction(outerpc);
|
||||
if (!leaveInnerFunction(outerpc))
|
||||
return null();
|
||||
|
||||
return funcNode;
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
bool
|
||||
typename ParseHandler::Node
|
||||
GeneralParser<ParseHandler, CharT>::innerFunction(Node funcNode, ParseContext* outerpc,
|
||||
HandleFunction fun, uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
@ -3610,22 +3627,22 @@ GeneralParser<ParseHandler, CharT>::innerFunction(Node funcNode, ParseContext* o
|
||||
FunctionBox* funbox = newFunctionBox(funcNode, fun, toStringStart, inheritedDirectives,
|
||||
generatorKind, asyncKind);
|
||||
if (!funbox)
|
||||
return false;
|
||||
return null();
|
||||
funbox->initWithEnclosingParseContext(outerpc, kind);
|
||||
|
||||
if (!innerFunctionForFunctionBox(funcNode, outerpc, funbox, inHandling, yieldHandling, kind,
|
||||
newDirectives))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Node innerFunc =
|
||||
innerFunctionForFunctionBox(funcNode, outerpc, funbox, inHandling, yieldHandling, kind,
|
||||
newDirectives);
|
||||
if (!innerFunc)
|
||||
return null();
|
||||
|
||||
// Append possible Annex B function box only upon successfully parsing.
|
||||
if (tryAnnexB) {
|
||||
if (!pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
return true;
|
||||
return innerFunc;
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename CharT>
|
||||
@ -3695,7 +3712,7 @@ Parser<FullParseHandler, CharT>::standaloneLazyFunction(HandleFunction fun, uint
|
||||
else if (fun->isArrow())
|
||||
syntaxKind = Arrow;
|
||||
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, pn, syntaxKind)) {
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &pn, syntaxKind)) {
|
||||
MOZ_ASSERT(directives == newDirectives);
|
||||
return null();
|
||||
}
|
||||
@ -3710,7 +3727,7 @@ template <class ParseHandler, typename CharT>
|
||||
bool
|
||||
GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
Node pn,
|
||||
Node* pn,
|
||||
FunctionSyntaxKind kind,
|
||||
const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
|
||||
bool isStandaloneFunction /* = false */)
|
||||
@ -3729,7 +3746,7 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
? AwaitIsKeyword
|
||||
: AwaitIsName;
|
||||
AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, awaitHandling);
|
||||
if (!functionArguments(yieldHandling, kind, pn))
|
||||
if (!functionArguments(yieldHandling, kind, *pn))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3779,6 +3796,7 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
this->addTelemetry(DeprecatedLanguageExtension::ExpressionClosure);
|
||||
if (!warnOnceAboutExprClosure())
|
||||
return false;
|
||||
handler.noteExpressionClosure(pn);
|
||||
} else {
|
||||
error(JSMSG_CURLY_BEFORE_BODY);
|
||||
return false;
|
||||
@ -3833,7 +3851,7 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
// We already use the correct await-handling at this point, therefore
|
||||
// we don't need call AutoAwaitIsKeyword here.
|
||||
|
||||
uint32_t nameOffset = handler.getFunctionNameOffset(pn, anyChars);
|
||||
uint32_t nameOffset = handler.getFunctionNameOffset(*pn, anyChars);
|
||||
if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling))
|
||||
return false;
|
||||
}
|
||||
@ -3860,8 +3878,8 @@ GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling i
|
||||
return false;
|
||||
|
||||
handler.setEndPosition(body, pos().begin);
|
||||
handler.setEndPosition(pn, pos().end);
|
||||
handler.setFunctionBody(pn, body);
|
||||
handler.setEndPosition(*pn, pos().end);
|
||||
handler.setFunctionBody(*pn, body);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -941,7 +941,7 @@ class GeneralParser
|
||||
bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling, Node nodeList,
|
||||
TokenKind* ttp);
|
||||
|
||||
inline bool trySyntaxParseInnerFunction(Node funcNode, HandleFunction fun,
|
||||
inline bool trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun,
|
||||
uint32_t toStringStart, InHandling inHandling,
|
||||
YieldHandling yieldHandling, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind,
|
||||
@ -958,14 +958,15 @@ class GeneralParser
|
||||
|
||||
// Parse an inner function given an enclosing ParseContext and a
|
||||
// FunctionBox for the inner function.
|
||||
bool innerFunctionForFunctionBox(Node funcNode, ParseContext* outerpc, FunctionBox* funbox,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, Directives* newDirectives);
|
||||
MOZ_MUST_USE Node
|
||||
innerFunctionForFunctionBox(Node funcNode, ParseContext* outerpc, FunctionBox* funbox,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, Directives* newDirectives);
|
||||
|
||||
// Parse a function's formal parameters and its body assuming its function
|
||||
// ParseContext is already on the stack.
|
||||
bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
|
||||
Node pn, FunctionSyntaxKind kind,
|
||||
Node* pn, FunctionSyntaxKind kind,
|
||||
const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
|
||||
bool isStandaloneFunction = false);
|
||||
|
||||
@ -1246,11 +1247,12 @@ class GeneralParser
|
||||
|
||||
Node statementList(YieldHandling yieldHandling);
|
||||
|
||||
bool innerFunction(Node funcNode, ParseContext* outerpc, HandleFunction fun,
|
||||
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
|
||||
Directives* newDirectives);
|
||||
MOZ_MUST_USE Node
|
||||
innerFunction(Node funcNode, ParseContext* outerpc, HandleFunction fun,
|
||||
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
|
||||
Directives* newDirectives);
|
||||
|
||||
bool matchOrInsertSemicolon();
|
||||
|
||||
@ -1353,7 +1355,7 @@ class Parser<SyntaxParseHandler, CharT> final
|
||||
inline bool checkExportedNameForClass(Node node);
|
||||
inline bool checkExportedNameForClause(Node node);
|
||||
|
||||
bool trySyntaxParseInnerFunction(Node funcNode, HandleFunction fun, uint32_t toStringStart,
|
||||
bool trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun, uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind, bool tryAnnexB,
|
||||
@ -1469,7 +1471,7 @@ class Parser<FullParseHandler, CharT> final
|
||||
bool checkExportedNameForClass(Node node);
|
||||
inline bool checkExportedNameForClause(Node node);
|
||||
|
||||
bool trySyntaxParseInnerFunction(Node funcNode, HandleFunction fun, uint32_t toStringStart,
|
||||
bool trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun, uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind, bool tryAnnexB,
|
||||
|
@ -360,6 +360,10 @@ class SyntaxParseHandler
|
||||
return node == NodeFunctionExpressionClosure;
|
||||
}
|
||||
|
||||
void noteExpressionClosure(Node* funcNode) const {
|
||||
*funcNode = NodeFunctionExpressionClosure;
|
||||
}
|
||||
|
||||
void setFunctionFormalParametersAndBody(Node funcNode, Node kid) {}
|
||||
void setFunctionBody(Node pn, Node kid) {}
|
||||
void setFunctionBox(Node pn, FunctionBox* funbox) {}
|
||||
|
@ -1017,22 +1017,17 @@ js::Nursery::sweep(JSTracer* trc)
|
||||
void
|
||||
js::Nursery::clear()
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
#if defined(JS_GC_ZEAL) || defined(JS_CRASH_DIAGNOSTICS)
|
||||
/* Poison the nursery contents so touching a freed object will crash. */
|
||||
for (unsigned i = 0; i < allocatedChunkCount(); i++)
|
||||
for (unsigned i = currentStartChunk_; i < allocatedChunkCount(); ++i)
|
||||
chunk(i).poisonAndInit(runtime(), JS_SWEPT_NURSERY_PATTERN);
|
||||
#endif
|
||||
|
||||
if (runtime()->hasZealMode(ZealMode::GenerationalGC)) {
|
||||
/* Only reset the alloc point when we are close to the end. */
|
||||
if (currentChunk_ + 1 == maxChunkCount())
|
||||
setCurrentChunk(0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
for (unsigned i = 0; i < allocatedChunkCount(); ++i)
|
||||
chunk(i).poisonAndInit(runtime(), JS_SWEPT_NURSERY_PATTERN);
|
||||
#endif
|
||||
} else {
|
||||
setCurrentChunk(0);
|
||||
}
|
||||
|
||||
|
@ -3791,6 +3791,36 @@ CodeGenerator::visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject*
|
||||
callVM(CopyLexicalEnvironmentObjectInfo, lir);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Label bail;
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
Label bail;
|
||||
masm.branchTestObjGroup(cond, obj, guard->mir()->group(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
Label bail;
|
||||
masm.branchTestObjClass(Assembler::NotEqual, obj, tmp, guard->mir()->getClass(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity* guard)
|
||||
{
|
||||
|
@ -155,6 +155,9 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||
void visitConvertElementsToDoubles(LConvertElementsToDoubles* lir);
|
||||
void visitMaybeToDoubleElement(LMaybeToDoubleElement* lir);
|
||||
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
|
||||
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
|
||||
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
|
||||
|
@ -3997,11 +3997,32 @@ LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity* ins)
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardClass(MGuardClass* ins)
|
||||
{
|
||||
LDefinition t = temp();
|
||||
LGuardClass* guard = new(alloc()) LGuardClass(useRegister(ins->object()), t);
|
||||
LGuardClass* guard = new(alloc()) LGuardClass(useRegister(ins->object()), temp());
|
||||
assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard);
|
||||
add(guard, ins);
|
||||
}
|
||||
|
@ -264,6 +264,8 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
void visitBindNameCache(MBindNameCache* ins) override;
|
||||
void visitCallBindVar(MCallBindVar* ins) override;
|
||||
void visitGuardObjectIdentity(MGuardObjectIdentity* ins) override;
|
||||
void visitGuardShape(MGuardShape* ins) override;
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins) override;
|
||||
void visitGuardClass(MGuardClass* ins) override;
|
||||
void visitGuardObject(MGuardObject* ins) override;
|
||||
void visitGuardString(MGuardString* ins) override;
|
||||
|
@ -1742,36 +1742,6 @@ CodeGeneratorARM::visitNotF(LNotF* ins)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Label bail;
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
Label bail;
|
||||
masm.branchTestObjGroup(cond, obj, guard->mir()->group(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
Label bail;
|
||||
masm.branchTestObjClass(Assembler::NotEqual, obj, tmp, guard->mir()->getClass(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM::generateInvalidateEpilogue()
|
||||
{
|
||||
|
@ -222,11 +222,6 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
void visitValue(LValue* value);
|
||||
void visitDouble(LDouble* ins);
|
||||
void visitFloat32(LFloat32* ins);
|
||||
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
|
||||
void visitNegI(LNegI* lir);
|
||||
void visitNegD(LNegD* lir);
|
||||
void visitNegF(LNegF* lir);
|
||||
|
@ -383,38 +383,6 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape);
|
||||
|
||||
explicit LGuardShape(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup);
|
||||
|
||||
explicit LGuardObjectGroup(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
|
@ -480,28 +480,6 @@ LIRGeneratorARM::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
temp(), tempDouble(), tableswitch);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM::lowerUrshD(MUrsh* mir)
|
||||
{
|
||||
|
@ -100,8 +100,6 @@ class LIRGeneratorARM : public LIRGeneratorShared
|
||||
void visitUnbox(MUnbox* unbox) override;
|
||||
void visitReturn(MReturn* ret) override;
|
||||
void lowerPhi(MPhi* phi);
|
||||
void visitGuardShape(MGuardShape* ins) override;
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins) override;
|
||||
void visitWasmSelect(MWasmSelect* ins) override;
|
||||
void visitWasmUnsignedToDouble(MWasmUnsignedToDouble* ins) override;
|
||||
void visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins) override;
|
||||
|
@ -576,24 +576,6 @@ CodeGeneratorARM64::storeElementTyped(const LAllocation* value, MIRType valueTyp
|
||||
MOZ_CRASH("CodeGeneratorARM64::storeElementTyped");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
MOZ_CRASH("visitGuardShape");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
MOZ_CRASH("visitGuardObjectGroup");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
MOZ_CRASH("CodeGeneratorARM64::visitGuardClass");
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorARM64::visitInterruptCheck(LInterruptCheck* lir)
|
||||
{
|
||||
|
@ -184,10 +184,6 @@ class CodeGeneratorARM64 : public CodeGeneratorShared
|
||||
|
||||
void visitLoadElementT(LLoadElementT* load);
|
||||
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
|
||||
void visitInterruptCheck(LInterruptCheck* lir);
|
||||
|
||||
void visitNegI(LNegI* lir);
|
||||
|
@ -308,40 +308,6 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape);
|
||||
|
||||
LGuardShape(const LAllocation& in, const LDefinition& temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup);
|
||||
|
||||
LGuardObjectGroup(const LAllocation& in, const LDefinition& temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
|
@ -197,18 +197,6 @@ LIRGeneratorARM64::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
MOZ_CRASH("newLTableSwitchV");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_CRASH("visitGuardShape");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_CRASH("visitGuardObjectGroup");
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM64::lowerUrshD(MUrsh* mir)
|
||||
{
|
||||
|
@ -101,8 +101,6 @@ class LIRGeneratorARM64 : public LIRGeneratorShared
|
||||
void visitUnbox(MUnbox* unbox) override;
|
||||
void visitReturn(MReturn* ret) override;
|
||||
void lowerPhi(MPhi* phi);
|
||||
void visitGuardShape(MGuardShape* ins) override;
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins) override;
|
||||
void visitWasmUnsignedToDouble(MWasmUnsignedToDouble* ins) override;
|
||||
void visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins) override;
|
||||
void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins) override;
|
||||
|
@ -1768,36 +1768,6 @@ CodeGeneratorMIPSShared::visitNotF(LNotF* ins)
|
||||
masm.ma_cmp_set_float32(dest, in, ScratchFloat32Reg, Assembler::DoubleEqualOrUnordered);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Label bail;
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
Label bail;
|
||||
masm.branchTestObjGroup(cond, obj, guard->mir()->group(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
Label bail;
|
||||
masm.branchTestObjClass(Assembler::NotEqual, obj, tmp, guard->mir()->getClass(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorMIPSShared::visitMemoryBarrier(LMemoryBarrier* ins)
|
||||
{
|
||||
|
@ -206,11 +206,6 @@ class CodeGeneratorMIPSShared : public CodeGeneratorShared
|
||||
void visitValue(LValue* value);
|
||||
void visitDouble(LDouble* ins);
|
||||
void visitFloat32(LFloat32* ins);
|
||||
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
|
||||
void visitNegI(LNegI* lir);
|
||||
void visitNegD(LNegD* lir);
|
||||
void visitNegF(LNegF* lir);
|
||||
|
@ -210,38 +210,6 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3>
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape);
|
||||
|
||||
explicit LGuardShape(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup);
|
||||
|
||||
explicit LGuardObjectGroup(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
const LDefinition* tempInt() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0>
|
||||
{
|
||||
public:
|
||||
|
@ -287,28 +287,6 @@ LIRGeneratorMIPSShared::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
temp(), tempDouble(), temp(), tableswitch);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorMIPSShared::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorMIPSShared::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorMIPSShared::lowerUrshD(MUrsh* mir)
|
||||
{
|
||||
|
@ -81,8 +81,6 @@ class LIRGeneratorMIPSShared : public LIRGeneratorShared
|
||||
|
||||
public:
|
||||
void lowerPhi(MPhi* phi);
|
||||
void visitGuardShape(MGuardShape* ins);
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins);
|
||||
void visitWasmUnsignedToDouble(MWasmUnsignedToDouble* ins);
|
||||
void visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins);
|
||||
void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins);
|
||||
|
@ -101,8 +101,6 @@ class LModPowTwoI : public LInstructionHelper<1, 1, 0>
|
||||
MMod* mir() const { MOZ_CRASH(); }
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstruction {};
|
||||
class LGuardObjectGroup : public LInstruction {};
|
||||
class LMulI : public LInstruction {};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -75,8 +75,6 @@ class LIRGeneratorNone : public LIRGeneratorShared
|
||||
void visitReturn(MReturn* ret) override { MOZ_CRASH(); }
|
||||
void visitPowHalf(MPowHalf*) override { MOZ_CRASH(); }
|
||||
void visitWasmNeg(MWasmNeg*) override { MOZ_CRASH(); }
|
||||
void visitGuardShape(MGuardShape* ins) override { MOZ_CRASH(); }
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins) override { MOZ_CRASH(); }
|
||||
void visitWasmUnsignedToDouble(MWasmUnsignedToDouble* ins) override { MOZ_CRASH(); }
|
||||
void visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins) override { MOZ_CRASH(); }
|
||||
void visitAsmJSLoadHeap(MAsmJSLoadHeap* ins) override { MOZ_CRASH(); }
|
||||
|
@ -8041,6 +8041,32 @@ class LGuardObjectIdentity : public LInstructionHelper<0, 2, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape)
|
||||
|
||||
explicit LGuardShape(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup)
|
||||
|
||||
explicit LGuardObjectGroup(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
};
|
||||
|
||||
// Guard against an object's class.
|
||||
class LGuardClass : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
|
@ -2372,36 +2372,6 @@ CodeGeneratorX86Shared::visitNearbyIntF(LNearbyIntF* lir)
|
||||
masm.vroundss(Assembler::ToX86RoundingMode(roundingMode), input, output, output);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86Shared::visitGuardShape(LGuardShape* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Label bail;
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86Shared::visitGuardObjectGroup(LGuardObjectGroup* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
Label bail;
|
||||
masm.branchTestObjGroup(cond, obj, guard->mir()->group(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86Shared::visitGuardClass(LGuardClass* guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
Label bail;
|
||||
masm.branchTestObjClass(Assembler::NotEqual, obj, tmp, guard->mir()->getClass(), &bail);
|
||||
bailoutFrom(&bail, guard->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86Shared::visitEffectiveAddress(LEffectiveAddress* ins)
|
||||
{
|
||||
|
@ -241,9 +241,6 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
void visitRoundF(LRoundF* lir);
|
||||
void visitNearbyInt(LNearbyInt* lir);
|
||||
void visitNearbyIntF(LNearbyIntF* lir);
|
||||
void visitGuardShape(LGuardShape* guard);
|
||||
void visitGuardObjectGroup(LGuardObjectGroup* guard);
|
||||
void visitGuardClass(LGuardClass* guard);
|
||||
void visitEffectiveAddress(LEffectiveAddress* ins);
|
||||
void visitUDivOrMod(LUDivOrMod* ins);
|
||||
void visitUDivOrModConstant(LUDivOrModConstant *ins);
|
||||
|
@ -304,32 +304,6 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3>
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShape)
|
||||
|
||||
explicit LGuardShape(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardShape* mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectGroup : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectGroup)
|
||||
|
||||
explicit LGuardObjectGroup(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectGroup* mir() const {
|
||||
return mir_->toGuardObjectGroup();
|
||||
}
|
||||
};
|
||||
|
||||
class LMulI : public LBinaryMath<0, 1>
|
||||
{
|
||||
public:
|
||||
|
@ -33,28 +33,6 @@ LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
temp(), tempDouble(), temp(), tableswitch);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX86Shared::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX86Shared::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX86Shared::visitPowHalf(MPowHalf* ins)
|
||||
{
|
||||
|
@ -23,8 +23,6 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared
|
||||
MTableSwitch* ins);
|
||||
LTableSwitchV* newLTableSwitchV(MTableSwitch* ins);
|
||||
|
||||
void visitGuardShape(MGuardShape* ins) override;
|
||||
void visitGuardObjectGroup(MGuardObjectGroup* ins) override;
|
||||
void visitPowHalf(MPowHalf* ins) override;
|
||||
void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs,
|
||||
MDefinition* rhs);
|
||||
|
@ -2988,6 +2988,15 @@ SetJitExceptionHandler(JitExceptionHandler handler);
|
||||
extern JS_FRIEND_API(JSObject*)
|
||||
GetFirstSubsumedSavedFrame(JSContext* cx, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted);
|
||||
|
||||
/**
|
||||
* Get the first SavedFrame object in this SavedFrame stack whose principals are
|
||||
* subsumed by the given |principals|. If there is no such frame, return nullptr.
|
||||
*
|
||||
* Do NOT pass a non-SavedFrame object here.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSObject*)
|
||||
GetFirstSubsumedSavedFrame(JSContext* cx, JSPrincipals* principals, JS::HandleObject savedFrame, JS::SavedFrameSelfHosted selfHosted);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
ReportIsNotFunction(JSContext* cx, JS::HandleValue v);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/WrappingOperations.h"
|
||||
|
||||
#include <algorithm> // for std::max
|
||||
#include <fcntl.h>
|
||||
@ -114,6 +115,7 @@ using mozilla::IsNegative;
|
||||
using mozilla::IsNegativeZero;
|
||||
using mozilla::PositiveInfinity;
|
||||
using mozilla::NegativeInfinity;
|
||||
using mozilla::WrappingMultiply;
|
||||
using JS::ToNumber;
|
||||
using JS::GenericNaN;
|
||||
|
||||
@ -482,16 +484,13 @@ js::math_floor(JSContext* cx, unsigned argc, Value* vp)
|
||||
bool
|
||||
js::math_imul_handle(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
|
||||
{
|
||||
uint32_t a = 0, b = 0;
|
||||
if (!lhs.isUndefined() && !ToUint32(cx, lhs, &a))
|
||||
int32_t a = 0, b = 0;
|
||||
if (!lhs.isUndefined() && !ToInt32(cx, lhs, &a))
|
||||
return false;
|
||||
if (!rhs.isUndefined() && !ToUint32(cx, rhs, &b))
|
||||
if (!rhs.isUndefined() && !ToInt32(cx, rhs, &b))
|
||||
return false;
|
||||
|
||||
uint32_t product = a * b;
|
||||
res.setInt32(product > INT32_MAX
|
||||
? int32_t(INT32_MIN + (product - INT32_MAX - 1))
|
||||
: int32_t(product));
|
||||
res.setInt32(WrappingMultiply(a, b));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -16,17 +16,48 @@ assertEq(typeof ec1, "function");
|
||||
assertEq(typeof ec1(), "function");
|
||||
assertEq(ec1()(), undefined);
|
||||
|
||||
function inFunction1()
|
||||
{
|
||||
var ec1f = function() 0 ? 1 : a => {};
|
||||
assertEq(typeof ec1f, "function");
|
||||
assertEq(typeof ec1f(), "function");
|
||||
assertEq(ec1f()(), undefined);
|
||||
}
|
||||
inFunction1();
|
||||
|
||||
var ec2 = function() 0 ? 1 : a => {} // deliberately exercise ASI here
|
||||
assertEq(typeof ec2, "function");
|
||||
assertEq(typeof ec2(), "function");
|
||||
assertEq(ec2()(), undefined);
|
||||
|
||||
function inFunction2()
|
||||
{
|
||||
var ec2f = function() 0 ? 1 : a => {} // deliberately exercise ASI here
|
||||
assertEq(typeof ec2f, "function");
|
||||
assertEq(typeof ec2f(), "function");
|
||||
assertEq(ec2f()(), undefined);
|
||||
}
|
||||
inFunction2();
|
||||
|
||||
function ec3() 0 ? 1 : a => {} // exercise ASI here
|
||||
assertEq(typeof ec3(), "function");
|
||||
|
||||
function inFunction3()
|
||||
{
|
||||
function ec3f() 0 ? 1 : a => {} // exercise ASI here
|
||||
assertEq(typeof ec3f(), "function");
|
||||
}
|
||||
inFunction3();
|
||||
|
||||
function ec4() 0 ? 1 : a => {};
|
||||
assertEq(typeof ec4(), "function");
|
||||
|
||||
function inFunction4()
|
||||
{
|
||||
function ec4f() 0 ? 1 : a => {};
|
||||
assertEq(typeof ec4f(), "function");
|
||||
}
|
||||
|
||||
var needle = "@";
|
||||
var x = 42;
|
||||
var g = { test() { assertEq(true, false, "shouldn't be called"); } };
|
||||
@ -34,6 +65,18 @@ var g = { test() { assertEq(true, false, "shouldn't be called"); } };
|
||||
function ec5() 0 ? 1 : a => {} // ASI
|
||||
/x/g.test((needle = "x"));
|
||||
assertEq(needle, "x");
|
||||
|
||||
function inFunction5()
|
||||
{
|
||||
var needle = "@";
|
||||
var x = 42;
|
||||
var g = { test() { assertEq(true, false, "shouldn't be called"); } };
|
||||
|
||||
function ec5f() 0 ? 1 : a => {} // ASI
|
||||
/x/g.test((needle = "x"));
|
||||
assertEq(needle, "x");
|
||||
}
|
||||
inFunction5();
|
||||
`);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
|
@ -261,7 +261,7 @@ static uint32_t quorem2(Bigint* b, int32_t k)
|
||||
int32_t w;
|
||||
int32_t n = k >> 5;
|
||||
k &= 0x1F;
|
||||
mask = (1<<k) - 1;
|
||||
mask = (ULong(1)<<k) - 1;
|
||||
|
||||
w = b->wds - n;
|
||||
if (w <= 0)
|
||||
|
@ -51,7 +51,8 @@ struct MatchPair
|
||||
}
|
||||
};
|
||||
|
||||
/* Base class for RegExp execution output. */
|
||||
// MachPairs is used as base class for VectorMatchPairs but can also be
|
||||
// stack-allocated (without a Vector) in JIT code.
|
||||
class MatchPairs
|
||||
{
|
||||
protected:
|
||||
@ -72,10 +73,6 @@ class MatchPairs
|
||||
friend class RegExpShared;
|
||||
friend class RegExpStatics;
|
||||
|
||||
/* MatchPair buffer allocator: set pairs_ and pairCount_. */
|
||||
virtual bool allocOrExpandArray(size_t pairCount) = 0;
|
||||
|
||||
bool initArrayFrom(MatchPairs& copyFrom);
|
||||
void forgetArray() { pairs_ = nullptr; }
|
||||
|
||||
void checkAgainst(size_t inputLength) {
|
||||
@ -114,37 +111,18 @@ class MatchPairs
|
||||
}
|
||||
};
|
||||
|
||||
/* MatchPairs allocated into temporary storage, removed when out of scope. */
|
||||
class ScopedMatchPairs : public MatchPairs
|
||||
{
|
||||
LifoAllocScope lifoScope_;
|
||||
|
||||
public:
|
||||
/* Constructs an implicit LifoAllocScope. */
|
||||
explicit ScopedMatchPairs(LifoAlloc* lifoAlloc)
|
||||
: lifoScope_(lifoAlloc)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
bool allocOrExpandArray(size_t pairCount) override;
|
||||
};
|
||||
|
||||
/*
|
||||
* MatchPairs allocated into permanent storage, for RegExpStatics.
|
||||
* The Vector of MatchPairs is reusable by Vector expansion.
|
||||
*/
|
||||
class VectorMatchPairs : public MatchPairs
|
||||
{
|
||||
Vector<MatchPair, 10, SystemAllocPolicy> vec_;
|
||||
|
||||
public:
|
||||
VectorMatchPairs() {
|
||||
vec_.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class RegExpShared;
|
||||
friend class RegExpStatics;
|
||||
bool allocOrExpandArray(size_t pairCount) override;
|
||||
|
||||
/* MatchPair buffer allocator: set pairs_ and pairCount_. */
|
||||
bool allocOrExpandArray(size_t pairCount);
|
||||
|
||||
bool initArrayFrom(VectorMatchPairs& copyFrom);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -70,7 +70,7 @@ js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nu
|
||||
/* MatchPairs */
|
||||
|
||||
bool
|
||||
MatchPairs::initArrayFrom(MatchPairs& copyFrom)
|
||||
VectorMatchPairs::initArrayFrom(VectorMatchPairs& copyFrom)
|
||||
{
|
||||
MOZ_ASSERT(copyFrom.pairCount() > 0);
|
||||
|
||||
@ -82,29 +82,10 @@ MatchPairs::initArrayFrom(MatchPairs& copyFrom)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScopedMatchPairs::allocOrExpandArray(size_t pairCount)
|
||||
{
|
||||
/* Array expansion is forbidden, but array reuse is acceptable. */
|
||||
if (pairCount_) {
|
||||
MOZ_ASSERT(pairs_);
|
||||
MOZ_ASSERT(pairCount_ == pairCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!pairs_);
|
||||
pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount);
|
||||
if (!pairs_)
|
||||
return false;
|
||||
|
||||
pairCount_ = pairCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VectorMatchPairs::allocOrExpandArray(size_t pairCount)
|
||||
{
|
||||
if (!vec_.resizeUninitialized(sizeof(MatchPair) * pairCount))
|
||||
if (!vec_.resizeUninitialized(pairCount))
|
||||
return false;
|
||||
|
||||
pairs_ = &vec_[0];
|
||||
@ -1082,7 +1063,7 @@ RegExpShared::compileIfNecessary(JSContext* cx, MutableHandleRegExpShared re,
|
||||
|
||||
/* static */ RegExpRunStatus
|
||||
RegExpShared::execute(JSContext* cx, MutableHandleRegExpShared re, HandleLinearString input,
|
||||
size_t start, MatchPairs* matches, size_t* endIndex)
|
||||
size_t start, VectorMatchPairs* matches, size_t* endIndex)
|
||||
{
|
||||
MOZ_ASSERT_IF(matches, !endIndex);
|
||||
MOZ_ASSERT_IF(!matches, endIndex);
|
||||
|
@ -28,10 +28,10 @@
|
||||
namespace js {
|
||||
|
||||
class ArrayObject;
|
||||
class MatchPairs;
|
||||
class RegExpCompartment;
|
||||
class RegExpShared;
|
||||
class RegExpStatics;
|
||||
class VectorMatchPairs;
|
||||
|
||||
using RootedRegExpShared = JS::Rooted<RegExpShared*>;
|
||||
using HandleRegExpShared = JS::Handle<RegExpShared*>;
|
||||
@ -159,7 +159,7 @@ class RegExpShared : public gc::TenuredCell
|
||||
// matches if specified and otherwise only determining if there is a match.
|
||||
static RegExpRunStatus execute(JSContext* cx, MutableHandleRegExpShared res,
|
||||
HandleLinearString input, size_t searchIndex,
|
||||
MatchPairs* matches, size_t* endIndex);
|
||||
VectorMatchPairs* matches, size_t* endIndex);
|
||||
|
||||
// Register a table with this RegExpShared, and take ownership.
|
||||
bool addTable(JitCodeTable table) {
|
||||
|
@ -62,7 +62,8 @@ class RegExpStatics
|
||||
/* Mutators. */
|
||||
inline void updateLazily(JSContext* cx, JSLinearString* input,
|
||||
RegExpShared* shared, size_t lastIndex);
|
||||
inline bool updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs);
|
||||
inline bool updateFromMatchPairs(JSContext* cx, JSLinearString* input,
|
||||
VectorMatchPairs& newPairs);
|
||||
|
||||
inline void clear();
|
||||
|
||||
@ -251,7 +252,8 @@ RegExpStatics::updateLazily(JSContext* cx, JSLinearString* input,
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs)
|
||||
RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input,
|
||||
VectorMatchPairs& newPairs)
|
||||
{
|
||||
MOZ_ASSERT(input);
|
||||
|
||||
|
@ -572,13 +572,14 @@ SavedFrameSubsumedByCaller(JSContext* cx, HandleSavedFrame frame)
|
||||
}
|
||||
|
||||
// Return the first SavedFrame in the chain that starts with |frame| whose
|
||||
// principals are subsumed by |principals|, according to |subsumes|. If there is
|
||||
// no such frame, return nullptr. |skippedAsync| is set to true if any of the
|
||||
// skipped frames had the |asyncCause| property set, otherwise it is explicitly
|
||||
// set to false.
|
||||
// for which the given match function returns true. If there is no such frame,
|
||||
// return nullptr. |skippedAsync| is set to true if any of the skipped frames
|
||||
// had the |asyncCause| property set, otherwise it is explicitly set to false.
|
||||
template<typename Matcher>
|
||||
static SavedFrame*
|
||||
GetFirstSubsumedFrame(JSContext* cx, HandleSavedFrame frame, JS::SavedFrameSelfHosted selfHosted,
|
||||
bool& skippedAsync)
|
||||
GetFirstMatchedFrame(JSContext* cx, Matcher& matches,
|
||||
HandleSavedFrame frame, JS::SavedFrameSelfHosted selfHosted,
|
||||
bool& skippedAsync)
|
||||
{
|
||||
skippedAsync = false;
|
||||
|
||||
@ -586,7 +587,7 @@ GetFirstSubsumedFrame(JSContext* cx, HandleSavedFrame frame, JS::SavedFrameSelfH
|
||||
while (rootedFrame) {
|
||||
if ((selfHosted == JS::SavedFrameSelfHosted::Include ||
|
||||
!rootedFrame->isSelfHosted(cx)) &&
|
||||
SavedFrameSubsumedByCaller(cx, rootedFrame))
|
||||
matches(cx, rootedFrame))
|
||||
{
|
||||
return rootedFrame;
|
||||
}
|
||||
@ -600,6 +601,18 @@ GetFirstSubsumedFrame(JSContext* cx, HandleSavedFrame frame, JS::SavedFrameSelfH
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Return the first SavedFrame in the chain that starts with |frame| whose
|
||||
// principals are subsumed by the principals of the context's current
|
||||
// compartment, according to |subsumes|. If there is no such frame, return
|
||||
// nullptr. |skippedAsync| is set to true if any of the skipped frames had the
|
||||
// |asyncCause| property set, otherwise it is explicitly set to false.
|
||||
static SavedFrame*
|
||||
GetFirstSubsumedFrame(JSContext* cx, HandleSavedFrame frame, JS::SavedFrameSelfHosted selfHosted,
|
||||
bool& skippedAsync)
|
||||
{
|
||||
return GetFirstMatchedFrame(cx, SavedFrameSubsumedByCaller, frame, selfHosted, skippedAsync);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject*)
|
||||
GetFirstSubsumedSavedFrame(JSContext* cx, HandleObject savedFrame,
|
||||
JS::SavedFrameSelfHosted selfHosted)
|
||||
@ -611,6 +624,27 @@ GetFirstSubsumedSavedFrame(JSContext* cx, HandleObject savedFrame,
|
||||
return GetFirstSubsumedFrame(cx, frame, selfHosted, skippedAsync);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject*)
|
||||
GetFirstSubsumedSavedFrame(JSContext* cx, JSPrincipals* principals,
|
||||
HandleObject savedFrame,
|
||||
JS::SavedFrameSelfHosted selfHosted)
|
||||
{
|
||||
if (!savedFrame)
|
||||
return nullptr;
|
||||
|
||||
auto subsumes = cx->runtime()->securityCallbacks->subsumes;
|
||||
if (!subsumes)
|
||||
return nullptr;
|
||||
|
||||
auto matcher = [&](JSContext* cx, HandleSavedFrame frame) -> bool {
|
||||
return subsumes(principals, frame->getPrincipals());
|
||||
};
|
||||
|
||||
bool skippedAsync;
|
||||
RootedSavedFrame frame(cx, &savedFrame->as<SavedFrame>());
|
||||
return GetFirstMatchedFrame(cx, matcher, frame, selfHosted, skippedAsync);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
SavedFrame_checkThis(JSContext* cx, CallArgs& args, const char* fnName,
|
||||
MutableHandleObject frame)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user