diff --git a/docshell/test/browser/frame-head.js b/docshell/test/browser/frame-head.js index 6e79f404f7..5cb3b15133 100644 --- a/docshell/test/browser/frame-head.js +++ b/docshell/test/browser/frame-head.js @@ -4,9 +4,11 @@ // Functions that are automatically loaded as frame scripts for // timeline tests. -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; -let { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); -let { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {}); +var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; +var { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); +var { Promise } = Cu.import('resource://gre/modules/Promise.jsm', {}); + +Cu.import("resource://gre/modules/Timer.jsm"); // Functions that look like mochitest functions but forward to the // browser process. @@ -85,8 +87,9 @@ this.timelineContentTest = function(tests) { function timelineWaitForMarkers(docshell, searchFor) { if (typeof(searchFor) == "string") { + let searchForString = searchFor; let f = function (markers) { - return markers.some(m => m.name == searchFor); + return markers.some(m => m.name == searchForString); }; searchFor = f; } @@ -96,14 +99,15 @@ function timelineWaitForMarkers(docshell, searchFor) { let maxWaitIterationCount = 10; // Wait for 2sec maximum let markers = []; - let interval = content.setInterval(() => { + setTimeout(function timeoutHandler() { let newMarkers = docshell.popProfileTimelineMarkers(); markers = [...markers, ...newMarkers]; if (searchFor(markers) || waitIterationCount > maxWaitIterationCount) { - content.clearInterval(interval); resolve(markers); + } else { + setTimeout(timeoutHandler, 200); + waitIterationCount++; } - waitIterationCount++; }, 200); }); } diff --git a/ipc/glue/BackgroundImpl.cpp b/ipc/glue/BackgroundImpl.cpp index b701f40c88..9434aea024 100644 --- a/ipc/glue/BackgroundImpl.cpp +++ b/ipc/glue/BackgroundImpl.cpp @@ -440,6 +440,8 @@ private: // This class is reference counted. ~ChildImpl() { + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new DeleteTask(GetTransport())); AssertActorDestroyed(); } diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 241e4a569d..08bbd7fed8 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -18,7 +18,7 @@ #endif #include "MainThreadUtils.h" -#include "prprf.h" +#include "mozilla/Snprintf.h" #include "prenv.h" #include "nsXPCOMPrivate.h" @@ -51,8 +51,9 @@ using mozilla::MonitorAutoLock; using mozilla::ipc::GeckoChildProcessHost; #ifdef ANDROID -// This is the magic number of a file descriptor -// remapping we must preserve for the child process. +// Like its predecessor in nsExceptionHandler.cpp, this is +// the magic number of a file descriptor remapping we must +// preserve for the child process. static const int kMagicAndroidSystemPropFd = 5; #endif @@ -286,6 +287,11 @@ GeckoChildProcessHost::GetUniqueID() void GeckoChildProcessHost::PrepareLaunch() { +#ifdef MOZ_CRASHREPORTER + if (CrashReporter::GetEnabled()) { + CrashReporter::OOPInit(); + } +#endif #ifdef XP_WIN if (mProcessType == GeckoProcessType_Plugin) { @@ -537,7 +543,7 @@ AddAppDirToCommandLine(std::vector& aCmdLine) nsString path; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(appDir->GetPath(path))); aCmdLine.AppendLooseValue(UTF8ToWide("-appdir")); - std::wstring wpath = path.get(); + std::wstring wpath(path.get()); aCmdLine.AppendLooseValue(wpath); #else nsAutoCString path; @@ -609,8 +615,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt // send the child the PID so that it can open a ProcessHandle back to us. // probably don't want to do this in the long run char pidstring[32]; - PR_snprintf(pidstring, sizeof(pidstring) - 1, - "%ld", base::Process::Current().pid()); + snprintf_literal(pidstring,"%d", base::Process::Current().pid()); const char* const childProcessType = XRE_ChildProcessTypeToString(mProcessType); @@ -748,6 +753,26 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt childArgv.push_back(pidstring); +#if defined(MOZ_CRASHREPORTER) +# if defined(OS_LINUX) || defined(OS_BSD) + int childCrashFd, childCrashRemapFd; + if (!CrashReporter::CreateNotificationPipeForChild( + &childCrashFd, &childCrashRemapFd)) + return false; + if (0 <= childCrashFd) { + mFileMap.push_back(std::pair(childCrashFd, childCrashRemapFd)); + // "true" == crash reporting enabled + childArgv.push_back("true"); + } + else { + // "false" == crash reporting disabled + childArgv.push_back("false"); + } +# elif defined(MOZ_WIDGET_COCOA) + childArgv.push_back(CrashReporter::GetChildNotificationPipe()); +# endif // OS_LINUX +#endif + #ifdef MOZ_WIDGET_COCOA // Add a mach port to the command line so the child can communicate its // 'task_t' back to the parent. @@ -946,6 +971,11 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt // Process id cmdLine.AppendLooseValue(UTF8ToWide(pidstring)); +#if defined(MOZ_CRASHREPORTER) + cmdLine.AppendLooseValue( + UTF8ToWide(CrashReporter::GetChildNotificationPipe())); +#endif + // Process type cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 8456b2d316..4aa13455a0 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -18,8 +18,7 @@ #include "nsDebug.h" #include "nsISupportsImpl.h" #include "nsContentUtils.h" - -#include "prprf.h" +#include "mozilla/Snprintf.h" // Undo the damage done by mozzconf.h #undef compress @@ -1697,9 +1696,8 @@ MessageChannel::ReportConnectionError(const char* aChannelName, Message* aMsg) c if (aMsg) { char reason[512]; - PR_snprintf(reason, sizeof(reason), - "(msgtype=0x%lX,name=%s) %s", - aMsg->type(), aMsg->name(), errorMsg); + snprintf_literal(reason,"(msgtype=0x%X,name=%s) %s", + aMsg->type(), aMsg->name(), errorMsg); PrintErrorMessage(mSide, aChannelName, reason); } else { @@ -1743,9 +1741,8 @@ MessageChannel::MaybeHandleError(Result code, const Message& aMsg, const char* c } char reason[512]; - PR_snprintf(reason, sizeof(reason), - "(msgtype=0x%lX,name=%s) %s", - aMsg.type(), aMsg.name(), errorMsg); + snprintf_literal(reason,"(msgtype=0x%X,name=%s) %s", + aMsg.type(), aMsg.name(), errorMsg); PrintErrorMessage(mSide, channelName, reason); diff --git a/js/src/asmjs/AsmJSLink.cpp b/js/src/asmjs/AsmJSLink.cpp index c8ed4dab03..2f0e1775d9 100644 --- a/js/src/asmjs/AsmJSLink.cpp +++ b/js/src/asmjs/AsmJSLink.cpp @@ -553,7 +553,6 @@ DynamicallyLinkModule(JSContext* cx, const CallArgs& args, AsmJSModule& module) return false; break; case AsmJSModule::Global::ArrayView: - case AsmJSModule::Global::SharedArrayView: case AsmJSModule::Global::ArrayViewCtor: if (!ValidateArrayView(cx, global, globalVal)) return false; diff --git a/js/src/asmjs/AsmJSModule.h b/js/src/asmjs/AsmJSModule.h index d5a8628951..5af0b094eb 100644 --- a/js/src/asmjs/AsmJSModule.h +++ b/js/src/asmjs/AsmJSModule.h @@ -100,7 +100,7 @@ class AsmJSModule class Global { public: - enum Which { Variable, FFI, ArrayView, ArrayViewCtor, SharedArrayView, MathBuiltinFunction, + enum Which { Variable, FFI, ArrayView, ArrayViewCtor, MathBuiltinFunction, AtomicsBuiltinFunction, Constant, SimdCtor, SimdOperation, ByteLength }; enum VarInitKind { InitConstant, InitImport }; enum ConstantKind { GlobalConstant, MathConstant }; @@ -189,17 +189,13 @@ class AsmJSModule // var i32 = new I32(buffer); // the second import has nothing to validate and thus has a null field. PropertyName* maybeViewName() const { - MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == SharedArrayView || pod.which_ == ArrayViewCtor); + MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == ArrayViewCtor); return name_; } Scalar::Type viewType() const { - MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == SharedArrayView || pod.which_ == ArrayViewCtor); + MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == ArrayViewCtor); return pod.u.viewType_; } - void makeViewShared() { - MOZ_ASSERT(pod.which_ == ArrayView); - pod.which_ = SharedArrayView; - } PropertyName* mathName() const { MOZ_ASSERT(pod.which_ == MathBuiltinFunction); return name_; @@ -910,20 +906,18 @@ class AsmJSModule g.pod.u.ffiIndex_ = *ffiIndex = pod.numFFIs_++; return globals_.append(g); } - bool addArrayView(Scalar::Type vt, PropertyName* maybeField, bool isSharedView) { + bool addArrayView(Scalar::Type vt, PropertyName* maybeField) { MOZ_ASSERT(!isFinished()); - MOZ_ASSERT(!pod.hasArrayView_ || (pod.isSharedView_ == isSharedView)); pod.hasArrayView_ = true; - pod.isSharedView_ = isSharedView; + pod.isSharedView_ = false; Global g(Global::ArrayView, maybeField); g.pod.u.viewType_ = vt; return globals_.append(g); } - bool addArrayViewCtor(Scalar::Type vt, PropertyName* field, bool isSharedView) { + bool addArrayViewCtor(Scalar::Type vt, PropertyName* field) { MOZ_ASSERT(!isFinished()); MOZ_ASSERT(field); - MOZ_ASSERT(!pod.isSharedView_ || isSharedView); - pod.isSharedView_ = isSharedView; + pod.isSharedView_ = false; Global g(Global::ArrayViewCtor, field); g.pod.u.viewType_ = vt; return globals_.append(g); @@ -978,19 +972,9 @@ class AsmJSModule Global& global(unsigned i) { return globals_[i]; } - bool isValidViewSharedness(bool shared) const { - if (pod.hasArrayView_) - return pod.isSharedView_ == shared; - return !pod.isSharedView_ || shared; - } void setViewsAreShared() { if (pod.hasArrayView_) pod.isSharedView_ = true; - for (size_t i=0 ; i < globals_.length() ; i++) { - Global& g = globals_[i]; - if (g.which() == Global::ArrayView) - g.makeViewShared(); - } } /*************************************************************************/ diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index a01e81d7a5..6046473491 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -1014,7 +1014,6 @@ class MOZ_STACK_CLASS ModuleValidator uint32_t ffiIndex_; struct { Scalar::Type viewType_; - bool isSharedView_; } viewInfo; AsmJSMathBuiltinFunction mathBuiltinFunc_; AsmJSAtomicsBuiltinFunction atomicsBuiltinFunc_; @@ -1072,14 +1071,6 @@ class MOZ_STACK_CLASS ModuleValidator MOZ_ASSERT(isAnyArrayView()); return u.viewInfo.viewType_; } - bool viewIsSharedView() const { - MOZ_ASSERT(isAnyArrayView()); - return u.viewInfo.isSharedView_; - } - void setViewIsSharedView() { - MOZ_ASSERT(isAnyArrayView()); - u.viewInfo.isSharedView_ = true; - } bool isMathFunction() const { return which_ == MathBuiltinFunction; } @@ -1402,18 +1393,16 @@ class MOZ_STACK_CLASS ModuleValidator global->u.varOrConst.type_ = Type::var(importType).which(); return globals_.putNew(varName, global); } - bool addArrayView(PropertyName* varName, Scalar::Type vt, PropertyName* maybeField, - bool isSharedView) + bool addArrayView(PropertyName* varName, Scalar::Type vt, PropertyName* maybeField) { if (!arrayViews_.append(ArrayView(varName, vt))) return false; Global* global = validationLifo_.new_(Global::ArrayView); if (!global) return false; - if (!module().addArrayView(vt, maybeField, isSharedView)) + if (!module().addArrayView(vt, maybeField)) return false; global->u.viewInfo.viewType_ = vt; - global->u.viewInfo.isSharedView_ = isSharedView; return globals_.putNew(varName, global); } bool addMathBuiltinFunction(PropertyName* varName, AsmJSMathBuiltinFunction func, @@ -1497,14 +1486,13 @@ class MOZ_STACK_CLASS ModuleValidator global->u.changeHeap.srcEnd_ = fn->pn_pos.end; return globals_.putNew(name, global); } - bool addArrayViewCtor(PropertyName* varName, Scalar::Type vt, PropertyName* fieldName, bool isSharedView) { + bool addArrayViewCtor(PropertyName* varName, Scalar::Type vt, PropertyName* fieldName) { Global* global = validationLifo_.new_(Global::ArrayViewCtor); if (!global) return false; - if (!module().addArrayViewCtor(vt, fieldName, isSharedView)) + if (!module().addArrayViewCtor(vt, fieldName)) return false; global->u.viewInfo.viewType_ = vt; - global->u.viewInfo.isSharedView_ = isSharedView; return globals_.putNew(varName, global); } bool addFFI(PropertyName* varName, PropertyName* field) { @@ -1612,6 +1600,10 @@ class MOZ_STACK_CLASS ModuleValidator return module().minHeapLength(); } + bool usesSharedMemory() const { + return atomicsPresent_; + } + // Error handling. bool hasAlreadyFailed() const { return !!errorString_; @@ -1740,14 +1732,8 @@ class MOZ_STACK_CLASS ModuleValidator } void startFunctionBodies() { - if (atomicsPresent_) { - for (GlobalMap::Range r = globals_.all() ; !r.empty() ; r.popFront()) { - Global* g = r.front().value(); - if (g->isAnyArrayView()) - g->setViewIsSharedView(); - } + if (atomicsPresent_) module().setViewsAreShared(); - } } }; @@ -2472,10 +2458,9 @@ CheckGlobalVariableInitImport(ModuleValidator& m, PropertyName* varName, ParseNo } static bool -IsArrayViewCtorName(ModuleValidator& m, PropertyName* name, Scalar::Type* type, bool* shared) +IsArrayViewCtorName(ModuleValidator& m, PropertyName* name, Scalar::Type* type) { JSAtomState& names = m.cx()->names(); - *shared = false; if (name == names.Int8Array) { *type = Scalar::Int8; } else if (name == names.Uint8Array) { @@ -2526,7 +2511,6 @@ CheckNewArrayView(ModuleValidator& m, PropertyName* varName, ParseNode* newExpr) PropertyName* field; Scalar::Type type; - bool shared = false; if (ctorExpr->isKind(PNK_DOT)) { ParseNode* base = DotBase(ctorExpr); @@ -2534,7 +2518,7 @@ CheckNewArrayView(ModuleValidator& m, PropertyName* varName, ParseNode* newExpr) return m.failName(base, "expecting '%s.*Array", globalName); field = DotMember(ctorExpr); - if (!IsArrayViewCtorName(m, field, &type, &shared)) + if (!IsArrayViewCtorName(m, field, &type)) return m.fail(ctorExpr, "could not match typed array name"); } else { if (!ctorExpr->isKind(PNK_NAME)) @@ -2550,16 +2534,12 @@ CheckNewArrayView(ModuleValidator& m, PropertyName* varName, ParseNode* newExpr) field = nullptr; type = global->viewType(); - shared = global->viewIsSharedView(); } if (!CheckNewArrayViewArgs(m, ctorExpr, bufferName)) return false; - if (!m.module().isValidViewSharedness(shared)) - return m.failName(ctorExpr, "%s has different sharedness than previous view constructors", globalName); - - return m.addArrayView(varName, type, field, shared); + return m.addArrayView(varName, type, field); } static bool @@ -2695,12 +2675,8 @@ CheckGlobalDotImport(ModuleValidator& m, PropertyName* varName, ParseNode* initN return m.addByteLength(varName); Scalar::Type type; - bool shared = false; - if (IsArrayViewCtorName(m, field, &type, &shared)) { - if (!m.module().isValidViewSharedness(shared)) - return m.failName(initNode, "'%s' has different sharedness than previous view constructors", field); - return m.addArrayViewCtor(varName, type, field, shared); - } + if (IsArrayViewCtorName(m, field, &type)) + return m.addArrayViewCtor(varName, type, field); return m.failName(initNode, "'%s' is not a standard constant or typed array name", field); } @@ -6787,6 +6763,12 @@ CheckModule(ExclusiveContext* cx, AsmJSParser& parser, ParseNode* stmtList, m.startFunctionBodies(); +#if !defined(ENABLE_SHARED_ARRAY_BUFFER) + if (m.usesSharedMemory()) + return m.failOffset(m.parser().tokenStream.currentToken().pos.begin, + "shared memory and atomics not supported by this build"); +#endif + if (!CheckFunctions(m)) return false; @@ -6888,7 +6870,7 @@ Warn(AsmJSParser& parser, int errorNumber, const char* str) static bool EstablishPreconditions(ExclusiveContext* cx, AsmJSParser& parser) { -#ifdef JS_CODEGEN_NONE +#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by lack of a JIT compiler"); #endif @@ -6998,7 +6980,7 @@ js::IsAsmJSCompilationAvailable(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); // See EstablishPreconditions. -#ifdef JS_CODEGEN_NONE +#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64) bool available = false; #else bool available = cx->jitSupportsFloatingPoint() && diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index df476e9086..daa239ad0b 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -104,7 +104,8 @@ class FunctionCompiler curBlock_->initSlot(info().localSlot(i.index()), ins); if (!mirGen_.ensureBallast()) return false; - localTypes_.append(args[i.index()]); + if (!localTypes_.append(args[i.index()])) + return false; } for (unsigned i = 0; i < func_.numVarInits(); i++) { @@ -134,7 +135,8 @@ class FunctionCompiler curBlock_->initSlot(info().localSlot(firstVarSlot + i), ins); if (!mirGen_.ensureBallast()) return false; - localTypes_.append(v.type()); + if (!localTypes_.append(v.type())) + return false; } return true; diff --git a/js/src/jit-test/tests/asm.js/gating.js b/js/src/jit-test/tests/asm.js/gating.js new file mode 100644 index 0000000000..93ab6b9587 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/gating.js @@ -0,0 +1,33 @@ +// Check gating of shared memory features in asm.js (bug 1171540, +// bug 1231624). +// +// In asm.js, importing any atomic is a signal that shared memory is +// being used. If an atomic is imported, and if shared memory is +// disabled in the build or in the run then a type error should be +// signaled for the module at the end of the declaration section and +// the module should not be an asm.js module. + +if (!this.SharedArrayBuffer || !isAsmJSCompilationAvailable()) + quit(0); + +// This code is not run, we only care whether it compiles as asm.js. + +function module_a(stdlib, foreign, heap) { + "use asm"; + + var i32a = new stdlib.Int32Array(heap); + var ld = stdlib.Atomics.load; + + // There should be a type error around this line if shared memory + // is not enabled. + + function do_load() { + var v = 0; + v = ld(i32a, 0)|0; // It's not actually necessary to use the atomic op + return v|0; + } + + return { load: do_load }; +} + +assertEq(isAsmJSModule(module_a), !!this.SharedArrayBuffer); diff --git a/js/src/jit-test/tests/basic/bug984766.js b/js/src/jit-test/tests/basic/bug984766.js index c565688094..bd44fc31bc 100644 --- a/js/src/jit-test/tests/basic/bug984766.js +++ b/js/src/jit-test/tests/basic/bug984766.js @@ -6,6 +6,8 @@ for (var i = 0; i < 10; i++) { gcslice() } +if (!this.SharedArrayBuffer) + quit(0); for (var i = 0; i < 10; i++) { x = new SharedArrayBuffer(4) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 1eb12884b3..31ed8a2512 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -4118,7 +4118,10 @@ nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent, return NS_OK; nsresult rv = creator->CreateAnonymousContent(aContent); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + // CreateAnonymousContent failed, e.g. because the page has a loop. + return rv; + } uint32_t count = aContent.Length(); for (uint32_t i=0; i < count; i++) { @@ -5197,7 +5200,8 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, } if ((aTag != nsGkAtoms::svg && !parentIsSVG) || - (aTag == nsGkAtoms::desc || aTag == nsGkAtoms::title)) { + (aTag == nsGkAtoms::desc || aTag == nsGkAtoms::title || + aTag == nsGkAtoms::metadata)) { // Sections 5.1 and G.4 of SVG 1.1 say that SVG elements other than // svg:svg not contained within svg:svg are incorrect, although they // don't seem to specify error handling. Ignore them, since many of @@ -5208,7 +5212,7 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, // Style mutation can't change this situation, so don't bother // adding to the undisplayed content map. // - // We don't currently handle any UI for desc/title + // We don't currently handle any UI for desc/title/metadata return &sSuppressData; } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 35009ee620..c44881eef0 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -702,6 +702,9 @@ nsBlockFrame::GetMinISize(nsRenderingContext *aRenderingContext) curFrame->LazyMarkLinesDirty(); } + if (RenumberLists(PresContext())) { + AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); + } if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION) ResolveBidi(); InlineMinISizeData data; @@ -787,6 +790,9 @@ nsBlockFrame::GetPrefISize(nsRenderingContext *aRenderingContext) curFrame->LazyMarkLinesDirty(); } + if (RenumberLists(PresContext())) { + AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); + } if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION) ResolveBidi(); InlinePrefISizeData data; @@ -1588,9 +1594,9 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } else if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { nscoord contentBSize = blockEndEdgeOfChildren - borderPadding.BStart(wm); - nscoord autoBSize = aReflowState.ApplyMinMaxHeight(contentBSize); + nscoord autoBSize = aReflowState.ApplyMinMaxBSize(contentBSize); if (autoBSize != contentBSize) { - // Our min-height or max-height made our height change. Don't carry out + // Our min- or max-bsize value made our bsize change. Don't carry out // our kids' block-end margins. aMetrics.mCarriedOutBEndMargin.Zero(); } @@ -2034,6 +2040,8 @@ nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent, aOldParent->CollectFloats(aFirstFrame, list, aReparentSiblings); if (list.NotEmpty()) { for (nsIFrame* f : list) { + MOZ_ASSERT(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT), + "CollectFloats should've removed that bit"); ReparentFrame(f, aOldParent, this); } mFloats.AppendFrames(nullptr, list); @@ -4629,6 +4637,12 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState, CollectFloats(overBegin->mFirstChild, floats, true); if (floats.NotEmpty()) { +#ifdef DEBUG + for (nsIFrame* f : floats) { + MOZ_ASSERT(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT), + "CollectFloats should've removed that bit"); + } +#endif // Push the floats onto the front of the overflow out-of-flows list nsAutoOOFFrameList oofs(this); oofs.mList.InsertFrames(nullptr, nullptr, floats); @@ -4756,12 +4770,20 @@ nsBlockFrame::DrainSelfOverflowList() // No need to reparent frames in our own overflow lines/oofs, because they're // already ours. But we should put overflow floats back in mFloats. - nsAutoOOFFrameList oofs(this); - if (oofs.mList.NotEmpty()) { - // The overflow floats go after our regular floats. - mFloats.AppendFrames(nullptr, oofs.mList); + // (explicit scope to remove the OOF list before VerifyOverflowSituation) + { + nsAutoOOFFrameList oofs(this); + if (oofs.mList.NotEmpty()) { +#ifdef DEBUG + for (nsIFrame* f : oofs.mList) { + MOZ_ASSERT(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT), + "CollectFloats should've removed that bit"); + } +#endif + // The overflow floats go after our regular floats. + mFloats.AppendFrames(nullptr, oofs.mList); + } } - if (!ourOverflowLines->mLines.empty()) { mFrames.AppendFrames(nullptr, ourOverflowLines->mFrames); mLines.splice(mLines.end(), ourOverflowLines->mLines); @@ -5227,7 +5249,8 @@ nsBlockFrame::AddFrames(nsFrameList& aFrameList, nsIFrame* aPrevSibling) if (overflowLines) { prevSibLine = overflowLines->mLines.end(); prevSiblingIndex = -1; - found = nsLineBox::RFindLineContaining(aPrevSibling, lineList->begin(), + found = nsLineBox::RFindLineContaining(aPrevSibling, + overflowLines->mLines.begin(), prevSibLine, overflowLines->mFrames.LastChild(), &prevSiblingIndex); @@ -5238,7 +5261,7 @@ nsBlockFrame::AddFrames(nsFrameList& aFrameList, nsIFrame* aPrevSibling) } else { // Note: defensive code! RFindLineContaining must not return // false in this case, so if it does... - NS_NOTREACHED("prev sibling not in line list"); + MOZ_ASSERT_UNREACHABLE("prev sibling not in line list"); aPrevSibling = nullptr; prevSibLine = lineList->end(); } @@ -6296,8 +6319,10 @@ nsBlockFrame::ReflowPushedFloats(nsBlockReflowState& aState, // If there are continued floats, then we may need to continue BR clearance if (0 != aState.ClearFloats(0, NS_STYLE_CLEAR_BOTH)) { - aState.mFloatBreakType = static_cast(GetPrevInFlow()) - ->FindTrailingClear(); + nsBlockFrame* prevBlock = static_cast(GetPrevInFlow()); + if (prevBlock) { + aState.mFloatBreakType = prevBlock->FindTrailingClear(); + } } } @@ -7242,6 +7267,9 @@ nsBlockFrame::DoCollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsLayoutUtils::GetFloatFromPlaceholder(aFrame) : nullptr; while (outOfFlowFrame && outOfFlowFrame->GetParent() == this) { RemoveFloat(outOfFlowFrame); + // Remove the IS_PUSHED_FLOAT bit, in case |outOfFlowFrame| came from + // the PushedFloats list. + outOfFlowFrame->RemoveStateBits(NS_FRAME_IS_PUSHED_FLOAT); aList.AppendFrame(nullptr, outOfFlowFrame); outOfFlowFrame = outOfFlowFrame->GetNextInFlow(); // FIXME: By not pulling floats whose parent is one of our diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index c6ad74e50c..44aa2f02d1 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -250,10 +250,16 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace, printf(" margin => %d, clearance => %d\n", mBStartMargin.get(), aClearance); #endif - // Adjust the available block size if it's constrained so that the + // Adjust the available size if it's constrained so that the // child frame doesn't think it can reflow into its margin area. - if (NS_UNCONSTRAINEDSIZE != aFrameRS.AvailableBSize()) { - aFrameRS.AvailableBSize() -= mBStartMargin.get() + aClearance; + if (mWritingMode.IsOrthogonalTo(mFrame->GetWritingMode())) { + if (NS_UNCONSTRAINEDSIZE != aFrameRS.AvailableISize()) { + aFrameRS.AvailableISize() -= mBStartMargin.get() + aClearance; + } + } else { + if (NS_UNCONSTRAINEDSIZE != aFrameRS.AvailableBSize()) { + aFrameRS.AvailableBSize() -= mBStartMargin.get() + aClearance; + } } } else { // nsBlockFrame::ReflowBlock might call us multiple times with diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index e51066c043..de0a5c3f01 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -12,6 +12,7 @@ #include "nsGkAtoms.h" #include "nsIScrollableFrame.h" #include "nsSubDocumentFrame.h" +#include "nsCanvasFrame.h" #include "nsAbsoluteContainingBlock.h" #include "GeckoProfiler.h" #include "nsIMozBrowserFrame.h" @@ -91,6 +92,22 @@ ShouldInTopLayerForFullscreen(Element* aElement) } #endif // DEBUG +static void +BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame, + nsDisplayList* aList) +{ + nsRect dirty; + nsDisplayListBuilder::OutOfFlowDisplayData* + savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(aFrame); + if (savedOutOfFlowData) { + dirty = savedOutOfFlowData->mDirtyRect; + } + nsDisplayList list; + aFrame->BuildDisplayListForStackingContext(aBuilder, dirty, &list); + aList->AppendToTop(&list); +} + void ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList) @@ -123,16 +140,16 @@ ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder, continue; } MOZ_ASSERT(frame->GetParent() == this); + BuildDisplayListForTopLayerFrame(aBuilder, frame, aList); + } + } - nsRect dirty; - nsDisplayListBuilder::OutOfFlowDisplayData* - savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(frame); - if (savedOutOfFlowData) { - dirty = savedOutOfFlowData->mDirtyRect; + nsIPresShell* shell = PresContext()->PresShell(); + if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) { + if (Element* container = canvasFrame->GetCustomContentContainer()) { + if (nsIFrame* frame = container->GetPrimaryFrame()) { + BuildDisplayListForTopLayerFrame(aBuilder, frame, aList); } - nsDisplayList list; - frame->BuildDisplayListForStackingContext(aBuilder, dirty, &list); - aList->AppendToTop(&list); } } } diff --git a/layout/reftests/list-item/bullet-intrinsic-isize-2-ref.html b/layout/reftests/list-item/bullet-intrinsic-isize-2-ref.html new file mode 100644 index 0000000000..b371dcbc67 --- /dev/null +++ b/layout/reftests/list-item/bullet-intrinsic-isize-2-ref.html @@ -0,0 +1,10 @@ + + + + + Bug 994418 + + + MMMCMXCIX. sometext + + diff --git a/layout/reftests/list-item/bullet-intrinsic-isize-2.html b/layout/reftests/list-item/bullet-intrinsic-isize-2.html new file mode 100644 index 0000000000..c59545dd29 --- /dev/null +++ b/layout/reftests/list-item/bullet-intrinsic-isize-2.html @@ -0,0 +1,17 @@ + + + + + Bug 994418 + + + +
sometext + + diff --git a/layout/reftests/list-item/reftest.list b/layout/reftests/list-item/reftest.list index 132e97b494..e74564420f 100644 --- a/layout/reftests/list-item/reftest.list +++ b/layout/reftests/list-item/reftest.list @@ -8,3 +8,4 @@ asserts(1) == ol-reversed-1b.html ol-reversed-1-ref.html # bug 478135 == bullet-space-1.html bullet-space-1-ref.html == bullet-space-2.html bullet-space-2-ref.html == bullet-intrinsic-isize-1.html bullet-intrinsic-isize-1-ref.html +== bullet-intrinsic-isize-2.html bullet-intrinsic-isize-2-ref.html diff --git a/layout/reftests/svg/clipPath-basic-07.svg b/layout/reftests/svg/clipPath-basic-07.svg new file mode 100644 index 0000000000..a4d3e4177c --- /dev/null +++ b/layout/reftests/svg/clipPath-basic-07.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index c77c57af4d..e9dbf06393 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -41,6 +41,7 @@ fuzzy-if(/^Windows\x20NT\x206\.[12]/.test(http.oscpu),1,5) fuzzy-if(azureQuartz, == clipPath-basic-04.svg pass.svg == clipPath-basic-05.svg pass.svg == clipPath-basic-06.svg pass.svg +== clipPath-basic-07.svg pass.svg == clipPath-winding-01.svg pass.svg == clip-surface-clone-01.svg clip-surface-clone-01-ref.svg == conditions-01.svg pass.svg diff --git a/layout/style/nsROCSSPrimitiveValue.h b/layout/style/nsROCSSPrimitiveValue.h index c1a0629816..ae99b84456 100644 --- a/layout/style/nsROCSSPrimitiveValue.h +++ b/layout/style/nsROCSSPrimitiveValue.h @@ -116,10 +116,11 @@ private: float mFloat; int32_t mInt32; uint32_t mUint32; - nsDOMCSSRGBColor* mColor; - nsDOMCSSRect* mRect; + // These can't be nsCOMPtr/nsRefPtr's because they are used inside a union. + nsDOMCSSRGBColor* MOZ_OWNING_REF mColor; + nsDOMCSSRect* MOZ_OWNING_REF mRect; char16_t* mString; - nsIURI* mURI; + nsIURI* MOZ_OWNING_REF mURI; nsCSSKeyword mKeyword; } mValue; }; diff --git a/layout/style/nsStyleCoord.h b/layout/style/nsStyleCoord.h index 8241fbe7c5..98afb3bf52 100644 --- a/layout/style/nsStyleCoord.h +++ b/layout/style/nsStyleCoord.h @@ -12,6 +12,7 @@ #include "nsStyleConsts.h" namespace mozilla { + class WritingMode; // Logical axis, edge and side constants for use in various places. @@ -29,7 +30,8 @@ enum LogicalSide { eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2 eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd // 0x3 }; -}; + +} // namespace mozilla enum nsStyleUnit : uint8_t { eStyleUnit_Null = 0, // (no value) value is not specified diff --git a/layout/style/ua.css b/layout/style/ua.css index 942add2e85..06ce0e9a21 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -420,12 +420,10 @@ div:-moz-native-anonymous.moz-accessiblecaret.none { everything else, not reacting to pointer events. */ div:-moz-native-anonymous.moz-custom-content-container { pointer-events: none; - + -moz-top-layer: top; position: fixed; top: 0; left: 0; width: 100%; height: 100%; - - z-index: 2147483648; } diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index a8e457f5b1..60733a197b 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -1067,8 +1067,12 @@ case "mouseup": case "mousedown": case "contextmenu": { - if (!this._ignoreMouseEvents) - this._autoScrollPopup.hidePopup(); + if (!this._ignoreMouseEvents) { + // Use a timeout to prevent the mousedown from opening the popup again. + // Ideally, we could use preventDefault here, but contenteditable + // and middlemouse paste don't interact well. See bug 1188536. + setTimeout(() => this._autoScrollPopup.hidePopup(), 0); + } this._ignoreMouseEvents = false; break; }