From f5154ea42031bcd5c0d55338d7eedd7e199126b5 Mon Sep 17 00:00:00 2001 From: Georgiana Chelu Date: Mon, 6 Jan 2014 10:03:09 -0500 Subject: [PATCH 01/33] Bug 856426 - Fix warning in /netwerk/sctp/src/user_environment.c. r=jesup --- netwerk/sctp/src/user_environment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/sctp/src/user_environment.c b/netwerk/sctp/src/user_environment.c index c32d889953c1..ee239be0f378 100755 --- a/netwerk/sctp/src/user_environment.c +++ b/netwerk/sctp/src/user_environment.c @@ -92,7 +92,7 @@ read_random_phony(void *buf, int count) /* Fill buf[] with random(9) output */ for (i = 0; i < count; i+= (int)sizeof(uint32_t)) { randval = random(); - size = MIN(count - i, sizeof(uint32_t)); + size = MIN(count - i, (int)sizeof(uint32_t)); memcpy(&((char *)buf)[i], &randval, (size_t)size); } From eadb0e55e423d3a472e750c0a135a436f99fcb30 Mon Sep 17 00:00:00 2001 From: masaya iseki Date: Mon, 6 Jan 2014 10:03:41 -0500 Subject: [PATCH 02/33] Bug 945596 - Define getJitCompilerOption to confirm jit-compiler-options. r=nbp, r=h4writer --- js/src/builtin/TestingFunctions.cpp | 28 ++++++++++++++++++++++++++ js/src/jit-test/tests/ion/bug909997.js | 3 +++ js/src/jsapi.cpp | 20 ++++++++++++++++++ js/src/jsapi.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index a529fa3ecbf5..8fea924b5e53 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1127,6 +1127,30 @@ SetJitCompilerOption(JSContext *cx, unsigned argc, jsval *vp) return true; } +static bool +GetJitCompilerOptions(JSContext *cx, unsigned argc, jsval *vp) +{ + RootedObject info(cx, JS_NewObject(cx, nullptr, nullptr, nullptr)); + if (!info) + return false; + + RootedValue value(cx); + +#define JIT_COMPILER_MATCH(key, string) \ + opt = JSJITCOMPILER_ ## key; \ + value.setInt32(JS_GetGlobalJitCompilerOption(cx, opt)); \ + if (!JS_SetProperty(cx, info, string, value)) \ + return false; + + JSJitCompilerOption opt = JSJITCOMPILER_NOT_AN_OPTION; + JIT_COMPILER_OPTIONS(JIT_COMPILER_MATCH); +#undef JIT_COMPILER_MATCH + + *vp = ObjectValue(*info); + + return true; +} + static bool SetIonCheckGraphCoherency(JSContext *cx, unsigned argc, jsval *vp) { @@ -1546,6 +1570,10 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { " Returns whether asm.js compilation is currently available or whether it is disabled\n" " (e.g., by the debugger)."), + JS_FN_HELP("getJitCompilerOptions", GetJitCompilerOptions, 0, 0, +"getCompilerOptions()", +"Return an object describing some of the JIT compiler options.\n"), + JS_FN_HELP("isAsmJSModule", IsAsmJSModule, 1, 0, "isAsmJSModule(fn)", " Returns whether the given value is a function containing \"use asm\" that has been\n" diff --git a/js/src/jit-test/tests/ion/bug909997.js b/js/src/jit-test/tests/ion/bug909997.js index 35dd1fea865b..f03cb9bd224e 100644 --- a/js/src/jit-test/tests/ion/bug909997.js +++ b/js/src/jit-test/tests/ion/bug909997.js @@ -21,6 +21,9 @@ var func = [method_A, method_B, method_C, method_D] for (var n = 0; n < 4; ++n) { setJitCompilerOption("baseline.enable", n & 1); setJitCompilerOption("ion.enable", n & 2 ? 1: 0); + var opt = getJitCompilerOptions(); + assertEq(opt["baseline.enable"], n & 1); + assertEq(opt["ion.enable"], n & 2 ? 1 : 0); for (var i = 0; i < 1001; ++i) func[n](); } \ No newline at end of file diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 8be17d4ca344..aadb0519ce22 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -6040,6 +6040,26 @@ JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t v #endif } +JS_PUBLIC_API(int) +JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt) +{ +#ifdef JS_ION + switch (opt) { + case JSJITCOMPILER_BASELINE_USECOUNT_TRIGGER: + return jit::js_JitOptions.baselineUsesBeforeCompile; + case JSJITCOMPILER_ION_USECOUNT_TRIGGER: + return jit::js_JitOptions.forcedDefaultIonUsesBeforeCompile; + case JSJITCOMPILER_ION_ENABLE: + return JS::ContextOptionsRef(cx).ion(); + case JSJITCOMPILER_BASELINE_ENABLE: + return JS::ContextOptionsRef(cx).baseline(); + default: + break; + } +#endif + return 0; +} + /************************************************************************/ #if !defined(STATIC_EXPORTABLE_JS_API) && !defined(STATIC_JS_API) && defined(XP_WIN) diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 0eaa4be04dbe..844bb3805838 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4557,6 +4557,8 @@ typedef enum JSJitCompilerOption { extern JS_PUBLIC_API(void) JS_SetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt, uint32_t value); +extern JS_PUBLIC_API(int) +JS_GetGlobalJitCompilerOption(JSContext *cx, JSJitCompilerOption opt); /* * Convert a uint32_t index into a jsid. From d7d0f83bb00b5a805efcee03733563ce6f59ca59 Mon Sep 17 00:00:00 2001 From: Kevin Simons Date: Mon, 6 Jan 2014 10:03:55 -0500 Subject: [PATCH 03/33] Bug 951686 - Set the SkBitmapDevice to opaque for BGRX surfaces. r=gwright --- gfx/2d/DrawTargetSkia.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 14c29cc8266e..5d4c62de46c3 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -751,7 +751,9 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface, bool DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat) { - SkAutoTUnref device(new SkDevice(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height)); + SkAutoTUnref device(new SkDevice(GfxFormatToSkiaConfig(aFormat), + aSize.width, aSize.height, + aFormat == FORMAT_B8G8R8X8)); SkBitmap bitmap = device->accessBitmap(true); if (!bitmap.allocPixels()) { From ee3c6259c8dcd2961aa328632fd8c17068a5c02e Mon Sep 17 00:00:00 2001 From: Anthony Jones Date: Mon, 6 Jan 2014 10:05:07 -0500 Subject: [PATCH 04/33] Bug 951463 - Rename ClampRect to ForceInside; r=botond --- gfx/2d/BaseRect.h | 12 ++++++------ gfx/layers/ipc/AsyncPanZoomController.cpp | 3 +-- layout/base/nsDisplayList.cpp | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/gfx/2d/BaseRect.h b/gfx/2d/BaseRect.h index 459892defeb3..08094a4fbda0 100644 --- a/gfx/2d/BaseRect.h +++ b/gfx/2d/BaseRect.h @@ -441,18 +441,18 @@ struct BaseRect { } /** - * Clamp aRect to this rectangle. This returns aRect after it is forced - * inside the bounds of this rectangle. It will attempt to retain the size - * but will shrink the dimensions that don't fit. + * Clamp this rectangle to be inside aRect. The function returns a copy of + * this rect after it is forced inside the bounds of aRect. It will attempt to + * retain the size but will shrink the dimensions that don't fit. */ - Sub ClampRect(const Sub& aRect) const + Sub ForceInside(const Sub& aRect) const { Sub rect(std::max(aRect.x, x), std::max(aRect.y, y), std::min(aRect.width, width), std::min(aRect.height, height)); - rect.x = std::min(rect.XMost(), XMost()) - rect.width; - rect.y = std::min(rect.YMost(), YMost()) - rect.height; + rect.x = std::min(rect.XMost(), aRect.XMost()) - rect.width; + rect.y = std::min(rect.YMost(), aRect.YMost()) - rect.height; return rect; } diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 789c4518a858..c5935e566026 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -1257,8 +1257,7 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort( scrollOffset.y = scrollableRect.y; } - CSSRect shiftedDisplayPort = displayPort + scrollOffset; - return scrollableRect.ClampRect(shiftedDisplayPort) - scrollOffset; + return displayPort.ForceInside(scrollableRect - scrollOffset); } void AsyncPanZoomController::ScheduleComposite() { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index cdddac27c088..57328ea7177f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -716,7 +716,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, ScreenIntRect screenBounds = ScreenIntRect::FromUnknownRect(mozilla::gfx::IntRect( bounds.x, bounds.y, bounds.width, bounds.height)); AdjustForScrollBars(screenBounds, scrollableFrame); - metrics.mCompositionBounds = screenBounds.ClampRect(metrics.mCompositionBounds); + metrics.mCompositionBounds = metrics.mCompositionBounds.ForceInside(screenBounds); useWidgetBounds = true; } } From 4f689105a18ef58af1c51d4b63bebabeb97b519c Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 6 Jan 2014 10:05:11 -0500 Subject: [PATCH 05/33] Fix the type passed to OpenNSPRFileDesc, no bug --HG-- extra : rebase_source : 68a47b23259d5eaf9171cb9b70adde7720a00727 --- dom/asmjscache/AsmJSCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/asmjscache/AsmJSCache.cpp b/dom/asmjscache/AsmJSCache.cpp index 7afd98a9e3d8..8f9e95cc0c2f 100644 --- a/dom/asmjscache/AsmJSCache.cpp +++ b/dom/asmjscache/AsmJSCache.cpp @@ -461,7 +461,7 @@ MainProcessRunnable::OpenFileOnIOThread() mGroup, mOrigin, path); NS_ENSURE_STATE(mQuotaObject); - int openFlags; + int32_t openFlags; if (mOpenMode == eOpenForRead) { rv = path->GetFileSize(&mFileSize); if (NS_FAILED(rv)) { From d05644b6b3b1a9610a6c3d87c23902552fc35f62 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Mon, 6 Jan 2014 10:06:04 -0500 Subject: [PATCH 06/33] Bug 784739 - Switch from NULL to nullptr in remaining directories; r=ehsan --HG-- extra : rebase_source : 1ff19b2c8fd0e77fa8e822f5007a9fa3a6b6d474 --- content/base/src/nsScriptLoader.cpp | 2 +- content/media/fmp4/wmf/MFTDecoder.cpp | 2 +- content/media/fmp4/wmf/WMFVideoDecoder.cpp | 2 +- dom/bluetooth/bluedroid/BluetoothSocket.cpp | 2 +- gfx/layers/Effects.h | 2 +- gfx/layers/composite/ImageHost.h | 8 ++++---- gfx/layers/d3d9/CompositorD3D9.cpp | 12 ++++++------ gfx/layers/d3d9/CompositorD3D9.h | 2 +- gfx/layers/d3d9/DeviceManagerD3D9.cpp | 2 +- gfx/layers/d3d9/TextureD3D9.cpp | 5 +++-- gfx/src/nsRegion.h | 2 +- gfx/thebes/gfxASurface.cpp | 2 +- js/src/builtin/SIMD.cpp | 8 ++++---- js/src/builtin/TypeRepresentation.cpp | 2 +- js/src/jit/AsmJS.cpp | 8 ++++---- js/src/jsapi.cpp | 2 +- js/src/jsproxy.cpp | 2 +- js/src/jsscript.cpp | 2 +- js/src/jswrapper.cpp | 2 +- js/src/vm/GlobalObject.cpp | 2 +- netwerk/dns/nsHostResolver.cpp | 4 ++-- widget/android/AndroidBridge.cpp | 14 +++++++------- widget/android/AndroidJNI.cpp | 2 +- widget/android/AndroidJavaWrappers.h | 12 ++++++------ widget/nsIWidget.h | 2 +- xpcom/base/nsMemoryReporterManager.cpp | 6 +++--- 26 files changed, 56 insertions(+), 55 deletions(-) diff --git a/content/base/src/nsScriptLoader.cpp b/content/base/src/nsScriptLoader.cpp index 5f342bd11d90..7f8792b08be0 100644 --- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -724,7 +724,7 @@ class NotifyOffThreadScriptLoadCompletedRunnable : public nsRunnable public: NotifyOffThreadScriptLoadCompletedRunnable(nsScriptLoadRequest* aRequest, nsScriptLoader* aLoader) - : mRequest(aRequest), mLoader(aLoader), mToken(NULL) + : mRequest(aRequest), mLoader(aLoader), mToken(nullptr) {} void SetToken(void* aToken) { diff --git a/content/media/fmp4/wmf/MFTDecoder.cpp b/content/media/fmp4/wmf/MFTDecoder.cpp index 65fe6224597a..7bdfa05a3f7b 100644 --- a/content/media/fmp4/wmf/MFTDecoder.cpp +++ b/content/media/fmp4/wmf/MFTDecoder.cpp @@ -36,7 +36,7 @@ MFTDecoder::Create(const GUID& aMFTClsID) // Create the IMFTransform to do the decoding. HRESULT hr; hr = CoCreateInstance(aMFTClsID, - NULL, + nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast(static_cast(byRef(mDecoder)))); diff --git a/content/media/fmp4/wmf/WMFVideoDecoder.cpp b/content/media/fmp4/wmf/WMFVideoDecoder.cpp index 74ff896fc61f..8fd284506113 100644 --- a/content/media/fmp4/wmf/WMFVideoDecoder.cpp +++ b/content/media/fmp4/wmf/WMFVideoDecoder.cpp @@ -245,7 +245,7 @@ WMFVideoDecoder::CreateBasicVideoFrame(IMFSample* aSample, hr = twoDBuffer->Lock2D(&data, &stride); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); } else { - hr = buffer->Lock(&data, NULL, NULL); + hr = buffer->Lock(&data, nullptr, nullptr); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); stride = mVideoStride; } diff --git a/dom/bluetooth/bluedroid/BluetoothSocket.cpp b/dom/bluetooth/bluedroid/BluetoothSocket.cpp index 8c45c49a94bd..6e38176be805 100644 --- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp +++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp @@ -426,7 +426,7 @@ DroidSocketImpl::ReadMsg(int aFd, void *aBuffer, size_t aLength) // Extract client fd from message header for (struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg); - cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { + cmsgptr != nullptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { if (cmsgptr->cmsg_level != SOL_SOCKET) { continue; } diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index 5199059f7432..7622e9d45b7b 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -189,7 +189,7 @@ struct EffectSolidColor : public Effect struct EffectChain { - EffectChain() : mLayerRef(NULL) {} + EffectChain() : mLayerRef(nullptr) {} explicit EffectChain(void* aLayerRef) : mLayerRef(aLayerRef) {} RefPtr mPrimaryEffect; diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index 7855ea7c81d4..13f788fd6586 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -6,7 +6,7 @@ #ifndef MOZILLA_GFX_IMAGEHOST_H #define MOZILLA_GFX_IMAGEHOST_H -#include // for FILE, NULL +#include // for FILE #include "CompositableHost.h" // for CompositableHost #include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/RefPtr.h" // for RefPtr @@ -70,9 +70,9 @@ public: virtual void PrintInfo(nsACString& aTo, const char* aPrefix); #ifdef MOZ_DUMP_PAINTING - virtual void Dump(FILE* aFile=NULL, - const char* aPrefix="", - bool aDumpHtml=false) MOZ_OVERRIDE; + virtual void Dump(FILE* aFile = nullptr, + const char* aPrefix = "", + bool aDumpHtml = false) MOZ_OVERRIDE; virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; #endif diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index ff05565f2e72..c287dfa781ca 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -98,7 +98,7 @@ CompositorD3D9::CreateRenderTarget(const gfx::IntRect &aRect, HRESULT hr = device()->CreateTexture(aRect.width, aRect.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, byRef(texture), - NULL); + nullptr); if (FAILED(hr)) { ReportFailure(NS_LITERAL_CSTRING("CompositorD3D9::CreateRenderTarget: Failed to create texture"), hr); @@ -124,7 +124,7 @@ CompositorD3D9::CreateRenderTargetFromSource(const gfx::IntRect &aRect, HRESULT hr = device()->CreateTexture(aRect.width, aRect.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, byRef(texture), - NULL); + nullptr); if (FAILED(hr)) { ReportFailure(NS_LITERAL_CSTRING("CompositorD3D9::CreateRenderTargetFromSource: Failed to create texture"), hr); @@ -409,7 +409,7 @@ CompositorD3D9::DrawQuad(const gfx::Rect &aRect, // Restore defaults d3d9Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); d3d9Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - d3d9Device->SetTexture(1, NULL); + d3d9Device->SetTexture(1, nullptr); } return; default: @@ -570,7 +570,7 @@ CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion, EnsureSize(); - device()->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 0, 0); + device()->Clear(0, nullptr, D3DCLEAR_TARGET, 0x00000000, 0, 0); device()->BeginScene(); if (aClipRectOut) { @@ -687,12 +687,12 @@ CompositorD3D9::PaintToTarget() device()->CreateOffscreenPlainSurface(desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, - getter_AddRefs(destSurf), NULL); + getter_AddRefs(destSurf), nullptr); device()->GetRenderTargetData(backBuff, destSurf); D3DLOCKED_RECT rect; - destSurf->LockRect(&rect, NULL, D3DLOCK_READONLY); + destSurf->LockRect(&rect, nullptr, D3DLOCK_READONLY); RefPtr sourceSurface = Factory::CreateWrappingDataSourceSurface((uint8_t*)rect.pBits, rect.Pitch, diff --git a/gfx/layers/d3d9/CompositorD3D9.h b/gfx/layers/d3d9/CompositorD3D9.h index 7b96fa561a3b..4cccb96edf61 100644 --- a/gfx/layers/d3d9/CompositorD3D9.h +++ b/gfx/layers/d3d9/CompositorD3D9.h @@ -159,7 +159,7 @@ private: nsIWidget *mWidget; /* - * Context target, NULL when drawing directly to our swap chain. + * Context target, nullptr when drawing directly to our swap chain. */ RefPtr mTarget; diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.cpp b/gfx/layers/d3d9/DeviceManagerD3D9.cpp index 46db2fd8591f..c482c27bdf50 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp +++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp @@ -155,7 +155,7 @@ SwapChainD3D9::Present(const nsIntRect &aRect) void SwapChainD3D9::Present() { - mSwapChain->Present(NULL, NULL, 0, 0, 0); + mSwapChain->Present(nullptr, nullptr, 0, 0, 0); } void diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 20398f30b8e8..a36982b539a2 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -184,7 +184,7 @@ TextureSourceD3D9::InitTextures(DeviceManagerD3D9* aDeviceManager, } tmpTexture->GetSurfaceLevel(0, byRef(aSurface)); - aSurface->LockRect(&aLockedRect, NULL, 0); + aSurface->LockRect(&aLockedRect, nullptr, 0); if (!aLockedRect.pBits) { NS_WARNING("Could not lock surface"); return nullptr; @@ -208,7 +208,8 @@ FinishTextures(DeviceManagerD3D9* aDeviceManager, aSurface->UnlockRect(); nsRefPtr dstSurface; aTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); - aDeviceManager->device()->UpdateSurface(aSurface, NULL, dstSurface, NULL); + aDeviceManager->device()->UpdateSurface(aSurface, nullptr, dstSurface, + nullptr); } TemporaryRef diff --git a/gfx/src/nsRegion.h b/gfx/src/nsRegion.h index 2b81c825a208..ebb82530c058 100644 --- a/gfx/src/nsRegion.h +++ b/gfx/src/nsRegion.h @@ -266,7 +266,7 @@ private: // pixman needs to distinguish between an empty region and a region // with one rect so that it can return a different number of rectangles. // Empty rect: data = empty_box - // 1 rect: data = NULL + // 1 rect: data = null // >1 rect: data = rects if (aRect.IsEmpty()) { pixman_region32_clear(&mImpl); diff --git a/gfx/thebes/gfxASurface.cpp b/gfx/thebes/gfxASurface.cpp index d3a51f41a36d..e6b58e1300c0 100644 --- a/gfx/thebes/gfxASurface.cpp +++ b/gfx/thebes/gfxASurface.cpp @@ -876,7 +876,7 @@ gfxASurface::WriteAsPNG_internal(FILE* aFile, bool aBinary) return; } - // base 64, result will be NULL terminated + // base 64, result will be null-terminated nsCString encodedImg; rv = Base64Encode(Substring(imgData, imgSize), encodedImg); moz_free(imgData); diff --git a/js/src/builtin/SIMD.cpp b/js/src/builtin/SIMD.cpp index 3bf7e4309282..2c06122c3b23 100644 --- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -78,7 +78,7 @@ struct Int32x4 { static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"}; \ CallArgs args = CallArgsFromVp(argc, vp); \ if(!args.thisv().isObject() || !IsTypedDatum(args.thisv().toObject())) { \ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \ + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \ X4Type::class_.name, laneNames[lane], \ InformalValueTypeName(args.thisv())); \ return false; \ @@ -86,7 +86,7 @@ struct Int32x4 { TypedDatum &datum = AsTypedDatum(args.thisv().toObject()); \ TypeRepresentation *typeRepr = datum.datumTypeRepresentation(); \ if (typeRepr->kind() != TypeRepresentation::X4 || typeRepr->asX4()->type() != Type32x4::type) { \ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \ + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \ X4Type::class_.name, laneNames[lane], \ InformalValueTypeName(args.thisv())); \ return false; \ @@ -109,7 +109,7 @@ struct Int32x4 { bool Type32x4##SignMask(JSContext *cx, unsigned argc, Value *vp) { \ CallArgs args = CallArgsFromVp(argc, vp); \ if(!args.thisv().isObject() || !IsTypedDatum(args.thisv().toObject())) { \ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \ + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \ X4Type::class_.name, "signMask", \ InformalValueTypeName(args.thisv())); \ return false; \ @@ -117,7 +117,7 @@ struct Int32x4 { TypedDatum &datum = AsTypedDatum(args.thisv().toObject()); \ TypeRepresentation *typeRepr = datum.datumTypeRepresentation(); \ if (typeRepr->kind() != TypeRepresentation::X4 || typeRepr->asX4()->type() != Type32x4::type) { \ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \ + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, \ X4Type::class_.name, "signMask", \ InformalValueTypeName(args.thisv())); \ return false; \ diff --git a/js/src/builtin/TypeRepresentation.cpp b/js/src/builtin/TypeRepresentation.cpp index 3f92f6ef8996..024e47cb66a9 100644 --- a/js/src/builtin/TypeRepresentation.cpp +++ b/js/src/builtin/TypeRepresentation.cpp @@ -781,7 +781,7 @@ SizedArrayTypeRepresentation::appendStringSizedArray(JSContext *cx, StringBuffer contents.append(".array("); SizedArrayTypeRepresentation *arrayType = this; - while (arrayType != NULL) { + while (arrayType != nullptr) { if (!NumberValueToStringBuffer(cx, NumberValue(length()), contents)) return false; diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 417ee939e306..18919df8853a 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -2078,7 +2078,7 @@ class FunctionCompiler MDefinition *constantFloat(float f) { if (!curBlock_) - return NULL; + return nullptr; MConstant *constant = MConstant::NewAsmJS(alloc(), DoubleValue(double(f)), MIRType_Float32); curBlock_->add(constant); @@ -3042,7 +3042,7 @@ static bool CheckGlobalVariableInitFloat32(ModuleCompiler &m, PropertyName *varName, ParseNode *initNode, bool isConst) { - ParseNode *arg = NULL; + ParseNode *arg = nullptr; if (!CheckFloat32Coercion(m, initNode, &arg, "call must be of the form fround(x)")) return false; @@ -3305,7 +3305,7 @@ CheckVariable(FunctionCompiler &f, ParseNode *var) return f.failName(var, "var '%s' needs explicit type declaration via an initial value", name); if (initNode->isKind(PNK_CALL)) { - ParseNode *coercedVar = NULL; + ParseNode *coercedVar = nullptr; if (!CheckFloat32Coercion(f.m(), initNode, &coercedVar, "caller in var initializer can only be fround")) return false; @@ -3986,7 +3986,7 @@ static bool CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDe static bool CheckFRoundArg(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type, const char* error) { - ParseNode *arg = NULL; + ParseNode *arg = nullptr; if (!CheckFloat32Coercion(f.m(), expr, &arg, error)) return false; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index aadb0519ce22..38a379fb8390 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2430,7 +2430,7 @@ JS_SetPrototype(JSContext *cx, JS::Handle obj, JS::Handle return false; if (!succeeded) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SETPROTOTYPEOF_FAIL); + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL); return false; } diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 502e83315d1a..1c5a2924efac 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -354,7 +354,7 @@ BaseProxyHandler::setPrototypeOf(JSContext *cx, HandleObject, HandleObject, bool // Disallow sets of protos on proxies with lazy protos, but no hook. // This keeps us away from the footgun of having the first proto set opt // you out of having dynamic protos altogether. - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SETPROTOTYPEOF_FAIL); + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL); return false; } diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 7332e286efaa..50700688f422 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -848,7 +848,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc /* see BytecodeEmitter::tellDebuggerAboutCompiledScript */ CallNewScriptHook(cx, script, fun); if (!fun) { - RootedGlobalObject global(cx, script->compileAndGo() ? &script->global() : NULL); + RootedGlobalObject global(cx, script->compileAndGo() ? &script->global() : nullptr); Debugger::onNewScript(cx, script, global); } } diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index 3a0db52e5784..7e7b4fb9ef65 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -665,7 +665,7 @@ bool SecurityWrapper::setPrototypeOf(JSContext *cx, HandleObject wrapper, HandleObject proto, bool *bp) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED); + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED); return false; } diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index ce678939f2f9..b62d678e410d 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -153,7 +153,7 @@ ProtoSetterImpl(JSContext *cx, CallArgs args) return false; if (!success) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SETPROTOTYPEOF_FAIL); + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL); return false; } diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index d5f5f5db9ac2..c26f83fe7437 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -1013,12 +1013,12 @@ public: dnsUUID.Assign(Substring(nsDependentCString(uuid), 1, NSID_LENGTH - 3)); // Create events for A and SRV resolvers - events[0] = CreateEvent(NULL, TRUE, FALSE, TEXT("FinishedA")); + events[0] = CreateEvent(nullptr, TRUE, FALSE, TEXT("FinishedA")); if (!events[0]) { goto library_cleanup; } - events[1] = CreateEvent(NULL, TRUE, FALSE, TEXT("FinishedSRV")); + events[1] = CreateEvent(nullptr, TRUE, FALSE, TEXT("FinishedSRV")); if (!events[1]) { goto aevent_cleanup; } diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index f202fbb4925b..8a32245fb914 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -164,7 +164,7 @@ AndroidBridge::Init(JNIEnv *jEnv) mJNIEnv = nullptr; mThread = -1; - mGLControllerObj = NULL; + mGLControllerObj = nullptr; mOpenedGraphicsLibraries = false; mHasNativeBitmapAccess = false; mHasNativeWindowAccess = false; @@ -269,11 +269,11 @@ extern "C" { __attribute__ ((visibility("default"))) JNIEnv * GetJNIForThread() { - JNIEnv *jEnv = NULL; + JNIEnv *jEnv = nullptr; JavaVM *jVm = mozilla::AndroidBridge::GetVM(); if (!jVm) { __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM"); - return NULL; + return nullptr; } jEnv = static_cast(PR_GetThreadPrivate(sJavaEnvThreadIndex)); @@ -283,10 +283,10 @@ extern "C" { int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2); if (status) { - status = jVm->AttachCurrentThread(&jEnv, NULL); + status = jVm->AttachCurrentThread(&jEnv, nullptr); if (status) { __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach"); - return NULL; + return nullptr; } PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv); @@ -304,7 +304,7 @@ void AutoGlobalWrappedJavaObject::Dispose() { } GetJNIForThread()->DeleteGlobalRef(wrapped_obj); - wrapped_obj = NULL; + wrapped_obj = nullptr; } AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() { @@ -694,7 +694,7 @@ AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj) void AndroidBridge::RegisterCompositor(JNIEnv *env) { - if (mGLControllerObj != NULL && !mGLControllerObj->isNull()) { + if (mGLControllerObj != nullptr && !mGLControllerObj->isNull()) { // we already have this set up, no need to do it again return; } diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index 77db5c20a7a2..cd58217aa93f 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -911,7 +911,7 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject return; } - NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL); + NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(nullptr); if (!oldRef || oldRef->isNull()) { MOZ_ASSERT(false, "Clearing a non-existent NPZC"); } else { diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index b07b9549151f..9db4ef99122d 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -67,10 +67,10 @@ private: class WrappedJavaObject { public: WrappedJavaObject() : - wrapped_obj(NULL) + wrapped_obj(nullptr) { } - WrappedJavaObject(jobject jobj) : wrapped_obj(NULL) { + WrappedJavaObject(jobject jobj) : wrapped_obj(nullptr) { Init(jobj); } @@ -79,7 +79,7 @@ public: } bool isNull() const { - return wrapped_obj == NULL; + return wrapped_obj == nullptr; } jobject wrappedObject() const { @@ -93,10 +93,10 @@ protected: class AutoGlobalWrappedJavaObject : protected WrappedJavaObject{ public: AutoGlobalWrappedJavaObject() : - wrapped_obj(NULL) + wrapped_obj(nullptr) { } - AutoGlobalWrappedJavaObject(jobject jobj, JNIEnv* env) : wrapped_obj(NULL) { + AutoGlobalWrappedJavaObject(jobject jobj, JNIEnv* env) : wrapped_obj(nullptr) { Init(jobj, env); } @@ -111,7 +111,7 @@ public: } bool isNull() const { - return wrapped_obj == NULL; + return wrapped_obj == nullptr; } jobject wrappedObject() const { diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 57f782f6b7a2..d402e43d369d 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -504,7 +504,7 @@ class nsIWidget : public nsISupports { /** * Create and initialize a widget. * - * All the arguments can be NULL in which case a top level window + * All the arguments can be null in which case a top level window * with size 0 is created. The event callback function has to be * provided only if the caller wants to deal with the events this * widget receives. The event callback is basically a preprocess diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 438667d79d45..59d333f9cafe 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -212,7 +212,7 @@ GetKinfoVmentrySelf(int64_t* prss, uint64_t* maxreg) { int cnt; struct kinfo_vmentry *vmmap, *kve; - if ((vmmap = kinfo_getvmmap(getpid(), &cnt)) == NULL) + if ((vmmap = kinfo_getvmmap(getpid(), &cnt)) == nullptr) return NS_ERROR_FAILURE; if (prss) @@ -238,7 +238,7 @@ static nsresult PrivateDistinguishedAmount(int64_t* aN) { int64_t priv; - nsresult rv = GetKinfoVmentrySelf(&priv, NULL); + nsresult rv = GetKinfoVmentrySelf(&priv, nullptr); NS_ENSURE_SUCCESS(rv, rv); *aN = priv * getpagesize(); return NS_OK; @@ -249,7 +249,7 @@ static nsresult VsizeMaxContiguousDistinguishedAmount(int64_t* aN) { uint64_t biggestRegion; - nsresult rv = GetKinfoVmentrySelf(NULL, &biggestRegion); + nsresult rv = GetKinfoVmentrySelf(nullptr, &biggestRegion); if (NS_SUCCEEDED(rv)) *aN = biggestRegion; From 7a614075df055eecddaefa3a87c217060cf17e14 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Mon, 6 Jan 2014 10:07:38 -0500 Subject: [PATCH 07/33] Bug 784739 - Switch from NULL to nullptr in js/src/devtools/vprof/ and tools/{jprof,trace-malloc}/; r=ehsan --HG-- extra : rebase_source : e44e854e1c946c89c38bbef73c53fe8a48510f65 --- js/src/devtools/vprof/vprof.cpp | 22 +++++++++++----------- tools/jprof/bfd.cpp | 18 +++++++++--------- tools/jprof/coff.cpp | 2 +- tools/jprof/leaky.cpp | 30 +++++++++++++++--------------- tools/jprof/stub/libmalloc.cpp | 20 ++++++++++---------- tools/trace-malloc/leaksoup.cpp | 4 ++-- 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/js/src/devtools/vprof/vprof.cpp b/js/src/devtools/vprof/vprof.cpp index 235ebf06145f..e208d04054ff 100644 --- a/js/src/devtools/vprof/vprof.cpp +++ b/js/src/devtools/vprof/vprof.cpp @@ -53,7 +53,7 @@ #define UNLOCK(lock) } #endif -static entry* entries = NULL; +static entry* entries = nullptr; static bool notInitialized = true; static long glock = LOCK_IS_FREE; @@ -82,7 +82,7 @@ static inline entry* reverse (entry* s) { entry_t e, n, p; - p = NULL; + p = nullptr; for (e = s; e; e = n) { n = e->next; e->next = p; @@ -158,7 +158,7 @@ static inline entry_t findEntry (char* file, int line) return e; } } - return NULL; + return nullptr; } // Initialize the location pointed to by 'id' to a new value profile entry @@ -174,14 +174,14 @@ int initValueProfile(void** id, char* file, int line, ...) notInitialized = false; } - if (e == NULL) { + if (e == nullptr) { e = findEntry (file, line); if (e) { *id = e; } } - if (e == NULL) { + if (e == nullptr) { va_list va; e = (entry_t) malloc (sizeof(entry)); e->lock = LOCK_IS_FREE; @@ -196,8 +196,8 @@ int initValueProfile(void** id, char* file, int line, ...) va_start (va, line); e->func = (void (__cdecl*)(void*)) va_arg (va, void*); va_end (va); - e->h = NULL; - e->genptr = NULL; + e->h = nullptr; + e->genptr = nullptr; VMPI_memset (&e->ivar, 0, sizeof(e->ivar)); VMPI_memset (&e->i64var, 0, sizeof(e->i64var)); VMPI_memset (&e->dvar, 0, sizeof(e->dvar)); @@ -247,14 +247,14 @@ int initHistProfile(void** id, char* file, int line, int nbins, ...) notInitialized = false; } - if (e == NULL) { + if (e == nullptr) { e = findEntry (file, line); if (e) { *id = e; } } - if (e == NULL) { + if (e == nullptr) { va_list va; hist_t h; int b, n, s; @@ -269,7 +269,7 @@ int initHistProfile(void** id, char* file, int line, int nbins, ...) e->count = 0; e->min = 0; e->max = 0; - e->func = NULL; + e->func = nullptr; e->h = h = (hist_t) malloc (sizeof(hist)); n = 1+MAX(nbins,0); h->nbins = n-1; @@ -288,7 +288,7 @@ int initHistProfile(void** id, char* file, int line, int nbins, ...) lb[b] = MAXINT64; va_end (va); - e->genptr = NULL; + e->genptr = nullptr; VMPI_memset (&e->ivar, 0, sizeof(e->ivar)); VMPI_memset (&e->i64var, 0, sizeof(e->i64var)); VMPI_memset (&e->dvar, 0, sizeof(e->dvar)); diff --git a/tools/jprof/bfd.cpp b/tools/jprof/bfd.cpp index 29940976c577..a890fd6d63dd 100644 --- a/tools/jprof/bfd.cpp +++ b/tools/jprof/bfd.cpp @@ -18,7 +18,7 @@ static bfd *try_debug_file(const char *filename, unsigned long crc32) { int fd = open(filename, O_RDONLY); if (fd < 0) - return NULL; + return nullptr; unsigned char buf[4*1024]; unsigned long crc = 0; @@ -34,12 +34,12 @@ static bfd *try_debug_file(const char *filename, unsigned long crc32) close(fd); if (crc != crc32) - return NULL; + return nullptr; - bfd *object = bfd_openr(filename, NULL); + bfd *object = bfd_openr(filename, nullptr); if (!bfd_check_format(object, bfd_object)) { bfd_close(object); - return NULL; + return nullptr; } return object; @@ -51,7 +51,7 @@ static bfd *find_debug_file(bfd *lib, const char *aFileName) asection *sect = bfd_get_section_by_name(lib, ".gnu_debuglink"); if (!sect) - return NULL; + return nullptr; bfd_size_type debuglinkSize = bfd_section_size (objfile->obfd, sect); @@ -125,7 +125,7 @@ Symbol ** leaky::ExtendSymbols(int num) void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) { int initialSymbols = usefulSymbols; - if (NULL == externalSymbols) { + if (nullptr == externalSymbols) { externalSymbols = (Symbol**) calloc(sizeof(Symbol*),10000); Symbol *new_array = new Symbol[10000]; for (int i = 0; i < 10000; i++) { @@ -149,8 +149,8 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) bfd_init (); } - bfd* lib = bfd_openr(aFileName, NULL); - if (NULL == lib) { + bfd* lib = bfd_openr(aFileName, nullptr); + if (nullptr == lib) { return; } if (!bfd_check_format(lib, bfd_object)) { @@ -199,7 +199,7 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) // if ((syminfo.type == 'T') || (syminfo.type == 't')) { const char* nm = bfd_asymbol_name(sym); if (nm && nm[0]) { - char* dnm = NULL; + char* dnm = nullptr; if (strncmp("__thunk", nm, 7)) { dnm = abi::__cxa_demangle(nm, 0, 0, 0); } diff --git a/tools/jprof/coff.cpp b/tools/jprof/coff.cpp index e20f3f5b2ba9..78aa26733db3 100644 --- a/tools/jprof/coff.cpp +++ b/tools/jprof/coff.cpp @@ -38,7 +38,7 @@ void leaky::readSymbols(const char *fileName) { LDFILE *ldptr; - ldptr = ldopen(fileName, NULL); + ldptr = ldopen(fileName, nullptr); if (!ldptr) { fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName); diff --git a/tools/jprof/leaky.cpp b/tools/jprof/leaky.cpp index f3244a69061c..37445ad94945 100644 --- a/tools/jprof/leaky.cpp +++ b/tools/jprof/leaky.cpp @@ -59,7 +59,7 @@ int main(int argc, char** argv) if (l->outputfd != stderr) { fclose(l->outputfd); - l->outputfd = NULL; + l->outputfd = nullptr; } } } @@ -115,8 +115,8 @@ htmlify(const char *in) leaky::leaky() { - applicationName = NULL; - progFile = NULL; + applicationName = nullptr; + progFile = nullptr; quiet = true; showAddress = false; @@ -135,7 +135,7 @@ leaky::leaky() lowestSymbolAddr = 0; highestSymbolAddr = 0; - loadMap = NULL; + loadMap = nullptr; collect_last = false; collect_start = -1; @@ -167,14 +167,14 @@ void leaky::usageError() } static struct option longopts[] = { - { "threads", 0, NULL, 't' }, - { "only-thread", 1, NULL, 'T' }, - { "last", 0, NULL, 'l' }, - { "start", 1, NULL, 'x' }, - { "end", 1, NULL, 'n' }, - { "cleo",0, NULL, 'c' }, - { "output-dir", 1, NULL, 'd' }, - { NULL, 0, NULL, 0 }, + { "threads", 0, nullptr, 't' }, + { "only-thread", 1, nullptr, 'T' }, + { "last", 0, nullptr, 'l' }, + { "start", 1, nullptr, 'x' }, + { "end", 1, nullptr, 'n' }, + { "cleo",0, nullptr, 'c' }, + { "output-dir", 1, nullptr, 'd' }, + { nullptr, 0, nullptr, 0 }, }; void leaky::initialize(int argc, char** argv) @@ -192,7 +192,7 @@ void leaky::initialize(int argc, char** argv) int longindex = 0; onlyThread = 0; - output_dir = NULL; + output_dir = nullptr; cleo = false; // XXX tons of cruft here left over from tracemalloc @@ -464,7 +464,7 @@ static int symbolOrder(void const* a, void const* b) void leaky::ReadSharedLibrarySymbols() { LoadMapEntry* lme = loadMap; - while (NULL != lme) { + while (nullptr != lme) { ReadSymbols(lme->name, lme->address); lme = lme->next; } @@ -526,7 +526,7 @@ Symbol* leaky::findSymbol(u_long addr) int idx = findSymbolIndex(addr); if(idx<0) { - return NULL; + return nullptr; } else { return externalSymbols[idx]; } diff --git a/tools/jprof/stub/libmalloc.cpp b/tools/jprof/stub/libmalloc.cpp index c68d65bf9eb8..5d4f519e6c96 100644 --- a/tools/jprof/stub/libmalloc.cpp +++ b/tools/jprof/stub/libmalloc.cpp @@ -171,7 +171,7 @@ static void DumpAddressMap() if (mfd >= 0) { malloc_map_entry mme; link_map* map = _r_debug.r_map; - while (NULL != map) { + while (nullptr != map) { if (map->l_name && *map->l_name) { mme.nameLen = strlen(map->l_name); mme.address = map->l_addr; @@ -439,9 +439,9 @@ static void startSignalCounter(unsigned long millisec) tvalue.it_value.tv_usec = (millisec%1000)*1000; if (realTime) { - setitimer(ITIMER_REAL, &tvalue, NULL); + setitimer(ITIMER_REAL, &tvalue, nullptr); } else { - setitimer(ITIMER_PROF, &tvalue, NULL); + setitimer(ITIMER_PROF, &tvalue, nullptr); } } @@ -456,7 +456,7 @@ static int setupRTCSignals(int hz, struct sigaction *sap) return 0; } - if (sigaction(SIGIO, sap, NULL) == -1) { + if (sigaction(SIGIO, sap, nullptr) == -1) { perror("JPROF_RTC setup: sigaction(SIGIO)"); return 0; } @@ -617,7 +617,7 @@ NS_EXPORT_(void) setupProfilingStuff(void) char *delay = strstr(tst,"JP_PERIOD="); if(delay) { - double tmp = strtod(delay+strlen("JP_PERIOD="), NULL); + double tmp = strtod(delay+strlen("JP_PERIOD="), nullptr); if (tmp>=1e-3) { timerMilliSec = static_cast(1000 * tmp); } else { @@ -708,7 +708,7 @@ NS_EXPORT_(void) setupProfilingStuff(void) // FIX! probably should block these against each other // Very unlikely. sigemptyset(&mset); - action.sa_handler = NULL; + action.sa_handler = nullptr; action.sa_sigaction = StackHook; action.sa_mask = mset; action.sa_flags = SA_RESTART | SA_SIGINFO; @@ -725,11 +725,11 @@ NS_EXPORT_(void) setupProfilingStuff(void) #endif { if (realTime) { - sigaction(SIGALRM, &action, NULL); + sigaction(SIGALRM, &action, nullptr); } } // enable PROF in all cases to simplify JP_DEFER/pause/restart - sigaction(SIGPROF, &action, NULL); + sigaction(SIGPROF, &action, nullptr); // make it so a SIGUSR1 will stop the profiling // Note: It currently does not close the logfile. @@ -740,14 +740,14 @@ NS_EXPORT_(void) setupProfilingStuff(void) stop_action.sa_handler = EndProfilingHook; stop_action.sa_mask = mset; stop_action.sa_flags = SA_RESTART; - sigaction(SIGUSR1, &stop_action, NULL); + sigaction(SIGUSR1, &stop_action, nullptr); // make it so a SIGUSR2 will clear the circular buffer stop_action.sa_handler = ClearProfilingHook; stop_action.sa_mask = mset; stop_action.sa_flags = SA_RESTART; - sigaction(SIGUSR2, &stop_action, NULL); + sigaction(SIGUSR2, &stop_action, nullptr); printf("Jprof: Initialized signal handler and set " "timer for %lu %s, %d s " diff --git a/tools/trace-malloc/leaksoup.cpp b/tools/trace-malloc/leaksoup.cpp index d42aeefef2d6..915c1dd9fd0b 100644 --- a/tools/trace-malloc/leaksoup.cpp +++ b/tools/trace-malloc/leaksoup.cpp @@ -102,7 +102,7 @@ int main(int argc, char **argv) return 1; } - NS_InitXPCOM2(NULL, NULL, NULL); + NS_InitXPCOM2(nullptr, nullptr, nullptr); ADLog log; if (!log.Read(argv[1])) { @@ -401,7 +401,7 @@ int main(int argc, char **argv) delete [] sorted_nodes; delete [] nodes; - NS_ShutdownXPCOM(NULL); + NS_ShutdownXPCOM(nullptr); return 0; } From 53392a793e2d7eb3d4816b38a06fbc6412a1e36f Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Mon, 6 Jan 2014 10:17:57 -0600 Subject: [PATCH 08/33] Bug 956402 - OdinMonkey: refactoring: add Float to NumLit (r=bbouvier) --HG-- extra : rebase_source : 7704ee36047dc19ab6a44cb3c820af5145116476 --- js/src/jit/AsmJS.cpp | 657 ++++++++++++++++++++----------------------- 1 file changed, 299 insertions(+), 358 deletions(-) diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index 18919df8853a..3e56d1b41362 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -495,7 +495,7 @@ class RetType Which which_; public: - RetType() {} + RetType() : which_(Which(-1)) {} RetType(Which w) : which_(w) {} RetType(AsmJSCoercion coercion) { switch (coercion) { @@ -592,7 +592,6 @@ class VarType case Float: return MIRType_Float32; } MOZ_ASSUME_UNREACHABLE("VarType can only be Int, Double or Float"); - return MIRType_None; } AsmJSCoercion toCoercion() const { switch(which_) { @@ -601,7 +600,6 @@ class VarType case Float: return AsmJS_FRound; } MOZ_ASSUME_UNREACHABLE("VarType can only be Int, Double or Float"); - return AsmJS_ToInt32; } static VarType FromMIRType(MIRType type) { JS_ASSERT(type == MIRType_Int32 || type == MIRType_Double || type == MIRType_Float32); @@ -609,8 +607,9 @@ class VarType case MIRType_Int32: return Int; case MIRType_Float32: return Float; case MIRType_Double: return Double; - default: MOZ_ASSUME_UNREACHABLE("FromMIRType MIR type not handled"); return Int; + default:; } + MOZ_ASSUME_UNREACHABLE("FromMIRType MIR type not handled"); } static VarType FromCheckedType(Type type) { JS_ASSERT(type.isInt() || type.isMaybeDouble() || type.isFloatish()); @@ -728,187 +727,6 @@ bool operator!=(const Signature &lhs, const Signature &rhs) return !(lhs == rhs); } -/*****************************************************************************/ -// Numeric literal utilities - -namespace { - -// Represents the type and value of an asm.js numeric literal. -// -// A literal is a double iff the literal contains an exponent or decimal point -// (even if the fractional part is 0). Otherwise, integers may be classified: -// fixnum: [0, 2^31) -// negative int: [-2^31, 0) -// big unsigned: [2^31, 2^32) -// out of range: otherwise -class NumLit -{ - public: - enum Which { - Fixnum = Type::Fixnum, - NegativeInt = Type::Signed, - BigUnsigned = Type::Unsigned, - Double = Type::Double, - OutOfRangeInt = -1 - }; - - private: - Which which_; - Value v_; - - public: - NumLit() {} - - NumLit(Which w, Value v) - : which_(w), v_(v) - {} - - Which which() const { - return which_; - } - - int32_t toInt32() const { - JS_ASSERT(which_ == Fixnum || which_ == NegativeInt || which_ == BigUnsigned); - return v_.toInt32(); - } - - double toDouble() const { - return v_.toDouble(); - } - - Type type() const { - JS_ASSERT(which_ != OutOfRangeInt); - return Type::Which(which_); - } - - Value value() const { - JS_ASSERT(which_ != OutOfRangeInt); - return v_; - } -}; - -} /* anonymous namespace */ - -// Note: '-' is never rolled into the number; numbers are always positive and -// negations must be applied manually. -static bool -IsNumericLiteral(ParseNode *pn) -{ - return pn->isKind(PNK_NUMBER) || - (pn->isKind(PNK_NEG) && UnaryKid(pn)->isKind(PNK_NUMBER)); -} - -static NumLit -ExtractNumericLiteral(ParseNode *pn) -{ - // The JS grammar treats -42 as -(42) (i.e., with separate grammar - // productions) for the unary - and literal 42). However, the asm.js spec - // recognizes -42 (modulo parens, so -(42) and -((42))) as a single literal - // so fold the two potential parse nodes into a single double value. - JS_ASSERT(IsNumericLiteral(pn)); - ParseNode *numberNode; - double d; - if (pn->isKind(PNK_NEG)) { - numberNode = UnaryKid(pn); - d = -NumberNodeValue(numberNode); - } else { - numberNode = pn; - d = NumberNodeValue(numberNode); - } - - // The asm.js spec syntactically distinguishes any literal containing a - // decimal point or the literal -0 as having double type. - if (NumberNodeHasFrac(numberNode) || IsNegativeZero(d)) - return NumLit(NumLit::Double, DoubleValue(d)); - - // The syntactic checks above rule out these double values. - JS_ASSERT(!IsNegativeZero(d)); - JS_ASSERT(!IsNaN(d)); - - // Although doubles can only *precisely* represent 53-bit integers, they - // can *imprecisely* represent integers much bigger than an int64_t. - // Furthermore, d may be inf or -inf. In both cases, casting to an int64_t - // is undefined, so test against the integer bounds using doubles. - if (d < double(INT32_MIN) || d > double(UINT32_MAX)) - return NumLit(NumLit::OutOfRangeInt, UndefinedValue()); - - // With the above syntactic and range limitations, d is definitely an - // integer in the range [INT32_MIN, UINT32_MAX] range. - int64_t i64 = int64_t(d); - if (i64 >= 0) { - if (i64 <= INT32_MAX) - return NumLit(NumLit::Fixnum, Int32Value(i64)); - JS_ASSERT(i64 <= UINT32_MAX); - return NumLit(NumLit::BigUnsigned, Int32Value(uint32_t(i64))); - } - JS_ASSERT(i64 >= INT32_MIN); - return NumLit(NumLit::NegativeInt, Int32Value(i64)); -} - -static bool -ExtractFRoundableLiteral(ParseNode *pn, double *value) -{ - if (!IsNumericLiteral(pn)) - return false; - - NumLit literal = ExtractNumericLiteral(pn); - switch (literal.which()) { - case NumLit::Double: - *value = literal.toDouble(); - return true; - case NumLit::Fixnum: - case NumLit::NegativeInt: - case NumLit::BigUnsigned: - literal = NumLit(NumLit::Double, DoubleValue(literal.toInt32())); - *value = literal.toDouble(); - return true; - case NumLit::OutOfRangeInt: - break; - } - return false; -} - -static inline bool -IsLiteralInt(ParseNode *pn, uint32_t *u32) -{ - if (!IsNumericLiteral(pn)) - return false; - - NumLit literal = ExtractNumericLiteral(pn); - switch (literal.which()) { - case NumLit::Fixnum: - case NumLit::BigUnsigned: - case NumLit::NegativeInt: - *u32 = uint32_t(literal.toInt32()); - return true; - case NumLit::Double: - case NumLit::OutOfRangeInt: - return false; - } - - MOZ_ASSUME_UNREACHABLE("Bad literal type"); -} - -static inline bool -IsBits32(ParseNode *pn, int32_t i) -{ - if (!IsNumericLiteral(pn)) - return false; - - NumLit literal = ExtractNumericLiteral(pn); - switch (literal.which()) { - case NumLit::Fixnum: - case NumLit::BigUnsigned: - case NumLit::NegativeInt: - return literal.toInt32() == i; - case NumLit::Double: - case NumLit::OutOfRangeInt: - return false; - } - - MOZ_ASSUME_UNREACHABLE("Bad literal type"); -} - /*****************************************************************************/ // Typed array utilities @@ -1846,6 +1664,232 @@ class MOZ_STACK_CLASS ModuleCompiler } /* anonymous namespace */ +/*****************************************************************************/ +// Numeric literal utilities + +namespace { + +// Represents the type and value of an asm.js numeric literal. +// +// A literal is a double iff the literal contains an exponent or decimal point +// (even if the fractional part is 0). Otherwise, integers may be classified: +// fixnum: [0, 2^31) +// negative int: [-2^31, 0) +// big unsigned: [2^31, 2^32) +// out of range: otherwise +// Lastly, a literal may be a float literal which is any double or integer +// literal coerced with Math.fround. +class NumLit +{ + public: + enum Which { + Fixnum = Type::Fixnum, + NegativeInt = Type::Signed, + BigUnsigned = Type::Unsigned, + Double = Type::Double, + Float = Type::Float, + OutOfRangeInt = -1 + }; + + private: + Which which_; + Value v_; + + public: + NumLit() {} + + NumLit(Which w, Value v) + : which_(w), v_(v) + {} + + Which which() const { + return which_; + } + + int32_t toInt32() const { + JS_ASSERT(which_ == Fixnum || which_ == NegativeInt || which_ == BigUnsigned); + return v_.toInt32(); + } + + double toDouble() const { + JS_ASSERT(which_ == Double); + return v_.toDouble(); + } + + float toFloat() const { + JS_ASSERT(which_ == Float); + return float(v_.toDouble()); + } + + Value value() const { + JS_ASSERT(which_ != OutOfRangeInt); + return v_; + } + + bool hasType() const { + return which_ != OutOfRangeInt; + } + + Type type() const { + JS_ASSERT(hasType()); + return Type::Which(which_); + } + + VarType varType() const { + JS_ASSERT(hasType()); + switch (which_) { + case NumLit::Fixnum: + case NumLit::NegativeInt: + case NumLit::BigUnsigned: + return VarType::Int; + case NumLit::Double: + return VarType::Double; + case NumLit::Float: + return VarType::Float; + case NumLit::OutOfRangeInt:; + } + MOZ_ASSUME_UNREACHABLE("Unexpected NumLit type"); + } +}; + +} /* anonymous namespace */ + +static bool +IsNumericNonFloatLiteral(ParseNode *pn) +{ + // Note: '-' is never rolled into the number; numbers are always positive + // and negations must be applied manually. + return pn->isKind(PNK_NUMBER) || + (pn->isKind(PNK_NEG) && UnaryKid(pn)->isKind(PNK_NUMBER)); +} + +static bool +IsFloatCoercion(ModuleCompiler &m, ParseNode *pn, ParseNode **coercedExpr) +{ + if (!pn->isKind(PNK_CALL)) + return false; + + ParseNode *callee = CallCallee(pn); + if (!callee->isKind(PNK_NAME)) + return false; + + const ModuleCompiler::Global *global = m.lookupGlobal(callee->name()); + if (!global || + global->which() != ModuleCompiler::Global::MathBuiltin || + global->mathBuiltin() != AsmJSMathBuiltin_fround) + { + return false; + } + + if (CallArgListLength(pn) != 1) + return false; + + if (coercedExpr) + *coercedExpr = CallArgList(pn); + + return true; +} + +static bool +IsNumericFloatLiteral(ModuleCompiler &m, ParseNode *pn) +{ + ParseNode *coercedExpr; + if (!IsFloatCoercion(m, pn, &coercedExpr)) + return false; + + return IsNumericNonFloatLiteral(coercedExpr); +} + +static bool +IsNumericLiteral(ModuleCompiler &m, ParseNode *pn) +{ + return IsNumericNonFloatLiteral(pn) || + IsNumericFloatLiteral(m, pn); +} + +// The JS grammar treats -42 as -(42) (i.e., with separate grammar +// productions) for the unary - and literal 42). However, the asm.js spec +// recognizes -42 (modulo parens, so -(42) and -((42))) as a single literal +// so fold the two potential parse nodes into a single double value. +static double +ExtractNumericNonFloatValue(ParseNode **pn) +{ + JS_ASSERT(IsNumericNonFloatLiteral(*pn)); + + if ((*pn)->isKind(PNK_NEG)) { + *pn = UnaryKid(*pn); + return -NumberNodeValue(*pn); + } + + return NumberNodeValue(*pn); +} + +static NumLit +ExtractNumericLiteral(ModuleCompiler &m, ParseNode *pn) +{ + JS_ASSERT(IsNumericLiteral(m, pn)); + + // Float literals are explicitly coerced and thus the coerced literal may be + // any valid (non-float) numeric literal. + if (pn->isKind(PNK_CALL)) { + pn = CallArgList(pn); + double d = ExtractNumericNonFloatValue(&pn); + return NumLit(NumLit::Float, DoubleValue(d)); + } + + double d = ExtractNumericNonFloatValue(&pn); + + // The asm.js spec syntactically distinguishes any literal containing a + // decimal point or the literal -0 as having double type. + if (NumberNodeHasFrac(pn) || IsNegativeZero(d)) + return NumLit(NumLit::Double, DoubleValue(d)); + + // The syntactic checks above rule out these double values. + JS_ASSERT(!IsNegativeZero(d)); + JS_ASSERT(!IsNaN(d)); + + // Although doubles can only *precisely* represent 53-bit integers, they + // can *imprecisely* represent integers much bigger than an int64_t. + // Furthermore, d may be inf or -inf. In both cases, casting to an int64_t + // is undefined, so test against the integer bounds using doubles. + if (d < double(INT32_MIN) || d > double(UINT32_MAX)) + return NumLit(NumLit::OutOfRangeInt, UndefinedValue()); + + // With the above syntactic and range limitations, d is definitely an + // integer in the range [INT32_MIN, UINT32_MAX] range. + int64_t i64 = int64_t(d); + if (i64 >= 0) { + if (i64 <= INT32_MAX) + return NumLit(NumLit::Fixnum, Int32Value(i64)); + JS_ASSERT(i64 <= UINT32_MAX); + return NumLit(NumLit::BigUnsigned, Int32Value(uint32_t(i64))); + } + JS_ASSERT(i64 >= INT32_MIN); + return NumLit(NumLit::NegativeInt, Int32Value(i64)); +} + +static inline bool +IsLiteralInt(ModuleCompiler &m, ParseNode *pn, uint32_t *u32) +{ + if (!IsNumericLiteral(m, pn)) + return false; + + NumLit literal = ExtractNumericLiteral(m, pn); + switch (literal.which()) { + case NumLit::Fixnum: + case NumLit::BigUnsigned: + case NumLit::NegativeInt: + *u32 = uint32_t(literal.toInt32()); + return true; + case NumLit::Double: + case NumLit::Float: + case NumLit::OutOfRangeInt: + return false; + } + + MOZ_ASSUME_UNREACHABLE("Bad literal type"); +} + /*****************************************************************************/ namespace { @@ -2065,22 +2109,11 @@ class FunctionCompiler /***************************** Code generation (after local scope setup) */ - MDefinition *constant(const Value &v) + MDefinition *constant(Value v, Type t) { if (!curBlock_) return nullptr; - JS_ASSERT(v.isNumber()); - MConstant *constant = MConstant::New(alloc(), v); - curBlock_->add(constant); - return constant; - } - - MDefinition *constantFloat(float f) - { - if (!curBlock_) - return nullptr; - - MConstant *constant = MConstant::NewAsmJS(alloc(), DoubleValue(double(f)), MIRType_Float32); + MConstant *constant = MConstant::NewAsmJS(alloc(), v, t.toMIRType()); curBlock_->add(constant); return constant; } @@ -2926,67 +2959,23 @@ static bool CheckGlobalVariableInitConstant(ModuleCompiler &m, PropertyName *varName, ParseNode *initNode, bool isConst) { - NumLit literal = ExtractNumericLiteral(initNode); - VarType type; - switch (literal.which()) { - case NumLit::Fixnum: - case NumLit::NegativeInt: - case NumLit::BigUnsigned: - type = VarType::Int; - break; - case NumLit::Double: - type = VarType::Double; - break; - case NumLit::OutOfRangeInt: + NumLit literal = ExtractNumericLiteral(m, initNode); + if (!literal.hasType()) return m.fail(initNode, "global initializer is out of representable integer range"); - } - return m.addGlobalVarInitConstant(varName, type, literal.value(), isConst); -} -static bool -CheckFloat32Coercion(ModuleCompiler &m, ParseNode *callNode, ParseNode **coercedExpr, - const char* errorMessage) -{ - JS_ASSERT(callNode->isKind(PNK_CALL)); - - ParseNode *callee = CallCallee(callNode); - if (!callee->isKind(PNK_NAME)) - return m.fail(callee, errorMessage); - - PropertyName *calleeName = callee->name(); - - const ModuleCompiler::Global *global = m.lookupGlobal(calleeName); - if (!global || global->which() != ModuleCompiler::Global::MathBuiltin || - global->mathBuiltin() != AsmJSMathBuiltin_fround) - { - return m.fail(callee, errorMessage); - } - - unsigned numArgs = CallArgListLength(callNode); - if (numArgs != 1) - return m.failf(callee, "fround passed %u arguments, expected one", numArgs); - - if (coercedExpr) - *coercedExpr = CallArgList(callNode); - return true; + return m.addGlobalVarInitConstant(varName, literal.varType(), literal.value(), isConst); } static bool CheckTypeAnnotation(ModuleCompiler &m, ParseNode *coercionNode, AsmJSCoercion *coercion, ParseNode **coercedExpr = nullptr) { - static const char *errorMessage = "in coercion expression, the expression must be of the form +x, fround(x) or x|0"; switch (coercionNode->getKind()) { case PNK_BITOR: { ParseNode *rhs = BinaryRight(coercionNode); - - if (!IsNumericLiteral(rhs)) + uint32_t i; + if (!IsLiteralInt(m, rhs, &i) || i != 0) return m.fail(rhs, "must use |0 for argument/return coercion"); - - NumLit rhsLiteral = ExtractNumericLiteral(rhs); - if (rhsLiteral.which() != NumLit::Fixnum || rhsLiteral.toInt32() != 0) - return m.fail(rhs, "must use |0 for argument/return coercion"); - *coercion = AsmJS_ToInt32; if (coercedExpr) *coercedExpr = BinaryLeft(coercionNode); @@ -3000,12 +2989,14 @@ CheckTypeAnnotation(ModuleCompiler &m, ParseNode *coercionNode, AsmJSCoercion *c } case PNK_CALL: { *coercion = AsmJS_FRound; - return CheckFloat32Coercion(m, coercionNode, coercedExpr, errorMessage); + if (!IsFloatCoercion(m, coercionNode, coercedExpr)) + return m.fail(coercionNode, "call must be to fround coercion"); + return true; } default:; } - return m.fail(coercionNode, errorMessage); + return m.fail(coercionNode, "must be of the form +x, fround(x) or x|0"); } static bool @@ -3038,24 +3029,6 @@ CheckGlobalVariableInitImport(ModuleCompiler &m, PropertyName *varName, ParseNod return CheckGlobalVariableImportExpr(m, varName, coercion, coercedExpr, isConst); } -static bool -CheckGlobalVariableInitFloat32(ModuleCompiler &m, PropertyName *varName, ParseNode *initNode, - bool isConst) -{ - ParseNode *arg = nullptr; - if (!CheckFloat32Coercion(m, initNode, &arg, "call must be of the form fround(x)")) - return false; - - if (IsNumericLiteral(arg)) { - double value; - if (!ExtractFRoundableLiteral(arg, &value)) - return m.fail(arg, "float global initializer needs to be a double literal"); - return m.addGlobalVarInitConstant(varName, VarType::Float, DoubleValue(value), isConst); - } - - return CheckGlobalVariableImportExpr(m, varName, AsmJSCoercion::AsmJS_FRound, arg, isConst); -} - static bool CheckNewArrayView(ModuleCompiler &m, PropertyName *varName, ParseNode *newExpr) { @@ -3152,15 +3125,12 @@ CheckModuleGlobal(ModuleCompiler &m, ParseNode *var, bool isConst) if (!initNode) return m.fail(var, "module import needs initializer"); - if (IsNumericLiteral(initNode)) + if (IsNumericLiteral(m, initNode)) return CheckGlobalVariableInitConstant(m, var->name(), initNode, isConst); - if (initNode->isKind(PNK_BITOR) || initNode->isKind(PNK_POS)) + if (initNode->isKind(PNK_BITOR) || initNode->isKind(PNK_POS) || initNode->isKind(PNK_CALL)) return CheckGlobalVariableInitImport(m, var->name(), initNode, isConst); - if (initNode->isKind(PNK_CALL)) - return CheckGlobalVariableInitFloat32(m, var->name(), initNode, isConst); - if (initNode->isKind(PNK_NEW)) return CheckNewArrayView(m, var->name(), initNode); @@ -3256,8 +3226,8 @@ CheckFinalReturn(FunctionCompiler &f, ParseNode *stmt, RetType *retType) { if (stmt && stmt->isKind(PNK_RETURN)) { if (ParseNode *coercionNode = UnaryKid(stmt)) { - if (IsNumericLiteral(coercionNode)) { - switch (ExtractNumericLiteral(coercionNode).which()) { + if (IsNumericLiteral(f.m(), coercionNode)) { + switch (ExtractNumericLiteral(f.m(), coercionNode).which()) { case NumLit::BigUnsigned: case NumLit::OutOfRangeInt: return f.fail(coercionNode, "returned literal is out of integer range"); @@ -3268,6 +3238,9 @@ CheckFinalReturn(FunctionCompiler &f, ParseNode *stmt, RetType *retType) case NumLit::Double: *retType = RetType::Double; break; + case NumLit::Float: + *retType = RetType::Float; + break; } return true; } @@ -3304,37 +3277,14 @@ CheckVariable(FunctionCompiler &f, ParseNode *var) if (!initNode) return f.failName(var, "var '%s' needs explicit type declaration via an initial value", name); - if (initNode->isKind(PNK_CALL)) { - ParseNode *coercedVar = nullptr; - if (!CheckFloat32Coercion(f.m(), initNode, &coercedVar, "caller in var initializer can only be fround")) - return false; - - double value; - if (!ExtractFRoundableLiteral(coercedVar, &value)) - return f.failName(coercedVar, "float initializer for '%s' needs to be a double literal", name); - - return f.addVariable(var, name, VarType::Float, DoubleValue(value)); - } - - if (!IsNumericLiteral(initNode)) + if (!IsNumericLiteral(f.m(), initNode)) return f.failName(initNode, "initializer for '%s' needs to be a numeric literal", name); - NumLit literal = ExtractNumericLiteral(initNode); - VarType type; - switch (literal.which()) { - case NumLit::Fixnum: - case NumLit::NegativeInt: - case NumLit::BigUnsigned: - type = VarType::Int; - break; - case NumLit::Double: - type = VarType::Double; - break; - case NumLit::OutOfRangeInt: + NumLit literal = ExtractNumericLiteral(f.m(), initNode); + if (!literal.hasType()) return f.failName(initNode, "initializer for '%s' is out of range", name); - } - return f.addVariable(var, name, type, literal.value()); + return f.addVariable(var, name, literal.varType(), literal.value()); } static bool @@ -3359,21 +3309,12 @@ CheckExpr(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type); static bool CheckNumericLiteral(FunctionCompiler &f, ParseNode *num, MDefinition **def, Type *type) { - JS_ASSERT(IsNumericLiteral(num)); - NumLit literal = ExtractNumericLiteral(num); - - switch (literal.which()) { - case NumLit::Fixnum: - case NumLit::NegativeInt: - case NumLit::BigUnsigned: - case NumLit::Double: - break; - case NumLit::OutOfRangeInt: + NumLit literal = ExtractNumericLiteral(f.m(), num); + if (!literal.hasType()) return f.fail(num, "numeric literal out of representable integer range"); - } *type = literal.type(); - *def = f.constant(literal.value()); + *def = f.constant(literal.value(), literal.type()); return true; } @@ -3391,7 +3332,7 @@ CheckVarRef(FunctionCompiler &f, ParseNode *varRef, MDefinition **def, Type *typ if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) { switch (global->which()) { case ModuleCompiler::Global::Constant: - *def = f.constant(DoubleValue(global->constant())); + *def = f.constant(DoubleValue(global->constant()), Type::Double); *type = Type::Double; break; case ModuleCompiler::Global::Variable: @@ -3414,7 +3355,7 @@ CheckVarRef(FunctionCompiler &f, ParseNode *varRef, MDefinition **def, Type *typ static inline bool IsLiteralOrConstInt(FunctionCompiler &f, ParseNode *pn, uint32_t *u32) { - if (IsLiteralInt(pn, u32)) + if (IsLiteralInt(f.m(), pn, u32)) return true; if (pn->getKind() != PNK_NAME) @@ -3422,8 +3363,10 @@ IsLiteralOrConstInt(FunctionCompiler &f, ParseNode *pn, uint32_t *u32) PropertyName *name = pn->name(); const ModuleCompiler::Global *global = f.lookupGlobal(name); - if (!global || global->which() != ModuleCompiler::Global::Variable || - !global->varIsLitConstant()) { + if (!global || + global->which() != ModuleCompiler::Global::Variable || + !global->varIsLitConstant()) + { return false; } @@ -3485,7 +3428,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *elem, ArrayBufferView::ViewType // will be rounded up to a larger alignment later. f.m().requireHeapLengthToBeAtLeast(uint32_t(pointer) + 1); *needsBoundsCheck = NO_BOUNDS_CHECK; - *def = f.constant(Int32Value(pointer)); + *def = f.constant(Int32Value(pointer), Type::Int); return true; } @@ -3500,7 +3443,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *elem, ArrayBufferView::ViewType ParseNode *pointerNode = BinaryLeft(indexExpr); uint32_t shift; - if (!IsLiteralInt(shiftNode, &shift)) + if (!IsLiteralInt(f.m(), shiftNode, &shift)) return f.failf(shiftNode, "shift amount must be constant"); unsigned requiredShift = TypedArrayShift(*viewType); @@ -3518,7 +3461,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *elem, ArrayBufferView::ViewType pointer &= mask; if (pointer < f.m().minHeapLength()) *needsBoundsCheck = NO_BOUNDS_CHECK; - *def = f.constant(Int32Value(pointer)); + *def = f.constant(Int32Value(pointer), Type::Int); return true; } @@ -3556,7 +3499,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *elem, ArrayBufferView::ViewType if (mask == -1) *def = pointerDef; else - *def = f.bitwise(pointerDef, f.constant(Int32Value(mask))); + *def = f.bitwise(pointerDef, f.constant(Int32Value(mask), Type::Int)); return true; } @@ -3922,7 +3865,7 @@ CheckFuncPtrCall(FunctionCompiler &f, ParseNode *callNode, RetType retType, MDef ParseNode *maskNode = BinaryRight(indexExpr); uint32_t mask; - if (!IsLiteralInt(maskNode, &mask) || mask == UINT32_MAX || !IsPowerOfTwo(mask + 1)) + if (!IsLiteralInt(f.m(), maskNode, &mask) || mask == UINT32_MAX || !IsPowerOfTwo(mask + 1)) return f.fail(maskNode, "function-pointer table index mask value must be a power of two"); MDefinition *indexDef; @@ -3984,25 +3927,11 @@ CheckFFICall(FunctionCompiler &f, ParseNode *callNode, unsigned ffiIndex, RetTyp static bool CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **def, Type *type); static bool -CheckFRoundArg(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type, const char* error) +CheckFRoundArg(FunctionCompiler &f, ParseNode *arg, MDefinition **def, Type *type) { - ParseNode *arg = nullptr; - if (!CheckFloat32Coercion(f.m(), expr, &arg, error)) - return false; - if (arg->isKind(PNK_CALL)) return CheckCall(f, arg, RetType::Float, def, type); - if (IsNumericLiteral(arg)) { - double value; - if (!ExtractFRoundableLiteral(arg, &value)) - return f.fail(arg, "call to fround with literal expects the literal to be a double"); - - *def = f.constantFloat(value); - *type = Type::Float; - return true; - } - MDefinition *inputDef; Type inputType; if (!CheckExpr(f, arg, &inputDef, &inputType)) @@ -4022,13 +3951,19 @@ CheckFRoundArg(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *ty } static bool -CheckFRound(FunctionCompiler &f, ParseNode *callNode, RetType retType, MDefinition **def, Type *type) +CheckMathFRound(FunctionCompiler &f, ParseNode *callNode, RetType retType, MDefinition **def, Type *type) { + ParseNode *argNode = nullptr; + if (!IsFloatCoercion(f.m(), callNode, &argNode)) + return f.fail(callNode, "invalid call to fround"); + MDefinition *operand; Type operandType; - if (!CheckFRoundArg(f, callNode, &operand, &operandType, "coercion to float should use fround")) + if (!CheckFRoundArg(f, argNode, &operand, &operandType)) return false; + JS_ASSERT(operandType == Type::Float); + switch (retType.which()) { case RetType::Double: *def = f.unary(operand); @@ -4076,7 +4011,7 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltin case AsmJSMathBuiltin_imul: return CheckMathIMul(f, callNode, retType, def, type); case AsmJSMathBuiltin_abs: return CheckMathAbs(f, callNode, retType, def, type); case AsmJSMathBuiltin_sqrt: return CheckMathSqrt(f, callNode, retType, def, type); - case AsmJSMathBuiltin_fround: return CheckFRound(f, callNode, retType, def, type); + case AsmJSMathBuiltin_fround: return CheckMathFRound(f, callNode, retType, def, type); case AsmJSMathBuiltin_sin: arity = 1; doubleCallee = AsmJSImm_SinD; floatCallee = AsmJSImm_SinF; break; case AsmJSMathBuiltin_cos: arity = 1; doubleCallee = AsmJSImm_CosD; floatCallee = AsmJSImm_CosF; break; case AsmJSMathBuiltin_tan: arity = 1; doubleCallee = AsmJSImm_TanD; floatCallee = AsmJSImm_TanF; break; @@ -4357,12 +4292,12 @@ CheckConditional(FunctionCompiler &f, ParseNode *ternary, MDefinition **def, Typ } static bool -IsValidIntMultiplyConstant(ParseNode *expr) +IsValidIntMultiplyConstant(ModuleCompiler &m, ParseNode *expr) { - if (!IsNumericLiteral(expr)) + if (!IsNumericLiteral(m, expr)) return false; - NumLit literal = ExtractNumericLiteral(expr); + NumLit literal = ExtractNumericLiteral(m, expr); switch (literal.which()) { case NumLit::Fixnum: case NumLit::NegativeInt: @@ -4371,6 +4306,7 @@ IsValidIntMultiplyConstant(ParseNode *expr) return false; case NumLit::BigUnsigned: case NumLit::Double: + case NumLit::Float: case NumLit::OutOfRangeInt: return false; } @@ -4396,7 +4332,7 @@ CheckMultiply(FunctionCompiler &f, ParseNode *star, MDefinition **def, Type *typ return false; if (lhsType.isInt() && rhsType.isInt()) { - if (!IsValidIntMultiplyConstant(lhs) && !IsValidIntMultiplyConstant(rhs)) + if (!IsValidIntMultiplyConstant(f.m(), lhs) && !IsValidIntMultiplyConstant(f.m(), rhs)) return f.fail(star, "one arg to int multiply must be a small (-2^20, 2^20) int literal"); *def = f.mul(lhsDef, rhsDef, MIRType_Int32, MMul::Integer); *type = Type::Intish; @@ -4594,7 +4530,8 @@ CheckBitwise(FunctionCompiler &f, ParseNode *bitwise, MDefinition **def, Type *t default: MOZ_ASSUME_UNREACHABLE("not a bitwise op"); } - if (!onlyOnRight && IsBits32(lhs, identityElement)) { + uint32_t i; + if (!onlyOnRight && IsLiteralInt(f.m(), lhs, &i) && i == uint32_t(identityElement)) { Type rhsType; if (!CheckExpr(f, rhs, def, &rhsType)) return false; @@ -4603,7 +4540,7 @@ CheckBitwise(FunctionCompiler &f, ParseNode *bitwise, MDefinition **def, Type *t return true; } - if (IsBits32(rhs, identityElement)) { + if (IsLiteralInt(f.m(), rhs, &i) && i == uint32_t(identityElement)) { if (bitwise->isKind(PNK_BITOR) && lhs->isKind(PNK_CALL)) return CheckCall(f, lhs, RetType::Signed, def, type); @@ -4646,13 +4583,16 @@ CheckBitwise(FunctionCompiler &f, ParseNode *bitwise, MDefinition **def, Type *t static bool CheckUncoercedCall(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type) { - static const char* callError = "all function calls must either be ignored (via " - "f(); or comma-expression), coerced to signed " - "(via f()|0), coerced to float (via fround(f()))" - " or coerced to double (via +f())"; - JS_ASSERT(expr->isKind(PNK_CALL)); - return CheckFRoundArg(f, expr, def, type, callError); + + ParseNode *arg; + if (!IsFloatCoercion(f.m(), expr, &arg)) { + return f.fail(expr, "all function calls must either be ignored (via f(); or " + "comma-expression), coerced to signed (via f()|0), coerced to float " + "(via fround(f())) or coerced to double (via +f())"); + } + + return CheckFRoundArg(f, arg, def, type); } static bool @@ -4663,7 +4603,7 @@ CheckExpr(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type) if (!f.mirGen().ensureBallast()) return false; - if (IsNumericLiteral(expr)) + if (IsNumericLiteral(f.m(), expr)) return CheckNumericLiteral(f, expr, def, type); switch (expr->getKind()) { @@ -4792,7 +4732,7 @@ CheckFor(FunctionCompiler &f, ParseNode *forStmt, const LabelVector *maybeLabels if (!condType.isInt()) return f.failf(maybeCond, "%s is not a subtype of int", condType.toChars()); } else { - condDef = f.constant(Int32Value(1)); + condDef = f.constant(Int32Value(1), Type::Int); } MBasicBlock *afterLoop; @@ -4930,10 +4870,10 @@ CheckIf(FunctionCompiler &f, ParseNode *ifStmt) static bool CheckCaseExpr(FunctionCompiler &f, ParseNode *caseExpr, int32_t *value) { - if (!IsNumericLiteral(caseExpr)) + if (!IsNumericLiteral(f.m(), caseExpr)) return f.fail(caseExpr, "switch case expression must be an integer literal"); - NumLit literal = ExtractNumericLiteral(caseExpr); + NumLit literal = ExtractNumericLiteral(f.m(), caseExpr); switch (literal.which()) { case NumLit::Fixnum: case NumLit::NegativeInt: @@ -4943,6 +4883,7 @@ CheckCaseExpr(FunctionCompiler &f, ParseNode *caseExpr, int32_t *value) case NumLit::BigUnsigned: return f.fail(caseExpr, "switch case expression out of integer range"); case NumLit::Double: + case NumLit::Float: return f.fail(caseExpr, "switch case expression must be an integer literal"); } @@ -5035,7 +4976,7 @@ CheckSwitch(FunctionCompiler &f, ParseNode *switchStmt) return false; for (; stmt && stmt->isKind(PNK_CASE); stmt = NextNode(stmt)) { - int32_t caseValue = ExtractNumericLiteral(CaseExpr(stmt)).toInt32(); + int32_t caseValue = ExtractNumericLiteral(f.m(), CaseExpr(stmt)).toInt32(); unsigned caseIndex = caseValue - low; if (cases[caseIndex]) @@ -5261,7 +5202,7 @@ CheckFunction(ModuleCompiler &m, LifoAlloc &lifo, MIRGenerator **mir, ModuleComp return false; Signature sig(Move(argTypes), retType); - ModuleCompiler::Func *func; + ModuleCompiler::Func *func = nullptr; if (!CheckFunctionSignature(m, fn, Move(sig), FunctionName(fn), &func)) return false; From 94b6e63c1b9ca3fdc5b5680859fb7e145bc6726e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 6 Jan 2014 08:59:58 -0800 Subject: [PATCH 09/33] Bug 953120 - IonMonkey: Don't use pushedAtCycle_ when using push/pop. r=jandem --- js/src/jit/shared/MoveEmitter-x86-shared.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/js/src/jit/shared/MoveEmitter-x86-shared.cpp b/js/src/jit/shared/MoveEmitter-x86-shared.cpp index a73c373027f0..d95b453bc3ba 100644 --- a/js/src/jit/shared/MoveEmitter-x86-shared.cpp +++ b/js/src/jit/shared/MoveEmitter-x86-shared.cpp @@ -256,9 +256,7 @@ MoveEmitterX86::breakCycle(const MoveOperand &to, MoveOp::Type type) case MoveOp::INT32: #endif case MoveOp::GENERAL: - JS_ASSERT(pushedAtCycle_ == -1); masm.Push(toOperand(to)); - pushedAtCycle_ = masm.framePushed(); break; default: MOZ_ASSUME_UNREACHABLE("Unexpected move type"); @@ -268,8 +266,6 @@ MoveEmitterX86::breakCycle(const MoveOperand &to, MoveOp::Type type) void MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type) { - JS_ASSERT(pushedAtCycle_ != -1); - // There is some pattern: // (A -> B) // (B -> A) @@ -278,6 +274,7 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type) // saved value of B, to A. switch (type) { case MoveOp::FLOAT32: + JS_ASSERT(pushedAtCycle_ != -1); JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= sizeof(float)); if (to.isMemory()) { masm.loadFloat32(cycleSlot(), ScratchFloatReg); @@ -287,6 +284,7 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type) } break; case MoveOp::DOUBLE: + JS_ASSERT(pushedAtCycle_ != -1); JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= sizeof(double)); if (to.isMemory()) { masm.loadDouble(cycleSlot(), ScratchFloatReg); @@ -297,6 +295,7 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type) break; #ifdef JS_CPU_X64 case MoveOp::INT32: + JS_ASSERT(pushedAtCycle_ != -1); JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= sizeof(int32_t)); // x64 can't pop to a 32-bit destination. if (to.isMemory()) { @@ -311,13 +310,8 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type) case MoveOp::INT32: #endif case MoveOp::GENERAL: - JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= sizeof(intptr_t)); - if (to.isMemory()) { - masm.Pop(toPopOperand(to)); - } else { - masm.Pop(to.reg()); - } - pushedAtCycle_ = -1; + JS_ASSERT(masm.framePushed() - pushedAtStart_ >= sizeof(intptr_t)); + masm.Pop(toPopOperand(to)); break; default: MOZ_ASSUME_UNREACHABLE("Unexpected move type"); From bb4ff66fb2e61e9404106b8d851a67c87addb14f Mon Sep 17 00:00:00 2001 From: Dan Minor Date: Thu, 2 Jan 2014 10:19:35 -0500 Subject: [PATCH 10/33] Bug 949538 - Add mach target for cpp unittests; r=gps --- testing/mach_commands.py | 40 ++++++++++++++++++++++++++++++++++++++ testing/runcppunittests.py | 7 ++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/testing/mach_commands.py b/testing/mach_commands.py index 8e585ff692a6..48144e278c43 100644 --- a/testing/mach_commands.py +++ b/testing/mach_commands.py @@ -42,6 +42,11 @@ MOCHITEST_CHUNK_BY_DIR = 4 MOCHITEST_TOTAL_CHUNKS = 5 TEST_SUITES = { + 'cppunittest': { + 'aliases': ('Cpp', 'cpp'), + 'mach_command': 'cppunittest', + 'kwargs': {'test_file': None}, + }, 'crashtest': { 'aliases': ('C', 'Rc', 'RC', 'rc'), 'mach_command': 'crashtest', @@ -164,3 +169,38 @@ class Test(MachCommandBase): print(UNKNOWN_TEST % what) return 1 + +@CommandProvider +class MachCommands(MachCommandBase): + @Command('cppunittest', category='testing', + description='Run cpp unit tests.') + @CommandArgument('test_files', nargs='*', metavar='N', + help='Test to run. Can be specified as one or more files or ' \ + 'directories, or omitted. If omitted, the entire test suite is ' \ + 'executed.') + + def run_cppunit_test(self, **params): + import runcppunittests as cppunittests + import logging + + if len(params['test_files']) == 0: + testdir = os.path.join(self.distdir, 'cppunittests') + progs = cppunittests.extract_unittests_from_args([testdir], None) + else: + progs = cppunittests.extract_unittests_from_args(params['test_files'], None) + + # See if we have crash symbols + symbols_path = os.path.join(self.distdir, 'crashreporter-symbols') + if not os.path.isdir(symbols_path): + symbols_path = None + + tester = cppunittests.CPPUnitTests() + try: + result = tester.run_tests(progs, self.bindir, symbols_path) + except Exception, e: + self.log(logging.ERROR, 'cppunittests', + {'exception': str(e)}, + 'Caught exception running cpp unit tests: {exception}') + result = False + + return 0 if result else 1 diff --git a/testing/runcppunittests.py b/testing/runcppunittests.py index 7c575e4c649b..593acd9af685 100644 --- a/testing/runcppunittests.py +++ b/testing/runcppunittests.py @@ -145,7 +145,9 @@ class CPPUnittestOptions(OptionParser): def extract_unittests_from_args(args, manifest_file): """Extract unittests from args, expanding directories as needed""" progs = [] - skipped_progs = set() + + # Known files commonly packaged with the cppunittests that are not tests + skipped_progs = set(['.mkdir.done', 'remotecppunittests.py', 'runcppunittests.py', 'runcppunittests.pyc']) if manifest_file: skipped_progs.add(os.path.basename(manifest_file)) @@ -162,8 +164,7 @@ def extract_unittests_from_args(args, manifest_file): elif p not in skipped_progs: progs.append(os.path.abspath(p)) - #filter out python files packaged with the unit tests - return filter(lambda x: not x.endswith('.py') and not x.endswith('.pyc'), progs) + return progs def main(): parser = CPPUnittestOptions() From 90f48f82d8ffbf2b5aac1db1decaee7b7e3cecd6 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 6 Jan 2014 12:25:56 -0500 Subject: [PATCH 11/33] Bug 952170 - Remove unnecessary static_cast. r=smaug --- dom/ipc/TabChild.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index ddfe6c2200f3..29328ef90e3e 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1776,7 +1776,7 @@ TabChild::UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus) return; } - Touch* touch = static_cast(aEvent.touches[0].get()); + Touch* touch = aEvent.touches[0]; mGestureDownPoint = LayoutDevicePoint(touch->mRefPoint.x, touch->mRefPoint.y); mActivePointerId = touch->mIdentifier; if (sClickHoldContextMenusEnabled) { From 9df47b77056f53b822d7b8600a35c428234d0356 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 6 Jan 2014 12:26:23 -0500 Subject: [PATCH 12/33] Bug 952170 - Add an explicit copy constructor for WidgetTouchEvent so the touches get copied properly. r=smaug --- widget/TouchEvents.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/widget/TouchEvents.h b/widget/TouchEvents.h index 40d484b1eff0..b912aaa06ea9 100644 --- a/widget/TouchEvents.h +++ b/widget/TouchEvents.h @@ -130,6 +130,16 @@ public: { } + WidgetTouchEvent(const WidgetTouchEvent& aOther) : + WidgetInputEvent(aOther.mFlags.mIsTrusted, aOther.message, aOther.widget, + NS_TOUCH_EVENT) + { + modifiers = aOther.modifiers; + time = aOther.time; + touches.AppendElements(aOther.touches); + MOZ_COUNT_CTOR(WidgetTouchEvent); + } + WidgetTouchEvent(bool aIsTrusted, WidgetTouchEvent* aEvent) : WidgetInputEvent(aIsTrusted, aEvent->message, aEvent->widget, NS_TOUCH_EVENT) From 7463789a9a9d78d66d331abfc183cbcdb213bd53 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 6 Jan 2014 12:40:03 -0500 Subject: [PATCH 13/33] Bug 956434 - Disable testArrayBufferSlice.js for unpredictable failures on ggc builds. --- js/src/jit-test/tests/basic/testArrayBufferSlice.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/src/jit-test/tests/basic/testArrayBufferSlice.js b/js/src/jit-test/tests/basic/testArrayBufferSlice.js index caff58f43ad4..fdd4b4dd1f25 100644 --- a/js/src/jit-test/tests/basic/testArrayBufferSlice.js +++ b/js/src/jit-test/tests/basic/testArrayBufferSlice.js @@ -1,3 +1,6 @@ +// Bug 956434 - Disable test due to unpredictable failures on ggc builds +quit(0); + function testSlice() { function test(subBuf, starts, size) { var byteLength = size; From 69a210f988ec7bb9b4b2b920925d8ef3ac214c00 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Mon, 6 Jan 2014 12:40:03 -0500 Subject: [PATCH 14/33] Bug 923468 - Safety patch for race condition. r=ekr --- media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c index 92aaf1d16cbc..99d2802afc3f 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_media_stream.c @@ -192,6 +192,8 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) { assert(index < attrct); + if (index >= attrct) + ABORT(R_INTERNAL); if(r=nr_ice_format_candidate_attribute(cand, attrs[index],NR_ICE_MAX_ATTRIBUTE_SIZE)) ABORT(r); From 92cec17caf9519980b936a2d859dd40afeb0a38b Mon Sep 17 00:00:00 2001 From: Steve Singer Date: Mon, 6 Jan 2014 12:40:03 -0500 Subject: [PATCH 15/33] Bug 950513 - Add jsscriptinlines to fix sparc64 link errors. r=luke --- js/src/jsworkers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/js/src/jsworkers.cpp b/js/src/jsworkers.cpp index c907cc7af18c..708fb7941837 100644 --- a/js/src/jsworkers.cpp +++ b/js/src/jsworkers.cpp @@ -21,6 +21,7 @@ #include "jscntxtinlines.h" #include "jscompartmentinlines.h" #include "jsobjinlines.h" +#include "jsscriptinlines.h" using namespace js; From 657b44ea6ac187e24801e96aa7def14fb96b8a5d Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Mon, 6 Jan 2014 11:54:22 -0600 Subject: [PATCH 16/33] Bug 945327 - Improve local ref management in AndroidBridge; r=blassey --- widget/android/AndroidBridge.cpp | 59 +++++++++++++++----------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index 8a32245fb914..15d51477f7db 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -320,6 +320,8 @@ getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen, { nsString empty = EmptyString(); for (jsize i = 0; i < aLen; i+=4) { + + AutoLocalJNIFrame jniFrame(aJNIEnv, 4); nsJNIString name( static_cast(aJNIEnv->GetObjectArrayElement(jArr, i)), aJNIEnv); nsJNIString isDefault( @@ -350,6 +352,7 @@ AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType, if (!env) return false; + AutoLocalJNIFrame jniFrame(env, 1); jobjectArray arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction); if (!arr) return false; @@ -362,8 +365,6 @@ AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType, getHandlersFromStringArray(env, arr, len, aHandlersArray, aDefaultApp, aAction, NS_ConvertUTF16toUTF8(aMimeType)); - - env->DeleteLocalRef(arr); return true; } @@ -379,6 +380,7 @@ AndroidBridge::GetHandlersForURL(const nsAString& aURL, if (!env) return false; + AutoLocalJNIFrame jniFrame(env, 1); jobjectArray arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction); if (!arr) return false; @@ -390,8 +392,6 @@ AndroidBridge::GetHandlersForURL(const nsAString& aURL, getHandlersFromStringArray(env, arr, len, aHandlersArray, aDefaultApp, aAction); - - env->DeleteLocalRef(arr); return true; } @@ -404,14 +404,13 @@ AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& if (!env) return; + AutoLocalJNIFrame jniFrame(env, 1); jstring jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt)); if (!jstrType) { return; } nsJNIString jniStr(jstrType, env); CopyUTF16toUTF8(jniStr.get(), aMimeType); - - env->DeleteLocalRef(jstrType); } void @@ -423,14 +422,13 @@ AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& if (!env) return; + AutoLocalJNIFrame jniFrame(env, 1); jstring jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType)); if (!jstrExt) { return; } nsJNIString jniStr(jstrExt, env); CopyUTF16toUTF8(jniStr.get(), aFileExt); - - env->DeleteLocalRef(jstrExt); } bool @@ -442,14 +440,13 @@ AndroidBridge::GetClipboardText(nsAString& aText) if (!env) return false; + AutoLocalJNIFrame jniFrame(env, 1); jstring result = Clipboard::GetClipboardTextWrapper(); if (!result) return false; nsJNIString jniStr(result, env); aText.Assign(jniStr); - - env->DeleteLocalRef(result); return true; } @@ -511,13 +508,13 @@ AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString if (!env) return; + AutoLocalJNIFrame jniFrame(env, 1); jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions); if (jstr == nullptr) { return; } aFilePath.Assign(nsJNIString(jstr, env)); - env->DeleteLocalRef(jstr); } void @@ -527,13 +524,13 @@ AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& if (!env) return; + AutoLocalJNIFrame jniFrame(env, 1); jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType); if (jstr == nullptr) { return; } aFilePath.Assign(nsJNIString(jstr, env)); - env->DeleteLocalRef(jstr); } void @@ -558,7 +555,7 @@ AndroidBridge::Vibrate(const nsTArray& aPattern) if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); // It's clear if this worth special-casing, but it creates less // java junk, so dodges the GC. @@ -609,7 +606,7 @@ AndroidBridge::GetSystemColors(AndroidSystemColors *aColors) if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jintArray arr = GeckoAppShell::GetSystemColoursWrapper(); if (!arr) @@ -647,7 +644,7 @@ AndroidBridge::GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSiz if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jbyteArray arr = GeckoAppShell::GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); @@ -720,12 +717,12 @@ AndroidBridge::CreateEGLSurfaceForCompositor() return nullptr; } + AutoLocalJNIFrame jniFrame(env, 1); jobject eglSurface = mGLControllerObj->CreateEGLSurfaceForCompositorWrapper(); if (!eglSurface) return nullptr; EGLSurface ret = reinterpret_cast(env->GetIntField(eglSurface, jEGLSurfacePointerField)); - env->DeleteLocalRef(eglSurface); return ret; } @@ -766,6 +763,7 @@ AndroidBridge::GetStaticStringField(const char *className, const char *fieldName return false; } + AutoLocalJNIFrame jniFrame(jEnv, 1); initInit(); getClassGlobalRef(className); jfieldID field = getStaticField(fieldName, "Ljava/lang/String;"); @@ -781,7 +779,6 @@ AndroidBridge::GetStaticStringField(const char *className, const char *fieldName return false; result.Assign(nsJNIString(jstr, jEnv)); - jEnv->DeleteLocalRef(jstr); return true; } @@ -987,7 +984,7 @@ AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_ if (!env) return false; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jintArray arr = GeckoAppShell::InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height); if (!arr) @@ -1015,7 +1012,7 @@ AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInf if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double and a boolean. @@ -1042,7 +1039,7 @@ AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet) if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage); if (!returnMessage) @@ -1072,7 +1069,7 @@ AndroidBridge::GetSegmentInfoForText(const nsAString& aText, if (!env) return NS_ERROR_FAILURE; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 2); jstring jText = NewJavaString(&jniFrame, aText); jobject obj = env->CallStaticObjectMethod(mAndroidSmsMessageClass, jCalculateLength, jText, JNI_FALSE); @@ -1151,7 +1148,7 @@ AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilte if (!QueueSmsRequest(aRequest, &requestId)) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 2); jobjectArray numbers = (jobjectArray)env->NewObjectArray(aFilter.numbers().Length(), @@ -1159,8 +1156,9 @@ AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilte NewJavaString(&jniFrame, EmptyString())); for (uint32_t i = 0; i < aFilter.numbers().Length(); ++i) { - env->SetObjectArrayElement(numbers, i, - NewJavaString(&jniFrame, aFilter.numbers()[i])); + jstring elem = NewJavaString(&jniFrame, aFilter.numbers()[i]); + env->SetObjectArrayElement(numbers, i, elem); + env->DeleteLocalRef(elem); } GeckoAppShell::CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(), @@ -1224,7 +1222,7 @@ AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInf if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double, two booleans, and an integer. @@ -1251,7 +1249,7 @@ AndroidBridge::LockBitmap(jobject bitmap) if (!env) return nullptr; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 0); int err; void *buf; @@ -1271,7 +1269,7 @@ AndroidBridge::UnlockBitmap(jobject bitmap) if (!env) return; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 0); int err; @@ -1652,7 +1650,7 @@ AndroidBridge::GetProxyForURI(const nsACString & aSpec, if (!env) return NS_ERROR_FAILURE; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec), NS_ConvertUTF8toUTF16(aScheme), NS_ConvertUTF8toUTF16(aHost), @@ -1704,7 +1702,7 @@ AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResul if (!env) return false; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jstring jstrThreadName = GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId); @@ -1724,7 +1722,7 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, if (!env) return false; - AutoLocalJNIFrame jniFrame(env); + AutoLocalJNIFrame jniFrame(env, 1); jstring jstrSampleName = GeckoJavaSampler::GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId); @@ -1733,7 +1731,6 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, nsJNIString jniStr(jstrSampleName, env); CopyUTF16toUTF8(jniStr.get(), aResult); - env->DeleteLocalRef(jstrSampleName); return true; } From e0b0ea92ee4d238f1d12c678d4239c9dd8695c5f Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Mon, 6 Jan 2014 19:02:28 +0100 Subject: [PATCH 17/33] Bug 956072 - Distinguish non-writable from non-data properties in type information. r=jandem --- js/src/jit/IonBuilder.cpp | 12 +++-- js/src/jit/MIR.cpp | 2 +- js/src/jsinfer.cpp | 104 ++++++++++++++++++++++++++++---------- js/src/jsinfer.h | 43 ++++++++++------ js/src/jsinferinlines.h | 57 +++++++++++++++------ js/src/jsobj.cpp | 24 +++++---- js/src/jsobjinlines.h | 8 +-- js/src/vm/OldDebugAPI.cpp | 2 +- js/src/vm/Shape.cpp | 4 +- 9 files changed, 176 insertions(+), 80 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 65a6dae3aab9..353af1061a3a 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6315,7 +6315,7 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc types::HeapTypeSetKey property = staticType->property(id); if (!property.maybeTypes() || !property.maybeTypes()->definiteProperty() || - property.configured(constraints())) + property.nonData(constraints())) { // The property has been reconfigured as non-configurable, non-enumerable // or non-writable. @@ -6404,7 +6404,8 @@ IonBuilder::setStaticName(JSObject *staticObject, PropertyName *name) types::HeapTypeSetKey property = staticType->property(id); if (!property.maybeTypes() || !property.maybeTypes()->definiteProperty() || - property.configured(constraints())) + property.nonData(constraints()) || + property.nonWritable(constraints())) { // The property has been reconfigured as non-configurable, non-enumerable // or non-writable. @@ -7854,7 +7855,7 @@ IonBuilder::getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name, *property = type->property(id); return property->maybeTypes() && property->maybeTypes()->definiteProperty() && - !property->configured(constraints()); + !property->nonData(constraints()); } bool @@ -7919,7 +7920,7 @@ IonBuilder::objectsHaveCommonPrototype(types::TemporaryTypeSet *types, PropertyN // property type sets later on. types::HeapTypeSetKey property = type->property(NameToId(name)); if (types::TypeSet *types = property.maybeTypes()) { - if (!types->empty() || types->configuredProperty()) + if (!types->empty() || types->nonDataProperty()) return false; } if (JSObject *obj = type->singleton()) { @@ -8915,6 +8916,9 @@ IonBuilder::setPropTryDefiniteSlot(bool *emitted, MDefinition *obj, if (!getDefiniteSlot(obj->resultTypeSet(), name, &property)) return true; + if (property.nonWritable(constraints())) + return true; + MStoreFixedSlot *fixed = MStoreFixedSlot::New(alloc(), obj, property.maybeTypes()->definiteSlot(), value); current->add(fixed); current->push(value); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index e14228bca56e..31b1d316c049 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -3140,7 +3140,7 @@ jit::PropertyReadIsIdempotent(types::CompilerConstraintList *constraints, // Check if the property has been reconfigured or is a getter. types::HeapTypeSetKey property = object->property(NameToId(name)); - if (property.configured(constraints)) + if (property.nonData(constraints)) return false; } } diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 48fb2e86083f..9988efdf4807 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -416,8 +416,11 @@ ConstraintTypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExist void TypeSet::print() { - if (flags & TYPE_FLAG_CONFIGURED_PROPERTY) - fprintf(stderr, " [configured]"); + if (flags & TYPE_FLAG_NON_DATA_PROPERTY) + fprintf(stderr, " [non-data]"); + + if (flags & TYPE_FLAG_NON_WRITABLE_PROPERTY) + fprintf(stderr, " [non-writable]"); if (definiteProperty()) fprintf(stderr, " [definite:%d]", definiteSlot()); @@ -1184,7 +1187,7 @@ HeapTypeSetKey::knownTypeTag(CompilerConstraintList *constraints) bool HeapTypeSetKey::isOwnProperty(CompilerConstraintList *constraints) { - if (maybeTypes() && (!maybeTypes()->empty() || maybeTypes()->configuredProperty())) + if (maybeTypes() && (!maybeTypes()->empty() || maybeTypes()->nonDataProperty())) return true; if (JSObject *obj = object()->singleton()) { if (CanHaveEmptyPropertyTypesForOwnProperty(obj)) @@ -1221,7 +1224,7 @@ HeapTypeSetKey::singleton(CompilerConstraintList *constraints) { HeapTypeSet *types = maybeTypes(); - if (!types || types->configuredProperty() || types->baseFlags() != 0 || types->getObjectCount() != 1) + if (!types || types->nonDataProperty() || types->baseFlags() != 0 || types->getObjectCount() != 1) return nullptr; JSObject *obj = types->getSingleObject(0); @@ -1505,24 +1508,32 @@ CheckNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun); namespace { -class ConstraintDataFreezeConfiguredProperty +class ConstraintDataFreezePropertyState { public: - ConstraintDataFreezeConfiguredProperty() + enum Which { + NON_DATA, + NON_WRITABLE + } which; + + ConstraintDataFreezePropertyState(Which which) + : which(which) {} - const char *kind() { return "freezeConfiguredProperty"; } + const char *kind() { return (which == NON_DATA) ? "freezeNonDataProperty" : "freezeNonWritableProperty"; } bool invalidateOnNewType(Type type) { return false; } bool invalidateOnNewPropertyState(TypeSet *property) { - return property->configuredProperty(); + return (which == NON_DATA) + ? property->nonDataProperty() + : property->nonWritableProperty(); } bool invalidateOnNewObjectState(TypeObject *object) { return false; } bool constraintHolds(JSContext *cx, const HeapTypeSetKey &property, TemporaryTypeSet *expected) { - return !property.maybeTypes()->configuredProperty(); + return !invalidateOnNewPropertyState(property.maybeTypes()); } bool shouldSweep() { return false; } @@ -1531,16 +1542,30 @@ class ConstraintDataFreezeConfiguredProperty } /* anonymous namespace */ bool -HeapTypeSetKey::configured(CompilerConstraintList *constraints) +HeapTypeSetKey::nonData(CompilerConstraintList *constraints) { - if (maybeTypes() && maybeTypes()->configuredProperty()) + if (maybeTypes() && maybeTypes()->nonDataProperty()) return true; LifoAlloc *alloc = constraints->alloc(); - typedef CompilerConstraintInstance T; + typedef CompilerConstraintInstance T; constraints->add(alloc->new_(alloc, *this, - ConstraintDataFreezeConfiguredProperty())); + ConstraintDataFreezePropertyState(ConstraintDataFreezePropertyState::NON_DATA))); + return false; +} + +bool +HeapTypeSetKey::nonWritable(CompilerConstraintList *constraints) +{ + if (maybeTypes() && maybeTypes()->nonWritableProperty()) + return true; + + LifoAlloc *alloc = constraints->alloc(); + + typedef CompilerConstraintInstance T; + constraints->add(alloc->new_(alloc, *this, + ConstraintDataFreezePropertyState(ConstraintDataFreezePropertyState::NON_WRITABLE))); return false; } @@ -2071,7 +2096,7 @@ PrototypeHasIndexedProperty(CompilerConstraintList *constraints, JSObject *obj) if (type->unknownProperties()) return true; HeapTypeSetKey index = type->property(JSID_VOID); - if (index.configured(constraints) || index.isOwnProperty(constraints)) + if (index.nonData(constraints) || index.isOwnProperty(constraints)) return true; if (!obj->hasTenuredProto()) return true; @@ -2739,10 +2764,10 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shap bool indexed) { if (!shape->writable()) - types->setConfiguredProperty(cx); + types->setNonWritableProperty(cx); if (shape->hasGetterValue() || shape->hasSetterValue()) { - types->setConfiguredProperty(cx); + types->setNonDataProperty(cx); if (!types->TypeSet::addType(Type::UnknownType(), &cx->typeLifoAlloc())) cx->compartment()->types.setPendingNukeTypes(cx); } else if (shape->hasDefaultGetter() && shape->hasSlot()) { @@ -2809,10 +2834,10 @@ TypeObject::addProperty(ExclusiveContext *cx, jsid id, Property **pprop) if (singleton()->watched()) { /* - * Mark the property as configured, to inhibit optimizations on it + * Mark the property as non-data, to inhibit optimizations on it * and avoid bypassing the watchpoint handler. */ - base->types.setConfiguredProperty(cx); + base->types.setNonDataProperty(cx); } } @@ -2928,7 +2953,7 @@ TypeObject::addPropertyType(ExclusiveContext *cx, const char *name, const Value } void -TypeObject::markPropertyConfigured(ExclusiveContext *cx, jsid id) +TypeObject::markPropertyNonData(ExclusiveContext *cx, jsid id) { AutoEnterAnalysis enter(cx); @@ -2936,15 +2961,36 @@ TypeObject::markPropertyConfigured(ExclusiveContext *cx, jsid id) HeapTypeSet *types = getProperty(cx, id); if (types) - types->setConfiguredProperty(cx); + types->setNonDataProperty(cx); +} + +void +TypeObject::markPropertyNonWritable(ExclusiveContext *cx, jsid id) +{ + AutoEnterAnalysis enter(cx); + + id = IdToTypeId(id); + + HeapTypeSet *types = getProperty(cx, id); + if (types) + types->setNonWritableProperty(cx); } bool -TypeObject::isPropertyConfigured(jsid id) +TypeObject::isPropertyNonData(jsid id) { TypeSet *types = maybeGetProperty(id); if (types) - return types->configuredProperty(); + return types->nonDataProperty(); + return false; +} + +bool +TypeObject::isPropertyNonWritable(jsid id) +{ + TypeSet *types = maybeGetProperty(id); + if (types) + return types->nonWritableProperty(); return false; } @@ -3022,7 +3068,7 @@ TypeObject::markUnknown(ExclusiveContext *cx) Property *prop = getProperty(i); if (prop) { prop->types.addType(cx, Type::UnknownType()); - prop->types.setConfiguredProperty(cx); + prop->types.setNonDataProperty(cx); } } } @@ -3086,7 +3132,7 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx) if (!prop) continue; if (prop->types.definiteProperty()) - prop->types.setConfiguredProperty(cx); + prop->types.setNonDataProperty(cx); } /* @@ -3248,11 +3294,13 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint /* * Clear out the newScript shape and definite property information from * an object if the source type set could be a setter or could be - * non-writable, both of which are indicated by the source type set - * being marked as configured. + * non-writable. */ - if (!(object->flags() & OBJECT_FLAG_ADDENDUM_CLEARED) && source->configuredProperty()) + if (!(object->flags() & OBJECT_FLAG_ADDENDUM_CLEARED) && + (source->nonDataProperty() || source->nonWritableProperty())) + { object->clearAddendum(cx); + } } void newType(JSContext *cx, TypeSet *source, Type type) {} @@ -3281,7 +3329,7 @@ types::AddClearDefiniteGetterSetterForPrototypeChain(JSContext *cx, TypeObject * if (!parentObject || parentObject->unknownProperties()) return false; HeapTypeSet *parentTypes = parentObject->getProperty(cx, id); - if (!parentTypes || parentTypes->configuredProperty()) + if (!parentTypes || parentTypes->nonDataProperty() || parentTypes->nonWritableProperty()) return false; parentTypes->add(cx, cx->typeLifoAlloc().new_(type)); parent = parent->getProto(); diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index bec7e8209524..6c30af3e1694 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -325,7 +325,7 @@ public: /* * For constraints attached to an object property's type set, mark the - * property as having been configured. + * property as having its configuration changed. */ virtual void newPropertyState(JSContext *cx, TypeSet *source) {} @@ -374,10 +374,13 @@ enum MOZ_ENUM_TYPE(uint32_t) { /* * Whether the property has ever been deleted or reconfigured to behave - * differently from a normal native property (e.g. made non-writable or - * given a scripted getter or setter). + * differently from a plain data property, other than making the property + * non-writable. */ - TYPE_FLAG_CONFIGURED_PROPERTY = 0x00010000, + TYPE_FLAG_NON_DATA_PROPERTY = 0x00004000, + + /* Whether the property has ever been made non-writable. */ + TYPE_FLAG_NON_WRITABLE_PROPERTY = 0x00008000, /* * Whether the property is definitely in a particular slot on all objects @@ -388,8 +391,8 @@ enum MOZ_ENUM_TYPE(uint32_t) { * If the property is definite, mask and shift storing the slot + 1. * Otherwise these bits are clear. */ - TYPE_FLAG_DEFINITE_MASK = 0xfffe0000, - TYPE_FLAG_DEFINITE_SHIFT = 17 + TYPE_FLAG_DEFINITE_MASK = 0xffff0000, + TYPE_FLAG_DEFINITE_SHIFT = 16 }; typedef uint32_t TypeFlags; @@ -514,8 +517,11 @@ class TypeSet return !!(baseFlags() & flags); } - bool configuredProperty() const { - return flags & TYPE_FLAG_CONFIGURED_PROPERTY; + bool nonDataProperty() const { + return flags & TYPE_FLAG_NON_DATA_PROPERTY; + } + bool nonWritableProperty() const { + return flags & TYPE_FLAG_NON_WRITABLE_PROPERTY; } bool definiteProperty() const { return flags & TYPE_FLAG_DEFINITE_MASK; } unsigned definiteSlot() const { @@ -547,9 +553,6 @@ class TypeSet /* The Class of an object in this set. */ inline const Class *getObjectClass(unsigned i) const; - void setConfiguredProperty() { - flags |= TYPE_FLAG_CONFIGURED_PROPERTY; - } bool canSetDefinite(unsigned slot) { // Note: the cast is required to work around an MSVC issue. return (slot + 1) <= (unsigned(TYPE_FLAG_DEFINITE_MASK) >> TYPE_FLAG_DEFINITE_SHIFT); @@ -613,9 +616,14 @@ class StackTypeSet : public ConstraintTypeSet class HeapTypeSet : public ConstraintTypeSet { + inline void newPropertyState(ExclusiveContext *cx); + public: - /* Mark this type set as representing a configured property. */ - inline void setConfiguredProperty(ExclusiveContext *cx); + /* Mark this type set as representing a non-data property. */ + inline void setNonDataProperty(ExclusiveContext *cx); + + /* Mark this type set as representing a non-writable property. */ + inline void setNonWritableProperty(ExclusiveContext *cx); }; class CompilerConstraintList; @@ -1123,14 +1131,16 @@ struct TypeObject : gc::BarrieredCell void addPropertyType(ExclusiveContext *cx, jsid id, const Value &value); void addPropertyType(ExclusiveContext *cx, const char *name, Type type); void addPropertyType(ExclusiveContext *cx, const char *name, const Value &value); - void markPropertyConfigured(ExclusiveContext *cx, jsid id); + void markPropertyNonData(ExclusiveContext *cx, jsid id); + void markPropertyNonWritable(ExclusiveContext *cx, jsid id); void markStateChange(ExclusiveContext *cx); void setFlags(ExclusiveContext *cx, TypeObjectFlags flags); void markUnknown(ExclusiveContext *cx); void clearAddendum(ExclusiveContext *cx); void clearNewScriptAddendum(ExclusiveContext *cx); void clearTypedObjectAddendum(ExclusiveContext *cx); - bool isPropertyConfigured(jsid id); + bool isPropertyNonData(jsid id); + bool isPropertyNonWritable(jsid id); void print(); @@ -1409,7 +1419,8 @@ class HeapTypeSetKey void freeze(CompilerConstraintList *constraints); JSValueType knownTypeTag(CompilerConstraintList *constraints); - bool configured(CompilerConstraintList *constraints); + bool nonData(CompilerConstraintList *constraints); + bool nonWritable(CompilerConstraintList *constraints); bool isOwnProperty(CompilerConstraintList *constraints); bool knownSubset(CompilerConstraintList *constraints, const HeapTypeSetKey &other); JSObject *singleton(CompilerConstraintList *constraints); diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 1f7b86613396..eb6094aa7fbc 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -486,24 +486,36 @@ MarkTypeObjectUnknownProperties(JSContext *cx, TypeObject *obj, } } -/* - * Mark any property which has been deleted or configured to be non-writable or - * have a getter/setter. - */ inline void -MarkTypePropertyConfigured(ExclusiveContext *cx, JSObject *obj, jsid id) +MarkTypePropertyNonData(ExclusiveContext *cx, JSObject *obj, jsid id) { if (cx->typeInferenceEnabled()) { id = IdToTypeId(id); if (TrackPropertyTypes(cx, obj, id)) - obj->type()->markPropertyConfigured(cx, id); + obj->type()->markPropertyNonData(cx, id); + } +} + +inline void +MarkTypePropertyNonWritable(ExclusiveContext *cx, JSObject *obj, jsid id) +{ + if (cx->typeInferenceEnabled()) { + id = IdToTypeId(id); + if (TrackPropertyTypes(cx, obj, id)) + obj->type()->markPropertyNonWritable(cx, id); } } inline bool -IsTypePropertyIdMarkedConfigured(JSObject *obj, jsid id) +IsTypePropertyIdMarkedNonData(JSObject *obj, jsid id) { - return obj->type()->isPropertyConfigured(id); + return obj->type()->isPropertyNonData(id); +} + +inline bool +IsTypePropertyIdMarkedNonWritable(JSObject *obj, jsid id) +{ + return obj->type()->isPropertyNonWritable(id); } /* Mark a state change on a particular object. */ @@ -1140,13 +1152,8 @@ ConstraintTypeSet::addType(ExclusiveContext *cxArg, Type type) } inline void -HeapTypeSet::setConfiguredProperty(ExclusiveContext *cxArg) +HeapTypeSet::newPropertyState(ExclusiveContext *cxArg) { - if (flags & TYPE_FLAG_CONFIGURED_PROPERTY) - return; - - flags |= TYPE_FLAG_CONFIGURED_PROPERTY; - /* Propagate the change to all constraints. */ if (JSContext *cx = cxArg->maybeJSContext()) { TypeConstraint *constraint = constraintList; @@ -1159,6 +1166,26 @@ HeapTypeSet::setConfiguredProperty(ExclusiveContext *cxArg) } } +inline void +HeapTypeSet::setNonDataProperty(ExclusiveContext *cx) +{ + if (flags & TYPE_FLAG_NON_DATA_PROPERTY) + return; + + flags |= TYPE_FLAG_NON_DATA_PROPERTY; + newPropertyState(cx); +} + +inline void +HeapTypeSet::setNonWritableProperty(ExclusiveContext *cx) +{ + if (flags & TYPE_FLAG_NON_WRITABLE_PROPERTY) + return; + + flags |= TYPE_FLAG_NON_WRITABLE_PROPERTY; + newPropertyState(cx); +} + inline unsigned TypeSet::getObjectCount() const { @@ -1302,7 +1329,7 @@ TypeObject::getProperty(ExclusiveContext *cx, jsid id) /* * Return an arbitrary property in the object, as all have unknown - * type and are treated as configured. + * type and are treated as non-data properties. */ unsigned count = getPropertyCount(); for (unsigned i = 0; i < count; i++) { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 7b97952889d3..db6d33dea954 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1134,8 +1134,8 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it) StackShape::AutoRooter rooter(cx, &child); child.attrs |= getSealedOrFrozenAttributes(child.attrs, it); - if (!JSID_IS_EMPTY(child.propid)) - MarkTypePropertyConfigured(cx, obj, child.propid); + if (!JSID_IS_EMPTY(child.propid) && it == FREEZE) + MarkTypePropertyNonWritable(cx, obj, child.propid); last = cx->compartment()->propertyTree.getChild(cx, last, obj->numFixedSlots(), child); if (!last) @@ -3427,14 +3427,20 @@ UpdateShapeTypeAndValue(typename ExecutionModeTraits::ExclusiveContextType obj->nativeSetSlotWithType(cx->asExclusiveContext(), shape, value); } } - if (!shape->hasSlot() || !shape->writable() || - !shape->hasDefaultGetter() || !shape->hasDefaultSetter()) - { + if (!shape->hasSlot() || !shape->hasDefaultGetter() || !shape->hasDefaultSetter()) { if (mode == ParallelExecution) { - if (!IsTypePropertyIdMarkedConfigured(obj, id)) + if (!IsTypePropertyIdMarkedNonData(obj, id)) return false; } else { - MarkTypePropertyConfigured(cx->asExclusiveContext(), obj, id); + MarkTypePropertyNonData(cx->asExclusiveContext(), obj, id); + } + } + if (!shape->writable()) { + if (mode == ParallelExecution) { + if (!IsTypePropertyIdMarkedNonWritable(obj, id)) + return false; + } else { + MarkTypePropertyNonWritable(cx->asExclusiveContext(), obj, id); } } return true; @@ -4886,7 +4892,7 @@ baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a if (!JSObject::changePropertyAttributes(cx, nobj, shape, *attrsp)) return false; if (*attrsp & JSPROP_READONLY) - MarkTypePropertyConfigured(cx, obj, id); + MarkTypePropertyNonWritable(cx, obj, id); return true; } else { return JSObject::setGenericAttributes(cx, nobj, id, attrsp); @@ -4980,7 +4986,7 @@ js::WatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id, JS::Hand if (!JSObject::sparsifyDenseElements(cx, obj)) return false; - types::MarkTypePropertyConfigured(cx, obj, id); + types::MarkTypePropertyNonData(cx, obj, id); } WatchpointMap *wpmap = cx->compartment()->watchpointMap; diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 0d5ef74e9997..53f72c3bcfa1 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -27,7 +27,7 @@ JSObject::setGenericAttributes(JSContext *cx, js::HandleObject obj, js::HandleId id, unsigned *attrsp) { - js::types::MarkTypePropertyConfigured(cx, obj, id); + js::types::MarkTypePropertyNonData(cx, obj, id); js::GenericAttributesOp op = obj->getOps()->setGenericAttributes; return (op ? op : js::baseops::SetAttributes)(cx, obj, id, attrsp); } @@ -45,7 +45,7 @@ JSObject::deleteProperty(JSContext *cx, js::HandleObject obj, js::HandleProperty bool *succeeded) { JS::RootedId id(cx, js::NameToId(name)); - js::types::MarkTypePropertyConfigured(cx, obj, id); + js::types::MarkTypePropertyNonData(cx, obj, id); js::DeletePropertyOp op = obj->getOps()->deleteProperty; return (op ? op : js::baseops::DeleteProperty)(cx, obj, name, succeeded); } @@ -56,7 +56,7 @@ JSObject::deleteElement(JSContext *cx, js::HandleObject obj, uint32_t index, boo JS::RootedId id(cx); if (!js::IndexToId(cx, index, &id)) return false; - js::types::MarkTypePropertyConfigured(cx, obj, id); + js::types::MarkTypePropertyNonData(cx, obj, id); js::DeleteElementOp op = obj->getOps()->deleteElement; return (op ? op : js::baseops::DeleteElement)(cx, obj, index, succeeded); } @@ -66,7 +66,7 @@ JSObject::deleteSpecial(JSContext *cx, js::HandleObject obj, js::HandleSpecialId bool *succeeded) { JS::RootedId id(cx, SPECIALID_TO_JSID(sid)); - js::types::MarkTypePropertyConfigured(cx, obj, id); + js::types::MarkTypePropertyNonData(cx, obj, id); js::DeleteSpecialOp op = obj->getOps()->deleteSpecial; return (op ? op : js::baseops::DeleteSpecial)(cx, obj, sid, succeeded); } diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index 5ef1236ba647..f806fe29b0d5 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -341,7 +341,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj_, jsid id_, if (!JSObject::sparsifyDenseElements(cx, obj)) return false; - types::MarkTypePropertyConfigured(cx, obj, propid); + types::MarkTypePropertyNonData(cx, obj, propid); WatchpointMap *wpmap = cx->compartment()->watchpointMap; if (!wpmap) { diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp index 0b313cffaebe..f1f5f718147f 100644 --- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -974,10 +974,10 @@ JSObject::changeProperty(typename ExecutionModeTraits::ExclusiveContextTyp !(attrs & JSPROP_SHARED)); if (mode == ParallelExecution) { - if (!types::IsTypePropertyIdMarkedConfigured(obj, shape->propid())) + if (!types::IsTypePropertyIdMarkedNonData(obj, shape->propid())) return nullptr; } else { - types::MarkTypePropertyConfigured(cx->asExclusiveContext(), obj, shape->propid()); + types::MarkTypePropertyNonData(cx->asExclusiveContext(), obj, shape->propid()); } if (getter == JS_PropertyStub) From 0ace8395a42a46e1ef384a75ad56f7a6731a90b9 Mon Sep 17 00:00:00 2001 From: Andrew Quartey Date: Mon, 6 Jan 2014 13:03:50 -0500 Subject: [PATCH 18/33] Bug 882718 - Part a: Add list of newly introduced cues to TextTrackManager. r=rillian --- .../html/content/public/HTMLMediaElement.h | 6 +++++ content/html/content/src/TextTrackManager.cpp | 24 ++++++++++++++++++- content/html/content/src/TextTrackManager.h | 6 +++++ content/media/TextTrack.cpp | 1 + 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/content/html/content/public/HTMLMediaElement.h b/content/html/content/public/HTMLMediaElement.h index abe169843e8f..7bcb547493f5 100644 --- a/content/html/content/public/HTMLMediaElement.h +++ b/content/html/content/public/HTMLMediaElement.h @@ -535,6 +535,12 @@ public: } } + void AddCue(TextTrackCue& aCue) { + if (mTextTrackManager) { + mTextTrackManager->AddCue(aCue); + } + } + /** * A public wrapper for FinishDecoderSetup() */ diff --git a/content/html/content/src/TextTrackManager.cpp b/content/html/content/src/TextTrackManager.cpp index 4a6e33e0fd92..fd9ab144eece 100644 --- a/content/html/content/src/TextTrackManager.cpp +++ b/content/html/content/src/TextTrackManager.cpp @@ -12,7 +12,8 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_2(TextTrackManager, mTextTracks, mPendingTextTracks) +NS_IMPL_CYCLE_COLLECTION_3(TextTrackManager, mTextTracks, + mPendingTextTracks, mNewCues) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TextTrackManager, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TextTrackManager, Release) @@ -20,6 +21,7 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement) : mMediaElement(aMediaElement) { MOZ_COUNT_CTOR(TextTrackManager); + mNewCues = new TextTrackCueList(mMediaElement->OwnerDoc()->GetParentObject()); mTextTracks = new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject()); mPendingTextTracks = new TextTrackList(mMediaElement->OwnerDoc()->GetParentObject()); @@ -43,6 +45,7 @@ TextTrackManager::AddTextTrack(TextTrackKind aKind, const nsAString& aLabel, nsRefPtr ttrack = mTextTracks->AddTextTrack(mMediaElement, aKind, aLabel, aLanguage); ttrack->SetReadyState(HTMLTrackElement::LOADED); + AddCues(ttrack); return ttrack.forget(); } @@ -50,6 +53,19 @@ void TextTrackManager::AddTextTrack(TextTrack* aTextTrack) { mTextTracks->AddTextTrack(aTextTrack); + AddCues(aTextTrack); +} + +void +TextTrackManager::AddCues(TextTrack* aTextTrack) +{ + TextTrackCueList* cueList = aTextTrack->GetCues(); + if (cueList) { + bool dummy; + for (uint32_t i = 0; i < cueList->Length(); ++i) { + mNewCues->AddCue(*cueList->IndexedGetter(i, dummy)); + } + } } void @@ -75,6 +91,12 @@ TextTrackManager::Update(double aTime) mTextTracks->Update(aTime); } +void +TextTrackManager::AddCue(TextTrackCue& aCue) +{ + mNewCues->AddCue(aCue); +} + void TextTrackManager::PopulatePendingList() { diff --git a/content/html/content/src/TextTrackManager.h b/content/html/content/src/TextTrackManager.h index 36b9c55eefb4..90cef65227a0 100644 --- a/content/html/content/src/TextTrackManager.h +++ b/content/html/content/src/TextTrackManager.h @@ -10,6 +10,7 @@ #include "mozilla/dom/TextTrack.h" #include "mozilla/dom/TextTrackList.h" +#include "mozilla/dom/TextTrackCueList.h" namespace mozilla { namespace dom { @@ -33,6 +34,9 @@ public: void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly); void DidSeek(); + void AddCue(TextTrackCue& aCue); + void AddCues(TextTrack* aTextTrack); + // Update the display of cues on the video as per the current play back time // of aTime. void Update(double aTime); @@ -49,6 +53,8 @@ private: nsRefPtr mTextTracks; // List of text track objects awaiting loading. nsRefPtr mPendingTextTracks; + // List of newly introduced Text Track cues. + nsRefPtr mNewCues; }; } // namespace dom diff --git a/content/media/TextTrack.cpp b/content/media/TextTrack.cpp index f5516e6932d2..3724d235d1b7 100644 --- a/content/media/TextTrack.cpp +++ b/content/media/TextTrack.cpp @@ -101,6 +101,7 @@ void TextTrack::AddCue(TextTrackCue& aCue) { mCueList->AddCue(aCue); + mMediaElement->AddCue(aCue); SetDirty(); } From 570d06ad25ee540d8d0b25d886004c3bbc204145 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 6 Jan 2014 13:26:44 -0500 Subject: [PATCH 19/33] Bug 915985 - Refactoring to introduce a ZoomConstraints class. r=botond --- dom/ipc/PBrowser.ipdl | 3 +- dom/ipc/TabChild.cpp | 8 ++-- dom/ipc/TabParent.cpp | 6 +-- dom/ipc/TabParent.h | 4 +- gfx/ipc/GfxMessageUtils.h | 20 +++++++++ gfx/layers/FrameMetrics.h | 39 ++++++++++++++++ gfx/layers/composite/APZCTreeManager.cpp | 24 ++++------ gfx/layers/composite/APZCTreeManager.h | 10 +---- gfx/layers/ipc/AsyncPanZoomController.cpp | 44 ++++++++----------- gfx/layers/ipc/AsyncPanZoomController.h | 14 ++---- gfx/layers/ipc/GeckoContentController.h | 4 +- .../gtest/TestAsyncPanZoomController.cpp | 6 +-- layout/ipc/RenderFrameParent.cpp | 31 ++++--------- layout/ipc/RenderFrameParent.h | 5 +-- widget/windows/winrt/MetroWidget.cpp | 3 +- 15 files changed, 118 insertions(+), 103 deletions(-) diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 07f4d7e8e455..fba6f69abbb1 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -24,6 +24,7 @@ using struct gfxSize from "gfxPoint.h"; using CSSRect from "Units.h"; using struct mozilla::layers::FrameMetrics from "FrameMetrics.h"; using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h"; +using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h"; using FrameMetrics::ViewID from "FrameMetrics.h"; using mozilla::layout::ScrollingBehavior from "mozilla/layout/RenderFrameUtils.h"; using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; @@ -301,7 +302,7 @@ parent: * have up-to-date zoom constraints. */ UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot, - bool aAllowZoom, CSSToScreenScale aMinZoom, CSSToScreenScale aMaxZoom); + ZoomConstraints aConstraints); __delete__(); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 29328ef90e3e..ba105b1fe824 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -521,12 +521,14 @@ TabChild::HandlePossibleViewportChange() ViewID viewId; if (APZCCallbackHelper::GetScrollIdentifiers(document->GetDocumentElement(), &presShellId, &viewId)) { + ZoomConstraints constraints( + viewportInfo.IsZoomAllowed(), + viewportInfo.GetMinZoom(), + viewportInfo.GetMaxZoom()); SendUpdateZoomConstraints(presShellId, viewId, /* isRoot = */ true, - viewportInfo.IsZoomAllowed(), - viewportInfo.GetMinZoom(), - viewportInfo.GetMaxZoom()); + constraints); } diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 9cb8eaed3133..d10da07763c6 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1713,12 +1713,10 @@ bool TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId, const ViewID& aViewId, const bool& aIsRoot, - const bool& aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom) + const ZoomConstraints& aConstraints) { if (RenderFrameParent* rfp = GetRenderFrame()) { - rfp->UpdateZoomConstraints(aPresShellId, aViewId, aIsRoot, aAllowZoom, aMinZoom, aMaxZoom); + rfp->UpdateZoomConstraints(aPresShellId, aViewId, aIsRoot, aConstraints); } return true; } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 867203e85a61..8c4767ce2d0b 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -168,9 +168,7 @@ public: virtual bool RecvUpdateZoomConstraints(const uint32_t& aPresShellId, const ViewID& aViewId, const bool& aIsRoot, - const bool& aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom); + const ZoomConstraints& aConstraints); virtual bool RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid, const bool& aPreventDefault); virtual PContentDialogParent* AllocPContentDialogParent(const uint32_t& aType, diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index f5c24e98cbe2..b2d8fdac390b 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -685,6 +685,26 @@ struct ParamTraits } }; +template <> +struct ParamTraits +{ + typedef mozilla::layers::ZoomConstraints paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mAllowZoom); + WriteParam(aMsg, aParam.mMinZoom); + WriteParam(aMsg, aParam.mMaxZoom); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + return (ReadParam(aMsg, aIter, &aResult->mAllowZoom) && + ReadParam(aMsg, aIter, &aResult->mMinZoom) && + ReadParam(aMsg, aIter, &aResult->mMaxZoom)); + } +}; + template <> struct ParamTraits { diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index 31cd2b1d5340..dbe5d10be424 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -349,6 +349,45 @@ struct ScrollableLayerGuid { } }; +struct ZoomConstraints { + bool mAllowZoom; + CSSToScreenScale mMinZoom; + CSSToScreenScale mMaxZoom; + + ZoomConstraints() + : mAllowZoom(true) + { + MOZ_COUNT_CTOR(ZoomConstraints); + } + + ZoomConstraints(bool aAllowZoom, + const CSSToScreenScale& aMinZoom, + const CSSToScreenScale& aMaxZoom) + : mAllowZoom(aAllowZoom) + , mMinZoom(aMinZoom) + , mMaxZoom(aMaxZoom) + { + MOZ_COUNT_CTOR(ZoomConstraints); + } + + ~ZoomConstraints() + { + MOZ_COUNT_DTOR(ZoomConstraints); + } + + bool operator==(const ZoomConstraints& other) const + { + return mAllowZoom == other.mAllowZoom + && mMinZoom == other.mMinZoom + && mMaxZoom == other.mMaxZoom; + } + + bool operator!=(const ZoomConstraints& other) const + { + return !(*this == other); + } +}; + } } diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 9f505512de4d..7815ac13a5ee 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -191,22 +191,20 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, aParent = apzc; if (newApzc) { - bool allowZoom; - CSSToScreenScale minZoom, maxZoom; if (apzc->IsRootForLayersId()) { // If we just created a new apzc that is the root for its layers ID, then // we need to update its zoom constraints which might have arrived before this // was created - if (state->mController->GetRootZoomConstraints(&allowZoom, &minZoom, &maxZoom)) { - apzc->UpdateZoomConstraints(allowZoom, minZoom, maxZoom); + ZoomConstraints constraints; + if (state->mController->GetRootZoomConstraints(&constraints)) { + apzc->UpdateZoomConstraints(constraints); } } else { // For an apzc that is not the root for its layers ID, we give it the // same zoom constraints as its parent. This ensures that if e.g. // user-scalable=no was specified, none of the APZCs allow double-tap // to zoom. - apzc->GetParent()->GetZoomConstraints(&allowZoom, &minZoom, &maxZoom); - apzc->UpdateZoomConstraints(allowZoom, minZoom, maxZoom); + apzc->UpdateZoomConstraints(apzc->GetParent()->GetZoomConstraints()); } } } @@ -576,32 +574,28 @@ APZCTreeManager::ContentReceivedTouch(const ScrollableLayerGuid& aGuid, void APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid, - bool aAllowZoom, - const CSSToScreenScale& aMinScale, - const CSSToScreenScale& aMaxScale) + const ZoomConstraints& aConstraints) { nsRefPtr apzc = GetTargetAPZC(aGuid); // For a given layers id, non-root APZCs inherit the zoom constraints // of their root. if (apzc && apzc->IsRootForLayersId()) { MonitorAutoLock lock(mTreeLock); - UpdateZoomConstraintsRecursively(apzc.get(), aAllowZoom, aMinScale, aMaxScale); + UpdateZoomConstraintsRecursively(apzc.get(), aConstraints); } } void APZCTreeManager::UpdateZoomConstraintsRecursively(AsyncPanZoomController* aApzc, - bool aAllowZoom, - const CSSToScreenScale& aMinScale, - const CSSToScreenScale& aMaxScale) + const ZoomConstraints& aConstraints) { mTreeLock.AssertCurrentThreadOwns(); - aApzc->UpdateZoomConstraints(aAllowZoom, aMinScale, aMaxScale); + aApzc->UpdateZoomConstraints(aConstraints); for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) { // We can have subtrees with their own layers id - leave those alone. if (!child->IsRootForLayersId()) { - UpdateZoomConstraintsRecursively(child, aAllowZoom, aMinScale, aMaxScale); + UpdateZoomConstraintsRecursively(child, aConstraints); } } } diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index 7c0c649d5e03..ff58281c0b3e 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -153,13 +153,9 @@ public: /** * Updates any zoom constraints contained in the tag. - * We try to obey everything it asks us elsewhere, but here we only handle - * minimum-scale, maximum-scale, and user-scalable. */ void UpdateZoomConstraints(const ScrollableLayerGuid& aGuid, - bool aAllowZoom, - const CSSToScreenScale& aMinScale, - const CSSToScreenScale& aMaxScale); + const ZoomConstraints& aConstraints); /** * Cancels any currently running animation. Note that all this does is set the @@ -265,9 +261,7 @@ private: nsEventStatus ProcessMouseEvent(const WidgetMouseEvent& mouseEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetMouseEvent* aOutEvent); nsEventStatus ProcessEvent(const WidgetInputEvent& inputEvent, ScrollableLayerGuid* aOutTargetGuid, WidgetInputEvent* aOutEvent); void UpdateZoomConstraintsRecursively(AsyncPanZoomController* aApzc, - bool aAllowZoom, - const CSSToScreenScale& aMinScale, - const CSSToScreenScale& aMaxScale); + const ZoomConstraints& aConstraints); /** * Recursive helper function to build the APZC tree. The tree of APZC instances has diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index c5935e566026..07bd1d6620f4 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -395,9 +395,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId, mTouchListenerTimeoutTask(nullptr), mX(MOZ_THIS_IN_INITIALIZER_LIST()), mY(MOZ_THIS_IN_INITIALIZER_LIST()), - mAllowZoom(true), - mMinZoom(MIN_ZOOM), - mMaxZoom(MAX_ZOOM), + mZoomConstraints(true, MIN_ZOOM, MAX_ZOOM), mLastSampleTime(GetFrameTime()), mState(NOTHING), mLastAsyncScrollTime(GetFrameTime()), @@ -416,7 +414,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId, mGestureEventListener = new GestureEventListener(this); } if (gAsyncZoomDisabled) { - mAllowZoom = false; + mZoomConstraints.mAllowZoom = false; } } @@ -713,7 +711,7 @@ nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEven nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) { APZC_LOG("%p got a scale-begin in state %d\n", this, mState); - if (!mAllowZoom) { + if (!mZoomConstraints.mAllowZoom) { return nsEventStatus_eConsumeNoDefault; } @@ -760,8 +758,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) { // either axis such that we don't overscroll the boundaries when zooming. CSSPoint neededDisplacement; - CSSToScreenScale realMinZoom = mMinZoom; - CSSToScreenScale realMaxZoom = mMaxZoom; + CSSToScreenScale realMinZoom = mZoomConstraints.mMinZoom; + CSSToScreenScale realMaxZoom = mZoomConstraints.mMaxZoom; realMinZoom.scale = std::max(realMinZoom.scale, mFrameMetrics.mCompositionBounds.width / mFrameMetrics.mScrollableRect.width); realMinZoom.scale = std::max(realMinZoom.scale, @@ -878,9 +876,9 @@ nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEven nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) { APZC_LOG("%p got a single-tap-up in state %d\n", this, mState); nsRefPtr controller = GetGeckoContentController(); - // If mAllowZoom is true we wait for a call to OnSingleTapConfirmed before + // If mZoomConstraints.mAllowZoom is true we wait for a call to OnSingleTapConfirmed before // sending event to content - if (controller && !mAllowZoom) { + if (controller && !mZoomConstraints.mAllowZoom) { int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers); CSSIntPoint geckoScreenPoint; if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) { @@ -909,7 +907,7 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) APZC_LOG("%p got a double-tap in state %d\n", this, mState); nsRefPtr controller = GetGeckoContentController(); if (controller) { - if (mAllowZoom) { + if (mZoomConstraints.mAllowZoom) { int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers); CSSIntPoint geckoScreenPoint; if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) { @@ -1546,10 +1544,10 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) { // then the CSS content rect, in layers pixels, will be smaller than the // composition bounds. If this happens, we can't fill the target composited // area with this frame. - CSSToScreenScale localMinZoom(std::max(mMinZoom.scale, + CSSToScreenScale localMinZoom(std::max(mZoomConstraints.mMinZoom.scale, std::max(compositionBounds.width / cssPageRect.width, compositionBounds.height / cssPageRect.height))); - CSSToScreenScale localMaxZoom = mMaxZoom; + CSSToScreenScale localMaxZoom = mZoomConstraints.mMaxZoom; if (!aRect.IsEmpty()) { // Intersect the zoom-to-rect to the CSS rect to make sure it fits. @@ -1558,7 +1556,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) { compositionBounds.height / aRect.height)); } // 1. If the rect is empty, request received from browserElementScrolling.js - // 2. currentZoom is equal to mMaxZoom and user still double-tapping it + // 2. currentZoom is equal to mZoomConstraints.mMaxZoom and user still double-tapping it // 3. currentZoom is equal to localMinZoom and user still double-tapping it // Treat these three cases as a request to zoom out as much as possible. if (aRect.IsEmpty() || @@ -1687,25 +1685,19 @@ void AsyncPanZoomController::TimeoutTouchListeners() { ContentReceivedTouch(false); } -void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom) { +void AsyncPanZoomController::UpdateZoomConstraints(const ZoomConstraints& aConstraints) { if (gAsyncZoomDisabled) { return; } - mAllowZoom = aAllowZoom; - mMinZoom = (MIN_ZOOM > aMinZoom ? MIN_ZOOM : aMinZoom); - mMaxZoom = (MAX_ZOOM > aMaxZoom ? aMaxZoom : MAX_ZOOM); + mZoomConstraints.mAllowZoom = aConstraints.mAllowZoom; + mZoomConstraints.mMinZoom = (MIN_ZOOM > aConstraints.mMinZoom ? MIN_ZOOM : aConstraints.mMinZoom); + mZoomConstraints.mMaxZoom = (MAX_ZOOM > aConstraints.mMaxZoom ? aConstraints.mMaxZoom : MAX_ZOOM); } -void -AsyncPanZoomController::GetZoomConstraints(bool* aAllowZoom, - CSSToScreenScale* aMinZoom, - CSSToScreenScale* aMaxZoom) +ZoomConstraints +AsyncPanZoomController::GetZoomConstraints() const { - *aAllowZoom = mAllowZoom; - *aMinZoom = mMinZoom; - *aMaxZoom = mMaxZoom; + return mZoomConstraints; } diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index b8ad7740dac3..21f2bd24d5cf 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -130,20 +130,14 @@ public: /** * Updates any zoom constraints contained in the tag. - * We try to obey everything it asks us elsewhere, but here we only handle - * minimum-scale, maximum-scale, and user-scalable. */ - void UpdateZoomConstraints(bool aAllowZoom, - const CSSToScreenScale& aMinScale, - const CSSToScreenScale& aMaxScale); + void UpdateZoomConstraints(const ZoomConstraints& aConstraints); /** * Return the zoom constraints last set for this APZC (in the constructor * or in UpdateZoomConstraints()). */ - void GetZoomConstraints(bool* aAllowZoom, - CSSToScreenScale* aMinScale, - CSSToScreenScale* aMaxScale); + ZoomConstraints GetZoomConstraints() const; /** * Schedules a runnable to run on the controller/UI thread at some time @@ -609,9 +603,7 @@ private: // Most up-to-date constraints on zooming. These should always be reasonable // values; for example, allowing a min zoom of 0.0 can cause very bad things // to happen. - bool mAllowZoom; - CSSToScreenScale mMinZoom; - CSSToScreenScale mMaxZoom; + ZoomConstraints mZoomConstraints; // The last time the compositor has sampled the content transform for this // frame. diff --git a/gfx/layers/ipc/GeckoContentController.h b/gfx/layers/ipc/GeckoContentController.h index 41072d0a0fc6..a441fe242584 100644 --- a/gfx/layers/ipc/GeckoContentController.h +++ b/gfx/layers/ipc/GeckoContentController.h @@ -76,9 +76,7 @@ public: * for this layers tree. This function should return false if there are no * last known zoom constraints. */ - virtual bool GetRootZoomConstraints(bool* aOutAllowZoom, - CSSToScreenScale* aOutMinZoom, - CSSToScreenScale* aOutMaxZoom) + virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints) { return false; } diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index ea8e5d5d3d81..c713728043e1 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -484,7 +484,7 @@ TEST(AsyncPanZoomController, ShortPress) { apzc->SetFrameMetrics(TestFrameMetrics()); apzc->NotifyLayersUpdated(TestFrameMetrics(), true); - apzc->UpdateZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)); + apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0))); EXPECT_CALL(*mcc, HandleSingleTap(CSSIntPoint(10, 10), 0)).Times(1); @@ -503,7 +503,7 @@ TEST(AsyncPanZoomController, MediumPress) { apzc->SetFrameMetrics(TestFrameMetrics()); apzc->NotifyLayersUpdated(TestFrameMetrics(), true); - apzc->UpdateZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)); + apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0))); EXPECT_CALL(*mcc, HandleSingleTap(CSSIntPoint(10, 10), 0)).Times(1); @@ -522,7 +522,7 @@ TEST(AsyncPanZoomController, LongPress) { apzc->SetFrameMetrics(TestFrameMetrics()); apzc->NotifyLayersUpdated(TestFrameMetrics(), true); - apzc->UpdateZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)); + apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0))); int time = 0; diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index a0a31ae973f1..077a5ddd2297 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -500,7 +500,6 @@ public: : mUILoop(MessageLoop::current()) , mRenderFrame(aRenderFrame) , mHaveZoomConstraints(false) - , mAllowZoom(true) { } virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) MOZ_OVERRIDE @@ -611,24 +610,16 @@ public: MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs); } - void SaveZoomConstraints(bool aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom) + void SaveZoomConstraints(const ZoomConstraints& aConstraints) { mHaveZoomConstraints = true; - mAllowZoom = aAllowZoom; - mMinZoom = aMinZoom; - mMaxZoom = aMaxZoom; + mZoomConstraints = aConstraints; } - virtual bool GetRootZoomConstraints(bool* aOutAllowZoom, - CSSToScreenScale* aOutMinZoom, - CSSToScreenScale* aOutMaxZoom) + virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints) { - if (mHaveZoomConstraints) { - *aOutAllowZoom = mAllowZoom; - *aOutMinZoom = mMinZoom; - *aOutMaxZoom = mMaxZoom; + if (mHaveZoomConstraints && aOutConstraints) { + *aOutConstraints = mZoomConstraints; } return mHaveZoomConstraints; } @@ -676,9 +667,7 @@ private: RenderFrameParent* mRenderFrame; bool mHaveZoomConstraints; - bool mAllowZoom; - CSSToScreenScale mMinZoom; - CSSToScreenScale mMaxZoom; + ZoomConstraints mZoomConstraints; }; RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, @@ -1093,16 +1082,14 @@ void RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot, - bool aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom) + const ZoomConstraints& aConstraints) { if (mContentController && aIsRoot) { - mContentController->SaveZoomConstraints(aAllowZoom, aMinZoom, aMaxZoom); + mContentController->SaveZoomConstraints(aConstraints); } if (GetApzcTreeManager()) { GetApzcTreeManager()->UpdateZoomConstraints(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId), - aAllowZoom, aMinZoom, aMaxZoom); + aConstraints); } } diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 469c94950bcc..9289db955ecd 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -49,6 +49,7 @@ class RenderFrameParent : public PRenderFrameParent, typedef mozilla::ContainerLayerParameters ContainerLayerParameters; typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier; typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid; + typedef mozilla::layers::ZoomConstraints ZoomConstraints; typedef FrameMetrics::ViewID ViewID; public: @@ -118,9 +119,7 @@ public: void UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId, bool aIsRoot, - bool aAllowZoom, - const CSSToScreenScale& aMinZoom, - const CSSToScreenScale& aMaxZoom); + const ZoomConstraints& aConstraints); bool HitTest(const nsRect& aRect); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index 1ac28ce9c133..cff2abfeb040 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -1615,7 +1615,8 @@ MetroWidget::Observe(nsISupports *subject, const char *topic, const char16_t *da } ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId); - APZController::sAPZC->UpdateZoomConstraints(guid, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f)); + APZController::sAPZC->UpdateZoomConstraints(guid, + ZoomConstraints(false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f))); } return NS_OK; } From ca3052911ba632bfabdeed37d4fe17a9458ecf14 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 19 Dec 2013 11:18:23 -0800 Subject: [PATCH 20/33] Bug 952206 - Abort execution when a required make file fails to remake; r=bsmedberg Previously, errors during make file making (either the main make file or an included make file) were ignored. This behavior diverged from GNU Make, which aborted execution if the make file was required and ignored the failure if it was optional. This patch changes pymake to abort if the make file is required, brining its behavior inline with GNU make. --HG-- extra : rebase_source : f9a3f4c54273930616f4a8e41dafc463f363c891 extra : amend_source : f02236c3127602357f8f82a66d021144b3cdf3a0 --- build/pymake/pymake/data.py | 9 +++++++-- build/pymake/tests/include-required-fails.mk | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 build/pymake/tests/include-required-fails.mk diff --git a/build/pymake/pymake/data.py b/build/pymake/pymake/data.py index dcd7e922580d..06af4499ca6d 100644 --- a/build/pymake/pymake/data.py +++ b/build/pymake/pymake/data.py @@ -1590,8 +1590,13 @@ class _RemakeContext(object): def remakecb(self, error, didanything): assert error in (True, False) - if error and self.required: - print "Error remaking makefiles (ignored)" + if error: + if self.required: + self.cb(remade=False, error=util.MakeError( + 'Error remaking required makefiles')) + return + else: + print 'Error remaking makefiles (ignored)' if len(self.toremake): target, self.required = self.toremake.pop(0) diff --git a/build/pymake/tests/include-required-fails.mk b/build/pymake/tests/include-required-fails.mk new file mode 100644 index 000000000000..c0211f5cf1d2 --- /dev/null +++ b/build/pymake/tests/include-required-fails.mk @@ -0,0 +1,12 @@ +#T returncode: 2 + +# Required include targets that fail should abort execution. + +include dummy.mk + +all: + @echo TEST-FAIL + +dummy.mk: + @echo "Evaluated dummy.mk" + exit 1 From 78e8a98b146178e36957e3a0731a90dcbe3d8fc1 Mon Sep 17 00:00:00 2001 From: Willian Gustavo Veiga Date: Mon, 6 Jan 2014 09:52:29 -0500 Subject: [PATCH 21/33] Bug 734666 - Style Editor default filename for saving. r=harth --- browser/devtools/styleeditor/StyleEditorUtil.jsm | 9 ++++++++- browser/devtools/styleeditor/StyleSheetEditor.jsm | 14 ++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/browser/devtools/styleeditor/StyleEditorUtil.jsm b/browser/devtools/styleeditor/StyleEditorUtil.jsm index f6df3953a20e..069244847e28 100644 --- a/browser/devtools/styleeditor/StyleEditorUtil.jsm +++ b/browser/devtools/styleeditor/StyleEditorUtil.jsm @@ -172,8 +172,11 @@ this.wire = function wire(aRoot, aSelectorOrElement, aDescriptor) * @param callback * The callback method, which will be called passing in the selected * file or null if the user did not pick one. + * @param AString suggestedFilename + * The suggested filename when toSave is true. */ -this.showFilePicker = function showFilePicker(path, toSave, parentWindow, callback) +this.showFilePicker = function showFilePicker(path, toSave, parentWindow, + callback, suggestedFilename) { if (typeof(path) == "string") { try { @@ -213,6 +216,10 @@ this.showFilePicker = function showFilePicker(path, toSave, parentWindow, callba } }; + if (toSave && suggestedFilename) { + fp.defaultString = suggestedFilename; + } + fp.init(parentWindow, _(key + ".title"), mode); fp.appendFilters(_(key + ".filter"), "*.css"); fp.appendFilters(fp.filterAll); diff --git a/browser/devtools/styleeditor/StyleSheetEditor.jsm b/browser/devtools/styleeditor/StyleSheetEditor.jsm index bc307b1afea2..d9c39bfb1aed 100644 --- a/browser/devtools/styleeditor/StyleSheetEditor.jsm +++ b/browser/devtools/styleeditor/StyleSheetEditor.jsm @@ -19,6 +19,7 @@ const {CssLogic} = require("devtools/styleinspector/css-logic"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource:///modules/devtools/shared/event-emitter.js"); Cu.import("resource:///modules/devtools/StyleEditorUtil.jsm"); @@ -359,8 +360,13 @@ StyleSheetEditor.prototype = { }.bind(this)); }; - showFilePicker(file || this._styleSheetFilePath, true, this._window, onFile); - }, + let defaultName; + if (this._friendlyName) { + defaultName = OS.Path.basename(this._friendlyName); + } + showFilePicker(file || this._styleSheetFilePath, true, this._window, + onFile, defaultName); + }, /** * Retrieve custom key bindings objects as expected by Editor. @@ -394,8 +400,8 @@ StyleSheetEditor.prototype = { const TAB_CHARS = "\t"; -const OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS; -const LINE_SEPARATOR = OS === "WINNT" ? "\r\n" : "\n"; +const CURRENT_OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS; +const LINE_SEPARATOR = CURRENT_OS === "WINNT" ? "\r\n" : "\n"; /** * Prettify minified CSS text. From cad14bcbce6d035ad9f5c9275d14d364044cbbd4 Mon Sep 17 00:00:00 2001 From: Sachin Hosmani Date: Mon, 6 Jan 2014 14:16:32 +0530 Subject: [PATCH 22/33] Bug 897735 - Support regular expression filters for name and creator in extension blocks. r=Unfocused --- browser/base/content/aboutDialog.js | 2 +- .../content/test/social/browser_blocklist.js | 6 +- .../content/flyoutpanels/AboutFlyoutPanel.js | 2 +- toolkit/components/social/SocialService.jsm | 22 +- .../mozapps/extensions/AddonUpdateChecker.jsm | 3 +- toolkit/mozapps/extensions/XPIProvider.jsm | 12 +- .../mozapps/extensions/nsBlocklistService.js | 106 ++++-- .../test_blocklist_metadata_filters_1.xml | 21 ++ .../test/xpcshell/data/test_bug393285.xml | 5 +- .../test_blocklist_metadata_filters.js | 159 ++++++++ .../test/xpcshell/test_bug335238.js | 10 +- .../test/xpcshell/test_bug393285.js | 344 ++++++++++++++++-- .../test/xpcshell/test_bug406118.js | 171 ++++++++- .../test/xpcshell/test_bug455906.js | 10 +- .../test/xpcshell/xpcshell-shared.ini | 1 + toolkit/mozapps/update/content/updates.js | 2 +- toolkit/mozapps/update/nsUpdateService.js | 2 +- xpcom/system/nsIBlocklistService.idl | 20 +- 18 files changed, 764 insertions(+), 134 deletions(-) create mode 100644 toolkit/mozapps/extensions/test/xpcshell/data/test_blocklist_metadata_filters_1.xml create mode 100644 toolkit/mozapps/extensions/test/xpcshell/test_blocklist_metadata_filters.js diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js index 82968beb1100..34b466191990 100644 --- a/browser/base/content/aboutDialog.js +++ b/browser/base/content/aboutDialog.js @@ -463,7 +463,7 @@ appUpdater.prototype = * See XPIProvider.jsm */ onUpdateAvailable: function(aAddon, aInstall) { - if (!Services.blocklist.isAddonBlocklisted(aAddon.id, aInstall.version, + if (!Services.blocklist.isAddonBlocklisted(aAddon, this.update.appVersion, this.update.platformVersion)) { // Compatibility or new version updates mean the same thing here. diff --git a/browser/base/content/test/social/browser_blocklist.js b/browser/base/content/test/social/browser_blocklist.js index 9f6436b13d8d..2c20dc2dba6b 100644 --- a/browser/base/content/test/social/browser_blocklist.js +++ b/browser/base/content/test/social/browser_blocklist.js @@ -36,10 +36,10 @@ var tests = { testSimpleBlocklist: function(next) { // this really just tests adding and clearing our blocklist for later tests setAndUpdateBlocklist(blocklistURL, function() { - ok(Services.blocklist.isAddonBlocklisted("test1.example.com@services.mozilla.org", "0", "0", "0"), "blocking 'blocked'"); - ok(!Services.blocklist.isAddonBlocklisted("example.com@services.mozilla.org", "0", "0", "0"), "not blocking 'good'"); + ok(Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocking 'blocked'"); + ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest)), "not blocking 'good'"); resetBlocklist(function() { - ok(!Services.blocklist.isAddonBlocklisted("test1.example.com@services.mozilla.org", "0", "0", "0"), "blocklist cleared"); + ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocklist cleared"); next(); }); }); diff --git a/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js b/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js index bb6c0ddc86ae..f1adcc4224e1 100644 --- a/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js +++ b/browser/metro/base/content/flyoutpanels/AboutFlyoutPanel.js @@ -454,7 +454,7 @@ appUpdater.prototype = * See XPIProvider.jsm */ onUpdateAvailable: function(aAddon, aInstall) { - if (!Services.blocklist.isAddonBlocklisted(aAddon.id, aInstall.version, + if (!Services.blocklist.isAddonBlocklisted(aAddon, this.update.appVersion, this.update.platformVersion)) { // Compatibility or new version updates mean the same thing here. diff --git a/toolkit/components/social/SocialService.jsm b/toolkit/components/social/SocialService.jsm index 7672d0402048..f5f94ee77a63 100644 --- a/toolkit/components/social/SocialService.jsm +++ b/toolkit/components/social/SocialService.jsm @@ -587,12 +587,12 @@ this.SocialService = { installProvider: function(aDOMDocument, data, installCallback) { let installOrigin = aDOMDocument.nodePrincipal.origin; - let id = getAddonIDFromOrigin(installOrigin); - let version = data && data.version ? data.version : "0"; - if (Services.blocklist.getAddonBlocklistState(id, version) == Ci.nsIBlocklistService.STATE_BLOCKED) + let addon = new AddonWrapper(data); + if (addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) throw new Error("installProvider: provider with origin [" + installOrigin + "] is blocklisted"); + let id = getAddonIDFromOrigin(installOrigin); AddonManager.getAddonByID(id, function(aAddon) { if (aAddon && aAddon.userDisabled) { aAddon.cancelUninstall(); @@ -662,6 +662,10 @@ this.SocialService = { } }, + createWrapper: function(manifest) { + return new AddonWrapper(manifest); + }, + /** * updateProvider is used from the worker to self-update. Since we do not * have knowledge of the currently selected provider here, we will notify @@ -716,8 +720,8 @@ function SocialProvider(input) { if (!input.origin) throw new Error("SocialProvider must be passed an origin"); - let id = getAddonIDFromOrigin(input.origin); - if (Services.blocklist.getAddonBlocklistState(id, input.version || "0") == Ci.nsIBlocklistService.STATE_BLOCKED) + let addon = new AddonWrapper(input); + if (addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) throw new Error("SocialProvider: provider with origin [" + input.origin + "] is blocklisted"); @@ -1011,8 +1015,8 @@ var SocialAddonProvider = { for (let manifest of SocialServiceInternal.manifests) { try { if (ActiveProviders.has(manifest.origin)) { - let id = getAddonIDFromOrigin(manifest.origin); - if (Services.blocklist.getAddonBlocklistState(id, manifest.version || "0") != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) { + let addon = new AddonWrapper(manifest); + if (addon.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) { SocialService.removeProvider(manifest.origin); } } @@ -1100,11 +1104,11 @@ AddonWrapper.prototype = { }, get blocklistState() { - return Services.blocklist.getAddonBlocklistState(this.id, this.version || "0"); + return Services.blocklist.getAddonBlocklistState(this); }, get blocklistURL() { - return Services.blocklist.getAddonBlocklistURL(this.id, this.version || "0"); + return Services.blocklist.getAddonBlocklistURL(this); }, get screenshots() { diff --git a/toolkit/mozapps/extensions/AddonUpdateChecker.jsm b/toolkit/mozapps/extensions/AddonUpdateChecker.jsm index 46d269bb4e19..f90dc094b35a 100644 --- a/toolkit/mozapps/extensions/AddonUpdateChecker.jsm +++ b/toolkit/mozapps/extensions/AddonUpdateChecker.jsm @@ -721,8 +721,7 @@ this.AddonUpdateChecker = { for (let update of aUpdates) { if (!update.updateURL) continue; - let state = blocklist.getAddonBlocklistState(update.id, update.version, - aAppVersion, aPlatformVersion); + let state = blocklist.getAddonBlocklistState(update, aAppVersion, aPlatformVersion); if (state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) continue; if ((newest == null || (Services.vc.compare(newest.version, update.version) < 0)) && diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index 667f77d34c17..f5387c517dea 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -550,12 +550,10 @@ function applyBlocklistChanges(aOldAddon, aNewAddon, aOldAppVersion, let bs = Cc["@mozilla.org/extensions/blocklist;1"]. getService(Ci.nsIBlocklistService); - let oldBlocklistState = bs.getAddonBlocklistState(aOldAddon.id, - aOldAddon.version, + let oldBlocklistState = bs.getAddonBlocklistState(createWrapper(aOldAddon), aOldAppVersion, aOldPlatformVersion); - let newBlocklistState = bs.getAddonBlocklistState(aNewAddon.id, - aNewAddon.version); + let newBlocklistState = bs.getAddonBlocklistState(createWrapper(aNewAddon)); // If the blocklist state hasn't changed then the properties don't need to // change @@ -6201,7 +6199,7 @@ AddonInternal.prototype = { let bs = Cc["@mozilla.org/extensions/blocklist;1"]. getService(Ci.nsIBlocklistService); - return bs.getAddonBlocklistState(this.id, this.version); + return bs.getAddonBlocklistState(createWrapper(this)); }, get blocklistURL() { @@ -6213,7 +6211,7 @@ AddonInternal.prototype = { let bs = Cc["@mozilla.org/extensions/blocklist;1"]. getService(Ci.nsIBlocklistService); - return bs.getAddonBlocklistURL(this.id, this.version); + return bs.getAddonBlocklistURL(createWrapper(this)); }, applyCompatibilityUpdate: function AddonInternal_applyCompatibilityUpdate(aUpdate, aSyncCompatibility) { @@ -6331,7 +6329,7 @@ function AddonWrapper(aAddon) { ["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible", "providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled", "softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents", - "strictCompatibility", "compatibilityOverrides"].forEach(function(aProp) { + "strictCompatibility", "compatibilityOverrides", "updateURL"].forEach(function(aProp) { this.__defineGetter__(aProp, function AddonWrapper_propertyGetter() aAddon[aProp]); }, this); diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index c43c1b749497..55c69ef73790 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -49,6 +49,8 @@ const VULNERABILITYSTATUS_NONE = 0; const VULNERABILITYSTATUS_UPDATE_AVAILABLE = 1; const VULNERABILITYSTATUS_NO_UPDATE = 2; +const EXTENSION_BLOCK_FILTERS = ["id", "name", "creator", "homepageURL", "updateURL"]; + var gLoggingEnabled = null; var gBlocklistEnabled = true; var gBlocklistLevel = DEFAULT_LEVEL; @@ -317,16 +319,16 @@ Blocklist.prototype = { }, /* See nsIBlocklistService */ - isAddonBlocklisted: function Blocklist_isAddonBlocklisted(id, version, appVersion, toolkitVersion) { - return this.getAddonBlocklistState(id, version, appVersion, toolkitVersion) == + isAddonBlocklisted: function Blocklist_isAddonBlocklisted(addon, appVersion, toolkitVersion) { + return this.getAddonBlocklistState(addon, appVersion, toolkitVersion) == Ci.nsIBlocklistService.STATE_BLOCKED; }, /* See nsIBlocklistService */ - getAddonBlocklistState: function Blocklist_getAddonBlocklistState(id, version, appVersion, toolkitVersion) { + getAddonBlocklistState: function Blocklist_getAddonBlocklistState(addon, appVersion, toolkitVersion) { if (!this._addonEntries) this._loadBlocklist(); - return this._getAddonBlocklistState(id, version, this._addonEntries, + return this._getAddonBlocklistState(addon, this._addonEntries, appVersion, toolkitVersion); }, @@ -349,8 +351,8 @@ Blocklist.prototype = { * @returns The blocklist state for the item, one of the STATE constants as * defined in nsIBlocklistService. */ - _getAddonBlocklistState: function Blocklist_getAddonBlocklistStateCall(id, - version, addonEntries, appVersion, toolkitVersion) { + _getAddonBlocklistState: function Blocklist_getAddonBlocklistStateCall(addon, + addonEntries, appVersion, toolkitVersion) { if (!gBlocklistEnabled) return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; @@ -359,12 +361,12 @@ Blocklist.prototype = { if (!toolkitVersion) toolkitVersion = gApp.platformVersion; - var blItem = this._findMatchingAddonEntry(addonEntries, id); + var blItem = this._findMatchingAddonEntry(addonEntries, addon); if (!blItem) return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; for (let currentblItem of blItem.versions) { - if (currentblItem.includesItem(version, appVersion, toolkitVersion)) + if (currentblItem.includesItem(addon.version, appVersion, toolkitVersion)) return currentblItem.severity >= gBlocklistLevel ? Ci.nsIBlocklistService.STATE_BLOCKED : Ci.nsIBlocklistService.STATE_SOFTBLOCKED; } @@ -374,36 +376,63 @@ Blocklist.prototype = { /** * Returns the set of prefs of the add-on stored in the blocklist file * (probably to revert them on disabling). - * @param id - * ID of the add-on. + * @param addon + * The add-on whose to-be-reset prefs are to be found. */ - _getAddonPrefs: function Blocklist_getAddonPrefs(id) { - let entry = this._findMatchingAddonEntry(this._addonEntries, id); + _getAddonPrefs: function Blocklist_getAddonPrefs(addon) { + let entry = this._findMatchingAddonEntry(this._addonEntries, addon); return entry.prefs.slice(0); }, _findMatchingAddonEntry: function Blocklist_findMatchingAddonEntry(aAddonEntries, - aId) { - for (let entry of aAddonEntries) { - if (entry.id instanceof RegExp) { - if (entry.id.test(aId)) - return entry; - } else if (entry.id == aId) { - return entry; + aAddon) { + if (!aAddon) + return null; + // Returns true if the params object passes the constraints set by entry. + // (For every non-null property in entry, the same key must exist in + // params and value must be the same) + function checkEntry(entry, params) { + for (let [key, value] of entry) { + if (value === null || value === undefined) + continue; + if (params[key]) { + if (value instanceof RegExp) { + if (!value.test(params[key])) { + return false; + } + } else if (value !== params[key]) { + return false; + } + } else { + return false; + } } + return true; } - return null; + + let params = {}; + for (let filter of EXTENSION_BLOCK_FILTERS) { + params[filter] = aAddon[filter]; + } + if (params.creator) + params.creator = params.creator.name; + for (let entry of aAddonEntries) { + if (checkEntry(entry.attributes, params)) { + return entry; + } + } + return null; }, /* See nsIBlocklistService */ - getAddonBlocklistURL: function Blocklist_getAddonBlocklistURL(id, version, appVersion, toolkitVersion) { + getAddonBlocklistURL: function Blocklist_getAddonBlocklistURL(addon, appVersion, toolkitVersion) { if (!gBlocklistEnabled) return ""; if (!this._addonEntries) this._loadBlocklist(); - let blItem = this._findMatchingAddonEntry(this._addonEntries, id); + let blItem = this._findMatchingAddonEntry(this._addonEntries, addon); if (!blItem || !blItem.blockID) return null; @@ -734,18 +763,26 @@ Blocklist.prototype = { return; let blockEntry = { - id: null, versions: [], prefs: [], - blockID: null + blockID: null, + attributes: new Map() + // Atleast one of EXTENSION_BLOCK_FILTERS must get added to attributes }; + // Any filter starting with '/' is interpreted as a regex. So if an attribute + // starts with a '/' it must be checked via a regex. + function regExpCheck(attr) { + return attr.startsWith("/") ? parseRegExp(attr) : attr; + } + + for (let filter of EXTENSION_BLOCK_FILTERS) { + let attr = blocklistElement.getAttribute(filter); + if (attr) + blockEntry.attributes.set(filter, regExpCheck(attr)); + } + var childNodes = blocklistElement.childNodes; - var id = blocklistElement.getAttribute("id"); - // Add-on IDs cannot contain '/', so an ID starting with '/' must be a regex - if (id.startsWith("/")) - id = parseRegExp(id); - blockEntry.id = id; for (let x = 0; x < childNodes.length; x++) { var childElement = childNodes.item(x); @@ -928,9 +965,8 @@ Blocklist.prototype = { for (let addon of addons) { let oldState = Ci.nsIBlocklistService.STATE_NOTBLOCKED; if (oldAddonEntries) - oldState = self._getAddonBlocklistState(addon.id, addon.version, - oldAddonEntries); - let state = self.getAddonBlocklistState(addon.id, addon.version); + oldState = self._getAddonBlocklistState(addon, oldAddonEntries); + let state = self.getAddonBlocklistState(addon); LOG("Blocklist state for " + addon.id + " changed from " + oldState + " to " + state); @@ -941,7 +977,7 @@ Blocklist.prototype = { if (state === Ci.nsIBlocklistService.STATE_BLOCKED) { // It's a hard block. We must reset certain preferences. - let prefs = self._getAddonPrefs(addon.id); + let prefs = self._getAddonPrefs(addon); resetPrefs(prefs); } @@ -973,7 +1009,7 @@ Blocklist.prototype = { disable: false, blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED, item: addon, - url: self.getAddonBlocklistURL(addon.id), + url: self.getAddonBlocklistURL(addon), }); } @@ -1056,7 +1092,7 @@ Blocklist.prototype = { // This add-on is softblocked. addon.item.softDisabled = true; // We must revert certain prefs. - let prefs = self._getAddonPrefs(addon.item.id); + let prefs = self._getAddonPrefs(addon.item); resetPrefs(prefs); } } diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_blocklist_metadata_filters_1.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_blocklist_metadata_filters_1.xml new file mode 100644 index 000000000000..368a6ed53fda --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_blocklist_metadata_filters_1.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_bug393285.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_bug393285.xml index fe92c132ca5f..1767b4332ff1 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_bug393285.xml +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_bug393285.xml @@ -3,7 +3,10 @@ - + + + + diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_metadata_filters.js b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_metadata_filters.js new file mode 100644 index 000000000000..15e951bce3a1 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_blocklist_metadata_filters.js @@ -0,0 +1,159 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Tests blocking of extensions by ID, name, creator, homepageURL, updateURL +// and RegExps for each. See bug 897735. + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; + +Cu.import("resource://testing-common/httpd.js"); +var testserver = new HttpServer(); +testserver.start(-1); +gPort = testserver.identity.primaryPort; + +// register static files with server and interpolate port numbers in them +mapFile("/data/test_blocklist_metadata_filters_1.xml", testserver); + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); + +// Don't need the full interface, attempts to call other methods will just +// throw which is just fine +var WindowWatcher = { + openWindow: function(parent, url, name, features, arguments) { + // Should be called to list the newly blocklisted items + do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG); + + // Simulate auto-disabling any softblocks + var list = arguments.wrappedJSObject.list; + list.forEach(function(aItem) { + if (!aItem.blocked) + aItem.disable = true; + }); + + //run the code after the blocklist is closed + Services.obs.notifyObservers(null, "addon-blocklist-closed", null); + + }, + + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWindowWatcher) + || iid.equals(Ci.nsISupports)) + return this; + + throw Cr.NS_ERROR_NO_INTERFACE; + } +}; + +var WindowWatcherFactory = { + createInstance: function createInstance(outer, iid) { + if (outer != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + return WindowWatcher.QueryInterface(iid); + } +}; + +var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); +registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"), + "Fake Window Watcher", + "@mozilla.org/embedcomp/window-watcher;1", + WindowWatcherFactory); + + +function load_blocklist(aFile, aCallback) { + Services.obs.addObserver(function() { + Services.obs.removeObserver(arguments.callee, "blocklist-updated"); + + do_execute_soon(aCallback); + }, "blocklist-updated", false); + + Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + + gPort + "/data/" + aFile); + var blocklist = Cc["@mozilla.org/extensions/blocklist;1"]. + getService(Ci.nsITimerCallback); + blocklist.notify(null); +} + + +function end_test() { + testserver.stop(do_test_finished); +} + +function run_test() { + do_test_pending(); + + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); + + // Should get blocked by name + writeInstallRDFForExtension({ + id: "block1@tests.mozilla.org", + version: "1.0", + name: "Mozilla Corp.", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + // Should get blocked by all the attributes. + writeInstallRDFForExtension({ + id: "block2@tests.mozilla.org", + version: "1.0", + name: "Moz-addon", + creator: "Dangerous", + homepageURL: "www.extension.dangerous.com", + updateURL: "www.extension.dangerous.com/update.rdf", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + // Fails to get blocked because of a different ID even though other + // attributes match against a blocklist entry. + writeInstallRDFForExtension({ + id: "block3@tests.mozilla.org", + version: "1.0", + name: "Moz-addon", + creator: "Dangerous", + homepageURL: "www.extensions.dangerous.com", + updateURL: "www.extension.dangerous.com/update.rdf", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + startupManager(); + + AddonManager.getAddonsByIDs(["block1@tests.mozilla.org", + "block2@tests.mozilla.org", + "block3@tests.mozilla.org"], function([a1, a2, a3]) { + do_check_eq(a1.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + do_check_eq(a2.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + do_check_eq(a3.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + + run_test_1(); + }); +} + +function run_test_1() { + load_blocklist("test_blocklist_metadata_filters_1.xml", function() { + restartManager(); + + AddonManager.getAddonsByIDs(["block1@tests.mozilla.org", + "block2@tests.mozilla.org", + "block3@tests.mozilla.org"], function([a1, a2, a3]) { + do_check_eq(a1.blocklistState, Ci.nsIBlocklistService.STATE_SOFTBLOCKED); + do_check_eq(a2.blocklistState, Ci.nsIBlocklistService.STATE_BLOCKED); + do_check_eq(a3.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + end_test(); + }); + }); +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_bug335238.js b/toolkit/mozapps/extensions/test/xpcshell/test_bug335238.js index 8bfef2feffdc..e691bb5708ec 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bug335238.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug335238.js @@ -79,10 +79,10 @@ var ADDONS = [ // This is a replacement for the blocklist service var BlocklistService = { - getAddonBlocklistState: function(aId, aVersion, aAppVersion, aToolkitVersion) { - if (aId == "bug335238_3@tests.mozilla.org") + getAddonBlocklistState: function(aAddon, aAppVersion, aToolkitVersion) { + if (aAddon.id == "bug335238_3@tests.mozilla.org") return Ci.nsIBlocklistService.STATE_SOFTBLOCKED; - if (aId == "bug335238_4@tests.mozilla.org") + if (aAddon.id == "bug335238_4@tests.mozilla.org") return Ci.nsIBlocklistService.STATE_BLOCKED; return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; }, @@ -91,8 +91,8 @@ var BlocklistService = { return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; }, - isAddonBlocklisted: function(aId, aVersion, aAppVersion, aToolkitVersion) { - return this.getAddonBlocklistState(aId, aVersion, aAppVersion, aToolkitVersion) == + isAddonBlocklisted: function(aAddon, aAppVersion, aToolkitVersion) { + return this.getAddonBlocklistState(aAddon, aAppVersion, aToolkitVersion) == Ci.nsIBlocklistService.STATE_BLOCKED; }, diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js b/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js index c631ba4325be..90cf29753301 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug393285.js @@ -3,53 +3,325 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; + +Cu.import("resource://testing-common/httpd.js"); +var testserver = new HttpServer(); +testserver.start(-1); +gPort = testserver.identity.primaryPort; + +// register static files with server and interpolate port numbers in them +mapFile("/data/test_bug393285.xml", testserver); + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); + +let addonIDs = ["test_bug393285_1@tests.mozilla.org", + "test_bug393285_2@tests.mozilla.org", + "test_bug393285_3a@tests.mozilla.org", + "test_bug393285_3b@tests.mozilla.org", + "test_bug393285_4@tests.mozilla.org", + "test_bug393285_5@tests.mozilla.org", + "test_bug393285_6@tests.mozilla.org", + "test_bug393285_7@tests.mozilla.org", + "test_bug393285_8@tests.mozilla.org", + "test_bug393285_9@tests.mozilla.org", + "test_bug393285_10@tests.mozilla.org", + "test_bug393285_11@tests.mozilla.org", + "test_bug393285_12@tests.mozilla.org", + "test_bug393285_13@tests.mozilla.org", + "test_bug393285_14@tests.mozilla.org"]; + +// A window watcher to deal with the blocklist UI dialog. +var WindowWatcher = { + openWindow: function(parent, url, name, features, arguments) { + // Should be called to list the newly blocklisted items + do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG); + + // Simulate auto-disabling any softblocks + var list = arguments.wrappedJSObject.list; + list.forEach(function(aItem) { + if (!aItem.blocked) + aItem.disable = true; + }); + + //run the code after the blocklist is closed + Services.obs.notifyObservers(null, "addon-blocklist-closed", null); + + }, + + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWindowWatcher) + || iid.equals(Ci.nsISupports)) + return this; + + throw Cr.NS_ERROR_NO_INTERFACE; + } +}; + +var WindowWatcherFactory = { + createInstance: function createInstance(outer, iid) { + if (outer != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + return WindowWatcher.QueryInterface(iid); + } +}; + +var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); +registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"), + "Fake Window Watcher", + "@mozilla.org/embedcomp/window-watcher;1", + WindowWatcherFactory); + + +function load_blocklist(aFile, aCallback) { + Services.obs.addObserver(function() { + Services.obs.removeObserver(arguments.callee, "blocklist-updated"); + + do_execute_soon(aCallback); + }, "blocklist-updated", false); + + Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + + gPort + "/data/" + aFile); + var blocklist = Cc["@mozilla.org/extensions/blocklist;1"]. + getService(Ci.nsITimerCallback); + blocklist.notify(null); +} + + +function end_test() { + testserver.stop(do_test_finished); +} + function run_test() { + do_test_pending(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); - // We cannot force the blocklist to update so just copy our test list to the profile - var blocklistFile = gProfD.clone(); - blocklistFile.append("blocklist.xml"); - if (blocklistFile.exists()) - blocklistFile.remove(false); - var source = do_get_file("data/test_bug393285.xml"); - source.copyTo(gProfD, "blocklist.xml"); + writeInstallRDFForExtension({ + id: "test_bug393285_1@tests.mozilla.org", + name: "extension 1", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"] - .getService(Components.interfaces.nsIBlocklistService); - - // No info in blocklist, shouldn't be blocked - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_1@tests.mozilla.org", "1", "1", "1.9")); - // Should always be blocked - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_2@tests.mozilla.org", "1", "1", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_2@tests.mozilla.org", + name: "extension 2", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Only version 1 should be blocked - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_3@tests.mozilla.org", "1", "1", "1.9")); - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_3@tests.mozilla.org", "2", "1", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_3a@tests.mozilla.org", + name: "extension 3a", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Should be blocked for app version 1 - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_4@tests.mozilla.org", "1", "1", "1.9")); - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_4@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_3b@tests.mozilla.org", + name: "extension 3b", + version: "2.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Not blocklisted because we are a different OS - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_5@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_4@tests.mozilla.org", + name: "extension 4", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Blocklisted based on OS - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_6@tests.mozilla.org", "1", "2", "1.9")); - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_7@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_5@tests.mozilla.org", + name: "extension 5", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Not blocklisted because we are a different ABI - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_8@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_6@tests.mozilla.org", + name: "extension 6", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Blocklisted based on ABI - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_9@tests.mozilla.org", "1", "2", "1.9")); - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_10@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_7@tests.mozilla.org", + name: "extension 7", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Doesnt match both os and abi so not blocked - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_11@tests.mozilla.org", "1", "2", "1.9")); - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_12@tests.mozilla.org", "1", "2", "1.9")); - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_13@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_8@tests.mozilla.org", + name: "extension 8", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - // Matches both os and abi so blocked - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_14@tests.mozilla.org", "1", "2", "1.9")); + writeInstallRDFForExtension({ + id: "test_bug393285_9@tests.mozilla.org", + name: "extension 9", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_10@tests.mozilla.org", + name: "extension 10", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_11@tests.mozilla.org", + name: "extension 11", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_12@tests.mozilla.org", + name: "extension 12", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_13@tests.mozilla.org", + name: "extension 13", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_14@tests.mozilla.org", + name: "extension 14", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + startupManager(); + + AddonManager.getAddonsByIDs(addonIDs, function(addons) { + for (addon of addons) { + do_check_eq(addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + } + run_test_1(); + }); +} + +function run_test_1() { + load_blocklist("test_bug393285.xml", function() { + restartManager(); + + var blocklist = Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsIBlocklistService); + + AddonManager.getAddonsByIDs(addonIDs, + function([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15]) { + // No info in blocklist, shouldn't be blocked + do_check_false(blocklist.isAddonBlocklisted(a1, "1", "1.9")); + + // Should always be blocked + do_check_true(blocklist.isAddonBlocklisted(a2, "1", "1.9")); + + // Only version 1 should be blocked + do_check_true(blocklist.isAddonBlocklisted(a3, "1", "1.9")); + do_check_false(blocklist.isAddonBlocklisted(a4, "1", "1.9")); + + // Should be blocked for app version 1 + do_check_true(blocklist.isAddonBlocklisted(a5, "1", "1.9")); + do_check_false(blocklist.isAddonBlocklisted(a5, "2", "1.9")); + + // Not blocklisted because we are a different OS + do_check_false(blocklist.isAddonBlocklisted(a6, "2", "1.9")); + + // Blocklisted based on OS + do_check_true(blocklist.isAddonBlocklisted(a7, "2", "1.9")); + do_check_true(blocklist.isAddonBlocklisted(a8, "2", "1.9")); + + // Not blocklisted because we are a different ABI + do_check_false(blocklist.isAddonBlocklisted(a9, "2", "1.9")); + + // Blocklisted based on ABI + do_check_true(blocklist.isAddonBlocklisted(a10, "2", "1.9")); + do_check_true(blocklist.isAddonBlocklisted(a11, "2", "1.9")); + + // Doesnt match both os and abi so not blocked + do_check_false(blocklist.isAddonBlocklisted(a12, "2", "1.9")); + do_check_false(blocklist.isAddonBlocklisted(a13, "2", "1.9")); + do_check_false(blocklist.isAddonBlocklisted(a14, "2", "1.9")); + + // Matches both os and abi so blocked + do_check_true(blocklist.isAddonBlocklisted(a15, "2", "1.9")); + end_test(); + }); + }); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js b/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js index 6ab86d2a0de2..724b48dd5bf9 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug406118.js @@ -3,24 +3,165 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +let addonIDs = ["test_bug393285_1@tests.mozilla.org", + "test_bug393285_2@tests.mozilla.org", + "test_bug393285_3a@tests.mozilla.org", + "test_bug393285_4@tests.mozilla.org"]; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; + +Cu.import("resource://testing-common/httpd.js"); +var testserver = new HttpServer(); +testserver.start(-1); +gPort = testserver.identity.primaryPort; + +// register static files with server and interpolate port numbers in them +mapFile("/data/test_bug393285.xml", testserver); + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); + +// A window watcher to deal with the blocklist UI dialog. +var WindowWatcher = { + openWindow: function(parent, url, name, features, arguments) { + // Should be called to list the newly blocklisted items + do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG); + + // Simulate auto-disabling any softblocks + var list = arguments.wrappedJSObject.list; + list.forEach(function(aItem) { + if (!aItem.blocked) + aItem.disable = true; + }); + + //run the code after the blocklist is closed + Services.obs.notifyObservers(null, "addon-blocklist-closed", null); + + }, + + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIWindowWatcher) + || iid.equals(Ci.nsISupports)) + return this; + + throw Cr.NS_ERROR_NO_INTERFACE; + } +}; + +var WindowWatcherFactory = { + createInstance: function createInstance(outer, iid) { + if (outer != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + return WindowWatcher.QueryInterface(iid); + } +}; + +var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); +registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"), + "Fake Window Watcher", + "@mozilla.org/embedcomp/window-watcher;1", + WindowWatcherFactory); + + +function load_blocklist(aFile, aCallback) { + Services.obs.addObserver(function() { + Services.obs.removeObserver(arguments.callee, "blocklist-updated"); + + do_execute_soon(aCallback); + }, "blocklist-updated", false); + + Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + + gPort + "/data/" + aFile); + var blocklist = Cc["@mozilla.org/extensions/blocklist;1"]. + getService(Ci.nsITimerCallback); + blocklist.notify(null); +} + + +function end_test() { + testserver.stop(do_test_finished); +} + function run_test() { + do_test_pending(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); - // We cannot force the blocklist to update so just copy our test list to the profile - var blocklistFile = gProfD.clone(); - blocklistFile.append("blocklist.xml"); - if (blocklistFile.exists()) - blocklistFile.remove(false); - var source = do_get_file("data/test_bug393285.xml"); - source.copyTo(gProfD, "blocklist.xml"); + writeInstallRDFForExtension({ + id: "test_bug393285_1@tests.mozilla.org", + name: "extension 1", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); - var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"] - .getService(Components.interfaces.nsIBlocklistService); - - // All these should be blocklisted for the current app. - do_check_false(blocklist.isAddonBlocklisted("test_bug393285_1@tests.mozilla.org", "1", null, null)); - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_2@tests.mozilla.org", "1", null, null)); - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_3@tests.mozilla.org", "1", null, null)); - do_check_true(blocklist.isAddonBlocklisted("test_bug393285_4@tests.mozilla.org", "1", null, null)); + writeInstallRDFForExtension({ + id: "test_bug393285_2@tests.mozilla.org", + name: "extension 2", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_3a@tests.mozilla.org", + name: "extension 3a", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + writeInstallRDFForExtension({ + id: "test_bug393285_4@tests.mozilla.org", + name: "extension 4", + version: "1.0", + targetApplications: [{ + id: "xpcshell@tests.mozilla.org", + minVersion: "1", + maxVersion: "3" + }] + }, profileDir); + + startupManager(); + + AddonManager.getAddonsByIDs(addonIDs, function(addons) { + for (addon of addons) { + do_check_eq(addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); + } + run_test_1(); + }); +} + +function run_test_1() { + load_blocklist("test_bug393285.xml", function() { + restartManager(); + + var blocklist = Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsIBlocklistService); + + AddonManager.getAddonsByIDs(addonIDs, + function([a1, a2, a3, a4]) { + // No info in blocklist, shouldn't be blocked + do_check_false(blocklist.isAddonBlocklisted(a1, null, null)); + + // All these should be blocklisted for the current app. + do_check_true(blocklist.isAddonBlocklisted(a2, null, null)); + do_check_true(blocklist.isAddonBlocklisted(a3, null, null)); + do_check_true(blocklist.isAddonBlocklisted(a4, null, null)); + + end_test(); + }); + }); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js b/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js index 1f0ec3e6f14b..8c1ebe5ff267 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js @@ -461,11 +461,11 @@ function check_test_pt3() { do_check_eq(check_addon_state(addons[3]), "false,false,true"); // Check blockIDs are correct - do_check_eq(blocklist.getAddonBlocklistURL(addons[0].id,''),create_blocklistURL(addons[0].id)); - do_check_eq(blocklist.getAddonBlocklistURL(addons[1].id,''),create_blocklistURL(addons[1].id)); - do_check_eq(blocklist.getAddonBlocklistURL(addons[2].id,''),create_blocklistURL(addons[2].id)); - do_check_eq(blocklist.getAddonBlocklistURL(addons[3].id,''),create_blocklistURL(addons[3].id)); - do_check_eq(blocklist.getAddonBlocklistURL(addons[4].id,''),create_blocklistURL(addons[4].id)); + do_check_eq(blocklist.getAddonBlocklistURL(addons[0]),create_blocklistURL(addons[0].id)); + do_check_eq(blocklist.getAddonBlocklistURL(addons[1]),create_blocklistURL(addons[1].id)); + do_check_eq(blocklist.getAddonBlocklistURL(addons[2]),create_blocklistURL(addons[2].id)); + do_check_eq(blocklist.getAddonBlocklistURL(addons[3]),create_blocklistURL(addons[3].id)); + do_check_eq(blocklist.getAddonBlocklistURL(addons[4]),create_blocklistURL(addons[4].id)); // All plugins have the same blockID on the test do_check_eq(blocklist.getPluginBlocklistURL(PLUGINS[0]), create_blocklistURL('test_bug455906_plugin')); diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini index 53f1b1a46c27..1b5c99b3f638 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini @@ -17,6 +17,7 @@ skip-if = os == "android" [test_badschema.js] [test_blocklistchange.js] [test_blocklist_prefs.js] +[test_blocklist_metadata_filters.js] # Bug 676992: test consistently hangs on Android skip-if = os == "android" [test_blocklist_regexp.js] diff --git a/toolkit/mozapps/update/content/updates.js b/toolkit/mozapps/update/content/updates.js index 494a22020567..7cebf0f2e36d 100644 --- a/toolkit/mozapps/update/content/updates.js +++ b/toolkit/mozapps/update/content/updates.js @@ -869,7 +869,7 @@ var gIncompatibleCheckPage = { // the add-on will become incompatible. let bs = CoC["@mozilla.org/extensions/blocklist;1"]. getService(CoI.nsIBlocklistService); - if (bs.isAddonBlocklisted(addon.id, install.version, + if (bs.isAddonBlocklisted(addon, gUpdates.update.appVersion, gUpdates.update.platformVersion)) return; diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index e6475389e9d2..8550e5e2bc39 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -2972,7 +2972,7 @@ UpdateService.prototype = { // the add-on will become incompatible. let bs = Cc["@mozilla.org/extensions/blocklist;1"]. getService(Ci.nsIBlocklistService); - if (bs.isAddonBlocklisted(addon.id, install.version, + if (bs.isAddonBlocklisted(addon, gUpdates.update.appVersion, gUpdates.update.platformVersion)) return; diff --git a/xpcom/system/nsIBlocklistService.idl b/xpcom/system/nsIBlocklistService.idl index 5f8104b0b6db..eecfc68afd0d 100644 --- a/xpcom/system/nsIBlocklistService.idl +++ b/xpcom/system/nsIBlocklistService.idl @@ -29,10 +29,8 @@ interface nsIBlocklistService : nsISupports /** * Determine if an item is blocklisted - * @param id - * The ID of the item. - * @param version - * The item's version. + * @param addon + * The addon item to be checked. * @param appVersion * The version of the application we are checking in the blocklist. * If this parameter is null, the version of the running application @@ -44,16 +42,14 @@ interface nsIBlocklistService : nsISupports * @returns true if the item is compatible with this version of the * application or this version of the toolkit, false, otherwise. */ - boolean isAddonBlocklisted(in AString id, in AString version, + boolean isAddonBlocklisted(in jsval addon, [optional] in AString appVersion, [optional] in AString toolkitVersion); /** * Determine the blocklist state of an add-on * @param id - * The ID of the item. - * @param version - * The item's version. + * The addon item to be checked. * @param appVersion * The version of the application we are checking in the blocklist. * If this parameter is null, the version of the running application @@ -64,7 +60,7 @@ interface nsIBlocklistService : nsISupports * is used. * @returns The STATE constant. */ - unsigned long getAddonBlocklistState(in AString id, in AString version, + unsigned long getAddonBlocklistState(in jsval addon, [optional] in AString appVersion, [optional] in AString toolkitVersion); @@ -88,11 +84,11 @@ interface nsIBlocklistService : nsISupports /** * Determine the blocklist web page of an add-on. - * @param id - * The ID of the blocked add-on. + * @param addon + * The addon item whose url is required. * @returns The URL of the description page. */ - AString getAddonBlocklistURL(in AString id, in AString version, + AString getAddonBlocklistURL(in jsval addon, [optional] in AString appVersion, [optional] in AString toolkitVersion); From 548263d14d1663390bf10b4d9ebfcae6ca81bc31 Mon Sep 17 00:00:00 2001 From: Ricardo Palomares Date: Mon, 6 Jan 2014 09:58:05 -0500 Subject: [PATCH 23/33] Bug 918017 - Add debugger accesskey entities and rename those that were named after ".key" but were accesskeys. r=fitzgen --- browser/devtools/debugger/debugger.xul | 30 ++++---- .../chrome/browser/devtools/debugger.dtd | 72 ++++++++++--------- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/browser/devtools/debugger/debugger.xul b/browser/devtools/debugger/debugger.xul index f6fec1854fc5..5c87349b1080 100644 --- a/browser/devtools/debugger/debugger.xul +++ b/browser/devtools/debugger/debugger.xul @@ -118,39 +118,39 @@ @@ -182,32 +182,32 @@ diff --git a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd index 8068ccc46826..7f2e7aba8c36 100644 --- a/browser/locales/en-US/chrome/browser/devtools/debugger.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/debugger.dtd @@ -68,36 +68,36 @@ - - + + - - + + - - + + - - + + - - + + - - + + @@ -105,39 +105,46 @@ - - - + + + + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + @@ -145,8 +152,8 @@ - - + + - + - - + + +