From ecc44651c4cf9e63a7d8083e6da7214388b45f12 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 22 Oct 2013 12:11:30 +0200 Subject: [PATCH 01/75] Bug 928727 - Share code for getting the user-space clip bounds in DrawTargetCairo. r=jrmuizel --- gfx/2d/DrawTargetCairo.cpp | 21 ++++++++++----------- gfx/2d/DrawTargetCairo.h | 2 ++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp index 44a5a0cf8db..213de9514dd 100644 --- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -512,13 +512,10 @@ DrawTargetCairo::DrawSurface(SourceSurface *aSurface, cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode)); - double clipX1, clipY1, clipX2, clipY2; - cairo_clip_extents(mContext, &clipX1, &clipY1, &clipX2, &clipY2); - Rect clip(clipX1, clipY1, clipX2 - clipX1, clipY2 - clipY1); // Narrowing of doubles to floats // If the destination rect covers the entire clipped area, then unbounded and bounded // operations are identical, and we don't need to push a group. bool needsGroup = !IsOperatorBoundByMask(aOptions.mCompositionOp) && - !aDest.Contains(clip); + !aDest.Contains(GetUserSpaceClip()); cairo_translate(mContext, aDest.X(), aDest.Y()); @@ -682,13 +679,7 @@ DrawTargetCairo::FillRect(const Rect &aRect, bool pathBoundsClip = false; - double cexts[4]; - cairo_clip_extents(mContext, &cexts[0], &cexts[1], &cexts[2], &cexts[3]); - Rect clipRect(cexts[0], cexts[1], cexts[2] - cexts[0], cexts[3] - cexts[1]); - double pexts[4]; - cairo_path_extents(mContext, &pexts[0], &pexts[1], &pexts[2], &pexts[3]); - Rect pathRect(pexts[0], pexts[1], pexts[2] - pexts[0], pexts[3] - pexts[1]); - if (pathRect.Contains(clipRect)) { + if (aRect.Contains(GetUserSpaceClip())) { pathBoundsClip = true; } @@ -1192,6 +1183,14 @@ DrawTargetCairo::SetTransform(const Matrix& aTransform) cairo_set_matrix(mContext, &mat); } +Rect +DrawTargetCairo::GetUserSpaceClip() +{ + double clipX1, clipY1, clipX2, clipY2; + cairo_clip_extents(mContext, &clipX1, &clipY1, &clipX2, &clipY2); + return Rect(clipX1, clipY1, clipX2 - clipX1, clipY2 - clipY1); // Narrowing of doubles to floats +} + cairo_t* BorrowedCairoContext::BorrowCairoContextFromDrawTarget(DrawTarget* aDT) { diff --git a/gfx/2d/DrawTargetCairo.h b/gfx/2d/DrawTargetCairo.h index f23b6241dce..22a006fe27f 100644 --- a/gfx/2d/DrawTargetCairo.h +++ b/gfx/2d/DrawTargetCairo.h @@ -172,6 +172,8 @@ private: // methods const IntRect& aSource, const IntPoint& aDest); + Rect GetUserSpaceClip(); + // Call before you make any changes to the backing surface with which this // context is associated. Pass the path you're going to be using if you have // one. From 3c5391d9b3f029c0137d13e1ba8e8971ce4444c9 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 22 Oct 2013 12:11:30 +0200 Subject: [PATCH 02/75] Bug 928727 - Don't clear before drawing with OPERATOR_SOURCE in DrawTargetCairo, since we know all required pixels will be clear already. r=jrmuizel --- gfx/2d/DrawTargetCairo.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp index 213de9514dd..3f4c7f8b5c6 100644 --- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -635,8 +635,6 @@ DrawTargetCairo::DrawPattern(const Pattern& aPattern, (!IsOperatorBoundByMask(aOptions.mCompositionOp) && !aPathBoundsClip)) { cairo_push_group_with_content(mContext, CAIRO_CONTENT_COLOR_ALPHA); - ClearSurfaceForUnboundedSource(aOptions.mCompositionOp); - // Don't want operators to be applied twice cairo_set_operator(mContext, CAIRO_OPERATOR_OVER); @@ -653,7 +651,6 @@ DrawTargetCairo::DrawPattern(const Pattern& aPattern, cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp)); cairo_paint_with_alpha(mContext, aOptions.mAlpha); } else { - ClearSurfaceForUnboundedSource(aOptions.mCompositionOp); cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp)); if (aDrawType == DRAW_STROKE) { From ffa5c8feb9347839b038ac100803ad78ad112f4c Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Tue, 22 Oct 2013 12:19:03 +0200 Subject: [PATCH 03/75] Bug 928889: Baseline: Return the correct *pc when in prologue, r=jandem --- js/src/jit/IonFrames.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/src/jit/IonFrames.cpp b/js/src/jit/IonFrames.cpp index cc20ed209d2..171465e510e 100644 --- a/js/src/jit/IonFrames.cpp +++ b/js/src/jit/IonFrames.cpp @@ -184,9 +184,10 @@ IonFrameIterator::baselineScriptAndPc(JSScript **scriptRes, jsbytecode **pcRes) *scriptRes = script; uint8_t *retAddr = returnAddressToFp(); if (pcRes) { - // If the return address is into the prologue entry addr, then assume PC 0. + // If the return address is into the prologue entry address, then assume start + // of script. if (retAddr == script->baselineScript()->prologueEntryAddr()) { - *pcRes = 0; + *pcRes = script->code; return; } From 14e4217296965341520165484233d1a3ef0184a4 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 22 Oct 2013 12:30:45 +0200 Subject: [PATCH 04/75] Bug 929362 - When refusing compositor animation during BuildLayer, set a property on the frame that disables all async animations on it forever. r=roc --HG-- extra : rebase_source : 98c9b690a4842c19314dd46f5e531601b77fe527 --- layout/base/nsDisplayList.cpp | 12 ++++++++++-- layout/generic/nsIFrame.h | 2 ++ layout/style/AnimationCommon.cpp | 7 +++++++ layout/style/AnimationCommon.h | 3 +++ layout/style/nsAnimationManager.cpp | 3 ++- layout/style/nsTransitionManager.cpp | 3 ++- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 6ce8705f123..9d6cf4a875f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -377,9 +377,17 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder return; } - // If the frame is not prerendered, bail out. Layout will still perform the - // animation. + // If the frame is not prerendered, bail out. if (!aItem->CanUseAsyncAnimations(aBuilder)) { + // AnimationManager or TransitionManager need to know that we refused to + // run this animation asynchronously so that they will not throttle the + // main thread animation. + frame->Properties().Set(nsIFrame::RefusedAsyncAnimation(), + reinterpret_cast(intptr_t(true))); + + // We need to schedule another refresh driver run so that AnimationManager + // or TransitionManager get a chance to unthrottle the animation. + frame->SchedulePaint(); return; } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 4680e7207c4..7ee21dae3a7 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -994,6 +994,8 @@ public: NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect) + NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr) + /** * Return the distance between the border edge of the frame and the * margin edge of the frame. Like GetRect(), returns the dimensions diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 39914edace6..dcda64cb328 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -288,6 +288,13 @@ CommonElementAnimationData::CanAnimatePropertyOnCompositor(const dom::Element *a return enabled && propertyAllowed; } +/* static */ bool +CommonElementAnimationData::IsCompositorAnimationDisabledForFrame(nsIFrame* aFrame) +{ + void* prop = aFrame->Properties().Get(nsIFrame::RefusedAsyncAnimation()); + return bool(reinterpret_cast(prop)); +} + /* static */ void CommonElementAnimationData::LogAsyncAnimationFailure(nsCString& aMessage, const nsIContent* aContent) diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 09f18a2f236..85e5b54b04e 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -19,6 +19,7 @@ #include "mozilla/Attributes.h" class nsPresContext; +class nsIFrame; namespace mozilla { @@ -175,6 +176,8 @@ struct CommonElementAnimationData : public PRCList nsCSSProperty aProperty, CanAnimateFlags aFlags); + static bool IsCompositorAnimationDisabledForFrame(nsIFrame* aFrame); + // True if this animation can be performed on the compositor thread. // Do not pass CanAnimate_AllowPartial to make sure that all properties of this // animation are supported by the compositor. diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 25efe0aae75..5c19a927bad 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -402,7 +402,8 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const const AnimationProperty& prop = anim.mProperties[propIdx]; if (!CanAnimatePropertyOnCompositor(mElement, prop.mProperty, - aFlags)) { + aFlags) || + IsCompositorAnimationDisabledForFrame(frame)) { return false; } if (prop.mProperty == eCSSProperty_opacity) { diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 9978693acff..3e969b34d3c 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -178,7 +178,8 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(mElement, pt.mProperty, - aFlags)) { + aFlags) || + !css::CommonElementAnimationData::IsCompositorAnimationDisabledForFrame(frame)) { return false; } if (pt.mProperty == eCSSProperty_opacity) { From adddcfb9eafb7a10022dd33f638118c541ea98a5 Mon Sep 17 00:00:00 2001 From: John Daggett Date: Tue, 22 Oct 2013 13:06:20 +0200 Subject: [PATCH 05/75] Bug 915440 - move null URL fix to after format hint is processed. r=dbaron --- layout/style/nsFontFaceLoader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index 95acb78ee79..dfa8930c4c3 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -622,12 +622,6 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType, case eCSSUnit_URL: face->mIsLocal = false; face->mURI = val.GetURLValue(); - if (!face->mURI) { - // if URI not valid, omit from src array - srcArray.RemoveElementAt(srcArray.Length() - 1); - NS_WARNING("null url in @font-face rule"); - continue; - } face->mReferrer = val.GetURLStructValue()->mReferrer; face->mOriginPrincipal = val.GetURLStructValue()->mOriginPrincipal; NS_ASSERTION(face->mOriginPrincipal, "null origin principal in @font-face rule"); @@ -663,6 +657,12 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType, } i++; } + if (!face->mURI) { + // if URI not valid, omit from src array + srcArray.RemoveElementAt(srcArray.Length() - 1); + NS_WARNING("null url in @font-face rule"); + continue; + } break; default: NS_ASSERTION(unit == eCSSUnit_Local_Font || unit == eCSSUnit_URL, From 8cf2c447b0109bf2409fb602aad41efce0e3bf0d Mon Sep 17 00:00:00 2001 From: John Daggett Date: Tue, 22 Oct 2013 13:06:20 +0200 Subject: [PATCH 06/75] Bug 915440. Crashtest for empty font URL. r=me --- layout/style/crashtests/915440.html | 4 ++++ layout/style/crashtests/crashtests.list | 1 + 2 files changed, 5 insertions(+) create mode 100644 layout/style/crashtests/915440.html diff --git a/layout/style/crashtests/915440.html b/layout/style/crashtests/915440.html new file mode 100644 index 00000000000..f3a291f1fee --- /dev/null +++ b/layout/style/crashtests/915440.html @@ -0,0 +1,4 @@ + + + + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index ad452bf767f..c6868516332 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -96,3 +96,4 @@ load 862113.html load 867487.html load 880862.html load 873222.html +load 915440.html From 4994ec8abe3394d245e69024dd15640a9034dc2b Mon Sep 17 00:00:00 2001 From: Christian Holler Date: Tue, 22 Oct 2013 13:27:23 +0200 Subject: [PATCH 07/75] Bug 844755 - TSan: Blacklist js::gc::ChunkBitmap::isMarked. r=jonco --- js/src/gc/Heap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 2ae6ac20b6f..47f4d96b969 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -684,7 +684,7 @@ struct ChunkBitmap GetGCThingMarkWordAndMask(cell, color, wordp, maskp); } - MOZ_ALWAYS_INLINE bool isMarked(const Cell *cell, uint32_t color) { + MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool isMarked(const Cell *cell, uint32_t color) { uintptr_t *word, mask; getMarkWordAndMask(cell, color, &word, &mask); return *word & mask; From d51d4f7e86a42e7fef1a9d7968251d409748065b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 22 Oct 2013 13:37:57 +0200 Subject: [PATCH 08/75] Bug 764299 (Part 1) - Add hashing to SVGImageContext. r=dholbert --- content/svg/content/src/SVGPreserveAspectRatio.h | 10 +++++++++- layout/svg/SVGImageContext.h | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/content/svg/content/src/SVGPreserveAspectRatio.h b/content/svg/content/src/SVGPreserveAspectRatio.h index bce48454b31..f32bbc8401a 100644 --- a/content/svg/content/src/SVGPreserveAspectRatio.h +++ b/content/svg/content/src/SVGPreserveAspectRatio.h @@ -3,8 +3,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#pragma once +#ifndef MOZILLA_CONTENT_SVGPRESERVEASPECTRATIO_H_ +#define MOZILLA_CONTENT_SVGPRESERVEASPECTRATIO_H_ +#include "mozilla/HashFunctions.h" // for HashGeneric #include "mozilla/TypedEnum.h" #include "nsWrapperCache.h" @@ -98,6 +100,10 @@ public: return mDefer; } + uint32_t Hash() const { + return HashGeneric(mAlign, mMeetOrSlice, mDefer); + } + private: // We can't use enum types here because some compilers fail to pack them. uint8_t mAlign; @@ -141,3 +147,5 @@ protected: } //namespace dom } //namespace mozilla + +#endif // MOZILLA_CONTENT_SVGPRESERVEASPECTRATIO_H_ diff --git a/layout/svg/SVGImageContext.h b/layout/svg/SVGImageContext.h index a0f4d5f32d7..22560620b07 100644 --- a/layout/svg/SVGImageContext.h +++ b/layout/svg/SVGImageContext.h @@ -16,6 +16,8 @@ namespace mozilla { class SVGImageContext { public: + SVGImageContext() { } + SVGImageContext(SVGPreserveAspectRatio aPreserveAspectRatio) : mPreserveAspectRatio(aPreserveAspectRatio) { } @@ -32,8 +34,12 @@ public: return !(*this == aOther); } + uint32_t Hash() const { + return mPreserveAspectRatio.Hash(); + } + private: - const SVGPreserveAspectRatio mPreserveAspectRatio; + SVGPreserveAspectRatio mPreserveAspectRatio; }; } // namespace mozilla From 140f10b0a1bbe52aeb11f65d95f229118c069708 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 22 Oct 2013 13:37:59 +0200 Subject: [PATCH 09/75] Bug 764299 (Part 2) - Add a temporary surface cache to imagelib. r=dholbert --- content/svg/content/src/moz.build | 1 + image/build/nsImageModule.cpp | 3 + image/src/SurfaceCache.cpp | 490 ++++++++++++++++++++++++++++++ image/src/SurfaceCache.h | 172 +++++++++++ image/src/moz.build | 1 + modules/libpref/src/init/all.js | 14 + 6 files changed, 681 insertions(+) create mode 100644 image/src/SurfaceCache.cpp create mode 100644 image/src/SurfaceCache.h diff --git a/content/svg/content/src/moz.build b/content/svg/content/src/moz.build index f33253988a7..f3bc1277f6d 100644 --- a/content/svg/content/src/moz.build +++ b/content/svg/content/src/moz.build @@ -8,6 +8,7 @@ MODULE = 'content' EXPORTS += [ 'SVGAttrValueWrapper.h', + 'SVGPreserveAspectRatio.h', 'SVGStringList.h', 'nsSVGClass.h', 'nsSVGElement.h', diff --git a/image/build/nsImageModule.cpp b/image/build/nsImageModule.cpp index a9023902b3c..837669082ff 100644 --- a/image/build/nsImageModule.cpp +++ b/image/build/nsImageModule.cpp @@ -9,6 +9,7 @@ #include "ImageFactory.h" #include "RasterImage.h" +#include "SurfaceCache.h" #include "imgLoader.h" #include "imgRequest.h" @@ -84,6 +85,7 @@ imglib_Initialize() mozilla::image::DiscardTracker::Initialize(); mozilla::image::ImageFactory::Initialize(); mozilla::image::RasterImage::Initialize(); + mozilla::image::SurfaceCache::Initialize(); imgLoader::GlobalInit(); return NS_OK; } @@ -92,6 +94,7 @@ static void imglib_Shutdown() { imgLoader::Shutdown(); + mozilla::image::SurfaceCache::Shutdown(); mozilla::image::DiscardTracker::Shutdown(); } diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp new file mode 100644 index 00000000000..06df33221e2 --- /dev/null +++ b/image/src/SurfaceCache.cpp @@ -0,0 +1,490 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * SurfaceCache is a service for caching temporary surfaces in imagelib. + */ + +#include "SurfaceCache.h" + +#include +#include "mozilla/Attributes.h" // for MOZ_THIS_IN_INITIALIZER_LIST +#include "mozilla/DebugOnly.h" +#include "mozilla/Preferences.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Util.h" // for Maybe +#include "gfxASurface.h" +#include "gfxPattern.h" // Workaround for flaw in bug 921753 part 2. +#include "gfxDrawable.h" +#include "gfxPlatform.h" +#include "nsAutoPtr.h" +#include "nsExpirationTracker.h" +#include "nsHashKeys.h" +#include "nsRefPtrHashtable.h" +#include "nsSize.h" +#include "nsTArray.h" +#include "prsystem.h" +#include "SVGImageContext.h" + +using std::max; +using std::min; +using mozilla::gfx::DrawTarget; + +/** + * Hashtable key class to use with objects for which Hash() and operator==() + * are defined. + * XXX(seth): This will get moved to xpcom/glue/nsHashKeys.h in a followup bug. + */ +template +class nsGenericHashKey : public PLDHashEntryHdr +{ +public: + typedef const T& KeyType; + typedef const T* KeyTypePointer; + + nsGenericHashKey(KeyTypePointer aKey) : mKey(*aKey) { } + nsGenericHashKey(const nsGenericHashKey& aOther) : mKey(aOther.mKey) { } + + KeyType GetKey() const { return mKey; } + bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mKey; } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); } + enum { ALLOW_MEMMOVE = true }; + +private: + T mKey; +}; + +namespace mozilla { +namespace image { + +/////////////////////////////////////////////////////////////////////////////// +// SurfaceCache Implementation +/////////////////////////////////////////////////////////////////////////////// + +class CachedSurface; +class SurfaceCacheImpl; + +/* + * Cost models the cost of storing a surface in the cache. Right now, this is + * simply an estimate of the size of the surface in bytes, but in the future it + * may be worth taking into account the cost of rematerializing the surface as + * well. + */ +typedef size_t Cost; + +static Cost ComputeCost(const nsIntSize aSize) +{ + return aSize.width * aSize.height * 4; // width * height * 4 bytes (32bpp) +} + +/* + * Since we want to be able to make eviction decisions based on cost, we need to + * be able to look up the CachedSurface which has a certain cost as well as the + * cost associated with a certain CachedSurface. To make this possible, in data + * structures we actually store a CostEntry, which contains a weak pointer to + * its associated surface. + * + * To make usage of the weak pointer safe, SurfaceCacheImpl always calls + * StartTracking after a surface is stored in the cache and StopTracking before + * it is removed. + */ +class CostEntry +{ +public: + CostEntry(CachedSurface* aSurface, Cost aCost) + : mSurface(aSurface) + , mCost(aCost) + { + MOZ_ASSERT(aSurface, "Must have a surface"); + } + + CachedSurface* GetSurface() const { return mSurface; } + Cost GetCost() const { return mCost; } + + bool operator==(const CostEntry& aOther) const + { + return mSurface == aOther.mSurface && + mCost == aOther.mCost; + } + + bool operator<(const CostEntry& aOther) const + { + return mCost < aOther.mCost || + (mCost == aOther.mCost && mSurface < aOther.mSurface); + } + +private: + CachedSurface* mSurface; + Cost mCost; +}; + +/* + * A CachedSurface associates a surface with a key that uniquely identifies that + * surface. + */ +class CachedSurface : public RefCounted +{ +public: + CachedSurface(DrawTarget* aTarget, + const nsIntSize aTargetSize, + const Cost aCost, + const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) + : mTarget(aTarget) + , mTargetSize(aTargetSize) + , mCost(aCost) + , mImageKey(aImageKey) + , mSurfaceKey(aSurfaceKey) + { + MOZ_ASSERT(mTarget, "Must have a valid DrawTarget"); + MOZ_ASSERT(mImageKey, "Must have a valid image key"); + } + + already_AddRefed Drawable() const + { + nsRefPtr surface = + gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget); + nsRefPtr drawable = new gfxSurfaceDrawable(surface, mTargetSize); + return drawable.forget(); + } + + ImageKey GetImageKey() const { return mImageKey; } + SurfaceKey GetSurfaceKey() const { return mSurfaceKey; } + CostEntry GetCostEntry() { return image::CostEntry(this, mCost); } + nsExpirationState* GetExpirationState() { return &mExpirationState; } + +private: + nsExpirationState mExpirationState; + nsRefPtr mTarget; + const nsIntSize mTargetSize; + const Cost mCost; + const ImageKey mImageKey; + const SurfaceKey mSurfaceKey; +}; + +/* + * An ImageSurfaceCache is a per-image surface cache. For correctness we must be + * able to remove all surfaces associated with an image when the image is + * destroyed or invalidated. Since this will happen frequently, it makes sense + * to make it cheap by storing the surfaces for each image separately. + */ +class ImageSurfaceCache : public RefCounted +{ +public: + typedef nsRefPtrHashtable, CachedSurface> SurfaceTable; + + bool IsEmpty() const { return mSurfaces.Count() == 0; } + + void Insert(const SurfaceKey& aKey, CachedSurface* aSurface) + { + MOZ_ASSERT(aSurface, "Should have a surface"); + mSurfaces.Put(aKey, aSurface); + } + + void Remove(CachedSurface* aSurface) + { + MOZ_ASSERT(aSurface, "Should have a surface"); + MOZ_ASSERT(mSurfaces.GetWeak(aSurface->GetSurfaceKey()), + "Should not be removing a surface we don't have"); + + mSurfaces.Remove(aSurface->GetSurfaceKey()); + } + + already_AddRefed Lookup(const SurfaceKey& aSurfaceKey) + { + nsRefPtr surface; + mSurfaces.Get(aSurfaceKey, getter_AddRefs(surface)); + return surface.forget(); + } + + void ForEach(SurfaceTable::EnumReadFunction aFunction, void* aData) + { + mSurfaces.EnumerateRead(aFunction, aData); + } + +private: + SurfaceTable mSurfaces; +}; + +/* + * SurfaceCacheImpl is responsible for determining which surfaces will be cached + * and managing the surface cache data structures. Rather than interact with + * SurfaceCacheImpl directly, client code interacts with SurfaceCache, which + * maintains high-level invariants and encapsulates the details of the surface + * cache's implementation. + */ +class SurfaceCacheImpl +{ +public: + SurfaceCacheImpl(uint32_t aSurfaceCacheExpirationTimeMS, + uint32_t aSurfaceCacheSize) + : mExpirationTracker(MOZ_THIS_IN_INITIALIZER_LIST(), + aSurfaceCacheExpirationTimeMS) + , mMaxCost(aSurfaceCacheSize) + , mAvailableCost(aSurfaceCacheSize) + { } + + void Insert(DrawTarget* aTarget, + nsIntSize aTargetSize, + const Cost aCost, + const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) + { + MOZ_ASSERT(!Lookup(aImageKey, aSurfaceKey).get(), + "Inserting a duplicate drawable into the SurfaceCache"); + + // If this is bigger than the maximum cache size, refuse to cache it. + if (!CanHold(aCost)) + return; + + nsRefPtr surface = + new CachedSurface(aTarget, aTargetSize, aCost, aImageKey, aSurfaceKey); + + // Remove elements in order of cost until we can fit this in the cache. + while (aCost > mAvailableCost) { + MOZ_ASSERT(!mCosts.IsEmpty(), "Removed everything and it still won't fit"); + Remove(mCosts.LastElement().GetSurface()); + } + + // Locate the appropriate per-image cache. If there's not an existing cache + // for this image, create it. + nsRefPtr cache = GetImageCache(aImageKey); + if (!cache) { + cache = new ImageSurfaceCache; + mImageCaches.Put(aImageKey, cache); + } + + // Insert. + MOZ_ASSERT(aCost <= mAvailableCost, "Inserting despite too large a cost"); + cache->Insert(aSurfaceKey, surface); + StartTracking(surface); + } + + void Remove(CachedSurface* aSurface) + { + MOZ_ASSERT(aSurface, "Should have a surface"); + const ImageKey imageKey = aSurface->GetImageKey(); + + nsRefPtr cache = GetImageCache(imageKey); + MOZ_ASSERT(cache, "Shouldn't try to remove a surface with no image cache"); + + StopTracking(aSurface); + cache->Remove(aSurface); + + // Remove the per-image cache if it's unneeded now. + if (cache->IsEmpty()) { + mImageCaches.Remove(imageKey); + } + } + + void StartTracking(CachedSurface* aSurface) + { + CostEntry costEntry = aSurface->GetCostEntry(); + MOZ_ASSERT(costEntry.GetCost() <= mAvailableCost, + "Cost too large and the caller didn't catch it"); + + mAvailableCost -= costEntry.GetCost(); + mCosts.InsertElementSorted(costEntry); + mExpirationTracker.AddObject(aSurface); + } + + void StopTracking(CachedSurface* aSurface) + { + MOZ_ASSERT(aSurface, "Should have a surface"); + CostEntry costEntry = aSurface->GetCostEntry(); + + mExpirationTracker.RemoveObject(aSurface); + DebugOnly foundInCosts = mCosts.RemoveElementSorted(costEntry); + mAvailableCost += costEntry.GetCost(); + + MOZ_ASSERT(foundInCosts, "Lost track of costs for this surface"); + MOZ_ASSERT(mAvailableCost <= mMaxCost, "More available cost than we started with"); + } + + already_AddRefed Lookup(const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) + { + nsRefPtr cache = GetImageCache(aImageKey); + if (!cache) + return nullptr; // No cached surfaces for this image. + + nsRefPtr surface = cache->Lookup(aSurfaceKey); + if (!surface) + return nullptr; // Lookup in the per-image cache missed. + + mExpirationTracker.MarkUsed(surface); + return surface->Drawable(); + } + + bool CanHold(const Cost aCost) const + { + return aCost <= mMaxCost; + } + + void Discard(const ImageKey aImageKey) + { + nsRefPtr cache = GetImageCache(aImageKey); + if (!cache) + return; // No cached surfaces for this image, so nothing to do. + + // Discard all of the cached surfaces for this image. + // XXX(seth): This is O(n^2) since for each item in the cache we are + // removing an element from the costs array. Since n is expected to be + // small, performance should be good, but if usage patterns change we should + // change the data structure used for mCosts. + cache->ForEach(DoStopTracking, this); + + // The per-image cache isn't needed anymore, so remove it as well. + mImageCaches.Remove(aImageKey); + } + + static PLDHashOperator DoStopTracking(const SurfaceKey&, + CachedSurface* aSurface, + void* aCache) + { + static_cast(aCache)->StopTracking(aSurface); + return PL_DHASH_NEXT; + } + +private: + already_AddRefed GetImageCache(const ImageKey aImageKey) + { + nsRefPtr imageCache; + mImageCaches.Get(aImageKey, getter_AddRefs(imageCache)); + return imageCache.forget(); + } + + struct SurfaceTracker : public nsExpirationTracker + { + SurfaceTracker(SurfaceCacheImpl* aCache, uint32_t aSurfaceCacheExpirationTimeMS) + : nsExpirationTracker(aSurfaceCacheExpirationTimeMS) + , mCache(aCache) + { } + + protected: + virtual void NotifyExpired(CachedSurface* aSurface) MOZ_OVERRIDE + { + if (mCache) { + mCache->Remove(aSurface); + } + } + + private: + SurfaceCacheImpl* const mCache; // Weak pointer to owner. + }; + + nsTArray mCosts; + nsRefPtrHashtable, ImageSurfaceCache> mImageCaches; + SurfaceTracker mExpirationTracker; + const Cost mMaxCost; + Cost mAvailableCost; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Static Data +/////////////////////////////////////////////////////////////////////////////// + +// The single surface cache instance. +static SurfaceCacheImpl* sInstance = nullptr; + + +/////////////////////////////////////////////////////////////////////////////// +// Public API +/////////////////////////////////////////////////////////////////////////////// + +/* static */ void +SurfaceCache::Initialize() +{ + // Initialize preferences. + MOZ_ASSERT(!sInstance, "Shouldn't initialize more than once"); + + // Length of time before an unused surface is removed from the cache, in milliseconds. + // The default value gives an expiration time of 1 minute. + uint32_t surfaceCacheExpirationTimeMS = + Preferences::GetUint("image.mem.surfacecache.min_expiration_ms", 60 * 1000); + + // Maximum size of the surface cache, in kilobytes. + // The default is 100MB. (But we may override this for e.g. B2G.) + uint32_t surfaceCacheMaxSizeKB = + Preferences::GetUint("image.mem.surfacecache.max_size_kb", 100 * 1024); + + // A knob determining the actual size of the surface cache. Currently the + // cache is (size of main memory) / (surface cache size factor) KB + // or (surface cache max size) KB, whichever is smaller. The formula + // may change in the future, though. + // The default value is 64, which yields a 64MB cache on a 4GB machine. + // The smallest machines we are likely to run this code on have 256MB + // of memory, which would yield a 4MB cache on the default setting. + uint32_t surfaceCacheSizeFactor = + Preferences::GetUint("image.mem.surfacecache.size_factor", 64); + + // Clamp to avoid division by zero below. + surfaceCacheSizeFactor = max(surfaceCacheSizeFactor, 1u); + + // Compute the size of the surface cache. + uint32_t proposedSize = PR_GetPhysicalMemorySize() / surfaceCacheSizeFactor; + uint32_t surfaceCacheSizeBytes = min(proposedSize, surfaceCacheMaxSizeKB * 1024); + + // Create the surface cache singleton with the requested expiration time and + // size. Note that the size is a limit that the cache may not grow beyond, but + // we do not actually allocate any storage for surfaces at this time. + sInstance = new SurfaceCacheImpl(surfaceCacheExpirationTimeMS, + surfaceCacheSizeBytes); +} + +/* static */ void +SurfaceCache::Shutdown() +{ + MOZ_ASSERT(sInstance, "No singleton - was Shutdown() called twice?"); + delete sInstance; + sInstance = nullptr; +} + +/* static */ already_AddRefed +SurfaceCache::Lookup(const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) +{ + MOZ_ASSERT(sInstance, "Should be initialized"); + MOZ_ASSERT(NS_IsMainThread()); + + return sInstance->Lookup(aImageKey, aSurfaceKey); +} + +/* static */ void +SurfaceCache::Insert(DrawTarget* aTarget, + const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey) +{ + MOZ_ASSERT(sInstance, "Should be initialized"); + MOZ_ASSERT(NS_IsMainThread()); + + Cost cost = ComputeCost(aSurfaceKey.Size()); + return sInstance->Insert(aTarget, aSurfaceKey.Size(), cost, aImageKey, aSurfaceKey); +} + +/* static */ bool +SurfaceCache::CanHold(const nsIntSize& aSize) +{ + MOZ_ASSERT(sInstance, "Should be initialized"); + MOZ_ASSERT(NS_IsMainThread()); + + Cost cost = ComputeCost(aSize); + return sInstance->CanHold(cost); +} + +/* static */ void +SurfaceCache::Discard(Image* aImageKey) +{ + MOZ_ASSERT(sInstance, "Should be initialized"); + MOZ_ASSERT(NS_IsMainThread()); + + return sInstance->Discard(aImageKey); +} + +} // namespace image +} // namespace mozilla diff --git a/image/src/SurfaceCache.h b/image/src/SurfaceCache.h new file mode 100644 index 00000000000..6c2f8f58c1a --- /dev/null +++ b/image/src/SurfaceCache.h @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * SurfaceCache is a service for caching temporary surfaces in imagelib. + */ + +#ifndef MOZILLA_IMAGELIB_SURFACECACHE_H_ +#define MOZILLA_IMAGELIB_SURFACECACHE_H_ + +#include "mozilla/HashFunctions.h" // for HashGeneric and AddToHash +#include "gfxPoint.h" // for gfxSize +#include "nsCOMPtr.h" // for already_AddRefed +#include "nsSize.h" // for nsIntSize +#include "SVGImageContext.h" // for SVGImageContext + +class gfxDrawable; + +namespace mozilla { + +namespace gfx { +class DrawTarget; +} // namespace gfx + +namespace image { + +class Image; + +/* + * ImageKey contains the information we need to look up all cached surfaces for + * a particular image. + */ +typedef Image* ImageKey; + +/* + * SurfaceKey contains the information we need to look up a specific cached + * surface. Together with an ImageKey, this uniquely identifies the surface. + * + * XXX(seth): Right now this is specialized to the needs of VectorImage. We'll + * generalize it in bug 919071. + */ +class SurfaceKey +{ +public: + SurfaceKey(const nsIntSize aSize, + const gfxSize aScale, + const SVGImageContext* aSVGContext, + const float aAnimationTime, + const uint32_t aFlags) + : mSize(aSize) + , mScale(aScale) + , mSVGContextIsValid(aSVGContext != nullptr) + , mAnimationTime(aAnimationTime) + , mFlags(aFlags) + { + // XXX(seth): Would love to use Maybe here, but see bug 913586. + if (mSVGContextIsValid) + mSVGContext = *aSVGContext; + } + + bool operator==(const SurfaceKey& aOther) const + { + bool matchesSVGContext = aOther.mSVGContextIsValid == mSVGContextIsValid && + (!mSVGContextIsValid || aOther.mSVGContext == mSVGContext); + return aOther.mSize == mSize && + aOther.mScale == mScale && + matchesSVGContext && + aOther.mAnimationTime == mAnimationTime && + aOther.mFlags == mFlags; + } + + uint32_t Hash() const + { + uint32_t hash = HashGeneric(mSize.width, mSize.height); + hash = AddToHash(hash, mScale.width, mScale.height); + hash = AddToHash(hash, mSVGContextIsValid, mSVGContext.Hash()); + hash = AddToHash(hash, mAnimationTime, mFlags); + return hash; + } + + nsIntSize Size() const { return mSize; } + +private: + nsIntSize mSize; + gfxSize mScale; + SVGImageContext mSVGContext; + bool mSVGContextIsValid; + float mAnimationTime; + uint32_t mFlags; +}; + +/** + * SurfaceCache is an imagelib-global service that allows caching of temporary + * surfaces. Surfaces expire from the cache automatically if they go too long + * without being accessed. + * + * SurfaceCache is not thread-safe; it should only be accessed from the main + * thread. + */ +struct SurfaceCache +{ + /* + * Initialize static data. Called during imagelib module initialization. + */ + static void Initialize(); + + /* + * Release static data. Called during imagelib module shutdown. + */ + static void Shutdown(); + + /* + * Look up a surface in the cache. + * + * @param aImageKey Key data identifying which image the surface belongs to. + * @param aSurfaceKey Key data which uniquely identifies the requested surface. + * + * @return the requested surface, or nullptr if not found. + */ + static already_AddRefed Lookup(const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey); + + /* + * Insert a surface into the cache. It is an error to call this function + * without first calling Lookup to verify that the surface is not already in + * the cache. + * + * @param aTarget The new surface (in the form of a DrawTarget) to insert + * into the cache. + * @param aImageKey Key data identifying which image the surface belongs to. + * @param aSurfaceKey Key data which uniquely identifies the requested surface. + */ + static void Insert(mozilla::gfx::DrawTarget* aTarget, + const ImageKey aImageKey, + const SurfaceKey& aSurfaceKey); + + /* + * Checks if a surface of a given size could possibly be stored in the cache. + * If CanHold() returns false, Insert() will always fail to insert the + * surface, but the inverse is not true: Insert() may take more information + * into account than just image size when deciding whether to cache the + * surface, so Insert() may still fail even if CanHold() returns true. + * + * Use CanHold() to avoid the need to create a temporary surface when we know + * for sure the cache can't hold it. + * + * @param aSize The dimensions of a surface in pixels. + * + * @return false if the surface cache can't hold a surface of that size. + */ + static bool CanHold(const nsIntSize& aSize); + + /* + * Evicts any cached surfaces associated with the given image from the cache. + * This MUST be called, at a minimum, when the image is destroyed. If + * another image were allocated at the same address it could result in + * subtle, difficult-to-reproduce bugs. + * + * @param aImageKey The image which should be removed from the cache. + */ + static void Discard(const ImageKey aImageKey); + +private: + virtual ~SurfaceCache() = 0; // Forbid instantiation. +}; + +} // namespace image +} // namespace mozilla + +#endif // MOZILLA_IMAGELIB_SURFACECACHE_H_ diff --git a/image/src/moz.build b/image/src/moz.build index 8f5330fe542..1dd397518b8 100644 --- a/image/src/moz.build +++ b/image/src/moz.build @@ -31,6 +31,7 @@ CPP_SOURCES += [ 'RasterImage.cpp', 'SVGDocumentWrapper.cpp', 'ScriptedNotificationObserver.cpp', + 'SurfaceCache.cpp', 'VectorImage.cpp', 'imgFrame.cpp', 'imgLoader.cpp', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 7ddc5462f95..0faf7ffdf2d 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -4087,6 +4087,20 @@ pref("image.mem.max_ms_before_yield", 5); // might keep around more than this, but we'll try to get down to this value). pref("image.mem.max_decoded_image_kb", 51200); +// Minimum timeout for expiring unused images from the surface cache, in +// milliseconds. This controls how long we store cached temporary surfaces. +pref("image.mem.surfacecache.min_expiration_ms", 60000); // 60ms + +// Maximum size for the surface cache, in kilobytes. +pref("image.mem.surfacecache.max_size_kb", 102400); // 100MB + +// The surface cache's size, within the constraints of the maximum size set +// above, is determined using a formula based on system capabilities like memory +// size. The size factor is used to tune this formula. Larger size factors +// result in smaller caches. The default should be a good balance for most +// systems. +pref("image.mem.surfacecache.size_factor", 64); + // Whether we decode images on multiple background threads rather than the // foreground thread. pref("image.multithreaded_decoding.enabled", true); From 5d5705049ebecdac2b669856386ddf5d3e72de72 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 22 Oct 2013 13:38:01 +0200 Subject: [PATCH 10/75] Bug 764299 (Part 3) - Add memory reporting to the surface cache. r=njn --- image/src/SurfaceCache.cpp | 93 +++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index 06df33221e2..faeba52f1e0 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -61,13 +61,21 @@ private: namespace mozilla { namespace image { +class CachedSurface; +class SurfaceCacheImpl; + +/////////////////////////////////////////////////////////////////////////////// +// Static Data +/////////////////////////////////////////////////////////////////////////////// + +// The single surface cache instance. +static SurfaceCacheImpl* sInstance = nullptr; + + /////////////////////////////////////////////////////////////////////////////// // SurfaceCache Implementation /////////////////////////////////////////////////////////////////////////////// -class CachedSurface; -class SurfaceCacheImpl; - /* * Cost models the cost of storing a surface in the cache. Right now, this is * simply an estimate of the size of the surface in bytes, but in the future it @@ -224,9 +232,26 @@ public: uint32_t aSurfaceCacheSize) : mExpirationTracker(MOZ_THIS_IN_INITIALIZER_LIST(), aSurfaceCacheExpirationTimeMS) + , mReporter(new SurfaceCacheReporter) + , mMemoryPressureObserver(new MemoryPressureObserver) , mMaxCost(aSurfaceCacheSize) , mAvailableCost(aSurfaceCacheSize) - { } + { + NS_RegisterMemoryReporter(mReporter); + + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) + os->AddObserver(mMemoryPressureObserver, "memory-pressure", false); + } + + ~SurfaceCacheImpl() + { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) + os->RemoveObserver(mMemoryPressureObserver, "memory-pressure"); + + NS_UnregisterMemoryReporter(mReporter); + } void Insert(DrawTarget* aTarget, nsIntSize aTargetSize, @@ -342,6 +367,15 @@ public: mImageCaches.Remove(aImageKey); } + void DiscardAll() + { + // Remove in order of cost because mCosts is an array and the other data + // structures are all hash tables. + while (!mCosts.IsEmpty()) { + Remove(mCosts.LastElement().GetSurface()); + } + } + static PLDHashOperator DoStopTracking(const SurfaceKey&, CachedSurface* aSurface, void* aCache) @@ -350,6 +384,11 @@ public: return PL_DHASH_NEXT; } + int64_t SizeOfSurfacesEstimate() const + { + return int64_t(mMaxCost - mAvailableCost); + } + private: already_AddRefed GetImageCache(const ImageKey aImageKey) { @@ -377,21 +416,51 @@ private: SurfaceCacheImpl* const mCache; // Weak pointer to owner. }; + // XXX(seth): This is currently only an estimate and, since we don't know which + // surfaces are in GPU memory and which aren't, it's reported as KIND_OTHER and + // will also show up in heap-unclassified. Bug 923302 will make this nicer. + struct SurfaceCacheReporter : public MemoryUniReporter + { + SurfaceCacheReporter() + : MemoryUniReporter("imagelib-surface-cache", + KIND_OTHER, + UNITS_BYTES, + "Memory used by the imagelib temporary surface cache.") + { } + + protected: + int64_t Amount() MOZ_OVERRIDE + { + return sInstance ? sInstance->SizeOfSurfacesEstimate() : 0; + } + }; + + struct MemoryPressureObserver : public nsIObserver + { + NS_DECL_ISUPPORTS + + virtual ~MemoryPressureObserver() { } + + NS_IMETHOD Observe(nsISupports*, const char* aTopic, const PRUnichar*) + { + if (sInstance && strcmp(aTopic, "memory-pressure") == 0) { + sInstance->DiscardAll(); + } + return NS_OK; + } + }; + + nsTArray mCosts; nsRefPtrHashtable, ImageSurfaceCache> mImageCaches; SurfaceTracker mExpirationTracker; + nsRefPtr mReporter; + nsRefPtr mMemoryPressureObserver; const Cost mMaxCost; Cost mAvailableCost; }; - -/////////////////////////////////////////////////////////////////////////////// -// Static Data -/////////////////////////////////////////////////////////////////////////////// - -// The single surface cache instance. -static SurfaceCacheImpl* sInstance = nullptr; - +NS_IMPL_ISUPPORTS1(SurfaceCacheImpl::MemoryPressureObserver, nsIObserver) /////////////////////////////////////////////////////////////////////////////// // Public API From 6e507300dcda71df698f1e2b3dab0f981a2bf62b Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Tue, 22 Oct 2013 13:38:08 +0200 Subject: [PATCH 11/75] Bug 764299 (Part 4) - Cache rasterized surfaces in VectorImage. r=dholbert --- image/src/VectorImage.cpp | 217 +++++++++++++++++++++++++++++++------- image/src/VectorImage.h | 13 ++- 2 files changed, 186 insertions(+), 44 deletions(-) diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index b6d5ae96980..94847d857c3 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -7,6 +7,7 @@ #include "gfxContext.h" #include "gfxDrawable.h" +#include "gfxPlatform.h" #include "gfxUtils.h" #include "imgDecoderObserver.h" #include "mozilla/AutoRestore.h" @@ -23,6 +24,7 @@ #include "Orientation.h" #include "SVGDocumentWrapper.h" #include "nsIDOMEventListener.h" +#include "SurfaceCache.h" namespace mozilla { @@ -316,6 +318,7 @@ VectorImage::VectorImage(imgStatusTracker* aStatusTracker, VectorImage::~VectorImage() { CancelAllListeners(); + SurfaceCache::Discard(this); } //------------------------------------------------------------------------------ @@ -487,6 +490,9 @@ VectorImage::RequestRefresh(const mozilla::TimeStamp& aTime) // under WillRefresh() (which would be called by our own refresh driver) so // that we only send these notifications if we actually have a document // that is observing us. + // XXX(seth): We may need to duplicate this code so that non-animated images + // get handled correctly. See bug 922899. + SurfaceCache::Discard(this); mStatusTracker->FrameChanged(&nsIntRect::GetMaxSizedIntRect()); mStatusTracker->OnStopFrame(); } @@ -676,6 +682,65 @@ VectorImage::GetImageContainer(LayerManager* aManager, return NS_OK; } +struct SVGDrawingParameters +{ + SVGDrawingParameters(gfxContext* aContext, + GraphicsFilter aFilter, + const gfxMatrix& aUserSpaceToImageSpace, + const gfxRect& aFill, + const nsIntRect& aSubimage, + const nsIntSize& aViewportSize, + const SVGImageContext* aSVGContext, + float aAnimationTime, + uint32_t aFlags) + : context(aContext) + , filter(aFilter) + , fill(aFill) + , viewportSize(aViewportSize) + , animationTime(aAnimationTime) + , svgContext(aSVGContext) + , flags(aFlags) + { + // gfxUtils::DrawPixelSnapped may rasterize this image to a temporary surface + // if we hit the tiling path. Unfortunately, the temporary surface isn't + // created at the size at which we'll ultimately draw, causing fuzzy output. + // To fix this we pre-apply the transform's scaling to the drawing parameters + // and remove the scaling from the transform, so the fact that temporary + // surfaces won't take the scaling into account doesn't matter. (Bug 600207.) + scale = aUserSpaceToImageSpace.ScaleFactors(true); + gfxPoint translation(aUserSpaceToImageSpace.GetTranslation()); + + // Remove the scaling from the transform. + gfxMatrix unscale; + unscale.Translate(gfxPoint(translation.x / scale.width, + translation.y / scale.height)); + unscale.Scale(1.0 / scale.width, 1.0 / scale.height); + unscale.Translate(-translation); + userSpaceToImageSpace = aUserSpaceToImageSpace * unscale; + + // Rescale drawing parameters. + gfxIntSize drawableSize(aViewportSize.width / scale.width, + aViewportSize.height / scale.height); + sourceRect = userSpaceToImageSpace.Transform(aFill); + imageRect = nsIntRect(0, 0, drawableSize.width, drawableSize.height); + subimage = gfxRect(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height); + subimage.ScaleRoundOut(1.0 / scale.width, 1.0 / scale.height); + } + + gfxContext* context; + GraphicsFilter filter; + gfxMatrix userSpaceToImageSpace; + gfxRect fill; + gfxRect subimage; + gfxRect sourceRect; + nsIntRect imageRect; + nsIntSize viewportSize; + gfxSize scale; + float animationTime; + const SVGImageContext* svgContext; + uint32_t flags; +}; + //****************************************************************************** /* [noscript] void draw(in gfxContext aContext, * in gfxGraphicsFilter aFilter, @@ -716,58 +781,130 @@ VectorImage::Draw(gfxContext* aContext, AutoRestore autoRestoreIsDrawing(mIsDrawing); mIsDrawing = true; - float time = aWhichFrame == FRAME_FIRST ? 0.0f - : mSVGDocumentWrapper->GetCurrentTime(); - AutoSVGRenderingState autoSVGState(aSVGContext, - time, + float animTime = (aWhichFrame == FRAME_FIRST) ? 0.0f + : mSVGDocumentWrapper->GetCurrentTime(); + AutoSVGRenderingState autoSVGState(aSVGContext, animTime, mSVGDocumentWrapper->GetRootSVGElem()); - // gfxUtils::DrawPixelSnapped may rasterize this image to a temporary surface - // if we hit the tiling path. Unfortunately, the temporary surface isn't - // created at the size at which we'll ultimately draw, causing fuzzy output. - // To fix this we pre-apply the transform's scaling to the drawing parameters - // and remove the scaling from the transform, so the fact that temporary - // surfaces won't take the scaling into account doesn't matter. (Bug 600207.) - gfxSize scale(aUserSpaceToImageSpace.ScaleFactors(true)); - gfxPoint translation(aUserSpaceToImageSpace.GetTranslation()); + // Pack up the drawing parameters. + SVGDrawingParameters params(aContext, aFilter, aUserSpaceToImageSpace, aFill, + aSubimage, aViewportSize, aSVGContext, animTime, aFlags); - // Remove the scaling from the transform. - gfxMatrix unscale; - unscale.Translate(gfxPoint(translation.x / scale.width, - translation.y / scale.height)); - unscale.Scale(1.0 / scale.width, 1.0 / scale.height); - unscale.Translate(-translation); - gfxMatrix unscaledTransform(aUserSpaceToImageSpace * unscale); + // Check the cache. + nsRefPtr drawable = + SurfaceCache::Lookup(ImageKey(this), + SurfaceKey(params.imageRect.Size(), params.scale, + aSVGContext, animTime, aFlags)); - mSVGDocumentWrapper->UpdateViewportBounds(aViewportSize); + // Draw. + if (drawable) { + Show(drawable, params); + } else { + CreateDrawableAndShow(params); + } + + return NS_OK; +} + +void +VectorImage::CreateDrawableAndShow(const SVGDrawingParameters& aParams) +{ + mSVGDocumentWrapper->UpdateViewportBounds(aParams.viewportSize); mSVGDocumentWrapper->FlushImageTransformInvalidation(); - // Rescale drawing parameters. - gfxIntSize drawableSize(aViewportSize.width / scale.width, - aViewportSize.height / scale.height); - gfxRect drawableSourceRect = unscaledTransform.Transform(aFill); - gfxRect drawableImageRect(0, 0, drawableSize.width, drawableSize.height); - gfxRect drawableSubimage(aSubimage.x, aSubimage.y, - aSubimage.width, aSubimage.height); - drawableSubimage.ScaleRoundOut(1.0 / scale.width, 1.0 / scale.height); - nsRefPtr cb = new SVGDrawingCallback(mSVGDocumentWrapper, - nsIntRect(nsIntPoint(0, 0), aViewportSize), - scale, - aFlags); + nsIntRect(nsIntPoint(0, 0), aParams.viewportSize), + aParams.scale, + aParams.flags); - nsRefPtr drawable = new gfxCallbackDrawable(cb, drawableSize); + nsRefPtr svgDrawable = new gfxCallbackDrawable(cb, aParams.imageRect.Size()); - gfxUtils::DrawPixelSnapped(aContext, drawable, unscaledTransform, - drawableSubimage, drawableSourceRect, - drawableImageRect, aFill, - gfxImageFormatARGB32, aFilter, aFlags); + // Refuse to cache animated images. + // XXX(seth): We may remove this restriction in bug 922893. + if (mHaveAnimations) + return Show(svgDrawable, aParams); + + // If the image is too big to fit in the cache, don't go any further. + if (!SurfaceCache::CanHold(aParams.imageRect.Size())) + return Show(svgDrawable, aParams); + + // Try to create an offscreen surface. + mozilla::RefPtr target; + nsRefPtr ctx; + nsRefPtr surface; + + if (gfxPlatform::GetPlatform()->SupportsAzureContent()) { + target = gfxPlatform::GetPlatform()-> + CreateOffscreenContentDrawTarget(aParams.imageRect.Size(), gfx::FORMAT_B8G8R8A8); + + // XXX(seth): All of this ugliness (the backend check, |surface|, the + // GetThebesSurfaceForDrawTarget call) is needed because we can't use Moz2D + // for drawing in all cases yet. See bug 923341. + if (target) { + switch (target->GetType()) { + case mozilla::gfx::BACKEND_DIRECT2D: + case mozilla::gfx::BACKEND_DIRECT2D1_1: + case mozilla::gfx::BACKEND_SKIA: + // Can't cache on this backend. + return Show(svgDrawable, aParams); + + default: + surface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(target); + ctx = new gfxContext(target); + } + } + } else { + target = gfxPlatform::GetPlatform()-> + CreateOffscreenCanvasDrawTarget(aParams.imageRect.Size(), gfx::FORMAT_B8G8R8A8); + surface = target ? gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(target) + : nullptr; + ctx = surface ? new gfxContext(surface) : nullptr; + } + + // If we couldn't create the draw target, it was probably because it would end + // up way too big. Generally it also wouldn't fit in the cache, but the prefs + // could be set such that the cache isn't the limiting factor. If we couldn't + // create the surface, we are on a platform that does not support + // GetThebesSurfaceForDrawTarget. This will be fixed in bug 923341. + if (!target || !surface) + return Show(svgDrawable, aParams); + + // Actually draw. (We use FILTER_NEAREST since we never scale here.) + gfxUtils::DrawPixelSnapped(ctx, svgDrawable, gfxMatrix(), + aParams.imageRect, aParams.imageRect, + aParams.imageRect, aParams.imageRect, + gfxImageFormatARGB32, + GraphicsFilter::FILTER_NEAREST, aParams.flags); + + // Attempt to cache the resulting surface. + SurfaceCache::Insert(target, + ImageKey(this), + SurfaceKey(aParams.imageRect.Size(), aParams.scale, + aParams.svgContext, aParams.animationTime, + aParams.flags)); + + // Draw. Note that if SurfaceCache::Insert failed for whatever reason, + // then |target| is all that is keeping the pixel data alive, so we have + // to draw before returning from this function. + nsRefPtr drawable = new gfxSurfaceDrawable(surface, aParams.imageRect.Size()); + Show(drawable, aParams); +} + + +void +VectorImage::Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams) +{ + MOZ_ASSERT(aDrawable, "Should have a gfxDrawable by now"); + gfxUtils::DrawPixelSnapped(aParams.context, aDrawable, + aParams.userSpaceToImageSpace, + aParams.subimage, aParams.sourceRect, + aParams.imageRect, aParams.fill, + gfxImageFormatARGB32, + aParams.filter, aParams.flags); MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now"); mRenderingObserver->ResumeHonoringInvalidations(); - - return NS_OK; } //****************************************************************************** @@ -815,7 +952,7 @@ VectorImage::UnlockImage() NS_IMETHODIMP VectorImage::RequestDiscard() { - // This method is for image-discarding, which only applies to RasterImages. + SurfaceCache::Discard(this); return NS_OK; } diff --git a/image/src/VectorImage.h b/image/src/VectorImage.h index fb6b5c40e8e..6eda36e9e83 100644 --- a/image/src/VectorImage.h +++ b/image/src/VectorImage.h @@ -11,6 +11,7 @@ #include "mozilla/MemoryReporting.h" class nsIRequest; +class gfxDrawable; namespace mozilla { namespace layers { @@ -19,10 +20,11 @@ class ImageContainer; } namespace image { -class SVGDocumentWrapper; -class SVGRootRenderingObserver; -class SVGLoadEventListener; -class SVGParseCompleteListener; +struct SVGDrawingParameters; +class SVGDocumentWrapper; +class SVGRootRenderingObserver; +class SVGLoadEventListener; +class SVGParseCompleteListener; class VectorImage : public ImageResource, public nsIStreamListener @@ -82,6 +84,9 @@ protected: virtual nsresult StopAnimation(); virtual bool ShouldAnimate(); + void CreateDrawableAndShow(const SVGDrawingParameters& aParams); + void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams); + private: void CancelAllListeners(); From 2d19654cb349b230865e7776e16a68a4a99dccdd Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Tue, 22 Oct 2013 15:06:01 +0300 Subject: [PATCH 12/75] Bug 928403 - optimize nsFrameConstructorState::ProcessFrameInsertions, r=roc --HG-- rename : testing/mochitest/b2g-debug.json => testing/mochitest/b2g.json extra : rebase_source : c45d39f4b50f248b28a6ebfb50128084bb59ebe4 --- layout/base/nsCSSFrameConstructor.cpp | 58 +++++++++++++++++++++++---- layout/base/nsLayoutUtils.cpp | 46 ++++++++++++++------- layout/base/nsLayoutUtils.h | 20 +++++++++ 3 files changed, 102 insertions(+), 22 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 94b9de9089c..4c418dd96fe 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1241,23 +1241,67 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems, // so this will make out-of-flows respect the ordering of placeholders, // which is great because it takes care of anonymous content. nsIFrame* firstNewFrame = aFrameItems.FirstChild(); + + // Cache the ancestor chain so that we can reuse it if needed. + nsAutoTArray firstNewFrameAncestors; + nsIFrame* notCommonAncestor = nullptr; + if (lastChild) { + notCommonAncestor = nsLayoutUtils::FillAncestors(firstNewFrame, + containingBlock, + &firstNewFrameAncestors); + } + if (!lastChild || - nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, containingBlock) < 0) { + nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, + firstNewFrameAncestors, + notCommonAncestor ? + containingBlock : nullptr) < 0) { // no lastChild, or lastChild comes before the new children, so just append rv = mFrameManager->AppendFrames(containingBlock, aChildListID, aFrameItems); } else { - // try the other children - nsIFrame* insertionPoint = nullptr; + // Try the other children. First collect them to an array so that a + // reasonable fast binary search can be used to find the insertion point. + nsAutoTArray children; for (nsIFrame* f = childList.FirstChild(); f != lastChild; f = f->GetNextSibling()) { + children.AppendElement(f); + } + + nsIFrame* insertionPoint = nullptr; + int32_t imin = 0; + int32_t max = children.Length(); + while (max > imin) { + int32_t imid = imin + ((max - imin) / 2); + nsIFrame* f = children[imid]; int32_t compare = - nsLayoutUtils::CompareTreePosition(f, firstNewFrame, containingBlock); + nsLayoutUtils::CompareTreePosition(f, firstNewFrame, firstNewFrameAncestors, + notCommonAncestor ? containingBlock : nullptr); if (compare > 0) { - // f comes after the new children, so stop here and insert after - // the previous frame + // f is after the new frame. + max = imid; + insertionPoint = imid > 0 ? children[imid - 1] : nullptr; + } else if (compare < 0) { + // f is before the new frame. + imin = imid + 1; + insertionPoint = f; + } else { + // This is for the old behavior. Should be removed once it is + // guaranteed that CompareTreePosition can't return 0! + // See bug 928645. + NS_WARNING("Something odd happening???"); + insertionPoint = nullptr; + for (uint32_t i = 0; i < children.Length(); ++i) { + nsIFrame* f = children[i]; + if (nsLayoutUtils::CompareTreePosition(f, firstNewFrame, + firstNewFrameAncestors, + notCommonAncestor ? + containingBlock : nullptr) > 0) { + break; + } + insertionPoint = f; + } break; } - insertionPoint = f; } rv = mFrameManager->InsertFrames(containingBlock, aChildListID, insertionPoint, aFrameItems); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 3c4bd03cec2..d3cf371e265 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1002,9 +1002,11 @@ nsLayoutUtils::DoCompareTreePosition(nsIContent* aContent1, return index1 - index2; } -static nsIFrame* FillAncestors(nsIFrame* aFrame, - nsIFrame* aStopAtAncestor, - nsTArray* aAncestors) +// static +nsIFrame* +nsLayoutUtils::FillAncestors(nsIFrame* aFrame, + nsIFrame* aStopAtAncestor, + nsTArray* aAncestors) { while (aFrame && aFrame != aStopAtAncestor) { aAncestors->AppendElement(aFrame); @@ -1036,6 +1038,27 @@ nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, NS_PRECONDITION(aFrame1, "aFrame1 must not be null"); NS_PRECONDITION(aFrame2, "aFrame2 must not be null"); + nsAutoTArray frame2Ancestors; + nsIFrame* nonCommonAncestor = + FillAncestors(aFrame2, aCommonAncestor, &frame2Ancestors); + + return DoCompareTreePosition(aFrame1, aFrame2, frame2Ancestors, + aIf1Ancestor, aIf2Ancestor, + nonCommonAncestor ? aCommonAncestor : nullptr); +} + +// static +int32_t +nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, + nsIFrame* aFrame2, + nsTArray& aFrame2Ancestors, + int32_t aIf1Ancestor, + int32_t aIf2Ancestor, + nsIFrame* aCommonAncestor) +{ + NS_PRECONDITION(aFrame1, "aFrame1 must not be null"); + NS_PRECONDITION(aFrame2, "aFrame2 must not be null"); + nsPresContext* presContext = aFrame1->PresContext(); if (presContext != aFrame2->PresContext()) { NS_ERROR("no common ancestor at all, different documents"); @@ -1043,25 +1066,18 @@ nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, } nsAutoTArray frame1Ancestors; - if (!FillAncestors(aFrame1, aCommonAncestor, &frame1Ancestors)) { + if (aCommonAncestor && + !FillAncestors(aFrame1, aCommonAncestor, &frame1Ancestors)) { // We reached the root of the frame tree ... if aCommonAncestor was set, // it is wrong - aCommonAncestor = nullptr; - } - - nsAutoTArray frame2Ancestors; - if (!FillAncestors(aFrame2, aCommonAncestor, &frame2Ancestors) && - aCommonAncestor) { - // We reached the root of the frame tree ... aCommonAncestor was wrong. - // Try again with no hint. return DoCompareTreePosition(aFrame1, aFrame2, aIf1Ancestor, aIf2Ancestor, nullptr); } int32_t last1 = int32_t(frame1Ancestors.Length()) - 1; - int32_t last2 = int32_t(frame2Ancestors.Length()) - 1; + int32_t last2 = int32_t(aFrame2Ancestors.Length()) - 1; while (last1 >= 0 && last2 >= 0 && - frame1Ancestors[last1] == frame2Ancestors[last2]) { + frame1Ancestors[last1] == aFrame2Ancestors[last2]) { last1--; last2--; } @@ -1081,7 +1097,7 @@ nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, } nsIFrame* ancestor1 = frame1Ancestors[last1]; - nsIFrame* ancestor2 = frame2Ancestors[last2]; + nsIFrame* ancestor2 = aFrame2Ancestors[last2]; // Now we should be able to walk sibling chains to find which one is first if (IsFrameAfter(ancestor2, ancestor1)) return -1; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index a35697d2e46..5fdf174bd3d 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -263,6 +263,15 @@ public: return DoCompareTreePosition(aFrame1, aFrame2, -1, 1, aCommonAncestor); } + static int32_t CompareTreePosition(nsIFrame* aFrame1, + nsIFrame* aFrame2, + nsTArray& aFrame2Ancestors, + nsIFrame* aCommonAncestor = nullptr) + { + return DoCompareTreePosition(aFrame1, aFrame2, aFrame2Ancestors, + -1, 1, aCommonAncestor); + } + /* * More generic version of |CompareTreePosition|. |aIf1Ancestor| * gives the value to return when 1 is an ancestor of 2, and likewise @@ -275,6 +284,17 @@ public: int32_t aIf2Ancestor, nsIFrame* aCommonAncestor = nullptr); + static nsIFrame* FillAncestors(nsIFrame* aFrame, + nsIFrame* aStopAtAncestor, + nsTArray* aAncestors); + + static int32_t DoCompareTreePosition(nsIFrame* aFrame1, + nsIFrame* aFrame2, + nsTArray& aFrame2Ancestors, + int32_t aIf1Ancestor, + int32_t aIf2Ancestor, + nsIFrame* aCommonAncestor); + /** * LastContinuationWithChild gets the last continuation in aFrame's chain * that has a child, or the first continuation if the frame has no children. From ff770018d8efd5ce69a9b5950777abf9f9c750a8 Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 22 Oct 2013 14:13:26 +0200 Subject: [PATCH 13/75] Bug 914847. Use a mini-flush instead of a full style flush. r=dbaron --- layout/base/nsPresShell.cpp | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 4ca00e01aff..7949d9acb66 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6004,6 +6004,20 @@ nsIFrame* GetNearestFrameContainingPresShell(nsIPresShell* aPresShell) return frame; } + +static bool +FlushThrottledStyles(nsIDocument *aDocument, void *aData) +{ + nsIPresShell* shell = aDocument->GetShell(); + if (shell && shell->IsVisible()) { + nsPresContext* presContext = shell->GetPresContext(); + if (presContext) { + presContext->TransitionManager()->UpdateAllThrottledStyles(); + } + } + + return true; +} nsresult PresShell::HandleEvent(nsIFrame* aFrame, @@ -6102,14 +6116,21 @@ PresShell::HandleEvent(nsIFrame* aFrame, nsIFrame* frame = aFrame; - if (aEvent->eventStructType == NS_TOUCH_EVENT) { - nsIDocument::UnlockPointer(); - FlushPendingNotifications(Flush_Layout); - frame = GetNearestFrameContainingPresShell(this); - } - bool dispatchUsingCoordinates = aEvent->IsUsingCoordinates(); if (dispatchUsingCoordinates) { + if (nsLayoutUtils::AreAsyncAnimationsEnabled() && mDocument) { + if (aEvent->eventStructType == NS_TOUCH_EVENT) { + nsIDocument::UnlockPointer(); + } + + { // scope for scriptBlocker. + nsAutoScriptBlocker scriptBlocker; + GetRootPresShell()->GetDocument()-> + EnumerateSubDocuments(FlushThrottledStyles, nullptr); + } + frame = GetNearestFrameContainingPresShell(this); + } + NS_WARN_IF_FALSE(frame, "Nothing to handle this event!"); if (!frame) return NS_OK; From 51bcfeb92dae31482b27fa3d04127bb800428091 Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 22 Oct 2013 14:14:41 +0200 Subject: [PATCH 14/75] Bug 914847. Mini-flush for animations. r=dbaron --- layout/base/nsPresContext.cpp | 25 +++- layout/base/nsPresContext.h | 12 +- layout/base/nsPresShell.cpp | 1 + layout/style/AnimationCommon.cpp | 159 +++++++++++++++++++++- layout/style/AnimationCommon.h | 83 +++++++++++- layout/style/nsAnimationManager.cpp | 73 +++++++++- layout/style/nsAnimationManager.h | 13 +- layout/style/nsTransitionManager.cpp | 191 ++------------------------- layout/style/nsTransitionManager.h | 20 +-- 9 files changed, 365 insertions(+), 212 deletions(-) diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 543b9fb0ac8..ea0532cda06 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -976,7 +976,8 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext) // Initialise refresh tick counters for OMTA mLastStyleUpdateForAllAnimations = - mLastUpdateThrottledStyle = mRefreshDriver->MostRecentRefresh(); + mLastUpdateThrottledAnimationStyle = + mLastUpdateThrottledTransitionStyle = mRefreshDriver->MostRecentRefresh(); mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID); @@ -1491,15 +1492,29 @@ nsPresContext::GetContainerExternal() const } bool -nsPresContext::ThrottledStyleIsUpToDate() const +nsPresContext::ThrottledTransitionStyleIsUpToDate() const { - return mLastUpdateThrottledStyle == mRefreshDriver->MostRecentRefresh(); + return + mLastUpdateThrottledTransitionStyle == mRefreshDriver->MostRecentRefresh(); } void -nsPresContext::TickLastUpdateThrottledStyle() +nsPresContext::TickLastUpdateThrottledTransitionStyle() { - mLastUpdateThrottledStyle = mRefreshDriver->MostRecentRefresh(); + mLastUpdateThrottledTransitionStyle = mRefreshDriver->MostRecentRefresh(); +} + +bool +nsPresContext::ThrottledAnimationStyleIsUpToDate() const +{ + return + mLastUpdateThrottledAnimationStyle == mRefreshDriver->MostRecentRefresh(); +} + +void +nsPresContext::TickLastUpdateThrottledAnimationStyle() +{ + mLastUpdateThrottledAnimationStyle = mRefreshDriver->MostRecentRefresh(); } bool diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 9dc4a9f4808..c088a5e1e5f 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -656,8 +656,10 @@ public: /** * Getter and setter for OMTA time counters */ - bool ThrottledStyleIsUpToDate() const; - void TickLastUpdateThrottledStyle(); + bool ThrottledTransitionStyleIsUpToDate() const; + void TickLastUpdateThrottledTransitionStyle(); + bool ThrottledAnimationStyleIsUpToDate() const; + void TickLastUpdateThrottledAnimationStyle(); bool StyleUpdateForAllAnimationsIsUpToDate(); void TickLastStyleUpdateForAllAnimations(); @@ -1226,8 +1228,10 @@ protected: mozilla::TimeStamp mReflowStartTime; - // last time animations/transition styles were flushed to their primary frames - mozilla::TimeStamp mLastUpdateThrottledStyle; + // last time animations styles were flushed to their primary frames + mozilla::TimeStamp mLastUpdateThrottledAnimationStyle; + // last time transition styles were flushed to their primary frames + mozilla::TimeStamp mLastUpdateThrottledTransitionStyle; // last time we did a full style flush mozilla::TimeStamp mLastStyleUpdateForAllAnimations; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 7949d9acb66..2f9b2cc475b 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6013,6 +6013,7 @@ FlushThrottledStyles(nsIDocument *aDocument, void *aData) nsPresContext* presContext = shell->GetPresContext(); if (presContext) { presContext->TransitionManager()->UpdateAllThrottledStyles(); + presContext->AnimationManager()->UpdateAllThrottledStyles(); } } diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index dcda64cb328..f85d6ee64ae 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -3,8 +3,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "gfxPlatform.h" #include "AnimationCommon.h" +#include "nsTransitionManager.h" +#include "nsAnimationManager.h" + +#include "gfxPlatform.h" #include "nsRuleData.h" #include "nsCSSValue.h" #include "nsStyleContext.h" @@ -16,6 +19,9 @@ #include "nsDisplayList.h" #include "mozilla/MemoryReporting.h" #include "RestyleManager.h" +#include "nsStyleSet.h" +#include "nsStyleChangeList.h" + using namespace mozilla::layers; @@ -136,6 +142,157 @@ CommonAnimationManager::ExtractComputedValueForTransition( return result; } +already_AddRefed +CommonAnimationManager::ReparentContent(nsIContent* aContent, + nsStyleContext* aParentStyle) +{ + nsStyleSet* styleSet = mPresContext->PresShell()->StyleSet(); + nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aContent); + if (!primaryFrame) { + return nullptr; + } + + dom::Element* element = aContent->IsElement() + ? aContent->AsElement() + : nullptr; + + nsRefPtr newStyle = + styleSet->ReparentStyleContext(primaryFrame->StyleContext(), + aParentStyle, element); + primaryFrame->SetStyleContext(newStyle); + ReparentBeforeAndAfter(element, primaryFrame, newStyle, styleSet); + + return newStyle.forget(); +} + +/* static */ void +CommonAnimationManager::ReparentBeforeAndAfter(dom::Element* aElement, + nsIFrame* aPrimaryFrame, + nsStyleContext* aNewStyle, + nsStyleSet* aStyleSet) +{ + if (nsIFrame* before = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) { + nsRefPtr beforeStyle = + aStyleSet->ReparentStyleContext(before->StyleContext(), + aNewStyle, aElement); + before->SetStyleContext(beforeStyle); + } + if (nsIFrame* after = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) { + nsRefPtr afterStyle = + aStyleSet->ReparentStyleContext(after->StyleContext(), + aNewStyle, aElement); + after->SetStyleContext(afterStyle); + } +} + +// Ensure that the next repaint rebuilds the layer tree for aFrame. That +// means that changes to animations on aFrame's layer are propagated to +// the compositor, which is needed for correct behaviour of new +// transitions. +static void +ForceLayerRerendering(nsIFrame* aFrame, CommonElementAnimationData* aData) +{ + if (aData->HasAnimationOfProperty(eCSSProperty_opacity)) { + if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer( + aFrame, nsDisplayItem::TYPE_OPACITY)) { + layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey()); + } + } + + if (aData->HasAnimationOfProperty(eCSSProperty_transform)) { + if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer( + aFrame, nsDisplayItem::TYPE_TRANSFORM)) { + layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey()); + } + } +} + +nsStyleContext* +CommonAnimationManager::UpdateThrottledStyle(dom::Element* aElement, + nsStyleContext* aParentStyle, + nsStyleChangeList& aChangeList) +{ + NS_ASSERTION(mPresContext->TransitionManager()->GetElementTransitions( + aElement, + nsCSSPseudoElements::ePseudo_NotPseudoElement, + false) || + mPresContext->AnimationManager()->GetElementAnimations( + aElement, + nsCSSPseudoElements::ePseudo_NotPseudoElement, + false), "element not animated"); + + nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aElement); + if (!primaryFrame) { + return nullptr; + } + + nsStyleContext* oldStyle = primaryFrame->StyleContext(); + nsRuleNode* ruleNode = oldStyle->RuleNode(); + nsTArray rules; + do { + if (ruleNode->IsRoot()) { + break; + } + + nsStyleSet::RuleAndLevel curRule; + curRule.mLevel = ruleNode->GetLevel(); + + if (curRule.mLevel == nsStyleSet::eAnimationSheet) { + ElementAnimations* ea = + mPresContext->AnimationManager()->GetElementAnimations( + aElement, + oldStyle->GetPseudoType(), + false); + NS_ASSERTION(ea, + "Rule has level eAnimationSheet without animation on manager"); + + mPresContext->AnimationManager()->EnsureStyleRuleFor(ea); + curRule.mRule = ea->mStyleRule; + + // FIXME: maybe not needed anymore: + ForceLayerRerendering(primaryFrame, ea); + } else if (curRule.mLevel == nsStyleSet::eTransitionSheet) { + ElementTransitions *et = + mPresContext->TransitionManager()->GetElementTransitions( + aElement, + oldStyle->GetPseudoType(), + false); + NS_ASSERTION(et, + "Rule has level eTransitionSheet without transition on manager"); + + et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh()); + curRule.mRule = et->mStyleRule; + + // FIXME: maybe not needed anymore: + ForceLayerRerendering(primaryFrame, et); + } else { + curRule.mRule = ruleNode->GetRule(); + } + + if (curRule.mRule) { + rules.AppendElement(curRule); + } + } while ((ruleNode = ruleNode->GetParent())); + + nsRefPtr newStyle = mPresContext->PresShell()->StyleSet()-> + ResolveStyleForRules(aParentStyle, oldStyle, rules); + + // We absolutely must call CalcStyleDifference in order to ensure the + // new context has all the structs cached that the old context had. + // We also need it for processing of the changes. + nsChangeHint styleChange = + oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0)); + aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(), + styleChange); + + primaryFrame->SetStyleContext(newStyle); + + ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, + mPresContext->PresShell()->StyleSet()); + + return newStyle; +} + NS_IMPL_ISUPPORTS1(AnimValuesStyleRule, nsIStyleRule) /* virtual */ void diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 85e5b54b04e..b0815ca5717 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -17,7 +17,8 @@ #include "nsSMILKeySpline.h" #include "nsStyleStruct.h" #include "mozilla/Attributes.h" - +#include "nsCSSPseudoElements.h" + class nsPresContext; class nsIFrame; @@ -70,10 +71,82 @@ protected: virtual void ElementDataRemoved() = 0; void RemoveAllElementData(); + // Update the style on aElement from the transition stored in this manager and + // the new parent style - aParentStyle. aElement must be transitioning or + // animated. Returns the updated style. + nsStyleContext* UpdateThrottledStyle(mozilla::dom::Element* aElement, + nsStyleContext* aParentStyle, + nsStyleChangeList &aChangeList); + // Reparent the style of aContent and any :before and :after pseudo-elements. + already_AddRefed ReparentContent(nsIContent* aContent, + nsStyleContext* aParentStyle); + // reparent :before and :after pseudo elements of aElement + static void ReparentBeforeAndAfter(dom::Element* aElement, + nsIFrame* aPrimaryFrame, + nsStyleContext* aNewStyle, + nsStyleSet* aStyleSet); + PRCList mElementData; nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect) }; +// The internals of UpdateAllThrottledStyles, used by nsAnimationManager and +// nsTransitionManager, see the comments in the declaration of the latter. +#define IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(class_, animations_getter_) \ +void \ +class_::UpdateAllThrottledStylesInternal() \ +{ \ + TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh(); \ + \ + nsStyleChangeList changeList; \ + \ + /* update each transitioning element by finding its root-most ancestor + with a transition, and flushing the style on that ancestor and all + its descendants*/ \ + PRCList *next = PR_LIST_HEAD(&mElementData); \ + while (next != &mElementData) { \ + CommonElementAnimationData* ea = \ + static_cast(next); \ + next = PR_NEXT_LINK(next); \ + \ + if (ea->mFlushGeneration == now) { \ + /* this element has been ticked already */ \ + continue; \ + } \ + \ + /* element is initialised to the starting element (i.e., one we know has + an animation) and ends up with the root-most animated ancestor, + that is, the element where we begin updates. */ \ + dom::Element* element = ea->mElement; \ + /* make a list of ancestors */ \ + nsTArray ancestors; \ + do { \ + ancestors.AppendElement(element); \ + } while ((element = element->GetParentElement())); \ + \ + /* walk down the ancestors until we find one with a throttled transition */\ + for (int32_t i = ancestors.Length() - 1; i >= 0; --i) { \ + if (animations_getter_(ancestors[i], \ + nsCSSPseudoElements::ePseudo_NotPseudoElement, \ + false)) { \ + element = ancestors[i]; \ + break; \ + } \ + } \ + \ + nsIFrame* primaryFrame; \ + if (element && \ + (primaryFrame = nsLayoutUtils::GetStyleFrame(element))) { \ + UpdateThrottledStylesForSubtree(element, \ + primaryFrame->StyleContext()->GetParent(), changeList); \ + } \ + } \ + \ + RestyleManager* restyleManager = mPresContext->RestyleManager(); \ + restyleManager->ProcessRestyledFrames(changeList); \ + restyleManager->FlushOverflowChangedTracker(); \ +} + /** * A style rule that maps property-nsStyleAnimation::Value pairs. */ @@ -132,11 +205,12 @@ private: struct CommonElementAnimationData : public PRCList { CommonElementAnimationData(dom::Element *aElement, nsIAtom *aElementProperty, - CommonAnimationManager *aManager) + CommonAnimationManager *aManager, TimeStamp aNow) : mElement(aElement) , mElementProperty(aElementProperty) , mManager(aManager) , mAnimationGeneration(0) + , mFlushGeneration(aNow) #ifdef DEBUG , mCalledPropertyDtor(false) #endif @@ -216,6 +290,11 @@ struct CommonElementAnimationData : public PRCList // The refresh time associated with mStyleRule. TimeStamp mStyleRuleRefreshTime; + // Generation counter for flushes of throttled animations. + // Used to prevent updating the styles twice for a given element during + // UpdateAllThrottledStyles. + TimeStamp mFlushGeneration; + #ifdef DEBUG bool mCalledPropertyDtor; #endif diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 5c19a927bad..0d60fd0a2c7 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -4,13 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsAnimationManager.h" +#include "nsTransitionManager.h" #include "mozilla/MemoryReporting.h" #include "nsPresContext.h" #include "nsRuleProcessorData.h" #include "nsStyleSet.h" +#include "nsStyleChangeList.h" #include "nsCSSRules.h" +#include "RestyleManager.h" #include "nsStyleAnimation.h" #include "nsEventDispatcher.h" #include "nsLayoutUtils.h" @@ -21,10 +24,12 @@ using namespace mozilla; using namespace mozilla::css; -ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsAnimationManager *aAnimationManager) +ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, + nsIAtom *aElementProperty, + nsAnimationManager *aAnimationManager, + TimeStamp aNow) : CommonElementAnimationData(aElement, aElementProperty, - aAnimationManager), + aAnimationManager, aNow), mNeedsRefreshes(true) { } @@ -451,7 +456,8 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement, aElement->GetProperty(propName)); if (!ea && aCreateIfNeeded) { // FIXME: Consider arena-allocating? - ea = new ElementAnimations(aElement, propName, this); + ea = new ElementAnimations(aElement, propName, this, + mPresContext->RefreshDriver()->MostRecentRefresh()); nsresult rv = aElement->SetProperty(propName, ea, ElementAnimationsPropertyDtor, false); if (NS_FAILED(rv)) { @@ -1088,3 +1094,62 @@ nsAnimationManager::DoDispatchEvents() } } } + +void +nsAnimationManager::UpdateThrottledStylesForSubtree(nsIContent* aContent, + nsStyleContext* aParentStyle, + nsStyleChangeList& aChangeList) +{ + dom::Element* element; + if (aContent->IsElement()) { + element = aContent->AsElement(); + } else { + element = nullptr; + } + + nsRefPtr newStyle; + + ElementAnimations* ea; + if (element && + (ea = GetElementAnimations(element, + nsCSSPseudoElements::ePseudo_NotPseudoElement, + false))) { + // re-resolve our style + newStyle = UpdateThrottledStyle(element, aParentStyle, aChangeList); + // remove the current transition from the working set + ea->mFlushGeneration = mPresContext->RefreshDriver()->MostRecentRefresh(); + } else { + newStyle = ReparentContent(aContent, aParentStyle); + } + + // walk the children + if (newStyle) { + for (nsIContent *child = aContent->GetFirstChild(); child; + child = child->GetNextSibling()) { + UpdateThrottledStylesForSubtree(child, newStyle, aChangeList); + } + } +} + +IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(nsAnimationManager, + GetElementAnimations) + +void +nsAnimationManager::UpdateAllThrottledStyles() +{ + if (PR_CLIST_IS_EMPTY(&mElementData)) { + // no throttled animations, leave early + mPresContext->TickLastUpdateThrottledAnimationStyle(); + return; + } + + if (mPresContext->ThrottledAnimationStyleIsUpToDate()) { + // throttled transitions are up to date, leave early + return; + } + + mPresContext->TickLastUpdateThrottledAnimationStyle(); + + UpdateAllThrottledStylesInternal(); +} + diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index c2e75817f53..13fc13a04b2 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -128,7 +128,7 @@ struct ElementAnimations MOZ_FINAL typedef mozilla::TimeDuration TimeDuration; ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsAnimationManager *aAnimationManager); + nsAnimationManager *aAnimationManager, TimeStamp aNow); // This function takes as input the start time, duration, and direction of an // animation and returns the position in the current iteration. Note that @@ -275,6 +275,9 @@ public: nsCSSPseudoElements::Type aPseudoType, bool aCreateIfNeeded); + // Updates styles on throttled animations. See note on nsTransitionManager + void UpdateAllThrottledStyles(); + protected: virtual void ElementDataRemoved() MOZ_OVERRIDE { @@ -298,6 +301,14 @@ private: nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement, nsCSSPseudoElements::Type aPseudoType); + // Update the animated styles of an element and its descendants. + // If the element has an animation, it is flushed back to its primary frame. + // If the element does not have an animation, then its style is reparented. + void UpdateThrottledStylesForSubtree(nsIContent* aContent, + nsStyleContext* aParentStyle, + nsStyleChangeList &aChangeList); + void UpdateAllThrottledStylesInternal(); + // The guts of DispatchEvents void DoDispatchEvents(); diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 3e969b34d3c..930764e2a71 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -40,8 +40,8 @@ ElementTransitions::ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, nsTransitionManager *aTransitionManager, TimeStamp aNow) - : CommonElementAnimationData(aElement, aElementProperty, aTransitionManager) - , mFlushGeneration(aNow) + : CommonElementAnimationData(aElement, aElementProperty, + aTransitionManager, aNow) { } @@ -209,122 +209,6 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const * nsTransitionManager * *****************************************************************************/ -// reparent :before and :after pseudo elements of aElement -static void ReparentBeforeAndAfter(dom::Element* aElement, - nsIFrame* aPrimaryFrame, - nsStyleContext* aNewStyle, - nsStyleSet* aStyleSet) -{ - if (nsIFrame* before = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) { - nsRefPtr beforeStyle = - aStyleSet->ReparentStyleContext(before->StyleContext(), - aNewStyle, aElement); - before->SetStyleContext(beforeStyle); - } - if (nsIFrame* after = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) { - nsRefPtr afterStyle = - aStyleSet->ReparentStyleContext(after->StyleContext(), - aNewStyle, aElement); - after->SetStyleContext(afterStyle); - } -} - -// Ensure that the next repaint rebuilds the layer tree for aFrame. That -// means that changes to animations on aFrame's layer are propagated to -// the compositor, which is needed for correct behaviour of new -// transitions. -static void -ForceLayerRerendering(nsIFrame* aFrame, CommonElementAnimationData* aData) -{ - if (aData->HasAnimationOfProperty(eCSSProperty_opacity)) { - if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer( - aFrame, nsDisplayItem::TYPE_OPACITY)) { - layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey()); - } - } - - if (aData->HasAnimationOfProperty(eCSSProperty_transform)) { - if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer( - aFrame, nsDisplayItem::TYPE_TRANSFORM)) { - layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey()); - } - } -} - -nsStyleContext* -nsTransitionManager::UpdateThrottledStyle(dom::Element* aElement, - nsStyleContext* aParentStyle, - nsStyleChangeList& aChangeList) -{ - NS_ASSERTION(GetElementTransitions(aElement, - nsCSSPseudoElements::ePseudo_NotPseudoElement, - false), "element not transitioning"); - - nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aElement); - if (!primaryFrame) { - return nullptr; - } - - nsStyleContext* oldStyle = primaryFrame->StyleContext(); - nsRuleNode* ruleNode = oldStyle->RuleNode(); - nsTArray rules; - do { - if (ruleNode->IsRoot()) { - break; - } - - nsStyleSet::RuleAndLevel curRule; - curRule.mLevel = ruleNode->GetLevel(); - - if (curRule.mLevel == nsStyleSet::eAnimationSheet) { - ElementAnimations* ea = - mPresContext->AnimationManager()->GetElementAnimations(aElement, - oldStyle->GetPseudoType(), - false); - NS_ASSERTION(ea, "Rule has level eAnimationSheet without animation on manager"); - - mPresContext->AnimationManager()->EnsureStyleRuleFor(ea); - curRule.mRule = ea->mStyleRule; - - // FIXME: maybe not needed anymore: - ForceLayerRerendering(primaryFrame, ea); - } else if (curRule.mLevel == nsStyleSet::eTransitionSheet) { - ElementTransitions *et = - GetElementTransitions(aElement, oldStyle->GetPseudoType(), false); - NS_ASSERTION(et, "Rule has level eTransitionSheet without transition on manager"); - - et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh()); - curRule.mRule = et->mStyleRule; - - // FIXME: maybe not needed anymore: - ForceLayerRerendering(primaryFrame, et); - } else { - curRule.mRule = ruleNode->GetRule(); - } - - if (curRule.mRule) { - rules.AppendElement(curRule); - } - } while ((ruleNode = ruleNode->GetParent())); - - nsRefPtr newStyle = mPresContext->PresShell()->StyleSet()-> - ResolveStyleForRules(aParentStyle, oldStyle, rules); - - // We absolutely must call CalcStyleDifference in order to ensure the - // new context has all the structs cached that the old context had. - // We also need it for processing of the changes. - nsChangeHint styleChange = - oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0)); - aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(), - styleChange); - - primaryFrame->SetStyleContext(newStyle); - - ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, mPresContext->PresShell()->StyleSet()); - - return newStyle; -} - void nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent, nsStyleContext* aParentStyle, @@ -349,17 +233,7 @@ nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent, // remove the current transition from the working set et->mFlushGeneration = mPresContext->RefreshDriver()->MostRecentRefresh(); } else { - // reparent the element's style - nsStyleSet* styleSet = mPresContext->PresShell()->StyleSet(); - nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aContent); - if (!primaryFrame) { - return; - } - - newStyle = styleSet->ReparentStyleContext(primaryFrame->StyleContext(), - aParentStyle, element); - primaryFrame->SetStyleContext(newStyle); - ReparentBeforeAndAfter(element, primaryFrame, newStyle, styleSet); + newStyle = ReparentContent(aContent, aParentStyle); } // walk the children @@ -371,68 +245,25 @@ nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent, } } +IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(nsTransitionManager, + GetElementTransitions) + void nsTransitionManager::UpdateAllThrottledStyles() { if (PR_CLIST_IS_EMPTY(&mElementData)) { // no throttled transitions, leave early - mPresContext->TickLastUpdateThrottledStyle(); + mPresContext->TickLastUpdateThrottledTransitionStyle(); return; } - if (mPresContext->ThrottledStyleIsUpToDate()) { + if (mPresContext->ThrottledTransitionStyleIsUpToDate()) { // throttled transitions are up to date, leave early return; } - mPresContext->TickLastUpdateThrottledStyle(); - TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh(); - - nsStyleChangeList changeList; - - // update each transitioning element by finding its root-most ancestor with a - // transition, and flushing the style on that ancestor and all its descendants - PRCList *next = PR_LIST_HEAD(&mElementData); - while (next != &mElementData) { - ElementTransitions* et = static_cast(next); - next = PR_NEXT_LINK(next); - - if (et->mFlushGeneration == now) { - // this element has been ticked already - continue; - } - - // element is initialised to the starting element (i.e., one we know has - // a transition) and ends up with the root-most transitioning ancestor, - // that is, the element where we begin updates. - dom::Element* element = et->mElement; - // make a list of ancestors - nsTArray ancestors; - do { - ancestors.AppendElement(element); - } while ((element = element->GetParentElement())); - - // walk down the ancestors until we find one with a throttled transition - for (int32_t i = ancestors.Length() - 1; i >= 0; --i) { - if (GetElementTransitions(ancestors[i], - nsCSSPseudoElements::ePseudo_NotPseudoElement, - false)) { - element = ancestors[i]; - break; - } - } - - nsIFrame* primaryFrame; - if (element && - (primaryFrame = nsLayoutUtils::GetStyleFrame(element))) { - UpdateThrottledStylesForSubtree(element, - primaryFrame->StyleContext()->GetParent(), changeList); - } - } - - RestyleManager* restyleManager = mPresContext->RestyleManager(); - restyleManager->ProcessRestyledFrames(changeList); - restyleManager->FlushOverflowChangedTracker(); + mPresContext->TickLastUpdateThrottledTransitionStyle(); + UpdateAllThrottledStylesInternal(); } void @@ -526,7 +357,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, } NS_WARN_IF_FALSE(!nsLayoutUtils::AreAsyncAnimationsEnabled() || - mPresContext->ThrottledStyleIsUpToDate(), + mPresContext->ThrottledTransitionStyleIsUpToDate(), "throttled animations not up to date"); // Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 352c94353ea..b9dde757906 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -91,11 +91,6 @@ struct ElementTransitions MOZ_FINAL // Either zero or one for each CSS property: nsTArray mPropertyTransitions; - - // Generation counter for flushes of throttled transitions. - // Used to prevent updating the styles twice for a given element during - // UpdateAllThrottledStyles. - mozilla::TimeStamp mFlushGeneration; }; @@ -203,6 +198,10 @@ public: // other than primary frames. void UpdateAllThrottledStyles(); + ElementTransitions* GetElementTransitions(mozilla::dom::Element *aElement, + nsCSSPseudoElements::Type aPseudoType, + bool aCreateIfNeeded); + protected: virtual void ElementDataRemoved() MOZ_OVERRIDE; virtual void AddElementData(mozilla::css::CommonElementAnimationData* aData) MOZ_OVERRIDE; @@ -216,24 +215,15 @@ private: nsStyleContext *aNewStyleContext, bool *aStartedAny, nsCSSPropertySet *aWhichStarted); - ElementTransitions* GetElementTransitions(mozilla::dom::Element *aElement, - nsCSSPseudoElements::Type aPseudoType, - bool aCreateIfNeeded); void WalkTransitionRule(ElementDependentRuleProcessorData* aData, nsCSSPseudoElements::Type aPseudoType); - // Update the animated styles of an element and its descendants. // If the element has a transition, it is flushed back to its primary frame. // If the element does not have a transition, then its style is reparented. void UpdateThrottledStylesForSubtree(nsIContent* aContent, nsStyleContext* aParentStyle, nsStyleChangeList &aChangeList); - // Update the style on aElement from the transition stored in this manager and - // the new parent style - aParentStyle. aElement must be transitioning or - // animated. Returns the updated style. - nsStyleContext* UpdateThrottledStyle(mozilla::dom::Element* aElement, - nsStyleContext* aParentStyle, - nsStyleChangeList &aChangeList); + void UpdateAllThrottledStylesInternal(); }; #endif /* !defined(nsTransitionManager_h_) */ From 6b19963a8c4ddd94a3b9960128d355018bf99f94 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Tue, 22 Oct 2013 15:17:13 +0300 Subject: [PATCH 15/75] Bug 927262, don't cache the encoder in case of unsual content type, r=hsivonen --- content/base/src/Element.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/base/src/Element.cpp b/content/base/src/Element.cpp index 9239223a27f..3084b0470c9 100644 --- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -3119,6 +3119,7 @@ Element::GetMarkup(bool aIncludeSelf, nsAString& aMarkup) nsAutoString contentType; doc->GetContentType(contentType); + bool tryToCacheEncoder = !aIncludeSelf; nsCOMPtr docEncoder = doc->GetCachedEncoder(); if (!docEncoder) { @@ -3133,6 +3134,9 @@ Element::GetMarkup(bool aIncludeSelf, nsAString& aMarkup) // again as XML contentType.AssignLiteral("application/xml"); docEncoder = do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "application/xml"); + // Don't try to cache the encoder since it would point to a different + // contentType once it has been reinitialized. + tryToCacheEncoder = false; } NS_ENSURE_TRUE_VOID(docEncoder); @@ -3163,7 +3167,7 @@ Element::GetMarkup(bool aIncludeSelf, nsAString& aMarkup) } rv = docEncoder->EncodeToString(aMarkup); MOZ_ASSERT(NS_SUCCEEDED(rv)); - if (!aIncludeSelf) { + if (tryToCacheEncoder) { doc->SetCachedEncoder(docEncoder.forget()); } } From e9bbb4d14aafaf9f9008db2d7db12267c89589d4 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 17 Oct 2013 19:09:20 -0400 Subject: [PATCH 16/75] Bug 928231 - Build the uconv library in unified mode; r=smontagu --HG-- extra : rebase_source : 8f92dcbec9e63aee39c9e15b58e8a189ba9cc2f6 --- intl/uconv/src/UnifiedUCV.cpp | 21 +++ intl/uconv/src/moz.build | 16 +-- intl/uconv/src/nsCP1252ToUnicode.cpp | 8 +- intl/uconv/src/nsConverterInputStream.cpp | 5 +- intl/uconv/src/nsConverterInputStream.h | 6 + intl/uconv/src/nsISO88591ToUnicode.cpp | 8 +- intl/uconv/src/nsMacRomanToUnicode.cpp | 8 +- intl/uconv/src/nsUnicodeToCP1252.cpp | 8 +- intl/uconv/src/nsUnicodeToISO88591.cpp | 8 +- intl/uconv/src/nsUnicodeToMacRoman.cpp | 8 +- intl/uconv/ucvcn/UnifiedUCVCN.cpp | 13 ++ intl/uconv/ucvcn/moz.build | 9 +- intl/uconv/ucvibm/UnifiedUCVIBM.cpp | 17 +++ intl/uconv/ucvibm/UnifiedUCVIBMOS2.cpp | 11 ++ intl/uconv/ucvibm/moz.build | 20 +-- intl/uconv/ucvibm/nsCP1125ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP1131ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP850ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP852ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP855ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP857ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP862ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP864ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsCP869ToUnicode.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP1125.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP1131.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP850.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP852.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP855.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP857.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP862.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP864.cpp | 8 +- intl/uconv/ucvibm/nsUnicodeToCP869.cpp | 8 +- intl/uconv/ucvja/UnifiedUCVJA.cpp | 11 ++ intl/uconv/ucvja/moz.build | 6 +- intl/uconv/ucvko/UnifiedUCVKO.cpp | 11 ++ intl/uconv/ucvko/moz.build | 6 +- intl/uconv/ucvlatin/UnifiedUCVLatin.cpp | 120 ++++++++++++++++++ intl/uconv/ucvlatin/moz.build | 115 +---------------- intl/uconv/ucvlatin/nsARMSCII8ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsAsciiToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1250ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1251ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1253ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1254ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1255ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1256ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1257ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP1258ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP866ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsCP874ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO885910ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO885913ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO885914ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO885915ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO885916ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88592ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88593ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88594ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88595ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88596ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88597ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISO88598ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsKOI8RToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsKOI8UToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacArabicToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacCEToUnicode.cpp | 8 +- .../uconv/ucvlatin/nsMacCroatianToUnicode.cpp | 8 +- .../uconv/ucvlatin/nsMacCyrillicToUnicode.cpp | 8 +- .../ucvlatin/nsMacDevanagariToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacFarsiToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacGreekToUnicode.cpp | 8 +- .../uconv/ucvlatin/nsMacGujaratiToUnicode.cpp | 8 +- .../uconv/ucvlatin/nsMacGurmukhiToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacHebrewToUnicode.cpp | 8 +- .../ucvlatin/nsMacIcelandicToUnicode.cpp | 8 +- .../uconv/ucvlatin/nsMacRomanianToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsMacTurkishToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsT61ToUnicode.cpp | 23 ++-- intl/uconv/ucvlatin/nsTCVN5712ToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToARMSCII8.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToAdobeEuro.cpp | 14 +- intl/uconv/ucvlatin/nsUnicodeToAscii.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1250.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1251.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1253.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1254.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1255.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1256.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1257.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP1258.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP866.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToCP874.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885910.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885911.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885913.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885914.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885915.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO885916.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88592.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88593.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88594.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88595.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88596.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88597.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88598.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISO88599.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToKOI8R.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToKOI8U.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacArabic.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacCE.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToMacCroatian.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToMacCyrillic.cpp | 8 +- .../ucvlatin/nsUnicodeToMacDevanagari.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacFarsi.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacGreek.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToMacGujarati.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToMacGurmukhi.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacHebrew.cpp | 8 +- .../ucvlatin/nsUnicodeToMacIcelandic.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToMacRomanian.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToMacTurkish.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToSymbol.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToT61.cpp | 21 +-- intl/uconv/ucvlatin/nsUnicodeToTCVN5712.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToTIS620.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToUserDefined.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToVISCII.cpp | 8 +- intl/uconv/ucvlatin/nsUnicodeToVPS.cpp | 8 +- .../uconv/ucvlatin/nsUnicodeToZapfDingbat.cpp | 8 +- .../uconv/ucvlatin/nsUserDefinedToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsVISCIIToUnicode.cpp | 8 +- intl/uconv/ucvlatin/nsVPSToUnicode.cpp | 8 +- intl/uconv/ucvtw/UnifiedUCVTW.cpp | 11 ++ intl/uconv/ucvtw/moz.build | 6 +- intl/uconv/ucvtw/nsUnicodeToBIG5HKSCS.cpp | 25 ++-- intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp | 18 ++- intl/uconv/ucvtw2/UnifiedUCVTW2.cpp | 8 ++ intl/uconv/ucvtw2/moz.build | 3 +- intl/uconv/ucvtw2/nsEUCTWToUnicode.cpp | 66 +++++----- intl/uconv/ucvtw2/nsUnicodeToEUCTW.cpp | 44 +++---- .../UnifiedUCVCUtils.c} | 5 + .../UnifiedUCVUtils.cpp} | 6 + intl/uconv/util/moz.build | 9 +- 146 files changed, 826 insertions(+), 756 deletions(-) create mode 100644 intl/uconv/src/UnifiedUCV.cpp create mode 100644 intl/uconv/ucvcn/UnifiedUCVCN.cpp create mode 100644 intl/uconv/ucvibm/UnifiedUCVIBM.cpp create mode 100644 intl/uconv/ucvibm/UnifiedUCVIBMOS2.cpp create mode 100644 intl/uconv/ucvja/UnifiedUCVJA.cpp create mode 100644 intl/uconv/ucvko/UnifiedUCVKO.cpp create mode 100644 intl/uconv/ucvlatin/UnifiedUCVLatin.cpp create mode 100644 intl/uconv/ucvtw/UnifiedUCVTW.cpp create mode 100644 intl/uconv/ucvtw2/UnifiedUCVTW2.cpp rename intl/uconv/{ucvcn/nsUnicodeToISO2022CN.cpp => util/UnifiedUCVCUtils.c} (83%) rename intl/uconv/{ucvcn/nsUnicodeToISO2022CN.h => util/UnifiedUCVUtils.cpp} (67%) diff --git a/intl/uconv/src/UnifiedUCV.cpp b/intl/uconv/src/UnifiedUCV.cpp new file mode 100644 index 00000000000..951f0f704e3 --- /dev/null +++ b/intl/uconv/src/UnifiedUCV.cpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCP1252ToUnicode.cpp" +#include "nsCharsetConverterManager.cpp" +#include "nsConverterInputStream.cpp" +#include "nsConverterOutputStream.cpp" +#include "nsISO88591ToUnicode.cpp" +#include "nsMacRomanToUnicode.cpp" +#include "nsScriptableUConv.cpp" +#include "nsTextToSubURI.cpp" +#include "nsUConvModule.cpp" +#include "nsUTF8ConverterService.cpp" +#include "nsUTF8ToUnicode.cpp" +#include "nsUnicodeToCP1252.cpp" +#include "nsUnicodeToISO88591.cpp" +#include "nsUnicodeToMacRoman.cpp" +#include "nsUnicodeToUTF8.cpp" + diff --git a/intl/uconv/src/moz.build b/intl/uconv/src/moz.build index 02cbc3ed3b6..47dd4d80124 100644 --- a/intl/uconv/src/moz.build +++ b/intl/uconv/src/moz.build @@ -7,21 +7,7 @@ MODULE = 'uconv' CPP_SOURCES += [ - 'nsCP1252ToUnicode.cpp', - 'nsCharsetConverterManager.cpp', - 'nsConverterInputStream.cpp', - 'nsConverterOutputStream.cpp', - 'nsISO88591ToUnicode.cpp', - 'nsMacRomanToUnicode.cpp', - 'nsScriptableUConv.cpp', - 'nsTextToSubURI.cpp', - 'nsUConvModule.cpp', - 'nsUTF8ConverterService.cpp', - 'nsUTF8ToUnicode.cpp', - 'nsUnicodeToCP1252.cpp', - 'nsUnicodeToISO88591.cpp', - 'nsUnicodeToMacRoman.cpp', - 'nsUnicodeToUTF8.cpp', + 'UnifiedUCV.cpp', ] if CONFIG['INTEL_ARCHITECTURE']: diff --git a/intl/uconv/src/nsCP1252ToUnicode.cpp b/intl/uconv/src/nsCP1252ToUnicode.cpp index 4eba3a469ce..1d0447acfe9 100644 --- a/intl/uconv/src/nsCP1252ToUnicode.cpp +++ b/intl/uconv/src/nsCP1252ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1252.ut" -}; - nsresult nsCP1252ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1252.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/src/nsConverterInputStream.cpp b/intl/uconv/src/nsConverterInputStream.cpp index 4350f67f384..b99dc33f794 100644 --- a/intl/uconv/src/nsConverterInputStream.cpp +++ b/intl/uconv/src/nsConverterInputStream.cpp @@ -15,8 +15,7 @@ NS_IMPL_ISUPPORTS3(nsConverterInputStream, nsIConverterInputStream, nsIUnicharInputStream, nsIUnicharLineInputStream) - -static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + NS_IMETHODIMP nsConverterInputStream::Init(nsIInputStream* aStream, @@ -24,6 +23,8 @@ nsConverterInputStream::Init(nsIInputStream* aStream, int32_t aBufferSize, PRUnichar aReplacementChar) { + static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + if (!aCharset) aCharset = "UTF-8"; diff --git a/intl/uconv/src/nsConverterInputStream.h b/intl/uconv/src/nsConverterInputStream.h index cd02909efc6..3586eeda318 100644 --- a/intl/uconv/src/nsConverterInputStream.h +++ b/intl/uconv/src/nsConverterInputStream.h @@ -3,6 +3,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsConverterInputStream_h +#define nsConverterInputStream_h + #include "nsIInputStream.h" #include "nsIConverterInputStream.h" #include "nsIUnicharLineInputStream.h" @@ -58,3 +61,6 @@ class nsConverterInputStream : public nsIConverterInputStream, nsAutoPtr > mLineBuffer; }; + +#endif + diff --git a/intl/uconv/src/nsISO88591ToUnicode.cpp b/intl/uconv/src/nsISO88591ToUnicode.cpp index cbc6ba9847b..a4e29af17d1 100644 --- a/intl/uconv/src/nsISO88591ToUnicode.cpp +++ b/intl/uconv/src/nsISO88591ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1252.ut" -}; - nsresult nsISO88591ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1252.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/src/nsMacRomanToUnicode.cpp b/intl/uconv/src/nsMacRomanToUnicode.cpp index c89f0bdce23..c4c4ca4223c 100644 --- a/intl/uconv/src/nsMacRomanToUnicode.cpp +++ b/intl/uconv/src/nsMacRomanToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacRomanMappingTable[] = { -#include "macroman.ut" -}; - nsresult nsMacRomanToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacRomanMappingTable[] = { +#include "macroman.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_MacRomanMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/src/nsUnicodeToCP1252.cpp b/intl/uconv/src/nsUnicodeToCP1252.cpp index c35f13d4d06..d4ec2bf59e1 100644 --- a/intl/uconv/src/nsUnicodeToCP1252.cpp +++ b/intl/uconv/src/nsUnicodeToCP1252.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1252.uf" -}; - nsresult nsUnicodeToCP1252Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1252.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/src/nsUnicodeToISO88591.cpp b/intl/uconv/src/nsUnicodeToISO88591.cpp index ae1e4bf3761..47fd6ae627b 100644 --- a/intl/uconv/src/nsUnicodeToISO88591.cpp +++ b/intl/uconv/src/nsUnicodeToISO88591.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-1.uf" -}; - nsresult nsUnicodeToISO88591Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-1.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/src/nsUnicodeToMacRoman.cpp b/intl/uconv/src/nsUnicodeToMacRoman.cpp index 270da6ad19c..f473362eb53 100644 --- a/intl/uconv/src/nsUnicodeToMacRoman.cpp +++ b/intl/uconv/src/nsUnicodeToMacRoman.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacRomanMappingTable[] = { -#include "macroman.uf" -}; - nsresult nsUnicodeToMacRomanConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacRomanMappingTable[] = { +#include "macroman.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_MacRomanMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvcn/UnifiedUCVCN.cpp b/intl/uconv/ucvcn/UnifiedUCVCN.cpp new file mode 100644 index 00000000000..013a400b0d9 --- /dev/null +++ b/intl/uconv/ucvcn/UnifiedUCVCN.cpp @@ -0,0 +1,13 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsGBKConvUtil.cpp" +#include "nsGBKToUnicode.cpp" +#include "nsHZToUnicode.cpp" +#include "nsISO2022CNToUnicode.cpp" +#include "nsUnicodeToGB2312V2.cpp" +#include "nsUnicodeToGBK.cpp" +#include "nsUnicodeToHZ.cpp" + diff --git a/intl/uconv/ucvcn/moz.build b/intl/uconv/ucvcn/moz.build index c5afb06a3a4..11260d8e299 100644 --- a/intl/uconv/ucvcn/moz.build +++ b/intl/uconv/ucvcn/moz.build @@ -11,14 +11,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsGBKConvUtil.cpp', - 'nsGBKToUnicode.cpp', - 'nsHZToUnicode.cpp', - 'nsISO2022CNToUnicode.cpp', - 'nsUnicodeToGB2312V2.cpp', - 'nsUnicodeToGBK.cpp', - 'nsUnicodeToHZ.cpp', - 'nsUnicodeToISO2022CN.cpp', + 'UnifiedUCVCN.cpp', ] LIBRARY_NAME = 'ucvcn_s' diff --git a/intl/uconv/ucvibm/UnifiedUCVIBM.cpp b/intl/uconv/ucvibm/UnifiedUCVIBM.cpp new file mode 100644 index 00000000000..15768b79055 --- /dev/null +++ b/intl/uconv/ucvibm/UnifiedUCVIBM.cpp @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCP850ToUnicode.cpp" +#include "nsCP852ToUnicode.cpp" +#include "nsCP855ToUnicode.cpp" +#include "nsCP857ToUnicode.cpp" +#include "nsCP862ToUnicode.cpp" +#include "nsCP864ToUnicode.cpp" +#include "nsUnicodeToCP850.cpp" +#include "nsUnicodeToCP852.cpp" +#include "nsUnicodeToCP855.cpp" +#include "nsUnicodeToCP857.cpp" +#include "nsUnicodeToCP862.cpp" +#include "nsUnicodeToCP864.cpp" + diff --git a/intl/uconv/ucvibm/UnifiedUCVIBMOS2.cpp b/intl/uconv/ucvibm/UnifiedUCVIBMOS2.cpp new file mode 100644 index 00000000000..f18ebe8fffb --- /dev/null +++ b/intl/uconv/ucvibm/UnifiedUCVIBMOS2.cpp @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCP869ToUnicode.cpp" +#include "nsUnicodeToCP869.cpp" +#include "nsCP1125ToUnicode.cpp" +#include "nsUnicodeToCP1125.cpp" +#include "nsCP1131ToUnicode.cpp" +#include "nsUnicodeToCP1131.cpp" + diff --git a/intl/uconv/ucvibm/moz.build b/intl/uconv/ucvibm/moz.build index 4de6f9c8efd..5c6feb6150a 100644 --- a/intl/uconv/ucvibm/moz.build +++ b/intl/uconv/ucvibm/moz.build @@ -11,28 +11,12 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsCP850ToUnicode.cpp', - 'nsCP852ToUnicode.cpp', - 'nsCP855ToUnicode.cpp', - 'nsCP857ToUnicode.cpp', - 'nsCP862ToUnicode.cpp', - 'nsCP864ToUnicode.cpp', - 'nsUnicodeToCP850.cpp', - 'nsUnicodeToCP852.cpp', - 'nsUnicodeToCP855.cpp', - 'nsUnicodeToCP857.cpp', - 'nsUnicodeToCP862.cpp', - 'nsUnicodeToCP864.cpp', + 'UnifiedUCVIBM.cpp', ] if CONFIG['OS_ARCH'] == 'OS2': CPP_SOURCES += [ - 'nsCP869ToUnicode.cpp', - 'nsUnicodeToCP869.cpp', - 'nsCP1125ToUnicode.cpp', - 'nsUnicodeToCP1125.cpp', - 'nsCP1131ToUnicode.cpp', - 'nsUnicodeToCP1131.cpp', + 'UnifiedUCVIBMOS2.cpp', ] LIBRARY_NAME = 'ucvibm_s' diff --git a/intl/uconv/ucvibm/nsCP1125ToUnicode.cpp b/intl/uconv/ucvibm/nsCP1125ToUnicode.cpp index ed6a3f53a36..3c959684d18 100644 --- a/intl/uconv/ucvibm/nsCP1125ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP1125ToUnicode.cpp @@ -8,10 +8,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1125.ut" -}; - //---------------------------------------------------------------------- // Class nsCP1125ToUnicode [implementation] @@ -19,6 +15,10 @@ nsresult nsCP1125ToUnicodeConstructor(nsISupports* aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1125.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP1131ToUnicode.cpp b/intl/uconv/ucvibm/nsCP1131ToUnicode.cpp index 7698b0ff683..efe4dbbbf28 100644 --- a/intl/uconv/ucvibm/nsCP1131ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP1131ToUnicode.cpp @@ -8,10 +8,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1131.ut" -}; - //---------------------------------------------------------------------- // Class nsCP1131ToUnicode [implementation] @@ -19,6 +15,10 @@ nsresult nsCP1131ToUnicodeConstructor(nsISupports* aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1131.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP850ToUnicode.cpp b/intl/uconv/ucvibm/nsCP850ToUnicode.cpp index 4ac88011664..006c65cd6ed 100644 --- a/intl/uconv/ucvibm/nsCP850ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP850ToUnicode.cpp @@ -23,10 +23,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp850.ut" -}; - //---------------------------------------------------------------------- // Class nsCP850ToUnicode [implementation] @@ -34,6 +30,10 @@ nsresult nsCP850ToUnicodeConstructor(nsISupports* aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp850.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP852ToUnicode.cpp b/intl/uconv/ucvibm/nsCP852ToUnicode.cpp index 5a3bac0c8d5..f5a15153da1 100644 --- a/intl/uconv/ucvibm/nsCP852ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP852ToUnicode.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp852.ut" -}; - nsresult nsCP852ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp852.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP855ToUnicode.cpp b/intl/uconv/ucvibm/nsCP855ToUnicode.cpp index 0c69ea53c24..4e88b484082 100644 --- a/intl/uconv/ucvibm/nsCP855ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP855ToUnicode.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp855.ut" -}; - nsresult nsCP855ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp855.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP857ToUnicode.cpp b/intl/uconv/ucvibm/nsCP857ToUnicode.cpp index 533eaaefa9a..b02a42bba9f 100644 --- a/intl/uconv/ucvibm/nsCP857ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP857ToUnicode.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp857.ut" -}; - nsresult nsCP857ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp857.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP862ToUnicode.cpp b/intl/uconv/ucvibm/nsCP862ToUnicode.cpp index c8b8ad63e57..66471fe44be 100644 --- a/intl/uconv/ucvibm/nsCP862ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP862ToUnicode.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp862.ut" -}; - nsresult nsCP862ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp862.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP864ToUnicode.cpp b/intl/uconv/ucvibm/nsCP864ToUnicode.cpp index 37548d0e238..5b40bd98a85 100644 --- a/intl/uconv/ucvibm/nsCP864ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP864ToUnicode.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp864.ut" -}; - nsresult nsCP864ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp864.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsCP869ToUnicode.cpp b/intl/uconv/ucvibm/nsCP869ToUnicode.cpp index aa63133fef6..182a306b01c 100644 --- a/intl/uconv/ucvibm/nsCP869ToUnicode.cpp +++ b/intl/uconv/ucvibm/nsCP869ToUnicode.cpp @@ -8,14 +8,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp869.ut" -}; - nsresult nsCP869ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp869.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvibm/nsUnicodeToCP1125.cpp b/intl/uconv/ucvibm/nsUnicodeToCP1125.cpp index c1d382d8dc1..78c93aa0f4d 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP1125.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP1125.cpp @@ -8,14 +8,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1125.uf" -}; - nsresult nsUnicodeToCP1125Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1125.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP1131.cpp b/intl/uconv/ucvibm/nsUnicodeToCP1131.cpp index b185565c20a..509ad494ec8 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP1131.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP1131.cpp @@ -8,14 +8,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1131.uf" -}; - nsresult nsUnicodeToCP1131Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1131.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP850.cpp b/intl/uconv/ucvibm/nsUnicodeToCP850.cpp index 9e841ae2ce3..68dc4e00b52 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP850.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP850.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp850.uf" -}; - nsresult nsUnicodeToCP850Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp850.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP852.cpp b/intl/uconv/ucvibm/nsUnicodeToCP852.cpp index 32120845b0e..134c90b5ea0 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP852.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP852.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp852.uf" -}; - nsresult nsUnicodeToCP852Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp852.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP855.cpp b/intl/uconv/ucvibm/nsUnicodeToCP855.cpp index 72cd58d8d89..f4ba685c0fa 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP855.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP855.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp855.uf" -}; - nsresult nsUnicodeToCP855Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp855.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP857.cpp b/intl/uconv/ucvibm/nsUnicodeToCP857.cpp index 9af17ffc0d6..19c17f2fe8f 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP857.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP857.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp857.uf" -}; - nsresult nsUnicodeToCP857Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp857.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP862.cpp b/intl/uconv/ucvibm/nsUnicodeToCP862.cpp index c7f2777485e..f957467336b 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP862.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP862.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp862.uf" -}; - nsresult nsUnicodeToCP862Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp862.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP864.cpp b/intl/uconv/ucvibm/nsUnicodeToCP864.cpp index 5bf8bb86386..ce9b9ad5b72 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP864.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP864.cpp @@ -23,14 +23,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp864.uf" -}; - nsresult nsUnicodeToCP864Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp864.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvibm/nsUnicodeToCP869.cpp b/intl/uconv/ucvibm/nsUnicodeToCP869.cpp index 7a28359d8fa..a45fbe35553 100644 --- a/intl/uconv/ucvibm/nsUnicodeToCP869.cpp +++ b/intl/uconv/ucvibm/nsUnicodeToCP869.cpp @@ -8,14 +8,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp869.uf" -}; - nsresult nsUnicodeToCP869Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp869.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvja/UnifiedUCVJA.cpp b/intl/uconv/ucvja/UnifiedUCVJA.cpp new file mode 100644 index 00000000000..9b2262d019c --- /dev/null +++ b/intl/uconv/ucvja/UnifiedUCVJA.cpp @@ -0,0 +1,11 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsJapaneseToUnicode.cpp" +#include "nsUnicodeToEUCJP.cpp" +#include "nsUnicodeToISO2022JP.cpp" +#include "nsUnicodeToJISx0201.cpp" +#include "nsUnicodeToSJIS.cpp" + diff --git a/intl/uconv/ucvja/moz.build b/intl/uconv/ucvja/moz.build index 2c479df2fe6..d0dfa1d52e6 100644 --- a/intl/uconv/ucvja/moz.build +++ b/intl/uconv/ucvja/moz.build @@ -12,11 +12,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsJapaneseToUnicode.cpp', - 'nsUnicodeToEUCJP.cpp', - 'nsUnicodeToISO2022JP.cpp', - 'nsUnicodeToJISx0201.cpp', - 'nsUnicodeToSJIS.cpp', + 'UnifiedUCVJA.cpp', ] LIBRARY_NAME = 'ucvja_s' diff --git a/intl/uconv/ucvko/UnifiedUCVKO.cpp b/intl/uconv/ucvko/UnifiedUCVKO.cpp new file mode 100644 index 00000000000..df8d7402fca --- /dev/null +++ b/intl/uconv/ucvko/UnifiedUCVKO.cpp @@ -0,0 +1,11 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCP949ToUnicode.cpp" +#include "nsISO2022KRToUnicode.cpp" +#include "nsJohabToUnicode.cpp" +#include "nsUnicodeToCP949.cpp" +#include "nsUnicodeToJohab.cpp" + diff --git a/intl/uconv/ucvko/moz.build b/intl/uconv/ucvko/moz.build index 96fa98d348f..ed6de03ca66 100644 --- a/intl/uconv/ucvko/moz.build +++ b/intl/uconv/ucvko/moz.build @@ -11,11 +11,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsCP949ToUnicode.cpp', - 'nsISO2022KRToUnicode.cpp', - 'nsJohabToUnicode.cpp', - 'nsUnicodeToCP949.cpp', - 'nsUnicodeToJohab.cpp', + 'UnifiedUCVKO.cpp', ] LIBRARY_NAME = 'ucvko_s' diff --git a/intl/uconv/ucvlatin/UnifiedUCVLatin.cpp b/intl/uconv/ucvlatin/UnifiedUCVLatin.cpp new file mode 100644 index 00000000000..8c3819fcf44 --- /dev/null +++ b/intl/uconv/ucvlatin/UnifiedUCVLatin.cpp @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsARMSCII8ToUnicode.cpp" +#include "nsAsciiToUnicode.cpp" +#include "nsCP1250ToUnicode.cpp" +#include "nsCP1251ToUnicode.cpp" +#include "nsCP1253ToUnicode.cpp" +#include "nsCP1254ToUnicode.cpp" +#include "nsCP1255ToUnicode.cpp" +#include "nsCP1256ToUnicode.cpp" +#include "nsCP1257ToUnicode.cpp" +#include "nsCP1258ToUnicode.cpp" +#include "nsCP866ToUnicode.cpp" +#include "nsCP874ToUnicode.cpp" +#include "nsISO885910ToUnicode.cpp" +#include "nsISO885911ToUnicode.cpp" +#include "nsISO885913ToUnicode.cpp" +#include "nsISO885914ToUnicode.cpp" +#include "nsISO885915ToUnicode.cpp" +#include "nsISO885916ToUnicode.cpp" +#include "nsISO88592ToUnicode.cpp" +#include "nsISO88593ToUnicode.cpp" +#include "nsISO88594ToUnicode.cpp" +#include "nsISO88595ToUnicode.cpp" +#include "nsISO88596EToUnicode.cpp" +#include "nsISO88596IToUnicode.cpp" +#include "nsISO88596ToUnicode.cpp" +#include "nsISO88597ToUnicode.cpp" +#include "nsISO88598EToUnicode.cpp" +#include "nsISO88598IToUnicode.cpp" +#include "nsISO88598ToUnicode.cpp" +#include "nsISO88599ToUnicode.cpp" +#include "nsISOIR111ToUnicode.cpp" +#include "nsKOI8RToUnicode.cpp" +#include "nsKOI8UToUnicode.cpp" +#include "nsMUTF7ToUnicode.cpp" +#include "nsMacArabicToUnicode.cpp" +#include "nsMacCEToUnicode.cpp" +#include "nsMacCroatianToUnicode.cpp" +#include "nsMacCyrillicToUnicode.cpp" +#include "nsMacDevanagariToUnicode.cpp" +#include "nsMacFarsiToUnicode.cpp" +#include "nsMacGreekToUnicode.cpp" +#include "nsMacGujaratiToUnicode.cpp" +#include "nsMacGurmukhiToUnicode.cpp" +#include "nsMacHebrewToUnicode.cpp" +#include "nsMacIcelandicToUnicode.cpp" +#include "nsMacRomanianToUnicode.cpp" +#include "nsMacTurkishToUnicode.cpp" +#include "nsT61ToUnicode.cpp" +#include "nsTCVN5712ToUnicode.cpp" +#include "nsTIS620ToUnicode.cpp" +#include "nsUTF16ToUnicode.cpp" +#include "nsUTF7ToUnicode.cpp" +#include "nsUnicodeToARMSCII8.cpp" +#include "nsUnicodeToAdobeEuro.cpp" +#include "nsUnicodeToAscii.cpp" +#include "nsUnicodeToCP1250.cpp" +#include "nsUnicodeToCP1251.cpp" +#include "nsUnicodeToCP1253.cpp" +#include "nsUnicodeToCP1254.cpp" +#include "nsUnicodeToCP1255.cpp" +#include "nsUnicodeToCP1256.cpp" +#include "nsUnicodeToCP1257.cpp" +#include "nsUnicodeToCP1258.cpp" +#include "nsUnicodeToCP866.cpp" +#include "nsUnicodeToCP874.cpp" +#include "nsUnicodeToISO885910.cpp" +#include "nsUnicodeToISO885911.cpp" +#include "nsUnicodeToISO885913.cpp" +#include "nsUnicodeToISO885914.cpp" +#include "nsUnicodeToISO885915.cpp" +#include "nsUnicodeToISO885916.cpp" +#include "nsUnicodeToISO88592.cpp" +#include "nsUnicodeToISO88593.cpp" +#include "nsUnicodeToISO88594.cpp" +#include "nsUnicodeToISO88595.cpp" +#include "nsUnicodeToISO88596.cpp" +#include "nsUnicodeToISO88596E.cpp" +#include "nsUnicodeToISO88596I.cpp" +#include "nsUnicodeToISO88597.cpp" +#include "nsUnicodeToISO88598.cpp" +#include "nsUnicodeToISO88598E.cpp" +#include "nsUnicodeToISO88598I.cpp" +#include "nsUnicodeToISO88599.cpp" +#include "nsUnicodeToISOIR111.cpp" +#include "nsUnicodeToKOI8R.cpp" +#include "nsUnicodeToKOI8U.cpp" +#include "nsUnicodeToMUTF7.cpp" +#include "nsUnicodeToMacArabic.cpp" +#include "nsUnicodeToMacCE.cpp" +#include "nsUnicodeToMacCroatian.cpp" +#include "nsUnicodeToMacCyrillic.cpp" +#include "nsUnicodeToMacDevanagari.cpp" +#include "nsUnicodeToMacFarsi.cpp" +#include "nsUnicodeToMacGreek.cpp" +#include "nsUnicodeToMacGujarati.cpp" +#include "nsUnicodeToMacGurmukhi.cpp" +#include "nsUnicodeToMacHebrew.cpp" +#include "nsUnicodeToMacIcelandic.cpp" +#include "nsUnicodeToMacRomanian.cpp" +#include "nsUnicodeToMacTurkish.cpp" +#include "nsUnicodeToSymbol.cpp" +#include "nsUnicodeToT61.cpp" +#include "nsUnicodeToTCVN5712.cpp" +#include "nsUnicodeToTIS620.cpp" +#include "nsUnicodeToTSCII.cpp" +#include "nsUnicodeToUTF16.cpp" +#include "nsUnicodeToUTF7.cpp" +#include "nsUnicodeToUserDefined.cpp" +#include "nsUnicodeToVISCII.cpp" +#include "nsUnicodeToVPS.cpp" +#include "nsUnicodeToZapfDingbat.cpp" +#include "nsUserDefinedToUnicode.cpp" +#include "nsVISCIIToUnicode.cpp" +#include "nsVPSToUnicode.cpp" + diff --git a/intl/uconv/ucvlatin/moz.build b/intl/uconv/ucvlatin/moz.build index dbb98b98719..d4330be3114 100644 --- a/intl/uconv/ucvlatin/moz.build +++ b/intl/uconv/ucvlatin/moz.build @@ -11,120 +11,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsARMSCII8ToUnicode.cpp', - 'nsAsciiToUnicode.cpp', - 'nsCP1250ToUnicode.cpp', - 'nsCP1251ToUnicode.cpp', - 'nsCP1253ToUnicode.cpp', - 'nsCP1254ToUnicode.cpp', - 'nsCP1255ToUnicode.cpp', - 'nsCP1256ToUnicode.cpp', - 'nsCP1257ToUnicode.cpp', - 'nsCP1258ToUnicode.cpp', - 'nsCP866ToUnicode.cpp', - 'nsCP874ToUnicode.cpp', - 'nsISO885910ToUnicode.cpp', - 'nsISO885911ToUnicode.cpp', - 'nsISO885913ToUnicode.cpp', - 'nsISO885914ToUnicode.cpp', - 'nsISO885915ToUnicode.cpp', - 'nsISO885916ToUnicode.cpp', - 'nsISO88592ToUnicode.cpp', - 'nsISO88593ToUnicode.cpp', - 'nsISO88594ToUnicode.cpp', - 'nsISO88595ToUnicode.cpp', - 'nsISO88596EToUnicode.cpp', - 'nsISO88596IToUnicode.cpp', - 'nsISO88596ToUnicode.cpp', - 'nsISO88597ToUnicode.cpp', - 'nsISO88598EToUnicode.cpp', - 'nsISO88598IToUnicode.cpp', - 'nsISO88598ToUnicode.cpp', - 'nsISO88599ToUnicode.cpp', - 'nsISOIR111ToUnicode.cpp', - 'nsKOI8RToUnicode.cpp', - 'nsKOI8UToUnicode.cpp', - 'nsMUTF7ToUnicode.cpp', - 'nsMacArabicToUnicode.cpp', - 'nsMacCEToUnicode.cpp', - 'nsMacCroatianToUnicode.cpp', - 'nsMacCyrillicToUnicode.cpp', - 'nsMacDevanagariToUnicode.cpp', - 'nsMacFarsiToUnicode.cpp', - 'nsMacGreekToUnicode.cpp', - 'nsMacGujaratiToUnicode.cpp', - 'nsMacGurmukhiToUnicode.cpp', - 'nsMacHebrewToUnicode.cpp', - 'nsMacIcelandicToUnicode.cpp', - 'nsMacRomanianToUnicode.cpp', - 'nsMacTurkishToUnicode.cpp', - 'nsT61ToUnicode.cpp', - 'nsTCVN5712ToUnicode.cpp', - 'nsTIS620ToUnicode.cpp', - 'nsUTF16ToUnicode.cpp', - 'nsUTF7ToUnicode.cpp', - 'nsUnicodeToARMSCII8.cpp', - 'nsUnicodeToAdobeEuro.cpp', - 'nsUnicodeToAscii.cpp', - 'nsUnicodeToCP1250.cpp', - 'nsUnicodeToCP1251.cpp', - 'nsUnicodeToCP1253.cpp', - 'nsUnicodeToCP1254.cpp', - 'nsUnicodeToCP1255.cpp', - 'nsUnicodeToCP1256.cpp', - 'nsUnicodeToCP1257.cpp', - 'nsUnicodeToCP1258.cpp', - 'nsUnicodeToCP866.cpp', - 'nsUnicodeToCP874.cpp', - 'nsUnicodeToISO885910.cpp', - 'nsUnicodeToISO885911.cpp', - 'nsUnicodeToISO885913.cpp', - 'nsUnicodeToISO885914.cpp', - 'nsUnicodeToISO885915.cpp', - 'nsUnicodeToISO885916.cpp', - 'nsUnicodeToISO88592.cpp', - 'nsUnicodeToISO88593.cpp', - 'nsUnicodeToISO88594.cpp', - 'nsUnicodeToISO88595.cpp', - 'nsUnicodeToISO88596.cpp', - 'nsUnicodeToISO88596E.cpp', - 'nsUnicodeToISO88596I.cpp', - 'nsUnicodeToISO88597.cpp', - 'nsUnicodeToISO88598.cpp', - 'nsUnicodeToISO88598E.cpp', - 'nsUnicodeToISO88598I.cpp', - 'nsUnicodeToISO88599.cpp', - 'nsUnicodeToISOIR111.cpp', - 'nsUnicodeToKOI8R.cpp', - 'nsUnicodeToKOI8U.cpp', - 'nsUnicodeToMUTF7.cpp', - 'nsUnicodeToMacArabic.cpp', - 'nsUnicodeToMacCE.cpp', - 'nsUnicodeToMacCroatian.cpp', - 'nsUnicodeToMacCyrillic.cpp', - 'nsUnicodeToMacDevanagari.cpp', - 'nsUnicodeToMacFarsi.cpp', - 'nsUnicodeToMacGreek.cpp', - 'nsUnicodeToMacGujarati.cpp', - 'nsUnicodeToMacGurmukhi.cpp', - 'nsUnicodeToMacHebrew.cpp', - 'nsUnicodeToMacIcelandic.cpp', - 'nsUnicodeToMacRomanian.cpp', - 'nsUnicodeToMacTurkish.cpp', - 'nsUnicodeToSymbol.cpp', - 'nsUnicodeToT61.cpp', - 'nsUnicodeToTCVN5712.cpp', - 'nsUnicodeToTIS620.cpp', - 'nsUnicodeToTSCII.cpp', - 'nsUnicodeToUTF16.cpp', - 'nsUnicodeToUTF7.cpp', - 'nsUnicodeToUserDefined.cpp', - 'nsUnicodeToVISCII.cpp', - 'nsUnicodeToVPS.cpp', - 'nsUnicodeToZapfDingbat.cpp', - 'nsUserDefinedToUnicode.cpp', - 'nsVISCIIToUnicode.cpp', - 'nsVPSToUnicode.cpp', + 'UnifiedUCVLatin.cpp', ] LIBRARY_NAME = 'ucvlatin_s' diff --git a/intl/uconv/ucvlatin/nsARMSCII8ToUnicode.cpp b/intl/uconv/ucvlatin/nsARMSCII8ToUnicode.cpp index 9d23533c7ea..1e30eb4b59a 100644 --- a/intl/uconv/ucvlatin/nsARMSCII8ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsARMSCII8ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "armscii.ut" -}; - nsresult nsARMSCII8ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "armscii.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsAsciiToUnicode.cpp b/intl/uconv/ucvlatin/nsAsciiToUnicode.cpp index 2a6d727003f..bc8f3f8a451 100644 --- a/intl/uconv/ucvlatin/nsAsciiToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsAsciiToUnicode.cpp @@ -12,14 +12,14 @@ // use iso-8859-1 decoder to interpret us-ascii. Some websites are mistakenly // labeled as us-ascii for iso-8859-1. Be generous here should be fine. -static const uint16_t g_utMappingTable[] = { -#include "cp1252.ut" -}; - nsresult nsAsciiToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1252.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1250ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1250ToUnicode.cpp index 75c114ec6aa..a42c439c05a 100644 --- a/intl/uconv/ucvlatin/nsCP1250ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1250ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1250.ut" -}; - nsresult nsCP1250ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1250.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1251ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1251ToUnicode.cpp index 90aebc8b2ff..1b3dcea852f 100644 --- a/intl/uconv/ucvlatin/nsCP1251ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1251ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1251.ut" -}; - nsresult nsCP1251ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1251.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1253ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1253ToUnicode.cpp index ac8446206d5..c231ae991d2 100644 --- a/intl/uconv/ucvlatin/nsCP1253ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1253ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1253.ut" -}; - nsresult nsCP1253ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1253.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1254ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1254ToUnicode.cpp index 54a41340383..b3b70fec90e 100644 --- a/intl/uconv/ucvlatin/nsCP1254ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1254ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1254.ut" -}; - nsresult nsCP1254ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1254.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1255ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1255ToUnicode.cpp index 0e421f042c4..57bac7bd010 100644 --- a/intl/uconv/ucvlatin/nsCP1255ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1255ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1255.ut" -}; - nsresult nsCP1255ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1255.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1256ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1256ToUnicode.cpp index c2ab10d5bd0..791f93c77c8 100644 --- a/intl/uconv/ucvlatin/nsCP1256ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1256ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1256.ut" -}; - nsresult nsCP1256ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1256.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1257ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1257ToUnicode.cpp index aa122a47075..b2e39c6f7c4 100644 --- a/intl/uconv/ucvlatin/nsCP1257ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1257ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1257.ut" -}; - nsresult nsCP1257ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1257.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP1258ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP1258ToUnicode.cpp index 9220ed73f87..6338c8c9891 100644 --- a/intl/uconv/ucvlatin/nsCP1258ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP1258ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp1258.ut" -}; - nsresult nsCP1258ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp1258.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP866ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP866ToUnicode.cpp index 2e00b4b22f0..c4fcb7b204a 100644 --- a/intl/uconv/ucvlatin/nsCP866ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP866ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp866.ut" -}; - nsresult nsCP866ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp866.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsCP874ToUnicode.cpp b/intl/uconv/ucvlatin/nsCP874ToUnicode.cpp index 28c5d2a66ef..1c5bea8c006 100644 --- a/intl/uconv/ucvlatin/nsCP874ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsCP874ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "cp874.ut" -}; - nsresult nsCP874ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "cp874.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO885910ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO885910ToUnicode.cpp index 7dc482eb3e3..b9c39e5be8f 100644 --- a/intl/uconv/ucvlatin/nsISO885910ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO885910ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-10.ut" -}; - nsresult nsISO885910ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-10.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO885913ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO885913ToUnicode.cpp index 5cbee625c4b..bbe71388981 100644 --- a/intl/uconv/ucvlatin/nsISO885913ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO885913ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-13.ut" -}; - nsresult nsISO885913ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-13.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO885914ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO885914ToUnicode.cpp index eb74b9698f5..92820f853e9 100644 --- a/intl/uconv/ucvlatin/nsISO885914ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO885914ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-14.ut" -}; - nsresult nsISO885914ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-14.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO885915ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO885915ToUnicode.cpp index 9c9421040ce..166553df8f7 100644 --- a/intl/uconv/ucvlatin/nsISO885915ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO885915ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-15.ut" -}; - nsresult nsISO885915ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-15.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO885916ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO885916ToUnicode.cpp index acf38edb727..3bfd3986950 100644 --- a/intl/uconv/ucvlatin/nsISO885916ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO885916ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-16.ut" -}; - nsresult nsISO885916ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-16.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88592ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88592ToUnicode.cpp index e3b27e968f8..c6575920dde 100644 --- a/intl/uconv/ucvlatin/nsISO88592ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88592ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-2.ut" -}; - nsresult nsISO88592ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-2.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88593ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88593ToUnicode.cpp index 2fef607f825..fec72cf489b 100644 --- a/intl/uconv/ucvlatin/nsISO88593ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88593ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-3.ut" -}; - nsresult nsISO88593ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-3.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88594ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88594ToUnicode.cpp index 36d0423c390..85351156ee9 100644 --- a/intl/uconv/ucvlatin/nsISO88594ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88594ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-4.ut" -}; - nsresult nsISO88594ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-4.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88595ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88595ToUnicode.cpp index 0cb2c0009d2..6216fa344e1 100644 --- a/intl/uconv/ucvlatin/nsISO88595ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88595ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-5.ut" -}; - nsresult nsISO88595ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-5.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88596ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88596ToUnicode.cpp index 0481f1d5ac2..6a5fe71595a 100644 --- a/intl/uconv/ucvlatin/nsISO88596ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88596ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-6.ut" -}; - nsresult nsISO88596ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-6.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88597ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88597ToUnicode.cpp index ccdfb4e94d9..d0de74b9127 100644 --- a/intl/uconv/ucvlatin/nsISO88597ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88597ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-7.ut" -}; - nsresult nsISO88597ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-7.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISO88598ToUnicode.cpp b/intl/uconv/ucvlatin/nsISO88598ToUnicode.cpp index 889cb9c6cc6..01edc2f82c9 100644 --- a/intl/uconv/ucvlatin/nsISO88598ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISO88598ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "8859-8.ut" -}; - nsresult nsISO88598ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "8859-8.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp b/intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp index 709d84fdcdc..cc188faa9f7 100644 --- a/intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "iso-ir-111.ut" -}; - nsresult nsISOIR111ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "iso-ir-111.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsKOI8RToUnicode.cpp b/intl/uconv/ucvlatin/nsKOI8RToUnicode.cpp index 07d69baba79..ff52e5a0be1 100644 --- a/intl/uconv/ucvlatin/nsKOI8RToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsKOI8RToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "koi8r.ut" -}; - nsresult nsKOI8RToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "koi8r.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsKOI8UToUnicode.cpp b/intl/uconv/ucvlatin/nsKOI8UToUnicode.cpp index 1f2daf9ba83..3a076a278bf 100644 --- a/intl/uconv/ucvlatin/nsKOI8UToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsKOI8UToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "koi8u.ut" -}; - nsresult nsKOI8UToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "koi8u.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacArabicToUnicode.cpp b/intl/uconv/ucvlatin/nsMacArabicToUnicode.cpp index 7d027d23487..4dd0ec96da2 100644 --- a/intl/uconv/ucvlatin/nsMacArabicToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacArabicToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macarabic.ut" -}; - nsresult nsMacArabicToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macarabic.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacCEToUnicode.cpp b/intl/uconv/ucvlatin/nsMacCEToUnicode.cpp index c006bb901a0..8ca009c94d8 100644 --- a/intl/uconv/ucvlatin/nsMacCEToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacCEToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacCEMappingTable[] = { -#include "macce.ut" -}; - nsresult nsMacCEToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacCEMappingTable[] = { +#include "macce.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_MacCEMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacCroatianToUnicode.cpp b/intl/uconv/ucvlatin/nsMacCroatianToUnicode.cpp index 31adad2b410..d47b0e450cb 100644 --- a/intl/uconv/ucvlatin/nsMacCroatianToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacCroatianToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "maccroat.ut" -}; - nsresult nsMacCroatianToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "maccroat.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacCyrillicToUnicode.cpp b/intl/uconv/ucvlatin/nsMacCyrillicToUnicode.cpp index 61e751d0619..891c884ee36 100644 --- a/intl/uconv/ucvlatin/nsMacCyrillicToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacCyrillicToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "maccyril.ut" -}; - nsresult nsMacCyrillicToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "maccyril.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacDevanagariToUnicode.cpp b/intl/uconv/ucvlatin/nsMacDevanagariToUnicode.cpp index 8f07ad76a03..72394909a72 100644 --- a/intl/uconv/ucvlatin/nsMacDevanagariToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacDevanagariToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macdevanaga.ut" -}; - nsresult nsMacDevanagariToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macdevanaga.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacFarsiToUnicode.cpp b/intl/uconv/ucvlatin/nsMacFarsiToUnicode.cpp index fb93b480f8e..1e002966738 100644 --- a/intl/uconv/ucvlatin/nsMacFarsiToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacFarsiToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macfarsi.ut" -}; - nsresult nsMacFarsiToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macfarsi.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacGreekToUnicode.cpp b/intl/uconv/ucvlatin/nsMacGreekToUnicode.cpp index cfc40c0bfc3..f24ffc9eb65 100644 --- a/intl/uconv/ucvlatin/nsMacGreekToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacGreekToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacGreekMappingTable[] = { -#include "macgreek.ut" -}; - nsresult nsMacGreekToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacGreekMappingTable[] = { +#include "macgreek.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_MacGreekMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacGujaratiToUnicode.cpp b/intl/uconv/ucvlatin/nsMacGujaratiToUnicode.cpp index 3fee3100296..0d01e33e4d5 100644 --- a/intl/uconv/ucvlatin/nsMacGujaratiToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacGujaratiToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macgujarati.ut" -}; - nsresult nsMacGujaratiToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macgujarati.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacGurmukhiToUnicode.cpp b/intl/uconv/ucvlatin/nsMacGurmukhiToUnicode.cpp index ac5da922962..eb9006a31c2 100644 --- a/intl/uconv/ucvlatin/nsMacGurmukhiToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacGurmukhiToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macgurmukhi.ut" -}; - nsresult nsMacGurmukhiToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macgurmukhi.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacHebrewToUnicode.cpp b/intl/uconv/ucvlatin/nsMacHebrewToUnicode.cpp index ee2fbc43fdc..f0cbe5c5850 100644 --- a/intl/uconv/ucvlatin/nsMacHebrewToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacHebrewToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "machebrew.ut" -}; - nsresult nsMacHebrewToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "machebrew.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacIcelandicToUnicode.cpp b/intl/uconv/ucvlatin/nsMacIcelandicToUnicode.cpp index 3e75c68d08b..bc3d3db6903 100644 --- a/intl/uconv/ucvlatin/nsMacIcelandicToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacIcelandicToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macicela.ut" -}; - nsresult nsMacIcelandicToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macicela.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacRomanianToUnicode.cpp b/intl/uconv/ucvlatin/nsMacRomanianToUnicode.cpp index e891cb8afa4..32e1518529a 100644 --- a/intl/uconv/ucvlatin/nsMacRomanianToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacRomanianToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "macro.ut" -}; - nsresult nsMacRomanianToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "macro.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsMacTurkishToUnicode.cpp b/intl/uconv/ucvlatin/nsMacTurkishToUnicode.cpp index 12cbea3d09f..671ab10c565 100644 --- a/intl/uconv/ucvlatin/nsMacTurkishToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsMacTurkishToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacTurkishMappingTable[] = { -#include "macturki.ut" -}; - nsresult nsMacTurkishToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacTurkishMappingTable[] = { +#include "macturki.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_MacTurkishMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsT61ToUnicode.cpp b/intl/uconv/ucvlatin/nsT61ToUnicode.cpp index 0ce3f02eec3..f71036f7276 100644 --- a/intl/uconv/ucvlatin/nsT61ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsT61ToUnicode.cpp @@ -9,22 +9,21 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_T61MappingTable[] = { -#include "t61.ut" -}; - - -static const int16_t g_T61ShiftInTable[] = { - 3, - ShiftInCell(u1ByteChar, 1, 0x00, 0xBF), - ShiftInCell(u1ByteChar, 1, 0xD0, 0xFF), - ShiftInCell(u2BytesChar, 2, 0xC0, 0xCF) -}; - nsresult nsT61ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_T61MappingTable[] = { +#include "t61.ut" + }; + + static const int16_t g_T61ShiftInTable[] = { + 3, + ShiftInCell(u1ByteChar, 1, 0x00, 0xBF), + ShiftInCell(u1ByteChar, 1, 0xD0, 0xFF), + ShiftInCell(u2BytesChar, 2, 0xC0, 0xCF) + }; + return CreateTableDecoder(uMultibytesCharset, (uShiftInTable*) &g_T61ShiftInTable, (uMappingTable*) &g_T61MappingTable, 1, diff --git a/intl/uconv/ucvlatin/nsTCVN5712ToUnicode.cpp b/intl/uconv/ucvlatin/nsTCVN5712ToUnicode.cpp index 465c723569e..b3ec46cd60d 100644 --- a/intl/uconv/ucvlatin/nsTCVN5712ToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsTCVN5712ToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "tcvn5712.ut" -}; - nsresult nsTCVN5712ToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "tcvn5712.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsUnicodeToARMSCII8.cpp b/intl/uconv/ucvlatin/nsUnicodeToARMSCII8.cpp index 73399efe78d..6f973f4088d 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToARMSCII8.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToARMSCII8.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "armscii.uf" -}; - nsresult nsUnicodeToARMSCII8Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "armscii.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToAdobeEuro.cpp b/intl/uconv/ucvlatin/nsUnicodeToAdobeEuro.cpp index 884881ae973..a45a158b525 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToAdobeEuro.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToAdobeEuro.cpp @@ -9,17 +9,17 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -/* "adobeeuro.uf" was generated like this: - * % echo '0xA4 0x20AC # EURO CURRENCY SIGN' | ./umaptable -uf >adobeeuro.uf - */ -#include "adobeeuro.uf" -}; - nsresult nsUnicodeToAdobeEuroConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { + /* "adobeeuro.uf" was generated like this: + * % echo '0xA4 0x20AC # EURO CURRENCY SIGN' | ./umaptable -uf >adobeeuro.uf + */ +#include "adobeeuro.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToAscii.cpp b/intl/uconv/ucvlatin/nsUnicodeToAscii.cpp index 3b636f6e5d5..0c6f430c5af 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToAscii.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToAscii.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { - 0x0001, 0x0004, 0x0005, 0x0008, 0x0000, 0x0000, 0x007F, 0x0000 -}; - nsresult nsUnicodeToAsciiConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { + 0x0001, 0x0004, 0x0005, 0x0008, 0x0000, 0x0000, 0x007F, 0x0000 + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1250.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1250.cpp index d276dd60613..58e896ba8c4 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1250.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1250.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1250.uf" -}; - nsresult nsUnicodeToCP1250Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1250.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1251.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1251.cpp index 880152f0245..95298cf8cec 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1251.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1251.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1251.uf" -}; - nsresult nsUnicodeToCP1251Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1251.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1253.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1253.cpp index 85b84000506..613eacd61cd 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1253.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1253.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1253.uf" -}; - nsresult nsUnicodeToCP1253Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1253.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1254.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1254.cpp index 3296b0208bd..c59bf1bfc50 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1254.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1254.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1254.uf" -}; - nsresult nsUnicodeToCP1254Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1254.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1255.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1255.cpp index 4c926081352..d2f9fb86c59 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1255.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1255.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1255.uf" -}; - nsresult nsUnicodeToCP1255Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1255.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1256.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1256.cpp index fd70f9c7314..ecd9cc7cccd 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1256.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1256.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1256.uf" -}; - nsresult nsUnicodeToCP1256Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1256.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1257.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1257.cpp index e84adf2fdd2..6deab814254 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1257.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1257.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1257.uf" -}; - nsresult nsUnicodeToCP1257Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1257.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP1258.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP1258.cpp index 97a222fc3e3..8450f90047a 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP1258.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP1258.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp1258.uf" -}; - nsresult nsUnicodeToCP1258Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp1258.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP866.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP866.cpp index cfcdf73c1e7..1f943c5055e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP866.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP866.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp866.uf" -}; - nsresult nsUnicodeToCP866Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp866.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToCP874.cpp b/intl/uconv/ucvlatin/nsUnicodeToCP874.cpp index 21b05081a0b..0c20091ab10 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToCP874.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToCP874.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "cp874.uf" -}; - nsresult nsUnicodeToCP874Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "cp874.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885910.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885910.cpp index 116576a5d53..b64701922f0 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885910.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885910.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-10.uf" -}; - nsresult nsUnicodeToISO885910Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-10.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885911.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885911.cpp index 869e6c0a286..80b0397310b 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885911.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885911.cpp @@ -10,14 +10,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-11.uf" -}; - nsresult nsUnicodeToISO885911Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-11.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885913.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885913.cpp index b8697c4bf9d..963375bc38b 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885913.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885913.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-13.uf" -}; - nsresult nsUnicodeToISO885913Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-13.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885914.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885914.cpp index 3c63ae7bcea..b1cefbbf65a 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885914.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885914.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-14.uf" -}; - nsresult nsUnicodeToISO885914Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-14.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885915.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885915.cpp index cdf4efa1a3a..39e481c5ee6 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885915.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885915.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-15.uf" -}; - nsresult nsUnicodeToISO885915Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-15.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO885916.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO885916.cpp index 1e9fdaed6c2..b39bd1beec8 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO885916.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO885916.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-16.uf" -}; - nsresult nsUnicodeToISO885916Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-16.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88592.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88592.cpp index 31a3480439b..4445400b987 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88592.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88592.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-2.uf" -}; - nsresult nsUnicodeToISO88592Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-2.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88593.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88593.cpp index fdf37ebcc5d..3387f4b2383 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88593.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88593.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-3.uf" -}; - nsresult nsUnicodeToISO88593Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-3.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88594.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88594.cpp index 020093b9c81..a2851b79b9f 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88594.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88594.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-4.uf" -}; - nsresult nsUnicodeToISO88594Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-4.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88595.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88595.cpp index c6f4e1b3d36..73568a64e91 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88595.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88595.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-5.uf" -}; - nsresult nsUnicodeToISO88595Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-5.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88596.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88596.cpp index 102654d0ff3..0932e5891d9 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88596.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88596.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-6.uf" -}; - nsresult nsUnicodeToISO88596Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-6.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88597.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88597.cpp index d3150916190..1f682a26c58 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88597.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88597.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-7.uf" -}; - nsresult nsUnicodeToISO88597Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-7.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88598.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88598.cpp index cb5d0880e65..0949fa88749 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88598.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88598.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-8.uf" -}; - nsresult nsUnicodeToISO88598Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-8.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISO88599.cpp b/intl/uconv/ucvlatin/nsUnicodeToISO88599.cpp index 9f6c1d7e514..e6bc3ca5580 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISO88599.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISO88599.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "8859-9.uf" -}; - nsresult nsUnicodeToISO88599Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "8859-9.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp b/intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp index fc1b425d343..e649d263c85 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "iso-ir-111.uf" -}; - nsresult nsUnicodeToISOIR111Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "iso-ir-111.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToKOI8R.cpp b/intl/uconv/ucvlatin/nsUnicodeToKOI8R.cpp index 4ec49684695..fb8bc1e84f3 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToKOI8R.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToKOI8R.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "koi8r.uf" -}; - nsresult nsUnicodeToKOI8RConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "koi8r.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToKOI8U.cpp b/intl/uconv/ucvlatin/nsUnicodeToKOI8U.cpp index e9ecd696090..904821f770c 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToKOI8U.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToKOI8U.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "koi8u.uf" -}; - nsresult nsUnicodeToKOI8UConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "koi8u.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacArabic.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacArabic.cpp index 4b04b3c2578..80a9b37ff1e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacArabic.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacArabic.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macarabic.uf" -}; - nsresult nsUnicodeToMacArabicConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macarabic.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacCE.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacCE.cpp index fa4c712b9ef..6e08eb96396 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacCE.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacCE.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacCEMappingTable[] = { -#include "macce.uf" -}; - nsresult nsUnicodeToMacCEConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacCEMappingTable[] = { +#include "macce.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_MacCEMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacCroatian.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacCroatian.cpp index 417174f1582..95a23985119 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacCroatian.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacCroatian.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "maccroat.uf" -}; - nsresult nsUnicodeToMacCroatianConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "maccroat.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacCyrillic.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacCyrillic.cpp index cddcc078c5b..cd4b4c852e2 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacCyrillic.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacCyrillic.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "maccyril.uf" -}; - nsresult nsUnicodeToMacCyrillicConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "maccyril.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacDevanagari.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacDevanagari.cpp index 0aff0027925..8d2eb6a3dc2 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacDevanagari.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacDevanagari.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macdevanaga.uf" -}; - nsresult nsUnicodeToMacDevanagariConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macdevanaga.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacFarsi.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacFarsi.cpp index 79203234872..6bc1ee77464 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacFarsi.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacFarsi.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macfarsi.uf" -}; - nsresult nsUnicodeToMacFarsiConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macfarsi.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacGreek.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacGreek.cpp index 4965ffcdd4d..2e5fd28690e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacGreek.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacGreek.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacGreekMappingTable[] = { -#include "macgreek.uf" -}; - nsresult nsUnicodeToMacGreekConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacGreekMappingTable[] = { +#include "macgreek.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_MacGreekMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacGujarati.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacGujarati.cpp index faf82c133c3..7c175c9efb5 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacGujarati.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacGujarati.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macgujarati.uf" -}; - nsresult nsUnicodeToMacGujaratiConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macgujarati.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacGurmukhi.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacGurmukhi.cpp index 61de5bdfc41..6b35e94057e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacGurmukhi.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacGurmukhi.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macgurmukhi.uf" -}; - nsresult nsUnicodeToMacGurmukhiConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macgurmukhi.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacHebrew.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacHebrew.cpp index dc6fd47fee7..324ced7d5e3 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacHebrew.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacHebrew.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "machebrew.uf" -}; - nsresult nsUnicodeToMacHebrewConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "machebrew.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacIcelandic.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacIcelandic.cpp index e329caa7dc1..f83e3582516 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacIcelandic.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacIcelandic.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macicela.uf" -}; - nsresult nsUnicodeToMacIcelandicConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macicela.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacRomanian.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacRomanian.cpp index 41ebcd825cd..f636c09c558 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacRomanian.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacRomanian.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "macro.uf" -}; - nsresult nsUnicodeToMacRomanianConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "macro.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToMacTurkish.cpp b/intl/uconv/ucvlatin/nsUnicodeToMacTurkish.cpp index 7a0781ea2c5..0f3c20eaf5e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToMacTurkish.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToMacTurkish.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_MacTurkishMappingTable[] = { -#include "macturki.uf" -}; - nsresult nsUnicodeToMacTurkishConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_MacTurkishMappingTable[] = { +#include "macturki.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_MacTurkishMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToSymbol.cpp b/intl/uconv/ucvlatin/nsUnicodeToSymbol.cpp index a7ae1417671..db004074a6c 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToSymbol.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToSymbol.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "adobesymbol.uf" -}; - nsresult nsUnicodeToSymbolConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "adobesymbol.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToT61.cpp b/intl/uconv/ucvlatin/nsUnicodeToT61.cpp index dbfd2e144a8..249e5719453 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToT61.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToT61.cpp @@ -9,20 +9,21 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_T61MappingTable[] = { -#include "t61.uf" -}; - -static const int16_t g_T61ShiftOutTable[] = { - 3, - ShiftOutCell(u1ByteChar, 1, 0x00, 0x00, 0x00, 0xBF), - ShiftOutCell(u1ByteChar, 1, 0x00, 0xD0, 0x00, 0xFF), - ShiftOutCell(u2BytesChar, 2, 0xC0, 0x41, 0xCF, 0x7A) -}; nsresult nsUnicodeToT61Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_T61MappingTable[] = { +#include "t61.uf" + }; + + static const int16_t g_T61ShiftOutTable[] = { + 3, + ShiftOutCell(u1ByteChar, 1, 0x00, 0x00, 0x00, 0xBF), + ShiftOutCell(u1ByteChar, 1, 0x00, 0xD0, 0x00, 0xFF), + ShiftOutCell(u2BytesChar, 2, 0xC0, 0x41, 0xCF, 0x7A) + }; + return CreateTableEncoder(uMultibytesCharset, (uShiftOutTable*) &g_T61ShiftOutTable, (uMappingTable*) &g_T61MappingTable, 2, diff --git a/intl/uconv/ucvlatin/nsUnicodeToTCVN5712.cpp b/intl/uconv/ucvlatin/nsUnicodeToTCVN5712.cpp index 1826d8bb3d1..f8e62020731 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToTCVN5712.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToTCVN5712.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "tcvn5712.uf" -}; - nsresult nsUnicodeToTCVN5712Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "tcvn5712.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToTIS620.cpp b/intl/uconv/ucvlatin/nsUnicodeToTIS620.cpp index 72b70f48b49..61ee97eca9a 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToTIS620.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToTIS620.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "tis620.uf" -}; - nsresult nsUnicodeToTIS620Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "tis620.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToUserDefined.cpp b/intl/uconv/ucvlatin/nsUnicodeToUserDefined.cpp index 229f4015407..68b92f07a29 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToUserDefined.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToUserDefined.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "userdefined.uf" -}; - nsresult nsUnicodeToUserDefinedConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "userdefined.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToVISCII.cpp b/intl/uconv/ucvlatin/nsUnicodeToVISCII.cpp index 92bd1cbb7e6..5822f71a778 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToVISCII.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToVISCII.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "viscii.uf" -}; - nsresult nsUnicodeToVISCIIConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "viscii.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToVPS.cpp b/intl/uconv/ucvlatin/nsUnicodeToVPS.cpp index 15be8d96a3b..adca586ae7e 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToVPS.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToVPS.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "vps.uf" -}; - nsresult nsUnicodeToVPSConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "vps.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUnicodeToZapfDingbat.cpp b/intl/uconv/ucvlatin/nsUnicodeToZapfDingbat.cpp index a1395a667be..7fd33586be4 100644 --- a/intl/uconv/ucvlatin/nsUnicodeToZapfDingbat.cpp +++ b/intl/uconv/ucvlatin/nsUnicodeToZapfDingbat.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_ufMappingTable[] = { -#include "adobezingbat.uf" -}; - nsresult nsUnicodeToZapfDingbatConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_ufMappingTable[] = { +#include "adobezingbat.uf" + }; + return CreateTableEncoder(u1ByteCharset, (uMappingTable*) &g_ufMappingTable, 1, aOuter, aIID, aResult); diff --git a/intl/uconv/ucvlatin/nsUserDefinedToUnicode.cpp b/intl/uconv/ucvlatin/nsUserDefinedToUnicode.cpp index e697726a599..c1a916aeffa 100644 --- a/intl/uconv/ucvlatin/nsUserDefinedToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsUserDefinedToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "userdefined.ut" -}; - nsresult nsUserDefinedToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "userdefined.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsVISCIIToUnicode.cpp b/intl/uconv/ucvlatin/nsVISCIIToUnicode.cpp index 57b8d546047..f0f9c9db2c3 100644 --- a/intl/uconv/ucvlatin/nsVISCIIToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsVISCIIToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "viscii.ut" -}; - nsresult nsVISCIIToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "viscii.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvlatin/nsVPSToUnicode.cpp b/intl/uconv/ucvlatin/nsVPSToUnicode.cpp index 7a5735505a6..b2044c84617 100644 --- a/intl/uconv/ucvlatin/nsVPSToUnicode.cpp +++ b/intl/uconv/ucvlatin/nsVPSToUnicode.cpp @@ -9,14 +9,14 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uint16_t g_utMappingTable[] = { -#include "vps.ut" -}; - nsresult nsVPSToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t g_utMappingTable[] = { +#include "vps.ut" + }; + return CreateOneByteDecoder((uMappingTable*) &g_utMappingTable, aOuter, aIID, aResult); } diff --git a/intl/uconv/ucvtw/UnifiedUCVTW.cpp b/intl/uconv/ucvtw/UnifiedUCVTW.cpp new file mode 100644 index 00000000000..a88f315ac3e --- /dev/null +++ b/intl/uconv/ucvtw/UnifiedUCVTW.cpp @@ -0,0 +1,11 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsBIG5HKSCSToUnicode.cpp" +#include "nsBIG5ToUnicode.cpp" +#include "nsUnicodeToBIG5.cpp" +#include "nsUnicodeToBIG5HKSCS.cpp" +#include "nsUnicodeToHKSCS.cpp" + diff --git a/intl/uconv/ucvtw/moz.build b/intl/uconv/ucvtw/moz.build index e6d4dcf0d90..878dff5a9e7 100644 --- a/intl/uconv/ucvtw/moz.build +++ b/intl/uconv/ucvtw/moz.build @@ -11,11 +11,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsBIG5HKSCSToUnicode.cpp', - 'nsBIG5ToUnicode.cpp', - 'nsUnicodeToBIG5.cpp', - 'nsUnicodeToBIG5HKSCS.cpp', - 'nsUnicodeToHKSCS.cpp', + 'UnifiedUCVTW.cpp', ] LIBRARY_NAME = 'ucvtw_s' diff --git a/intl/uconv/ucvtw/nsUnicodeToBIG5HKSCS.cpp b/intl/uconv/ucvtw/nsUnicodeToBIG5HKSCS.cpp index f317e02cce2..263c25f5951 100644 --- a/intl/uconv/ucvtw/nsUnicodeToBIG5HKSCS.cpp +++ b/intl/uconv/ucvtw/nsUnicodeToBIG5HKSCS.cpp @@ -10,23 +10,22 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] - -static const uint16_t *g_Big5HKSCSMappingTable[] = { - g_ASCIIMappingTable, - g_ufBig5Mapping, - g_ufBig5HKSCSMapping -}; - -static const uScanClassID g_Big5HKSCSScanClassIDs[] = { - u1ByteCharset, - u2BytesCharset, - u2BytesCharset -}; - nsresult nsUnicodeToBIG5HKSCSConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t *g_Big5HKSCSMappingTable[] = { + g_ASCIIMappingTable, + g_ufBig5Mapping, + g_ufBig5HKSCSMapping + }; + + static const uScanClassID g_Big5HKSCSScanClassIDs[] = { + u1ByteCharset, + u2BytesCharset, + u2BytesCharset + }; + return CreateMultiTableEncoder(3, (uScanClassID*) &g_Big5HKSCSScanClassIDs, (uMappingTable**) &g_Big5HKSCSMappingTable, diff --git a/intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp b/intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp index 03c8c8460ab..b66bb30f5b5 100644 --- a/intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp +++ b/intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp @@ -10,16 +10,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] - - -static const uint16_t *g_Big5HKSCSMappingTable[] = { - g_ufBig5HKSCSMapping -}; - -static const uScanClassID g_Big5HKSCSScanClassIDs[] = { - u2BytesCharset -}; - //---------------------------------------------------------------------- // Class nsUnicodeToHKSCS [implementation] @@ -27,6 +17,14 @@ nsresult nsUnicodeToHKSCSConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uint16_t *g_Big5HKSCSMappingTable[] = { + g_ufBig5HKSCSMapping + }; + + static const uScanClassID g_Big5HKSCSScanClassIDs[] = { + u2BytesCharset + }; + return CreateMultiTableEncoder(1, (uScanClassID*) &g_Big5HKSCSScanClassIDs, (uMappingTable**) &g_Big5HKSCSMappingTable, diff --git a/intl/uconv/ucvtw2/UnifiedUCVTW2.cpp b/intl/uconv/ucvtw2/UnifiedUCVTW2.cpp new file mode 100644 index 00000000000..91bc83bf338 --- /dev/null +++ b/intl/uconv/ucvtw2/UnifiedUCVTW2.cpp @@ -0,0 +1,8 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsEUCTWToUnicode.cpp" +#include "nsUnicodeToEUCTW.cpp" + diff --git a/intl/uconv/ucvtw2/moz.build b/intl/uconv/ucvtw2/moz.build index 2c9d9d15283..37d9fb43063 100644 --- a/intl/uconv/ucvtw2/moz.build +++ b/intl/uconv/ucvtw2/moz.build @@ -11,8 +11,7 @@ EXPORTS += [ ] CPP_SOURCES += [ - 'nsEUCTWToUnicode.cpp', - 'nsUnicodeToEUCTW.cpp', + 'UnifiedUCVTW2.cpp', ] LIBRARY_NAME = 'ucvtw2_s' diff --git a/intl/uconv/ucvtw2/nsEUCTWToUnicode.cpp b/intl/uconv/ucvtw2/nsEUCTWToUnicode.cpp index 107ff9b0f4b..f6fa2f511a5 100644 --- a/intl/uconv/ucvtw2/nsEUCTWToUnicode.cpp +++ b/intl/uconv/ucvtw2/nsEUCTWToUnicode.cpp @@ -9,39 +9,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uScanClassID g_EUCTWScanClassIDs [] = { - u1ByteCharset, - u2BytesGRCharset, - u2BytesGRPrefix8EA2Charset, - u2BytesGRPrefix8EA3Charset, - u2BytesGRPrefix8EA4Charset, - u2BytesGRPrefix8EA5Charset, - u2BytesGRPrefix8EA6Charset, - u2BytesGRPrefix8EA7Charset -}; - -static const uint16_t *g_EUCTWMappingTableSet [] ={ - g_ASCIIMappingTable, - g_utCNS1MappingTable, - g_utCNS2MappingTable, - g_utCNS3MappingTable, - g_utCNS4MappingTable, - g_utCNS5MappingTable, - g_utCNS6MappingTable, - g_utCNS7MappingTable -}; - -static const uRange g_EUCTWRanges[] = { - { 0x00, 0x7E }, - { 0xA1, 0xFE }, - { 0x8E, 0x8E }, - { 0x8E, 0x8E }, - { 0x8E, 0x8E }, - { 0x8E, 0x8E }, - { 0x8E, 0x8E }, - { 0x8E, 0x8E } -}; - //---------------------------------------------------------------------- // Class nsEUCTWToUnicode [implementation] @@ -50,6 +17,39 @@ nsresult nsEUCTWToUnicodeConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uScanClassID g_EUCTWScanClassIDs [] = { + u1ByteCharset, + u2BytesGRCharset, + u2BytesGRPrefix8EA2Charset, + u2BytesGRPrefix8EA3Charset, + u2BytesGRPrefix8EA4Charset, + u2BytesGRPrefix8EA5Charset, + u2BytesGRPrefix8EA6Charset, + u2BytesGRPrefix8EA7Charset + }; + + static const uint16_t *g_EUCTWMappingTableSet [] ={ + g_ASCIIMappingTable, + g_utCNS1MappingTable, + g_utCNS2MappingTable, + g_utCNS3MappingTable, + g_utCNS4MappingTable, + g_utCNS5MappingTable, + g_utCNS6MappingTable, + g_utCNS7MappingTable + }; + + static const uRange g_EUCTWRanges[] = { + { 0x00, 0x7E }, + { 0xA1, 0xFE }, + { 0x8E, 0x8E }, + { 0x8E, 0x8E }, + { 0x8E, 0x8E }, + { 0x8E, 0x8E }, + { 0x8E, 0x8E }, + { 0x8E, 0x8E } + }; + return CreateMultiTableDecoder(8, (const uRange*) &g_EUCTWRanges, (uScanClassID*) &g_EUCTWScanClassIDs, diff --git a/intl/uconv/ucvtw2/nsUnicodeToEUCTW.cpp b/intl/uconv/ucvtw2/nsUnicodeToEUCTW.cpp index 2b83f92727c..115736765af 100644 --- a/intl/uconv/ucvtw2/nsUnicodeToEUCTW.cpp +++ b/intl/uconv/ucvtw2/nsUnicodeToEUCTW.cpp @@ -10,28 +10,6 @@ //---------------------------------------------------------------------- // Global functions and data [declaration] -static const uScanClassID g_EUCTWScanClassSet [] = { - u1ByteCharset, - u2BytesGRCharset, - u2BytesGRPrefix8EA2Charset, - u2BytesGRPrefix8EA3Charset, - u2BytesGRPrefix8EA4Charset, - u2BytesGRPrefix8EA5Charset, - u2BytesGRPrefix8EA6Charset, - u2BytesGRPrefix8EA7Charset -}; - -static const uint16_t *g_EUCTWMappingTableSet [] ={ - g_ASCIIMappingTable, - g_ufCNS1MappingTable, - g_ufCNS2MappingTable, - g_ufCNS3MappingTable, - g_ufCNS4MappingTable, - g_ufCNS5MappingTable, - g_ufCNS6MappingTable, - g_ufCNS7MappingTable -}; - //---------------------------------------------------------------------- // Class nsUnicodeToEUCTW [implementation] @@ -39,6 +17,28 @@ nsresult nsUnicodeToEUCTWConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { + static const uScanClassID g_EUCTWScanClassSet [] = { + u1ByteCharset, + u2BytesGRCharset, + u2BytesGRPrefix8EA2Charset, + u2BytesGRPrefix8EA3Charset, + u2BytesGRPrefix8EA4Charset, + u2BytesGRPrefix8EA5Charset, + u2BytesGRPrefix8EA6Charset, + u2BytesGRPrefix8EA7Charset + }; + + static const uint16_t *g_EUCTWMappingTableSet [] ={ + g_ASCIIMappingTable, + g_ufCNS1MappingTable, + g_ufCNS2MappingTable, + g_ufCNS3MappingTable, + g_ufCNS4MappingTable, + g_ufCNS5MappingTable, + g_ufCNS6MappingTable, + g_ufCNS7MappingTable + }; + return CreateMultiTableEncoder(8, (uScanClassID*) &g_EUCTWScanClassSet, (uMappingTable**) &g_EUCTWMappingTableSet, diff --git a/intl/uconv/ucvcn/nsUnicodeToISO2022CN.cpp b/intl/uconv/util/UnifiedUCVCUtils.c similarity index 83% rename from intl/uconv/ucvcn/nsUnicodeToISO2022CN.cpp rename to intl/uconv/util/UnifiedUCVCUtils.c index b3de28acbb9..0aa658c8a99 100644 --- a/intl/uconv/ucvcn/nsUnicodeToISO2022CN.cpp +++ b/intl/uconv/util/UnifiedUCVCUtils.c @@ -2,3 +2,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ugen.c" +#include "umap.c" +#include "uscan.c" + diff --git a/intl/uconv/ucvcn/nsUnicodeToISO2022CN.h b/intl/uconv/util/UnifiedUCVUtils.cpp similarity index 67% rename from intl/uconv/ucvcn/nsUnicodeToISO2022CN.h rename to intl/uconv/util/UnifiedUCVUtils.cpp index b3de28acbb9..b9649134888 100644 --- a/intl/uconv/ucvcn/nsUnicodeToISO2022CN.h +++ b/intl/uconv/util/UnifiedUCVUtils.cpp @@ -2,3 +2,9 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsUCConstructors.cpp" +#include "nsUCSupport.cpp" +#include "nsUnicodeDecodeHelper.cpp" +#include "nsUnicodeEncodeHelper.cpp" + diff --git a/intl/uconv/util/moz.build b/intl/uconv/util/moz.build index 79229dc8765..7c9c4d7df02 100644 --- a/intl/uconv/util/moz.build +++ b/intl/uconv/util/moz.build @@ -7,10 +7,7 @@ MODULE = 'uconv' CPP_SOURCES += [ - 'nsUCConstructors.cpp', - 'nsUCSupport.cpp', - 'nsUnicodeDecodeHelper.cpp', - 'nsUnicodeEncodeHelper.cpp', + 'UnifiedUCVUtils.cpp', ] LIBRARY_NAME = 'ucvutil_s' @@ -18,9 +15,7 @@ LIBRARY_NAME = 'ucvutil_s' LIBXUL_LIBRARY = True CSRCS += [ - 'ugen.c', - 'umap.c', - 'uscan.c', + 'UnifiedUCVCUtils.c', ] MSVC_ENABLE_PGO = True From b22af4531480a137480ac5e74a17601cc435cd7d Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 22 Oct 2013 14:14:50 +0200 Subject: [PATCH 17/75] Bug 929414 - Fix small bug in MacroAssembler::extractTag. r=h4writer --- js/src/jit/IonMacroAssembler.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/src/jit/IonMacroAssembler.h b/js/src/jit/IonMacroAssembler.h index d766a5b70ca..557d293bb69 100644 --- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -737,10 +737,9 @@ class MacroAssembler : public MacroAssemblerSpecific using MacroAssemblerSpecific::extractTag; Register extractTag(const TypedOrValueRegister ®, Register scratch) { - if (reg.hasValue()) { + if (reg.hasValue()) return extractTag(reg.valueReg(), scratch); - } - mov(ImmWord(ValueTypeFromMIRType(reg.type())), scratch); + mov(ImmWord(MIRTypeToTag(reg.type())), scratch); return scratch; } From fee375536aec15bc3fc79982f3746c70d94d50f1 Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Tue, 22 Oct 2013 14:23:41 +0200 Subject: [PATCH 18/75] Bug 927765 - Options for createObjectIn. r=bholley --- js/xpconnect/src/Sandbox.cpp | 31 ++++++++++++++++---- js/xpconnect/src/XPCComponents.cpp | 45 ++++++++++++++++++++++-------- js/xpconnect/src/xpcprivate.h | 20 ++++++++++++- 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index fc667ce3acc..98c62736bcf 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1253,13 +1253,16 @@ GetExpandedPrincipal(JSContext *cx, HandleObject arrayObj, nsIExpandedPrincipal * Helper that tries to get a property form the options object. */ bool -OptionsBase::ParseValue(const char *name, MutableHandleValue prop, bool *found) +OptionsBase::ParseValue(const char *name, MutableHandleValue prop, bool *aFound) { - MOZ_ASSERT(found); - bool ok = JS_HasProperty(mCx, mObject, name, found); + bool found; + bool ok = JS_HasProperty(mCx, mObject, name, &found); NS_ENSURE_TRUE(ok, false); - if (!*found) + if (aFound) + *aFound = found; + + if (!found) return true; return JS_GetProperty(mCx, mObject, name, prop); @@ -1336,6 +1339,23 @@ OptionsBase::ParseString(const char *name, nsCString &prop) return true; } +/* + * Helper that tries to get jsid property form the options object. + */ +bool +OptionsBase::ParseId(const char *name, MutableHandleId prop) +{ + RootedValue value(mCx); + bool found; + bool ok = ParseValue(name, &value, &found); + NS_ENSURE_TRUE(ok, false); + + if (!found) + return true; + + return JS_ValueToId(mCx, value, prop.address()); +} + /* * Helper that tries to get a list of DOM constructors and other helpers from the options object. */ @@ -1369,7 +1389,6 @@ SandboxOptions::ParseGlobalProperties() bool SandboxOptions::Parse() { - bool found; return ParseObject("sandboxPrototype", &proto) && ParseBoolean("wantXrays", &wantXrays) && ParseBoolean("wantComponents", &wantComponents) && @@ -1377,7 +1396,7 @@ SandboxOptions::Parse() ParseString("sandboxName", sandboxName) && ParseObject("sameZoneAs", &sameZoneAs) && ParseGlobalProperties() && - ParseValue("metadata", &metadata, &found); + ParseValue("metadata", &metadata); } static nsresult diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index ec1acae390b..c374e91ea46 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3011,29 +3011,52 @@ nsXPCComponents_Utils::GetGlobalForObject(const Value& object, } /* jsval createObjectIn(in jsval vobj); */ -NS_IMETHODIMP -nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, JSContext *cx, Value *rval) +bool +xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectOptions &options, + MutableHandleValue rval) { - if (!cx) - return NS_ERROR_FAILURE; + if (!vobj.isObject()) { + JS_ReportError(cx, "Expected an object as the target scope"); + return false; + } - // first argument must be an object - if (vobj.isPrimitive()) - return NS_ERROR_XPC_BAD_CONVERT_JS; - - RootedObject scope(cx, js::UncheckedUnwrap(&vobj.toObject())); + RootedObject scope(cx, js::CheckedUnwrap(&vobj.toObject())); + if (!scope) { + JS_ReportError(cx, "Permission denied to create object in the target scope"); + return false; + } RootedObject obj(cx); { JSAutoCompartment ac(cx, scope); obj = JS_NewObject(cx, nullptr, nullptr, scope); if (!obj) - return NS_ERROR_FAILURE; + return false; + + if (!JSID_IS_VOID(options.defineAs) && + !JS_DefinePropertyById(cx, scope, options.defineAs, ObjectValue(*obj), + JS_PropertyStub, JS_StrictPropertyStub, + JSPROP_ENUMERATE)) + return false; } if (!JS_WrapObject(cx, &obj)) + return false; + + rval.setObject(*obj); + return true; +} + +/* jsval createObjectIn(in jsval vobj); */ +NS_IMETHODIMP +nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, JSContext *cx, Value *rval) +{ + CreateObjectOptions options; + RootedValue rvobj(cx, vobj); + RootedValue res(cx); + if (!xpc::CreateObjectIn(cx, rvobj, options, &res)) return NS_ERROR_FAILURE; - *rval = ObjectValue(*obj); + *rval = res; return NS_OK; } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 25a4c95124b..35f66815655 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3627,10 +3627,11 @@ public: virtual bool Parse() = 0; protected: - bool ParseValue(const char *name, JS::MutableHandleValue prop, bool *found); + bool ParseValue(const char *name, JS::MutableHandleValue prop, bool *found = nullptr); bool ParseBoolean(const char *name, bool *prop); bool ParseObject(const char *name, JS::MutableHandleObject prop); bool ParseString(const char *name, nsCString &prop); + bool ParseId(const char* name, JS::MutableHandleId id); JSContext *mCx; JS::RootedObject mObject; @@ -3664,6 +3665,19 @@ protected: bool ParseGlobalProperties(); }; +class MOZ_STACK_CLASS CreateObjectOptions : public OptionsBase { +public: + CreateObjectOptions(JSContext *cx = xpc_GetSafeJSContext(), + JS::HandleObject options = JS::NullPtr()) + : OptionsBase(cx, options) + , defineAs(cx, JSID_VOID) + { } + + virtual bool Parse() { return ParseId("defineAs", &defineAs); }; + + JS::RootedId defineAs; +}; + JSObject * CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, JS::CompartmentOptions& aOptions); @@ -3706,6 +3720,10 @@ nsresult SetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg, JS::HandleValue metadata); +bool +CreateObjectIn(JSContext *cx, JS::HandleValue vobj, CreateObjectOptions &options, + JS::MutableHandleValue rval); + } /* namespace xpc */ From 97ce6e62364f5a0f3e8b8d9dc18dceb989d1105d Mon Sep 17 00:00:00 2001 From: Gabor Krizsanits Date: Tue, 22 Oct 2013 14:24:07 +0200 Subject: [PATCH 19/75] Bug 927765 - createObjectIn for exportHelpers. r=bholley --- js/xpconnect/src/Sandbox.cpp | 31 ++++++++++++++++++- js/xpconnect/src/XPCComponents.cpp | 4 +-- js/xpconnect/src/xpcprivate.h | 8 ++--- .../tests/unit/test_exportFunction.js | 17 +++++++++- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 98c62736bcf..5ec00a2fe9e 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -557,6 +557,34 @@ EvalInWindow(JSContext *cx, unsigned argc, jsval *vp) return true; } +namespace xpc { +static bool +CreateObjectIn(JSContext *cx, unsigned argc, jsval *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + if (args.length() < 1) { + JS_ReportError(cx, "Function requires at least 1 argument"); + return false; + } + + RootedObject optionsObj(cx); + bool calledWithOptions = args.length() > 1; + if (calledWithOptions) { + if (!args[1].isObject()) { + JS_ReportError(cx, "Expected the 2nd argument (options) to be an object"); + return false; + } + optionsObj = &args[1].toObject(); + } + + CreateObjectInOptions options(cx, optionsObj); + if (calledWithOptions && !options.Parse()) + return false; + + return xpc::CreateObjectIn(cx, args[0], options, args.rval()); +} +} /* namespace xpc */ + static bool sandbox_enumerate(JSContext *cx, HandleObject obj) { @@ -1059,7 +1087,8 @@ xpc::CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandb if (options.wantExportHelpers && (!JS_DefineFunction(cx, sandbox, "exportFunction", ExportFunction, 3, 0) || - !JS_DefineFunction(cx, sandbox, "evalInWindow", EvalInWindow, 2, 0))) + !JS_DefineFunction(cx, sandbox, "evalInWindow", EvalInWindow, 2, 0) || + !JS_DefineFunction(cx, sandbox, "createObjectIn", CreateObjectIn, 2, 0))) return NS_ERROR_XPC_UNEXPECTED; if (!options.globalProperties.Define(cx, sandbox)) diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index c374e91ea46..b111b98b675 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -3012,7 +3012,7 @@ nsXPCComponents_Utils::GetGlobalForObject(const Value& object, /* jsval createObjectIn(in jsval vobj); */ bool -xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectOptions &options, +xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options, MutableHandleValue rval) { if (!vobj.isObject()) { @@ -3050,7 +3050,7 @@ xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectOptions &option NS_IMETHODIMP nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, JSContext *cx, Value *rval) { - CreateObjectOptions options; + CreateObjectInOptions options; RootedValue rvobj(cx, vobj); RootedValue res(cx); if (!xpc::CreateObjectIn(cx, rvobj, options, &res)) diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 35f66815655..cd244aa0e5e 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3665,10 +3665,10 @@ protected: bool ParseGlobalProperties(); }; -class MOZ_STACK_CLASS CreateObjectOptions : public OptionsBase { +class MOZ_STACK_CLASS CreateObjectInOptions : public OptionsBase { public: - CreateObjectOptions(JSContext *cx = xpc_GetSafeJSContext(), - JS::HandleObject options = JS::NullPtr()) + CreateObjectInOptions(JSContext *cx = xpc_GetSafeJSContext(), + JS::HandleObject options = JS::NullPtr()) : OptionsBase(cx, options) , defineAs(cx, JSID_VOID) { } @@ -3721,7 +3721,7 @@ SetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg, JS::HandleValue metadata); bool -CreateObjectIn(JSContext *cx, JS::HandleValue vobj, CreateObjectOptions &options, +CreateObjectIn(JSContext *cx, JS::HandleValue vobj, CreateObjectInOptions &options, JS::MutableHandleValue rval); } /* namespace xpc */ diff --git a/js/xpconnect/tests/unit/test_exportFunction.js b/js/xpconnect/tests/unit/test_exportFunction.js index d84a8af4b05..15c81ffb719 100644 --- a/js/xpconnect/tests/unit/test_exportFunction.js +++ b/js/xpconnect/tests/unit/test_exportFunction.js @@ -17,7 +17,7 @@ function run_test() { Object.prototype.protoProp = "common"; var wasCalled = false; var _this = this; - var funToExport = function(a, obj, native, mixed) { + this.funToExport = function(a, obj, native, mixed) { do_check_eq(a, 42); do_check_neq(obj, subsb.tobecloned); do_check_eq(obj.cloned, "cloned"); @@ -70,4 +70,19 @@ function run_test() { do_check_true(e.toString().indexOf('Permission denied') > -1); } }.toSource() + ")()", epsb); + + // Let's create an object in the target scope and add privileged + // function to it as a property. + Cu.evalInSandbox("(" + function() { + var newContentObject = createObjectIn(subsb, {defineAs:"importedObject"}); + exportFunction(funToExport, newContentObject, "privMethod"); + }.toSource() + ")()", epsb); + + Cu.evalInSandbox("(" + function () { + importedObject.privMethod(42, tobecloned, native, mixed); + }.toSource() + ")()", subsb); + + Cu.evalInSandbox("(" + function() { + checkIfCalled(); + }.toSource() + ")()", epsb); } From 16bbccbc9c1ea7302f368cb90ce5e418f3ca17d0 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 18 Jul 2013 16:45:16 -0700 Subject: [PATCH 20/75] Bug 913282: More Float32 operators: TruncateToInt32; p=dougc,bbouvier, r=jonco,jandem dougc for the ARM parts, bbouvier for the rest. --HG-- extra : rebase_source : ab8ab9bd043cb04e6a98d793688298c0e5c3a7e7 --- js/src/assembler/assembler/X86Assembler.h | 19 +++- js/src/jit/LIR-Common.h | 18 +++ js/src/jit/LOpcodes.h | 1 + js/src/jit/Lowering.cpp | 3 + js/src/jit/MCallOptimize.cpp | 4 +- js/src/jit/MIR.h | 5 + js/src/jit/TypePolicy.cpp | 12 -- js/src/jit/arm/CodeGenerator-arm.cpp | 6 + js/src/jit/arm/CodeGenerator-arm.h | 1 + js/src/jit/arm/Lowering-arm.cpp | 9 ++ js/src/jit/arm/Lowering-arm.h | 1 + js/src/jit/arm/MacroAssembler-arm.h | 9 +- js/src/jit/shared/CodeGenerator-shared.cpp | 29 ++++- js/src/jit/shared/CodeGenerator-shared.h | 1 + js/src/jit/shared/Lowering-x86-shared.cpp | 10 ++ js/src/jit/shared/Lowering-x86-shared.h | 1 + js/src/jit/x64/Assembler-x64.h | 3 + js/src/jit/x64/CodeGenerator-x64.cpp | 12 ++ js/src/jit/x64/CodeGenerator-x64.h | 1 + js/src/jit/x64/MacroAssembler-x64.h | 9 ++ js/src/jit/x86/Assembler-x86.h | 10 ++ js/src/jit/x86/CodeGenerator-x86.cpp | 124 +++++++++++++++++++++ js/src/jit/x86/CodeGenerator-x86.h | 3 + 23 files changed, 270 insertions(+), 21 deletions(-) diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index ab98e0dd059..dc4a149c50d 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -269,7 +269,8 @@ private: OP_INT3 = 0xCC, OP_GROUP2_Ev1 = 0xD1, OP_GROUP2_EvCL = 0xD3, - OP_FPU6 = 0xDD, + OP_FPU6 = 0xDD, + OP_FLD32 = 0xD9, OP_CALL_rel32 = 0xE8, OP_JMP_rel32 = 0xE9, PRE_SSE_F2 = 0xF2, @@ -723,6 +724,11 @@ public: spew("fld %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base)); m_formatter.oneByteOp(OP_FPU6, FPU6_OP_FLD, base, offset); } + void fld32_m(int offset, RegisterID base) + { + spew("fld %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base)); + m_formatter.oneByteOp(OP_FLD32, FPU6_OP_FLD, base, offset); + } void fisttp_m(int offset, RegisterID base) { spew("fisttp %s0x%x(%s)", PRETTY_PRINT_OFFSET(offset), nameIReg(base)); @@ -2408,14 +2414,19 @@ public: #if WTF_CPU_X86_64 void cvttsd2sq_rr(XMMRegisterID src, RegisterID dst) { - // We call this instruction cvttsd2sq to differentiate the 64-bit - // version from the 32-bit version, but in assembler it's just - // called cvttsd2si and it's disambiguated by the register name. spew("cvttsd2si %s, %s", nameFPReg(src), nameIReg(dst)); m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); } + + void cvttss2sq_rr(XMMRegisterID src, RegisterID dst) + { + spew("cvttss2si %s, %s", + nameFPReg(src), nameIReg(dst)); + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); + } #endif void unpcklps_rr(XMMRegisterID src, XMMRegisterID dst) diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 5e17d5d567d..977427a2214 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -2774,6 +2774,24 @@ class LTruncateDToInt32 : public LInstructionHelper<1, 1, 1> } }; +// Convert a float32 to a truncated int32. +// Input: floating-point register +// Output: 32-bit integer +class LTruncateFToInt32 : public LInstructionHelper<1, 1, 1> +{ + public: + LIR_HEADER(TruncateFToInt32) + + LTruncateFToInt32(const LAllocation &in, const LDefinition &temp) { + setOperand(0, in); + setTemp(0, temp); + } + + const LDefinition *tempFloat() { + return getTemp(0); + } +}; + // Convert an integer hosted on one definition to a string with a function call. class LIntToString : public LInstructionHelper<1, 1, 0> { diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index cf04e783802..ded3a1d720e 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -130,6 +130,7 @@ _(DoubleToInt32) \ _(Float32ToInt32) \ _(TruncateDToInt32) \ + _(TruncateFToInt32) \ _(IntToString) \ _(DoubleToString) \ _(Start) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index d3fd89d5105..dff437527f6 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -1736,6 +1736,9 @@ LIRGenerator::visitTruncateToInt32(MTruncateToInt32 *truncate) case MIRType_Double: return lowerTruncateDToInt32(truncate); + case MIRType_Float32: + return lowerTruncateFToInt32(truncate); + default: // Objects might be effectful. // Strings are complicated - we don't handle them yet. diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 2b6ab170855..fb4ea0d679e 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -800,9 +800,9 @@ IonBuilder::inlineMathImul(CallInfo &callInfo) if (returnType != MIRType_Int32) return InliningStatus_NotInlined; - if (!IsNumberType(callInfo.getArg(0)->type()) || callInfo.getArg(0)->type() == MIRType_Float32) + if (!IsNumberType(callInfo.getArg(0)->type())) return InliningStatus_NotInlined; - if (!IsNumberType(callInfo.getArg(1)->type()) || callInfo.getArg(1)->type() == MIRType_Float32) + if (!IsNumberType(callInfo.getArg(1)->type())) return InliningStatus_NotInlined; callInfo.unwrapArgs(); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 4b2ea4f9412..25f6da7007d 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -2953,6 +2953,11 @@ class MTruncateToInt32 : public MUnaryInstruction void computeRange(); bool isOperandTruncated(size_t index) const; +# ifdef DEBUG + bool isConsistentFloat32Use() const { + return true; + } +#endif }; // Converts any type to a string diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index 1a0cbad14fc..15cc3350ae8 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -340,13 +340,6 @@ BitwisePolicy::adjustInputs(MInstruction *ins) if (in->type() == MIRType_Object || in->type() == MIRType_String) in = boxAt(ins, in); - if (in->type() == MIRType_Float32) { - MToDouble *replace = MToDouble::New(in); - ins->block()->insertBefore(ins, replace); - ins->replaceOperand(i, replace); - in = replace; - } - MInstruction *replace = MTruncateToInt32::New(in); ins->block()->insertBefore(ins, replace); ins->replaceOperand(i, replace); @@ -652,11 +645,6 @@ StoreTypedArrayPolicy::adjustValueInput(MInstruction *ins, int arrayType, case ScalarTypeRepresentation::TYPE_INT32: case ScalarTypeRepresentation::TYPE_UINT32: if (value->type() != MIRType_Int32) { - // Workaround for bug 915903 - if (value->type() == MIRType_Float32) { - value = MToDouble::New(value); - ins->block()->insertBefore(ins, value->toInstruction()); - } value = MTruncateToInt32::New(value); ins->block()->insertBefore(ins, value->toInstruction()); } diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index b5e5754cdb6..1c5427aecb9 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1213,6 +1213,12 @@ CodeGeneratorARM::visitTruncateDToInt32(LTruncateDToInt32 *ins) return emitTruncateDouble(ToFloatRegister(ins->input()), ToRegister(ins->output())); } +bool +CodeGeneratorARM::visitTruncateFToInt32(LTruncateFToInt32 *ins) +{ + return emitTruncateFloat32(ToFloatRegister(ins->input()), ToRegister(ins->output())); +} + static const uint32_t FrameSizes[] = { 128, 256, 512, 1024 }; FrameSizeClass diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 689da43e9fa..b6fd3bcc8fc 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -105,6 +105,7 @@ class CodeGeneratorARM : public CodeGeneratorShared virtual bool visitFloor(LFloor *lir); virtual bool visitRound(LRound *lir); virtual bool visitTruncateDToInt32(LTruncateDToInt32 *ins); + virtual bool visitTruncateFToInt32(LTruncateFToInt32 *ins); // Out of line visitors. bool visitOutOfLineBailout(OutOfLineBailout *ool); diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index 44704f9e28f..8dc985e42f4 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -521,6 +521,15 @@ LIRGeneratorARM::lowerTruncateDToInt32(MTruncateToInt32 *ins) return define(new LTruncateDToInt32(useRegister(opd), LDefinition::BogusTemp()), ins); } +bool +LIRGeneratorARM::lowerTruncateFToInt32(MTruncateToInt32 *ins) +{ + MDefinition *opd = ins->input(); + JS_ASSERT(opd->type() == MIRType_Float32); + + return define(new LTruncateFToInt32(useRegister(opd), LDefinition::BogusTemp()), ins); +} + bool LIRGeneratorARM::visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins) { diff --git a/js/src/jit/arm/Lowering-arm.h b/js/src/jit/arm/Lowering-arm.h index 6a6651f55ff..21fd2ea6719 100644 --- a/js/src/jit/arm/Lowering-arm.h +++ b/js/src/jit/arm/Lowering-arm.h @@ -61,6 +61,7 @@ class LIRGeneratorARM : public LIRGeneratorShared bool lowerConstantDouble(double d, MInstruction *ins); bool lowerConstantFloat32(float d, MInstruction *ins); bool lowerTruncateDToInt32(MTruncateToInt32 *ins); + bool lowerTruncateFToInt32(MTruncateToInt32 *ins); bool lowerDivI(MDiv *div); bool lowerModI(MMod *mod); bool lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs); diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 8705d44db35..2ddf29a3d5e 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -485,7 +485,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM enum Result { GENERAL, - DOUBLE + DOUBLE, + FLOAT }; MacroAssemblerARMCompat() @@ -605,6 +606,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void push(const Register ®) { ma_push(reg); } + void push(const FloatRegister ®) { + ma_vpush(VFPRegister(reg)); + } void pushWithPadding(const Register ®, const Imm32 extraSpace) { Imm32 totSpace = Imm32(extraSpace.value + 4); ma_dtr(IsStore, sp, totSpace, reg, PreIndex); @@ -620,6 +624,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void pop(const Register ®) { ma_pop(reg); } + void pop(const FloatRegister ®) { + ma_vpop(VFPRegister(reg)); + } void popN(const Register ®, Imm32 extraSpace) { Imm32 totSpace = Imm32(extraSpace.value + 4); diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 28731e8417e..1c5823d4ac0 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -676,10 +676,11 @@ class OutOfLineTruncateSlow : public OutOfLineCodeBase { FloatRegister src_; Register dest_; + bool needFloat32Conversion_; public: - OutOfLineTruncateSlow(FloatRegister src, Register dest) - : src_(src), dest_(dest) + OutOfLineTruncateSlow(FloatRegister src, Register dest, bool needFloat32Conversion = false) + : src_(src), dest_(dest), needFloat32Conversion_(needFloat32Conversion) { } bool accept(CodeGeneratorShared *codegen) { @@ -691,6 +692,10 @@ class OutOfLineTruncateSlow : public OutOfLineCodeBase Register dest() const { return dest_; } + bool needFloat32Conversion() const { + return needFloat32Conversion_; + } + }; OutOfLineCode * @@ -714,6 +719,18 @@ CodeGeneratorShared::emitTruncateDouble(const FloatRegister &src, const Register return true; } +bool +CodeGeneratorShared::emitTruncateFloat32(const FloatRegister &src, const Register &dest) +{ + OutOfLineTruncateSlow *ool = new OutOfLineTruncateSlow(src, dest, true); + if (!addOutOfLineCode(ool)) + return false; + + masm.branchTruncateFloat32(src, dest, ool->entry()); + masm.bind(ool->rejoin()); + return true; +} + bool CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool) { @@ -722,6 +739,11 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool) saveVolatile(dest); + if (ool->needFloat32Conversion()) { + masm.push(src); + masm.convertFloatToDouble(src, src); + } + masm.setupUnalignedABICall(1, dest); masm.passABIArg(src); if (gen->compilingAsmJS()) @@ -732,6 +754,9 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool) restoreVolatile(dest); + if (ool->needFloat32Conversion()) + masm.pop(src); + masm.jump(ool->rejoin()); return true; } diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h index 8845e0d802d..2addfa5d2e0 100644 --- a/js/src/jit/shared/CodeGenerator-shared.h +++ b/js/src/jit/shared/CodeGenerator-shared.h @@ -285,6 +285,7 @@ class CodeGeneratorShared : public LInstructionVisitor OutOfLineCode *oolTruncateDouble(const FloatRegister &src, const Register &dest); bool emitTruncateDouble(const FloatRegister &src, const Register &dest); + bool emitTruncateFloat32(const FloatRegister &src, const Register &dest); void emitPreBarrier(Register base, const LAllocation *index, MIRType type); void emitPreBarrier(Address address, MIRType type); diff --git a/js/src/jit/shared/Lowering-x86-shared.cpp b/js/src/jit/shared/Lowering-x86-shared.cpp index 7f2e8eb86c5..4f081e647f0 100644 --- a/js/src/jit/shared/Lowering-x86-shared.cpp +++ b/js/src/jit/shared/Lowering-x86-shared.cpp @@ -294,3 +294,13 @@ LIRGeneratorX86Shared::lowerTruncateDToInt32(MTruncateToInt32 *ins) LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempFloat(); return define(new LTruncateDToInt32(useRegister(opd), maybeTemp), ins); } + +bool +LIRGeneratorX86Shared::lowerTruncateFToInt32(MTruncateToInt32 *ins) +{ + MDefinition *opd = ins->input(); + JS_ASSERT(opd->type() == MIRType_Float32); + + LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempFloat(); + return define(new LTruncateFToInt32(useRegister(opd), maybeTemp), ins); +} diff --git a/js/src/jit/shared/Lowering-x86-shared.h b/js/src/jit/shared/Lowering-x86-shared.h index c2bf3cdaf3e..4f36026f8f1 100644 --- a/js/src/jit/shared/Lowering-x86-shared.h +++ b/js/src/jit/shared/Lowering-x86-shared.h @@ -48,6 +48,7 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared bool lowerConstantDouble(double d, MInstruction *ins); bool lowerConstantFloat32(float d, MInstruction *ins); bool lowerTruncateDToInt32(MTruncateToInt32 *ins); + bool lowerTruncateFToInt32(MTruncateToInt32 *ins); }; } // namespace jit diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index 060a21d353d..a7d50a19fc4 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -665,6 +665,9 @@ class Assembler : public AssemblerX86Shared void cvttsd2sq(const FloatRegister &src, const Register &dest) { masm.cvttsd2sq_rr(src.code(), dest.code()); } + void cvttss2sq(const FloatRegister &src, const Register &dest) { + masm.cvttss2sq_rr(src.code(), dest.code()); + } void cvtsq2sd(const Register &src, const FloatRegister &dest) { masm.cvtsq2sd_rr(src.code(), dest.code()); } diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp index 4415c574999..c9c68927448 100644 --- a/js/src/jit/x64/CodeGenerator-x64.cpp +++ b/js/src/jit/x64/CodeGenerator-x64.cpp @@ -568,3 +568,15 @@ CodeGeneratorX64::visitTruncateDToInt32(LTruncateDToInt32 *ins) // call a stub if it fails. return emitTruncateDouble(input, output); } + +bool +CodeGeneratorX64::visitTruncateFToInt32(LTruncateFToInt32 *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + Register output = ToRegister(ins->output()); + + // On x64, branchTruncateFloat32 uses cvttss2sq. Unlike the x86 + // implementation, this should handle most floats and we can just + // call a stub if it fails. + return emitTruncateFloat32(input, output); +} diff --git a/js/src/jit/x64/CodeGenerator-x64.h b/js/src/jit/x64/CodeGenerator-x64.h index 86abf4f522f..a00b639f229 100644 --- a/js/src/jit/x64/CodeGenerator-x64.h +++ b/js/src/jit/x64/CodeGenerator-x64.h @@ -50,6 +50,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared bool visitCompareV(LCompareV *lir); bool visitCompareVAndBranch(LCompareVAndBranch *lir); bool visitTruncateDToInt32(LTruncateDToInt32 *ins); + bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 383fdf15a7b..15b8cb243bb 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -1050,6 +1050,15 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared movl(dest, dest); // Zero upper 32-bits. } + void branchTruncateFloat32(const FloatRegister &src, const Register &dest, Label *fail) { + cvttss2sq(src, dest); + + // Same trick as for Doubles + cmpq(dest, Imm32(1)); + j(Assembler::Overflow, fail); + + movl(dest, dest); // Zero upper 32-bits. + } Condition testInt32Truthy(bool truthy, const ValueOperand &operand) { testl(operand.valueReg(), operand.valueReg()); diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index d8e93854b6f..199d7acdeb7 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -268,6 +268,16 @@ class Assembler : public AssemblerX86Shared return leal(src, dest); } + void fld32(const Operand &dest) { + switch (dest.kind()) { + case Operand::MEM_REG_DISP: + masm.fld32_m(dest.disp(), dest.base()); + break; + default: + MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); + } + } + void cmpl(const Register src, ImmWord ptr) { masm.cmpl_ir(ptr.value, src.code()); } diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index 9d037dcfb33..53960eac5ee 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -26,6 +26,9 @@ using namespace js::jit; using mozilla::DebugOnly; using mozilla::DoubleExponentBias; using mozilla::DoubleExponentShift; +using mozilla::FloatExponentBias; +using mozilla::FloatExponentShift; +using mozilla::FloatExponentBits; using JS::GenericNaN; CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm) @@ -790,6 +793,23 @@ class OutOfLineTruncate : public OutOfLineCodeBase } }; +class OutOfLineTruncateFloat32 : public OutOfLineCodeBase +{ + LTruncateFToInt32 *ins_; + + public: + OutOfLineTruncateFloat32(LTruncateFToInt32 *ins) + : ins_(ins) + { } + + bool accept(CodeGeneratorX86 *codegen) { + return codegen->visitOutOfLineTruncateFloat32(this); + } + LTruncateFToInt32 *ins() const { + return ins_; + } +}; + } // namespace jit } // namespace js @@ -808,6 +828,21 @@ CodeGeneratorX86::visitTruncateDToInt32(LTruncateDToInt32 *ins) return true; } +bool +CodeGeneratorX86::visitTruncateFToInt32(LTruncateFToInt32 *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + Register output = ToRegister(ins->output()); + + OutOfLineTruncateFloat32 *ool = new OutOfLineTruncateFloat32(ins); + if (!addOutOfLineCode(ool)) + return false; + + masm.branchTruncateFloat32(input, output, ool->entry()); + masm.bind(ool->rejoin()); + return true; +} + bool CodeGeneratorX86::visitOutOfLineTruncate(OutOfLineTruncate *ool) { @@ -895,3 +930,92 @@ CodeGeneratorX86::visitOutOfLineTruncate(OutOfLineTruncate *ool) masm.jump(ool->rejoin()); return true; } + +bool +CodeGeneratorX86::visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool) +{ + LTruncateFToInt32 *ins = ool->ins(); + FloatRegister input = ToFloatRegister(ins->input()); + Register output = ToRegister(ins->output()); + + Label fail; + + if (Assembler::HasSSE3()) { + // Push float32, but subtracts 64 bits so that the value popped by fisttp fits + masm.subl(Imm32(sizeof(uint64_t)), esp); + masm.storeFloat(input, Operand(esp, 0)); + + static const uint32_t EXPONENT_MASK = FloatExponentBits; + static const uint32_t EXPONENT_SHIFT = FloatExponentShift; + // Integers are still 64 bits long, so we can still test for an exponent > 63. + static const uint32_t TOO_BIG_EXPONENT = (FloatExponentBias + 63) << EXPONENT_SHIFT; + + // Check exponent to avoid fp exceptions. + Label failPopFloat; + masm.movl(Operand(esp, 0), output); + masm.and32(Imm32(EXPONENT_MASK), output); + masm.branch32(Assembler::GreaterThanOrEqual, output, Imm32(TOO_BIG_EXPONENT), &failPopFloat); + + // Load float, perform 32-bit truncation. + masm.fld32(Operand(esp, 0)); + masm.fisttp(Operand(esp, 0)); + + // Load low word, pop 64bits and jump back. + masm.movl(Operand(esp, 0), output); + masm.addl(Imm32(sizeof(uint64_t)), esp); + masm.jump(ool->rejoin()); + + masm.bind(&failPopFloat); + masm.addl(Imm32(sizeof(uint64_t)), esp); + masm.jump(&fail); + } else { + FloatRegister temp = ToFloatRegister(ins->tempFloat()); + + // Try to convert float32 representing integers within 2^32 of a signed + // integer, by adding/subtracting 2^32 and then trying to convert to int32. + // This has to be an exact conversion, as otherwise the truncation works + // incorrectly on the modified value. + masm.xorps(ScratchFloatReg, ScratchFloatReg); + masm.ucomiss(input, ScratchFloatReg); + masm.j(Assembler::Parity, &fail); + + { + Label positive; + masm.j(Assembler::Above, &positive); + + masm.loadConstantFloat32(4294967296.f, temp); + Label skip; + masm.jmp(&skip); + + masm.bind(&positive); + masm.loadConstantFloat32(-4294967296.f, temp); + masm.bind(&skip); + } + + masm.addss(input, temp); + masm.cvttss2si(temp, output); + masm.cvtsi2ss(output, ScratchFloatReg); + + masm.ucomiss(temp, ScratchFloatReg); + masm.j(Assembler::Parity, &fail); + masm.j(Assembler::Equal, ool->rejoin()); + } + + masm.bind(&fail); + { + saveVolatile(output); + + masm.push(input); + masm.setupUnalignedABICall(1, output); + masm.cvtss2sd(input, input); + masm.passABIArg(input); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32)); + masm.storeCallResult(output); + masm.pop(input); + + restoreVolatile(output); + } + + masm.jump(ool->rejoin()); + return true; +} diff --git a/js/src/jit/x86/CodeGenerator-x86.h b/js/src/jit/x86/CodeGenerator-x86.h index ee8fec03bdf..a422479a19a 100644 --- a/js/src/jit/x86/CodeGenerator-x86.h +++ b/js/src/jit/x86/CodeGenerator-x86.h @@ -15,6 +15,7 @@ namespace jit { class OutOfLineLoadTypedArrayOutOfBounds; class OutOfLineTruncate; +class OutOfLineTruncateFloat32; class CodeGeneratorX86 : public CodeGeneratorX86Shared { @@ -64,6 +65,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared bool visitCompareVAndBranch(LCompareVAndBranch *lir); bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); bool visitTruncateDToInt32(LTruncateDToInt32 *ins); + bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); @@ -75,6 +77,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared bool visitOutOfLineLoadTypedArrayOutOfBounds(OutOfLineLoadTypedArrayOutOfBounds *ool); bool visitOutOfLineTruncate(OutOfLineTruncate *ool); + bool visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool); void postAsmJSCall(LAsmJSCall *lir); }; From 9c77d0cea546fc99367735130b31b0b6e41da0bb Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:51:37 +0200 Subject: [PATCH 21/75] Bug 913282: More Float32 operators: comparisons; p=dougc,bbouvier, r=jonco,h4writer dougc for the ARM parts, bbouvier for the rest --- js/src/jit/LIR-Common.h | 71 +++++++++++++++++++ js/src/jit/LOpcodes.h | 3 + js/src/jit/Lowering.cpp | 21 ++++++ js/src/jit/MIR.cpp | 26 ++++++- js/src/jit/MIR.h | 15 ++++ js/src/jit/TypePolicy.cpp | 17 ++++- js/src/jit/arm/CodeGenerator-arm.cpp | 43 +++++++++++ js/src/jit/arm/CodeGenerator-arm.h | 3 + js/src/jit/arm/MacroAssembler-arm.cpp | 5 ++ js/src/jit/arm/MacroAssembler-arm.h | 1 + .../jit/shared/CodeGenerator-x86-shared.cpp | 37 ++++++++++ js/src/jit/shared/CodeGenerator-x86-shared.h | 3 + 12 files changed, 243 insertions(+), 2 deletions(-) diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 977427a2214..26b6ef09fe0 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -1399,6 +1399,27 @@ class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0> } }; +// Takes in either an integer or boolean input and tests it for truthiness. +class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0> +{ + public: + LIR_HEADER(TestFAndBranch) + + LTestFAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse) + { + setOperand(0, in); + setSuccessor(0, ifTrue); + setSuccessor(1, ifFalse); + } + + MBasicBlock *ifTrue() const { + return getSuccessor(0); + } + MBasicBlock *ifFalse() const { + return getSuccessor(1); + } +}; + // Takes an object and tests it for truthiness. An object is falsy iff it // emulates |undefined|; see js::EmulatesUndefined. class LTestOAndBranch : public LControlInstructionHelper<2, 1, 1> @@ -1611,6 +1632,26 @@ class LCompareD : public LInstructionHelper<1, 2, 0> } }; +class LCompareF : public LInstructionHelper<1, 2, 0> +{ + public: + LIR_HEADER(CompareF) + LCompareF(const LAllocation &left, const LAllocation &right) { + setOperand(0, left); + setOperand(1, right); + } + + const LAllocation *left() { + return getOperand(0); + } + const LAllocation *right() { + return getOperand(1); + } + MCompare *mir() { + return mir_->toCompare(); + } +}; + class LCompareDAndBranch : public LControlInstructionHelper<2, 2, 0> { public: @@ -1641,6 +1682,36 @@ class LCompareDAndBranch : public LControlInstructionHelper<2, 2, 0> } }; +class LCompareFAndBranch : public LControlInstructionHelper<2, 2, 0> +{ + public: + LIR_HEADER(CompareFAndBranch) + LCompareFAndBranch(const LAllocation &left, const LAllocation &right, + MBasicBlock *ifTrue, MBasicBlock *ifFalse) + { + setOperand(0, left); + setOperand(1, right); + setSuccessor(0, ifTrue); + setSuccessor(1, ifFalse); + } + + MBasicBlock *ifTrue() const { + return getSuccessor(0); + } + MBasicBlock *ifFalse() const { + return getSuccessor(1); + } + const LAllocation *left() { + return getOperand(0); + } + const LAllocation *right() { + return getOperand(1); + } + MCompare *mir() { + return mir_->toCompare(); + } +}; + class LCompareS : public LInstructionHelper<1, 2, 1> { public: diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index ded3a1d720e..7d402d94c49 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -71,6 +71,7 @@ _(Phi) \ _(TestIAndBranch) \ _(TestDAndBranch) \ + _(TestFAndBranch) \ _(TestVAndBranch) \ _(TestOAndBranch) \ _(FunctionDispatch) \ @@ -79,6 +80,8 @@ _(CompareAndBranch) \ _(CompareD) \ _(CompareDAndBranch) \ + _(CompareF) \ + _(CompareFAndBranch) \ _(CompareS) \ _(CompareStrictS) \ _(CompareB) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index dff437527f6..a6acb5be9ec 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -661,6 +661,12 @@ LIRGenerator::visitTest(MTest *test) return add(new LGoto(result ? ifTrue : ifFalse)); } + // Constant Float32 operand. + if (opd->type() == MIRType_Float32 && opd->isConstant()) { + bool result = ToBoolean(opd->toConstant()->value()); + return add(new LGoto(result ? ifTrue : ifFalse)); + } + // Constant Int32 operand. if (opd->type() == MIRType_Int32 && opd->isConstant()) { int32_t num = opd->toConstant()->value().toInt32(); @@ -758,6 +764,14 @@ LIRGenerator::visitTest(MTest *test) return add(lir, comp); } + // Compare and branch floats. + if (comp->isFloat32Comparison()) { + LAllocation lhs = useRegister(left); + LAllocation rhs = useRegister(right); + LCompareFAndBranch *lir = new LCompareFAndBranch(lhs, rhs, ifTrue, ifFalse); + return add(lir, comp); + } + // Compare values. if (comp->compareType() == MCompare::Compare_Value) { LCompareVAndBranch *lir = new LCompareVAndBranch(ifTrue, ifFalse); @@ -783,6 +797,9 @@ LIRGenerator::visitTest(MTest *test) if (opd->type() == MIRType_Double) return add(new LTestDAndBranch(useRegister(opd), ifTrue, ifFalse)); + if (opd->type() == MIRType_Float32) + return add(new LTestFAndBranch(useRegister(opd), ifTrue, ifFalse)); + JS_ASSERT(opd->type() == MIRType_Int32 || opd->type() == MIRType_Boolean); return add(new LTestIAndBranch(useRegister(opd), ifTrue, ifFalse)); } @@ -931,6 +948,10 @@ LIRGenerator::visitCompare(MCompare *comp) if (comp->isDoubleComparison()) return define(new LCompareD(useRegister(left), useRegister(right)), comp); + // Compare float32. + if (comp->isFloat32Comparison()) + return define(new LCompareF(useRegister(left), useRegister(right)), comp); + // Compare values. if (comp->compareType() == MCompare::Compare_Value) { LCompareV *lir = new LCompareV(); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index c48efb61b23..4c2208eefa1 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -666,7 +666,7 @@ MCompare * MCompare::NewAsmJS(MDefinition *left, MDefinition *right, JSOp op, CompareType compareType) { JS_ASSERT(compareType == Compare_Int32 || compareType == Compare_UInt32 || - compareType == Compare_Double); + compareType == Compare_Double || compareType == Compare_Float32); MCompare *comp = new MCompare(left, right, op); comp->compareType_ = compareType; comp->operandMightEmulateUndefined_ = false; @@ -1680,6 +1680,8 @@ MCompare::inputType() case Compare_DoubleMaybeCoerceLHS: case Compare_DoubleMaybeCoerceRHS: return MIRType_Double; + case Compare_Float32: + return MIRType_Float32; case Compare_String: case Compare_StrictString: return MIRType_String; @@ -2206,6 +2208,7 @@ MCompare::tryFold(bool *result) /* FALL THROUGH */ case MIRType_Int32: case MIRType_Double: + case MIRType_Float32: case MIRType_String: case MIRType_Boolean: *result = (op == JSOP_NE || op == JSOP_STRICTNE); @@ -2224,6 +2227,7 @@ MCompare::tryFold(bool *result) return false; case MIRType_Int32: case MIRType_Double: + case MIRType_Float32: case MIRType_String: case MIRType_Object: case MIRType_Null: @@ -2248,6 +2252,7 @@ MCompare::tryFold(bool *result) case MIRType_Boolean: case MIRType_Int32: case MIRType_Double: + case MIRType_Float32: case MIRType_Object: case MIRType_Null: case MIRType_Undefined: @@ -2392,6 +2397,25 @@ MCompare::foldsTo(bool useValueNumbers) return this; } +void +MCompare::trySpecializeFloat32() +{ + MDefinition *lhs = getOperand(0); + MDefinition *rhs = getOperand(1); + + if (compareType_ == Compare_Float32) + return; + + if (lhs->canProduceFloat32() && rhs->canProduceFloat32() && compareType_ == Compare_Double) { + compareType_ = Compare_Float32; + } else { + if (lhs->type() == MIRType_Float32) + ConvertDefinitionToDouble<0>(lhs, this); + if (rhs->type() == MIRType_Float32) + ConvertDefinitionToDouble<1>(rhs, this); + } +} + void MNot::infer() { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 25f6da7007d..562816823a4 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -2111,6 +2111,9 @@ class MCompare Compare_DoubleMaybeCoerceLHS, Compare_DoubleMaybeCoerceRHS, + // Float compared to Float + Compare_Float32, + // String compared to String Compare_String, @@ -2166,6 +2169,9 @@ class MCompare compareType() == Compare_DoubleMaybeCoerceLHS || compareType() == Compare_DoubleMaybeCoerceRHS; } + bool isFloat32Comparison() const { + return compareType() == Compare_Float32; + } void setCompareType(CompareType type) { compareType_ = type; } @@ -2195,6 +2201,15 @@ class MCompare void printOpcode(FILE *fp) const; + void trySpecializeFloat32(); + bool isFloat32Commutative() const { return true; } + +# ifdef DEBUG + bool isConsistentFloat32Use() const { + return compareType_ == Compare_Float32; + } +# endif + protected: bool congruentTo(MDefinition *ins) const { if (!MBinaryInstruction::congruentTo(ins)) diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index 15cc3350ae8..9ef5ae01b6c 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -198,7 +198,7 @@ ComparePolicy::adjustInputs(MInstruction *def) // Convert all inputs to the right input type MIRType type = compare->inputType(); JS_ASSERT(type == MIRType_Int32 || type == MIRType_Double || - type == MIRType_Object || type == MIRType_String); + type == MIRType_Object || type == MIRType_String || type == MIRType_Float32); for (size_t i = 0; i < 2; i++) { MDefinition *in = def->getOperand(i); if (in->type() == type) @@ -228,6 +228,20 @@ ComparePolicy::adjustInputs(MInstruction *def) replace = MToDouble::New(in, convert); break; } + case MIRType_Float32: { + MToFloat32::ConversionKind convert = MToFloat32::NumbersOnly; + if (compare->compareType() == MCompare::Compare_DoubleMaybeCoerceLHS && i == 0) + convert = MToFloat32::NonNullNonStringPrimitives; + else if (compare->compareType() == MCompare::Compare_DoubleMaybeCoerceRHS && i == 1) + convert = MToFloat32::NonNullNonStringPrimitives; + if (in->type() == MIRType_Null || + (in->type() == MIRType_Boolean && convert == MToFloat32::NumbersOnly)) + { + in = boxAt(def, in); + } + replace = MToFloat32::New(in, convert); + break; + } case MIRType_Int32: replace = MToInt32::New(in); break; @@ -303,6 +317,7 @@ TestPolicy::adjustInputs(MInstruction *ins) case MIRType_Boolean: case MIRType_Int32: case MIRType_Double: + case MIRType_Float32: case MIRType_Object: break; diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 1c5427aecb9..9e60673c2ef 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1384,6 +1384,25 @@ CodeGeneratorARM::visitTestDAndBranch(LTestDAndBranch *test) return true; } +bool +CodeGeneratorARM::visitTestFAndBranch(LTestFAndBranch *test) +{ + const LAllocation *opd = test->input(); + masm.ma_vcmpz_f32(ToFloatRegister(opd)); + masm.as_vmrs(pc); + + MBasicBlock *ifTrue = test->ifTrue(); + MBasicBlock *ifFalse = test->ifFalse(); + // If the compare set the 0 bit, then the result + // is definately false. + jumpToBlock(ifFalse, Assembler::Zero); + // it is also false if one of the operands is NAN, which is + // shown as Overflow. + jumpToBlock(ifFalse, Assembler::Overflow); + jumpToBlock(ifTrue); + return true; +} + bool CodeGeneratorARM::visitCompareD(LCompareD *comp) { @@ -1396,6 +1415,18 @@ CodeGeneratorARM::visitCompareD(LCompareD *comp) return true; } +bool +CodeGeneratorARM::visitCompareF(LCompareF *comp) +{ + FloatRegister lhs = ToFloatRegister(comp->left()); + FloatRegister rhs = ToFloatRegister(comp->right()); + + Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + masm.compareFloat(lhs, rhs); + masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output())); + return true; +} + bool CodeGeneratorARM::visitCompareDAndBranch(LCompareDAndBranch *comp) { @@ -1408,6 +1439,18 @@ CodeGeneratorARM::visitCompareDAndBranch(LCompareDAndBranch *comp) return true; } +bool +CodeGeneratorARM::visitCompareFAndBranch(LCompareFAndBranch *comp) +{ + FloatRegister lhs = ToFloatRegister(comp->left()); + FloatRegister rhs = ToFloatRegister(comp->right()); + + Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + masm.compareFloat(lhs, rhs); + emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse()); + return true; +} + bool CodeGeneratorARM::visitCompareB(LCompareB *lir) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index b6fd3bcc8fc..85a10468b34 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -89,8 +89,11 @@ class CodeGeneratorARM : public CodeGeneratorShared virtual bool visitCompare(LCompare *comp); virtual bool visitCompareAndBranch(LCompareAndBranch *comp); virtual bool visitTestDAndBranch(LTestDAndBranch *test); + virtual bool visitTestFAndBranch(LTestFAndBranch *test); virtual bool visitCompareD(LCompareD *comp); + virtual bool visitCompareF(LCompareF *comp); virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp); + virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp); virtual bool visitCompareB(LCompareB *lir); virtual bool visitCompareBAndBranch(LCompareBAndBranch *lir); virtual bool visitCompareV(LCompareV *lir); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 3b1280dee43..55355e1ddba 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1525,6 +1525,11 @@ MacroAssemblerARM::ma_vcmpz(FloatRegister src1, Condition cc) { as_vcmpz(VFPRegister(src1), cc); } +void +MacroAssemblerARM::ma_vcmpz_f32(FloatRegister src1, Condition cc) +{ + as_vcmpz(VFPRegister(src1).singleOverlay(), cc); +} void MacroAssemblerARM::ma_vcvt_F64_I32(FloatRegister src, FloatRegister dest, Condition cc) diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 2ddf29a3d5e..e6275a47a39 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -326,6 +326,7 @@ class MacroAssemblerARM : public Assembler void ma_vcmp(FloatRegister src1, FloatRegister src2, Condition cc = Always); void ma_vcmp_f32(FloatRegister src1, FloatRegister src2, Condition cc = Always); void ma_vcmpz(FloatRegister src1, Condition cc = Always); + void ma_vcmpz_f32(FloatRegister src1, Condition cc = Always); void ma_vadd_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst); void ma_vsub_f32(FloatRegister src1, FloatRegister src2, FloatRegister dst); diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 9e859ca6d50..4a8cf1ec3de 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -128,6 +128,17 @@ CodeGeneratorX86Shared::visitTestDAndBranch(LTestDAndBranch *test) return true; } +bool +CodeGeneratorX86Shared::visitTestFAndBranch(LTestFAndBranch *test) +{ + const LAllocation *opd = test->input(); + // ucomiss flags are the same as doubles; see comment above + masm.xorps(ScratchFloatReg, ScratchFloatReg); + masm.ucomiss(ToFloatRegister(opd), ScratchFloatReg); + emitBranch(Assembler::NotEqual, test->ifTrue(), test->ifFalse()); + return true; +} + bool CodeGeneratorX86Shared::visitBitAndAndBranch(LBitAndAndBranch *baab) { @@ -187,6 +198,19 @@ CodeGeneratorX86Shared::visitCompareD(LCompareD *comp) return true; } +bool +CodeGeneratorX86Shared::visitCompareF(LCompareF *comp) +{ + FloatRegister lhs = ToFloatRegister(comp->left()); + FloatRegister rhs = ToFloatRegister(comp->right()); + + Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + masm.compareFloat(cond, lhs, rhs); + masm.emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()), + Assembler::NaNCondFromDoubleCondition(cond)); + return true; +} + bool CodeGeneratorX86Shared::visitNotI(LNotI *ins) { @@ -219,6 +243,19 @@ CodeGeneratorX86Shared::visitCompareDAndBranch(LCompareDAndBranch *comp) return true; } +bool +CodeGeneratorX86Shared::visitCompareFAndBranch(LCompareFAndBranch *comp) +{ + FloatRegister lhs = ToFloatRegister(comp->left()); + FloatRegister rhs = ToFloatRegister(comp->right()); + + Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop()); + masm.compareFloat(cond, lhs, rhs); + emitBranch(Assembler::ConditionFromDoubleCondition(cond), comp->ifTrue(), comp->ifFalse(), + Assembler::NaNCondFromDoubleCondition(cond)); + return true; +} + bool CodeGeneratorX86Shared::visitAsmJSPassStackArg(LAsmJSPassStackArg *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index a6686fb3954..b226a0eae85 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -98,10 +98,13 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared virtual bool visitUrshD(LUrshD *ins); virtual bool visitTestIAndBranch(LTestIAndBranch *test); virtual bool visitTestDAndBranch(LTestDAndBranch *test); + virtual bool visitTestFAndBranch(LTestFAndBranch *test); virtual bool visitCompare(LCompare *comp); virtual bool visitCompareAndBranch(LCompareAndBranch *comp); virtual bool visitCompareD(LCompareD *comp); virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp); + virtual bool visitCompareF(LCompareF *comp); + virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp); virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab); virtual bool visitNotI(LNotI *comp); virtual bool visitNotD(LNotD *comp); From 864abd23f60dd68cb035d427d4c5871d8eca9942 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 18 Jul 2013 16:16:58 -0700 Subject: [PATCH 22/75] Bug 913282: More Float32 operators: Sqrt; p=dougc,bbouvier, r=jonco,nbp dougc for the ARM parts, bbouvier for the rest --- js/src/assembler/assembler/X86Assembler.h | 9 +++++++++ js/src/jit/LIR-Common.h | 10 ++++++++++ js/src/jit/LOpcodes.h | 1 + js/src/jit/Lowering.cpp | 9 +++++++-- js/src/jit/MIR.cpp | 12 ++++++++++++ js/src/jit/MIR.h | 16 ++++++++++------ js/src/jit/arm/CodeGenerator-arm.cpp | 9 +++++++++ js/src/jit/arm/CodeGenerator-arm.h | 1 + js/src/jit/arm/MacroAssembler-arm.cpp | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.h | 1 + js/src/jit/shared/Assembler-x86-shared.h | 4 ++++ js/src/jit/shared/CodeGenerator-x86-shared.cpp | 9 +++++++++ js/src/jit/shared/CodeGenerator-x86-shared.h | 1 + 13 files changed, 80 insertions(+), 8 deletions(-) diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index dc4a149c50d..f7603de8347 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -301,6 +301,7 @@ private: OP2_DIVSD_VsdWsd = 0x5E, OP2_MAXSD_VsdWsd = 0x5F, OP2_SQRTSD_VsdWsd = 0x51, + OP2_SQRTSS_VssWss = 0x51, OP2_ANDPD_VpdWpd = 0x54, OP2_ORPD_VpdWpd = 0x56, OP2_XORPD_VpdWpd = 0x57, @@ -2906,6 +2907,14 @@ public: m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src); } + void sqrtss_rr(XMMRegisterID src, XMMRegisterID dst) + { + spew("sqrtss %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp(OP2_SQRTSS_VssWss, (RegisterID)dst, (RegisterID)src); + } + void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingMode mode) { spew("roundsd %s, %s, %d", diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 26b6ef09fe0..9031ccdc34c 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -2303,6 +2303,16 @@ class LSqrtD : public LInstructionHelper<1, 1, 0> } }; +// Square root of a float32. +class LSqrtF : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(SqrtF) + LSqrtF(const LAllocation &num) { + setOperand(0, num); + } +}; + class LAtan2D : public LCallInstructionHelper<1, 2, 1> { public: diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 7d402d94c49..122b3b61641 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -102,6 +102,7 @@ _(AbsI) \ _(AbsD) \ _(SqrtD) \ + _(SqrtF) \ _(Atan2D) \ _(PowI) \ _(PowD) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index a6acb5be9ec..ecb1e5360fe 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -1185,8 +1185,13 @@ bool LIRGenerator::visitSqrt(MSqrt *ins) { MDefinition *num = ins->num(); - JS_ASSERT(num->type() == MIRType_Double); - LSqrtD *lir = new LSqrtD(useRegisterAtStart(num)); + JS_ASSERT(IsFloatingPointType(num->type())); + if (num->type() == MIRType_Double) { + LSqrtD *lir = new LSqrtD(useRegisterAtStart(num)); + return define(lir, ins); + } + + LSqrtF *lir = new LSqrtF(useRegisterAtStart(num)); return define(lir, ins); } diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 4c2208eefa1..070c724aa96 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2729,6 +2729,18 @@ MAsmJSCall::New(Callee callee, const Args &args, MIRType resultType, size_t spIn return call; } +void +MSqrt::trySpecializeFloat32() { + if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) { + if (input()->type() == MIRType_Float32) + ConvertDefinitionToDouble<0>(input(), this); + return; + } + + setResultType(MIRType_Float32); + setPolicyType(MIRType_Float32); +} + bool jit::ElementAccessIsDenseNative(MDefinition *obj, MDefinition *id) { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 562816823a4..c9f20a47395 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -3455,23 +3455,24 @@ class MAbs // Inline implementation of Math.sqrt(). class MSqrt : public MUnaryInstruction, - public DoublePolicy<0> + public FloatingPointPolicy<0> { - MSqrt(MDefinition *num) + MSqrt(MDefinition *num, MIRType type) : MUnaryInstruction(num) { - setResultType(MIRType_Double); + setResultType(type); + setPolicyType(type); setMovable(); } public: INSTRUCTION_HEADER(Sqrt) static MSqrt *New(MDefinition *num) { - return new MSqrt(num); + return new MSqrt(num, MIRType_Double); } static MSqrt *NewAsmJS(MDefinition *num, MIRType type) { - JS_ASSERT(type == MIRType_Double); - return new MSqrt(num); + JS_ASSERT(IsFloatingPointType(type)); + return new MSqrt(num, type); } MDefinition *num() const { return getOperand(0); @@ -3487,6 +3488,9 @@ class MSqrt return AliasSet::None(); } void computeRange(); + + bool isFloat32Commutative() const { return true; } + void trySpecializeFloat32(); }; // Inline implementation of atan2 (arctangent of y/x). diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 9e60673c2ef..52fde26668c 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -348,6 +348,15 @@ CodeGeneratorARM::visitSqrtD(LSqrtD *ins) return true; } +bool +CodeGeneratorARM::visitSqrtF(LSqrtF *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + FloatRegister output = ToFloatRegister(ins->output()); + masm.ma_vsqrt_f32(input, output); + return true; +} + bool CodeGeneratorARM::visitAddI(LAddI *ins) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 85a10468b34..f0e3da4014a 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -67,6 +67,7 @@ class CodeGeneratorARM : public CodeGeneratorShared virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitAbsD(LAbsD *ins); virtual bool visitSqrtD(LSqrtD *ins); + virtual bool visitSqrtF(LSqrtF *ins); virtual bool visitAddI(LAddI *ins); virtual bool visitSubI(LSubI *ins); virtual bool visitBitNotI(LBitNotI *ins); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 55355e1ddba..52a2041a715 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1431,6 +1431,12 @@ MacroAssemblerARM::ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc) as_vsqrt(dest, src, cc); } +void +MacroAssemblerARM::ma_vsqrt_f32(FloatRegister src, FloatRegister dest, Condition cc) +{ + as_vsqrt(VFPRegister(dest).singleOverlay(), VFPRegister(src).singleOverlay(), cc); +} + union DoublePun { struct diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index e6275a47a39..f6d3b2a4df9 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -319,6 +319,7 @@ class MacroAssemblerARM : public Assembler void ma_vabs(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc = Always); + void ma_vsqrt_f32(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vimm(double value, FloatRegister dest, Condition cc = Always); void ma_vimm_f32(float value, FloatRegister dest, Condition cc = Always); diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index e5f7269bdd2..dcaaafcbe2d 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1452,6 +1452,10 @@ class AssemblerX86Shared JS_ASSERT(HasSSE2()); masm.sqrtsd_rr(src.code(), dest.code()); } + void sqrtss(const FloatRegister &src, const FloatRegister &dest) { + JS_ASSERT(HasSSE2()); + masm.sqrtss_rr(src.code(), dest.code()); + } void roundsd(const FloatRegister &src, const FloatRegister &dest, JSC::X86Assembler::RoundingMode mode) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 4a8cf1ec3de..bbaf04cd825 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -482,6 +482,15 @@ CodeGeneratorX86Shared::visitSqrtD(LSqrtD *ins) return true; } +bool +CodeGeneratorX86Shared::visitSqrtF(LSqrtF *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + FloatRegister output = ToFloatRegister(ins->output()); + masm.sqrtss(input, output); + return true; +} + bool CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index b226a0eae85..ad50cc2edb9 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -83,6 +83,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitAbsD(LAbsD *ins); virtual bool visitSqrtD(LSqrtD *ins); + virtual bool visitSqrtF(LSqrtF *ins); virtual bool visitPowHalfD(LPowHalfD *ins); virtual bool visitAddI(LAddI *ins); virtual bool visitSubI(LSubI *ins); From 04a6f849178c99df096a162e53218663c64181f6 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:53:12 +0200 Subject: [PATCH 23/75] Bug 913282: More Float32 operators: Abs; p=dougc,bbouvier; r=jonco,sstangl dougc for the ARM parts, bbouvier for the rest. --- js/src/assembler/assembler/X86Assembler.h | 7 +++++ js/src/jit/LIR-Common.h | 10 +++++++ js/src/jit/LOpcodes.h | 1 + js/src/jit/Lowering.cpp | 6 +++- js/src/jit/MCallOptimize.cpp | 17 ++++++++--- js/src/jit/MIR.cpp | 13 +++++++++ js/src/jit/MIR.h | 4 ++- js/src/jit/arm/CodeGenerator-arm.cpp | 9 ++++++ js/src/jit/arm/CodeGenerator-arm.h | 1 + js/src/jit/arm/MacroAssembler-arm.cpp | 6 ++++ js/src/jit/arm/MacroAssembler-arm.h | 1 + js/src/jit/shared/Assembler-x86-shared.h | 4 +++ .../jit/shared/CodeGenerator-x86-shared.cpp | 13 +++++++++ js/src/jit/shared/CodeGenerator-x86-shared.h | 1 + mfbt/FloatingPoint.h | 28 +++++++++++++++++++ 15 files changed, 115 insertions(+), 6 deletions(-) diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index f7603de8347..3e65c196184 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -2899,6 +2899,13 @@ public: m_formatter.twoByteOp(OP2_ANDPD_VpdWpd, (RegisterID)dst, (RegisterID)src); } + void andps_rr(XMMRegisterID src, XMMRegisterID dst) + { + spew("andps %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_ANDPD_VpdWpd, (RegisterID)dst, (RegisterID)src); + } + void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst) { spew("sqrtsd %s, %s", diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 9031ccdc34c..02c33a0e3db 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -2293,6 +2293,16 @@ class LAbsD : public LInstructionHelper<1, 1, 0> } }; +// Absolute value of a float32. +class LAbsF : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(AbsF) + LAbsF(const LAllocation &num) { + setOperand(0, num); + } +}; + // Square root of a double. class LSqrtD : public LInstructionHelper<1, 1, 0> { diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 122b3b61641..c4b4bc423e4 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -101,6 +101,7 @@ _(NegF) \ _(AbsI) \ _(AbsD) \ + _(AbsF) \ _(SqrtD) \ _(SqrtF) \ _(Atan2D) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index ecb1e5360fe..4183d8d13ab 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -1167,6 +1167,7 @@ bool LIRGenerator::visitAbs(MAbs *ins) { MDefinition *num = ins->num(); + JS_ASSERT(IsNumberType(num->type())); if (num->type() == MIRType_Int32) { LAbsI *lir = new LAbsI(useRegisterAtStart(num)); @@ -1175,8 +1176,11 @@ LIRGenerator::visitAbs(MAbs *ins) return false; return defineReuseInput(lir, ins, 0); } + if (num->type() == MIRType_Float32) { + LAbsF *lir = new LAbsF(useRegisterAtStart(num)); + return defineReuseInput(lir, ins, 0); + } - JS_ASSERT(num->type() == MIRType_Double); LAbsD *lir = new LAbsD(useRegisterAtStart(num)); return defineReuseInput(lir, ins, 0); } diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index fb4ea0d679e..e716cc02d95 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -520,18 +520,27 @@ IonBuilder::inlineMathAbs(CallInfo &callInfo) MIRType returnType = getInlineReturnType(); MIRType argType = callInfo.getArg(0)->type(); - if (argType != MIRType_Int32 && argType != MIRType_Double) + if (!IsNumberType(argType)) return InliningStatus_NotInlined; - if (argType != returnType && returnType != MIRType_Int32) + // Either argType == returnType, or + // argType == Double or Float32, returnType == Int, or + // argType == Float32, returnType == Double + if (argType != returnType && !(IsFloatingPointType(argType) && returnType == MIRType_Int32) + && !(argType == MIRType_Float32 && returnType == MIRType_Double)) + { return InliningStatus_NotInlined; + } callInfo.unwrapArgs(); - MInstruction *ins = MAbs::New(callInfo.getArg(0), argType); + // If the arg is a Float32, we specialize the op as double, it will be specialized + // as float32 if necessary later. + MIRType absType = (argType == MIRType_Float32) ? MIRType_Double : argType; + MInstruction *ins = MAbs::New(callInfo.getArg(0), absType); current->add(ins); - if (argType != returnType) { + if (IsFloatingPointType(argType) && returnType == MIRType_Int32) { MToInt32 *toInt = MToInt32::New(ins); toInt->setCanBeNegativeZero(false); current->add(toInt); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 070c724aa96..2456d25b7a3 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -1279,6 +1279,19 @@ MAbs::fallible() const return !implicitTruncate_ && (!range() || !range()->hasInt32Bounds()); } +void +MAbs::trySpecializeFloat32() +{ + if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) { + if (input()->type() == MIRType_Float32) + ConvertDefinitionToDouble<0>(input(), this); + return; + } + + setResultType(MIRType_Float32); + specialization_ = MIRType_Float32; +} + MDefinition * MDiv::foldsTo(bool useValueNumbers) { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index c9f20a47395..cb26bd88469 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -3418,7 +3418,7 @@ class MAbs : MUnaryInstruction(num), implicitTruncate_(false) { - JS_ASSERT(type == MIRType_Double || type == MIRType_Int32); + JS_ASSERT(IsNumberType(type)); setResultType(type); setMovable(); specialization_ = type; @@ -3450,6 +3450,8 @@ class MAbs return AliasSet::None(); } void computeRange(); + bool isFloat32Commutative() const { return true; } + void trySpecializeFloat32(); }; // Inline implementation of Math.sqrt(). diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 52fde26668c..115cc5c9a90 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -339,6 +339,15 @@ CodeGeneratorARM::visitAbsD(LAbsD *ins) return true; } +bool +CodeGeneratorARM::visitAbsF(LAbsF *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + JS_ASSERT(input == ToFloatRegister(ins->output())); + masm.ma_vabs_f32(input, input); + return true; +} + bool CodeGeneratorARM::visitSqrtD(LSqrtD *ins) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index f0e3da4014a..45a41acaa3e 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -66,6 +66,7 @@ class CodeGeneratorARM : public CodeGeneratorShared // Instruction visitors. virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitAbsD(LAbsD *ins); + virtual bool visitAbsF(LAbsF *ins); virtual bool visitSqrtD(LSqrtD *ins); virtual bool visitSqrtF(LSqrtF *ins); virtual bool visitAddI(LAddI *ins); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 52a2041a715..effde0f826f 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1425,6 +1425,12 @@ MacroAssemblerARM::ma_vabs(FloatRegister src, FloatRegister dest, Condition cc) as_vabs(dest, src, cc); } +void +MacroAssemblerARM::ma_vabs_f32(FloatRegister src, FloatRegister dest, Condition cc) +{ + as_vabs(VFPRegister(dest).singleOverlay(), VFPRegister(src).singleOverlay(), cc); +} + void MacroAssemblerARM::ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index f6d3b2a4df9..4639d8682b8 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -317,6 +317,7 @@ class MacroAssemblerARM : public Assembler void ma_vneg(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vmov(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vabs(FloatRegister src, FloatRegister dest, Condition cc = Always); + void ma_vabs_f32(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc = Always); void ma_vsqrt_f32(FloatRegister src, FloatRegister dest, Condition cc = Always); diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index dcaaafcbe2d..a88325c38d7 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1448,6 +1448,10 @@ class AssemblerX86Shared JS_ASSERT(HasSSE2()); masm.andpd_rr(src.code(), dest.code()); } + void andps(const FloatRegister &src, const FloatRegister &dest) { + JS_ASSERT(HasSSE2()); + masm.andps_rr(src.code(), dest.code()); + } void sqrtsd(const FloatRegister &src, const FloatRegister &dest) { JS_ASSERT(HasSSE2()); masm.sqrtsd_rr(src.code(), dest.code()); diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index bbaf04cd825..5262b789be7 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -19,9 +19,11 @@ using namespace js; using namespace js::jit; using mozilla::DoubleSignificandBits; +using mozilla::FloatSignificandBits; using mozilla::FloorLog2; using mozilla::NegativeInfinity; using mozilla::SpecificNaN; +using mozilla::SpecificFloatNaN; namespace js { namespace jit { @@ -473,6 +475,17 @@ CodeGeneratorX86Shared::visitAbsD(LAbsD *ins) return true; } +bool +CodeGeneratorX86Shared::visitAbsF(LAbsF *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + JS_ASSERT(input == ToFloatRegister(ins->output())); + // Same trick as visitAbsD above. + masm.loadConstantFloat32(SpecificFloatNaN(0, FloatSignificandBits), ScratchFloatReg); + masm.andps(ScratchFloatReg, input); + return true; +} + bool CodeGeneratorX86Shared::visitSqrtD(LSqrtD *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index ad50cc2edb9..9ab47503c1c 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -82,6 +82,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared virtual bool visitFloat32(LFloat32 *ins); virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitAbsD(LAbsD *ins); + virtual bool visitAbsF(LAbsF *ins); virtual bool visitSqrtD(LSqrtD *ins); virtual bool visitSqrtF(LSqrtF *ins); virtual bool visitPowHalfD(LPowHalfD *ins); diff --git a/mfbt/FloatingPoint.h b/mfbt/FloatingPoint.h index b80ce266f1a..ad0250efdc6 100644 --- a/mfbt/FloatingPoint.h +++ b/mfbt/FloatingPoint.h @@ -241,6 +241,34 @@ DoublesAreIdentical(double d1, double d2) return BitwiseCast(d1) == BitwiseCast(d2); } +/** Determines whether a float is NaN. */ +static MOZ_ALWAYS_INLINE bool +IsFloatNaN(float f) +{ + /* + * A float is NaN if all exponent bits are 1 and the significand contains at + * least one non-zero bit. + */ + uint32_t bits = BitwiseCast(f); + return (bits & FloatExponentBits) == FloatExponentBits && + (bits & FloatSignificandBits) != 0; +} + +/** Constructs a NaN value with the specified sign bit and significand bits. */ +static MOZ_ALWAYS_INLINE float +SpecificFloatNaN(int signbit, uint32_t significand) +{ + MOZ_ASSERT(signbit == 0 || signbit == 1); + MOZ_ASSERT((significand & ~FloatSignificandBits) == 0); + MOZ_ASSERT(significand & FloatSignificandBits); + + float f = BitwiseCast((signbit ? FloatSignBit : 0) | + FloatExponentBits | + significand); + MOZ_ASSERT(IsFloatNaN(f)); + return f; +} + } /* namespace mozilla */ #endif /* mozilla_FloatingPoint_h */ From e04df088110e885549aaafb3dd29eb75cbc81916 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:53:52 +0200 Subject: [PATCH 24/75] Bug 913282: More Float32 Operators: Not; p=dougc,bbouvier, r=jonco,nbp dougc for the ARM parts, bbouvier for the rest --- js/src/jit/LIR-Common.h | 11 ++++++ js/src/jit/LOpcodes.h | 1 + js/src/jit/Lowering.cpp | 2 + js/src/jit/MIR.cpp | 8 ++++ js/src/jit/MIR.h | 8 ++++ js/src/jit/arm/CodeGenerator-arm.cpp | 38 +++++++++++++++++++ js/src/jit/arm/CodeGenerator-arm.h | 1 + .../jit/shared/CodeGenerator-x86-shared.cpp | 11 ++++++ js/src/jit/shared/CodeGenerator-x86-shared.h | 1 + 9 files changed, 81 insertions(+) diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 02c33a0e3db..17adb2ee916 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -2020,6 +2020,17 @@ class LNotD : public LInstructionHelper<1, 1, 0> } }; +// Not operation on a float32. +class LNotF : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(NotF) + + LNotF(const LAllocation &input) { + setOperand(0, input); + } +}; + // Boolean complement operation on an object. class LNotO : public LInstructionHelper<1, 1, 0> { diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index c4b4bc423e4..c8f898f76ec 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -112,6 +112,7 @@ _(MathFunctionF) \ _(NotI) \ _(NotD) \ + _(NotF) \ _(NotO) \ _(NotV) \ _(AddI) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 4183d8d13ab..dc63240c3fe 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2259,6 +2259,8 @@ LIRGenerator::visitNot(MNot *ins) } case MIRType_Double: return define(new LNotD(useRegister(op)), ins); + case MIRType_Float32: + return define(new LNotF(useRegister(op)), ins); case MIRType_Undefined: case MIRType_Null: return define(new LInteger(1), ins); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 2456d25b7a3..62c76e2dd67 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2462,6 +2462,14 @@ MNot::foldsTo(bool useValueNumbers) return this; } +void +MNot::trySpecializeFloat32() +{ + MDefinition *in = input(); + if (!in->canProduceFloat32() && in->type() == MIRType_Float32) + ConvertDefinitionToDouble<0>(in, this); +} + void MBeta::printOpcode(FILE *fp) const { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index cb26bd88469..6b0f47e563f 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -5131,6 +5131,14 @@ class MNot TypePolicy *typePolicy() { return this; } + + void trySpecializeFloat32(); + bool isFloat32Commutative() const { return true; } +#ifdef DEBUG + bool isConsistentFloat32Use() const { + return true; + } +#endif }; // Bailout if index + minimum < 0 or index + maximum >= length. The length used diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 115cc5c9a90..4447a8f2a67 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1609,6 +1609,44 @@ CodeGeneratorARM::visitNotD(LNotD *ins) // Do the compare masm.ma_vcmpz(opd); + // TODO There are three variations here to compare performance-wise. + bool nocond = true; + if (nocond) { + // Load the value into the dest register + masm.as_vmrs(dest); + masm.ma_lsr(Imm32(28), dest, dest); + masm.ma_alu(dest, lsr(dest, 2), dest, op_orr); // 28 + 2 = 30 + masm.ma_and(Imm32(1), dest); + } else { + masm.as_vmrs(pc); + masm.ma_mov(Imm32(0), dest); + masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); + masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); +#if 0 + masm.as_vmrs(ToRegister(dest)); + // Mask out just the two bits we care about. If neither bit is set, + // the dest is already zero + masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond); + // If it is non-zero, then force it to be 1. + masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual); +#endif + } + return true; +} + +bool +CodeGeneratorARM::visitNotF(LNotF *ins) +{ + // Since this operation is not, we want to set a bit if + // the double is falsey, which means 0.0, -0.0 or NaN. + // when comparing with 0, an input of 0 will set the Z bit (30) + // and NaN will set the V bit (28) of the APSR. + FloatRegister opd = ToFloatRegister(ins->input()); + Register dest = ToRegister(ins->output()); + + // Do the compare + masm.ma_vcmpz_f32(opd); + // TODO There are three variations here to compare performance-wise. bool nocond = true; if (nocond) { // Load the value into the dest register diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 45a41acaa3e..dc3c8971a0c 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -104,6 +104,7 @@ class CodeGeneratorARM : public CodeGeneratorShared virtual bool visitUInt32ToDouble(LUInt32ToDouble *lir); virtual bool visitNotI(LNotI *ins); virtual bool visitNotD(LNotD *ins); + virtual bool visitNotF(LNotF *ins); virtual bool visitMathD(LMathD *math); virtual bool visitMathF(LMathF *math); diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 5262b789be7..8a87225b44b 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -232,6 +232,17 @@ CodeGeneratorX86Shared::visitNotD(LNotD *ins) return true; } +bool +CodeGeneratorX86Shared::visitNotF(LNotF *ins) +{ + FloatRegister opd = ToFloatRegister(ins->input()); + + masm.xorps(ScratchFloatReg, ScratchFloatReg); + masm.compareFloat(Assembler::DoubleEqualOrUnordered, opd, ScratchFloatReg); + masm.emitSet(Assembler::Equal, ToRegister(ins->output()), Assembler::NaN_IsTrue); + return true; +} + bool CodeGeneratorX86Shared::visitCompareDAndBranch(LCompareDAndBranch *comp) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index 9ab47503c1c..899652d2d74 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -110,6 +110,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab); virtual bool visitNotI(LNotI *comp); virtual bool visitNotD(LNotD *comp); + virtual bool visitNotF(LNotF *comp); virtual bool visitMathD(LMathD *math); virtual bool visitMathF(LMathF *math); virtual bool visitFloor(LFloor *lir); From 963afd76891bb2e2648831d39444686499d94617 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 21 Oct 2013 08:58:12 -0400 Subject: [PATCH 25/75] Bug 928916 - use services::GetObserverService more in dom/; r=smaug --- dom/base/nsGlobalWindow.cpp | 3 ++- dom/ipc/TabChild.cpp | 5 +++-- dom/system/gonk/SystemWorkerManager.cpp | 7 +++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1d84de25c5b..cb3bf59cdbb 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -205,6 +205,7 @@ #include "nsRefreshDriver.h" +#include "mozilla/Services.h" #include "mozilla/Telemetry.h" #include "nsLocation.h" #include "nsHTMLDocument.h" @@ -8394,7 +8395,7 @@ void nsGlobalWindow::MaybeUpdateTouchState() if (mMayHaveTouchEventListener) { nsCOMPtr observerService = - do_GetService(NS_OBSERVERSERVICE_CONTRACTID); + services::GetObserverService(); if (observerService) { observerService->NotifyObservers(static_cast(this), diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 64e6475dd94..9e246ec9b49 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -24,6 +24,7 @@ #include "mozilla/layers/ShadowLayers.h" #include "mozilla/layout/RenderFrameChild.h" #include "mozilla/MouseEvents.h" +#include "mozilla/Services.h" #include "mozilla/StaticPtr.h" #include "mozilla/TextEvents.h" #include "mozilla/TouchEvents.h" @@ -2103,7 +2104,7 @@ TabChild::RecvDestroy() } nsCOMPtr observerService = - do_GetService(NS_OBSERVERSERVICE_CONTRACTID); + mozilla::services::GetObserverService(); observerService->RemoveObserver(this, CANCEL_DEFAULT_PAN_ZOOM); observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT); @@ -2240,7 +2241,7 @@ TabChild::InitRenderingState() mRemoteFrame = remoteFrame; nsCOMPtr observerService = - do_GetService(NS_OBSERVERSERVICE_CONTRACTID); + mozilla::services::GetObserverService(); if (observerService) { observerService->AddObserver(this, diff --git a/dom/system/gonk/SystemWorkerManager.cpp b/dom/system/gonk/SystemWorkerManager.cpp index 01d9635cc76..a3dd23cef4b 100644 --- a/dom/system/gonk/SystemWorkerManager.cpp +++ b/dom/system/gonk/SystemWorkerManager.cpp @@ -38,6 +38,7 @@ #include "nsThreadUtils.h" #include "nsRadioInterfaceLayer.h" #include "WifiWorker.h" +#include "mozilla/Services.h" USING_WORKERS_NAMESPACE @@ -353,8 +354,7 @@ SystemWorkerManager::Init() do_GetService(NS_AUDIOMANAGER_CONTRACTID); #endif - nsCOMPtr obs = - do_GetService(NS_OBSERVERSERVICE_CONTRACTID); + nsCOMPtr obs = mozilla::services::GetObserverService(); if (!obs) { NS_WARNING("Failed to get observer service!"); return NS_ERROR_FAILURE; @@ -399,8 +399,7 @@ SystemWorkerManager::Shutdown() } mWifiWorker = nullptr; - nsCOMPtr obs = - do_GetService(NS_OBSERVERSERVICE_CONTRACTID); + nsCOMPtr obs = mozilla::services::GetObserverService(); if (obs) { obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC); } From 733919732e40f2542382d499a8b079418b13d1db Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:55:35 +0200 Subject: [PATCH 26/75] Bug 913282: IsFloat32Representable function in mfbt; r=Waldo --HG-- extra : rebase_source : 0d4d6f02b880c37d29e3e41e9d105365d9f941b0 --- js/src/jit/MIR.cpp | 10 +--------- mfbt/FloatingPoint.cpp | 20 ++++++++++++++++++++ mfbt/FloatingPoint.h | 13 +++++++++++++ mfbt/sources.mk | 1 + 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 mfbt/FloatingPoint.cpp diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 62c76e2dd67..0c1d1bc3bfb 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -27,6 +27,7 @@ using namespace js; using namespace js::jit; using mozilla::DoublesAreIdentical; +using mozilla::IsFloat32Representable; using mozilla::Maybe; void @@ -493,15 +494,6 @@ MConstant::printOpcode(FILE *fp) const } } -// Needs a static function to avoid overzealous optimizations by certain compilers (MSVC). -static bool -IsFloat32Representable(double x) -{ - float asFloat = static_cast(x); - double floatAsDouble = static_cast(asFloat); - return floatAsDouble == x; -} - bool MConstant::canProduceFloat32() const { diff --git a/mfbt/FloatingPoint.cpp b/mfbt/FloatingPoint.cpp new file mode 100644 index 00000000000..99009b65a87 --- /dev/null +++ b/mfbt/FloatingPoint.cpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Implementations of FloatingPoint functions */ + +#include "mozilla/FloatingPoint.h" + +namespace mozilla { + +bool +IsFloat32Representable(double x) +{ + float asFloat = static_cast(x); + double floatAsDouble = static_cast(asFloat); + return floatAsDouble == x; +} + +} /* namespace mozilla */ diff --git a/mfbt/FloatingPoint.h b/mfbt/FloatingPoint.h index ad0250efdc6..eff26b4bb80 100644 --- a/mfbt/FloatingPoint.h +++ b/mfbt/FloatingPoint.h @@ -12,6 +12,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Casting.h" +#include "mozilla/Types.h" #include @@ -269,6 +270,18 @@ SpecificFloatNaN(int signbit, uint32_t significand) return f; } +/** + * Returns true if the given value can be losslessly represented as an IEEE-754 + * single format number, false otherwise. All NaN values are considered + * representable (notwithstanding that the exact bit pattern of a double format + * NaN value can't be exactly represented in single format). + * + * This function isn't inlined to avoid buggy optimizations by MSVC. + */ +MOZ_WARN_UNUSED_RESULT +extern MFBT_API bool +IsFloat32Representable(double x); + } /* namespace mozilla */ #endif /* mozilla_FloatingPoint_h */ diff --git a/mfbt/sources.mk b/mfbt/sources.mk index 78088d9b8a3..9323d65b0c3 100644 --- a/mfbt/sources.mk +++ b/mfbt/sources.mk @@ -9,6 +9,7 @@ endif CPPSRCS += \ Compression.cpp \ + FloatingPoint.cpp \ HashFunctions.cpp \ Poison.cpp \ SHA1.cpp \ From dc7dd64baba550184758d432bc18d73dbfb8bf6d Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 18 Jul 2013 16:27:14 -0700 Subject: [PATCH 27/75] Bug 913282: More Float32 operators: UnsignedToFloat32; p=dougc,bbouvier, r=jonco,h4writer dougc for the ARM parts, bbouvier for the rest --- js/src/assembler/assembler/X86Assembler.h | 7 ++++++ js/src/jit/MIR.cpp | 23 ++++++++++++++++++ js/src/jit/MIR.h | 29 +++++++++++++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jit/ParallelSafetyAnalysis.cpp | 1 + js/src/jit/arm/CodeGenerator-arm.cpp | 9 ++++++- js/src/jit/arm/CodeGenerator-arm.h | 3 ++- js/src/jit/arm/LIR-arm.h | 17 ++++++++++--- js/src/jit/arm/LOpcodes-arm.h | 3 ++- js/src/jit/arm/Lowering-arm.cpp | 10 +++++++- js/src/jit/arm/Lowering-arm.h | 1 + js/src/jit/arm/MacroAssembler-arm.cpp | 12 ++++++++-- js/src/jit/arm/MacroAssembler-arm.h | 1 + js/src/jit/x64/Assembler-x64.h | 3 +++ js/src/jit/x64/CodeGenerator-x64.cpp | 7 ++++++ js/src/jit/x64/CodeGenerator-x64.h | 1 + js/src/jit/x64/LIR-x64.h | 11 +++++++++ js/src/jit/x64/LOpcodes-x64.h | 1 + js/src/jit/x64/Lowering-x64.cpp | 8 +++++++ js/src/jit/x64/Lowering-x64.h | 1 + js/src/jit/x64/MacroAssembler-x64.h | 4 ++++ js/src/jit/x86/CodeGenerator-x86.cpp | 15 ++++++++++++ js/src/jit/x86/CodeGenerator-x86.h | 1 + js/src/jit/x86/LIR-x86.h | 15 ++++++++++++ js/src/jit/x86/LOpcodes-x86.h | 1 + js/src/jit/x86/Lowering-x86.cpp | 8 +++++++ js/src/jit/x86/Lowering-x86.h | 1 + 27 files changed, 185 insertions(+), 9 deletions(-) diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index 3e65c196184..552b5c94754 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -2352,6 +2352,13 @@ public: m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); } + void cvtsq2ss_rr(RegisterID src, XMMRegisterID dst) + { + spew("cvtsq2ss %s, %s", + nameIReg(src), nameFPReg(dst)); + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); + } #endif void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst) diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 0c1d1bc3bfb..3887b7040f6 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -401,6 +401,14 @@ MConstant::New(const Value &v) return new MConstant(v); } +MConstant * +MConstant::NewAsmJS(const Value &v, MIRType type) +{ + MConstant *constant = new MConstant(v); + constant->setResultType(type); + return constant; +} + types::TemporaryTypeSet * jit::MakeSingletonTypeSet(JSObject *obj) { @@ -2715,6 +2723,21 @@ MAsmJSUnsignedToDouble::foldsTo(bool useValueNumbers) return this; } +MDefinition * +MAsmJSUnsignedToFloat32::foldsTo(bool useValueNumbers) +{ + if (input()->isConstant()) { + const Value &v = input()->toConstant()->value(); + if (v.isInt32()) { + double dval = double(uint32_t(v.toInt32())); + if (IsFloat32Representable(dval)) + return MConstant::NewAsmJS(JS::Float32Value(float(dval)), MIRType_Float32); + } + } + + return this; +} + MAsmJSCall * MAsmJSCall::New(Callee callee, const Args &args, MIRType resultType, size_t spIncrement) { diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 6b0f47e563f..be94d692c76 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -961,6 +961,7 @@ class MConstant : public MNullaryInstruction public: INSTRUCTION_HEADER(Constant) static MConstant *New(const Value &v); + static MConstant *NewAsmJS(const Value &v, MIRType type); const js::Value &value() const { return value_; @@ -2889,6 +2890,34 @@ class MAsmJSUnsignedToDouble } }; +// Converts a uint32 to a float32 (coming from asm.js). +class MAsmJSUnsignedToFloat32 + : public MUnaryInstruction +{ + MAsmJSUnsignedToFloat32(MDefinition *def) + : MUnaryInstruction(def) + { + setResultType(MIRType_Float32); + setMovable(); + } + + public: + INSTRUCTION_HEADER(AsmJSUnsignedToFloat32); + static MAsmJSUnsignedToFloat32 *NewAsmJS(MDefinition *def) { + return new MAsmJSUnsignedToFloat32(def); + } + + MDefinition *foldsTo(bool useValueNumbers); + bool congruentTo(MDefinition *ins) const { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const { + return AliasSet::None(); + } + + bool canProduceFloat32() const { return true; } +}; + // Converts a primitive (either typed or untyped) to an int32. If the input is // not primitive at runtime, a bailout occurs. If the input cannot be converted // to an int32 without loss (i.e. "5.5" or undefined) then a bailout occurs. diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 3fd8e1a9000..a8d759e6e52 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -184,6 +184,7 @@ namespace jit { _(AsmJSUDiv) \ _(AsmJSUMod) \ _(AsmJSUnsignedToDouble) \ + _(AsmJSUnsignedToFloat32) \ _(AsmJSLoadHeap) \ _(AsmJSStoreHeap) \ _(AsmJSLoadGlobalVar) \ diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp index fb4b2a5ce67..dee2f004249 100644 --- a/js/src/jit/ParallelSafetyAnalysis.cpp +++ b/js/src/jit/ParallelSafetyAnalysis.cpp @@ -287,6 +287,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor SAFE_OP(HaveSameClass) UNSAFE_OP(EffectiveAddress) UNSAFE_OP(AsmJSUnsignedToDouble) + UNSAFE_OP(AsmJSUnsignedToFloat32) UNSAFE_OP(AsmJSNeg) UNSAFE_OP(AsmJSUDiv) UNSAFE_OP(AsmJSUMod) diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index 4447a8f2a67..2e8b79fa27e 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -1582,12 +1582,19 @@ CodeGeneratorARM::visitBitAndAndBranch(LBitAndAndBranch *baab) } bool -CodeGeneratorARM::visitUInt32ToDouble(LUInt32ToDouble *lir) +CodeGeneratorARM::visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir) { masm.convertUInt32ToDouble(ToRegister(lir->input()), ToFloatRegister(lir->output())); return true; } +bool +CodeGeneratorARM::visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir) +{ + masm.convertUInt32ToFloat32(ToRegister(lir->input()), ToFloatRegister(lir->output())); + return true; +} + bool CodeGeneratorARM::visitNotI(LNotI *ins) { diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index dc3c8971a0c..b508b058689 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -101,7 +101,8 @@ class CodeGeneratorARM : public CodeGeneratorShared virtual bool visitCompareV(LCompareV *lir); virtual bool visitCompareVAndBranch(LCompareVAndBranch *lir); virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab); - virtual bool visitUInt32ToDouble(LUInt32ToDouble *lir); + virtual bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); + virtual bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); virtual bool visitNotI(LNotI *ins); virtual bool visitNotD(LNotD *ins); virtual bool visitNotF(LNotF *ins); diff --git a/js/src/jit/arm/LIR-arm.h b/js/src/jit/arm/LIR-arm.h index 2a0279b39ff..b1024129f40 100644 --- a/js/src/jit/arm/LIR-arm.h +++ b/js/src/jit/arm/LIR-arm.h @@ -95,12 +95,23 @@ class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0> }; // Convert a 32-bit unsigned integer to a double. -class LUInt32ToDouble : public LInstructionHelper<1, 1, 0> +class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 0> { public: - LIR_HEADER(UInt32ToDouble) + LIR_HEADER(AsmJSUInt32ToDouble) - LUInt32ToDouble(const LAllocation &input) { + LAsmJSUInt32ToDouble(const LAllocation &input) { + setOperand(0, input); + } +}; + +// Convert a 32-bit unsigned integer to a float32. +class LAsmJSUInt32ToFloat32 : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(AsmJSUInt32ToFloat32) + + LAsmJSUInt32ToFloat32(const LAllocation &input) { setOperand(0, input); } }; diff --git a/js/src/jit/arm/LOpcodes-arm.h b/js/src/jit/arm/LOpcodes-arm.h index de4654d31e0..d412640393e 100644 --- a/js/src/jit/arm/LOpcodes-arm.h +++ b/js/src/jit/arm/LOpcodes-arm.h @@ -20,7 +20,8 @@ _(ModPowTwoI) \ _(ModMaskI) \ _(PowHalfD) \ - _(UInt32ToDouble) \ + _(AsmJSUInt32ToDouble) \ + _(AsmJSUInt32ToFloat32) \ _(UDiv) \ _(UMod) \ _(SoftUDivOrMod) \ diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp index 8dc985e42f4..9bf9092a0f3 100644 --- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -467,7 +467,15 @@ bool LIRGeneratorARM::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins) { JS_ASSERT(ins->input()->type() == MIRType_Int32); - LUInt32ToDouble *lir = new LUInt32ToDouble(useRegisterAtStart(ins->input())); + LAsmJSUInt32ToDouble *lir = new LAsmJSUInt32ToDouble(useRegisterAtStart(ins->input())); + return define(lir, ins); +} + +bool +LIRGeneratorARM::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins) +{ + JS_ASSERT(ins->input()->type() == MIRType_Int32); + LAsmJSUInt32ToFloat32 *lir = new LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input())); return define(lir, ins); } diff --git a/js/src/jit/arm/Lowering-arm.h b/js/src/jit/arm/Lowering-arm.h index 21fd2ea6719..d408ed69d9b 100644 --- a/js/src/jit/arm/Lowering-arm.h +++ b/js/src/jit/arm/Lowering-arm.h @@ -85,6 +85,7 @@ class LIRGeneratorARM : public LIRGeneratorShared bool visitGuardShape(MGuardShape *ins); bool visitGuardObjectType(MGuardObjectType *ins); bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins); + bool visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins); bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins); bool visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index effde0f826f..064c855de3f 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -61,11 +61,19 @@ MacroAssemblerARM::convertUInt32ToDouble(const Register &src, const FloatRegiste { // direct conversions aren't possible. VFPRegister dest = VFPRegister(dest_); - as_vxfer(src, InvalidReg, dest.uintOverlay(), - CoreToFloat); + as_vxfer(src, InvalidReg, dest.uintOverlay(), CoreToFloat); as_vcvt(dest, dest.uintOverlay()); } +void +MacroAssemblerARM::convertUInt32ToFloat32(const Register &src, const FloatRegister &dest_) +{ + // direct conversions aren't possible. + VFPRegister dest = VFPRegister(dest_); + as_vxfer(src, InvalidReg, dest.uintOverlay(), CoreToFloat); + as_vcvt(VFPRegister(dest).singleOverlay(), dest.uintOverlay()); +} + void MacroAssemblerARM::convertDoubleToFloat(const FloatRegister &src, const FloatRegister &dest) { as_vcvt(VFPRegister(dest).singleOverlay(), VFPRegister(src)); diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 4639d8682b8..a46eeeda97c 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -48,6 +48,7 @@ class MacroAssemblerARM : public Assembler void convertBoolToInt32(Register source, Register dest); void convertInt32ToDouble(const Register &src, const FloatRegister &dest); void convertInt32ToDouble(const Address &src, FloatRegister dest); + void convertUInt32ToFloat32(const Register &src, const FloatRegister &dest); void convertUInt32ToDouble(const Register &src, const FloatRegister &dest); void convertDoubleToFloat(const FloatRegister &src, const FloatRegister &dest); void branchTruncateDouble(const FloatRegister &src, const Register &dest, Label *fail); diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index a7d50a19fc4..39c514c9c2b 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -671,6 +671,9 @@ class Assembler : public AssemblerX86Shared void cvtsq2sd(const Register &src, const FloatRegister &dest) { masm.cvtsq2sd_rr(src.code(), dest.code()); } + void cvtsq2ss(const Register &src, const FloatRegister &dest) { + masm.cvtsq2ss_rr(src.code(), dest.code()); + } }; static inline void diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp index c9c68927448..552aff9e337 100644 --- a/js/src/jit/x64/CodeGenerator-x64.cpp +++ b/js/src/jit/x64/CodeGenerator-x64.cpp @@ -382,6 +382,13 @@ CodeGeneratorX64::visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir) return true; } +bool +CodeGeneratorX64::visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir) +{ + masm.convertUInt32ToFloat32(ToRegister(lir->input()), ToFloatRegister(lir->output())); + return true; +} + bool CodeGeneratorX64::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins) { diff --git a/js/src/jit/x64/CodeGenerator-x64.h b/js/src/jit/x64/CodeGenerator-x64.h index a00b639f229..2f33b64623b 100644 --- a/js/src/jit/x64/CodeGenerator-x64.h +++ b/js/src/jit/x64/CodeGenerator-x64.h @@ -60,6 +60,7 @@ class CodeGeneratorX64 : public CodeGeneratorX86Shared bool visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins); bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins); bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); + bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); void postAsmJSCall(LAsmJSCall *lir) {} }; diff --git a/js/src/jit/x64/LIR-x64.h b/js/src/jit/x64/LIR-x64.h index bf3f7f5ce67..29d630708f3 100644 --- a/js/src/jit/x64/LIR-x64.h +++ b/js/src/jit/x64/LIR-x64.h @@ -87,6 +87,17 @@ class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 0> } }; +// Convert a 32-bit unsigned integer to a float32. +class LAsmJSUInt32ToFloat32 : public LInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(AsmJSUInt32ToFloat32) + + LAsmJSUInt32ToFloat32(const LAllocation &input) { + setOperand(0, input); + } +}; + class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 1> { public: diff --git a/js/src/jit/x64/LOpcodes-x64.h b/js/src/jit/x64/LOpcodes-x64.h index 2c2a219c4c6..d2b09f1c4b7 100644 --- a/js/src/jit/x64/LOpcodes-x64.h +++ b/js/src/jit/x64/LOpcodes-x64.h @@ -18,6 +18,7 @@ _(ModPowTwoI) \ _(PowHalfD) \ _(AsmJSUInt32ToDouble) \ + _(AsmJSUInt32ToFloat32) \ _(AsmJSLoadFuncPtr) \ _(UDivOrMod) diff --git a/js/src/jit/x64/Lowering-x64.cpp b/js/src/jit/x64/Lowering-x64.cpp index c0a1cca15be..6ce3e45bcaf 100644 --- a/js/src/jit/x64/Lowering-x64.cpp +++ b/js/src/jit/x64/Lowering-x64.cpp @@ -118,6 +118,14 @@ LIRGeneratorX64::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins) return define(lir, ins); } +bool +LIRGeneratorX64::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins) +{ + JS_ASSERT(ins->input()->type() == MIRType_Int32); + LAsmJSUInt32ToFloat32 *lir = new LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input())); + return define(lir, ins); +} + bool LIRGeneratorX64::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins) { diff --git a/js/src/jit/x64/Lowering-x64.h b/js/src/jit/x64/Lowering-x64.h index 27ed77c33be..8294ceb3d75 100644 --- a/js/src/jit/x64/Lowering-x64.h +++ b/js/src/jit/x64/Lowering-x64.h @@ -46,6 +46,7 @@ class LIRGeneratorX64 : public LIRGeneratorX86Shared bool visitUnbox(MUnbox *unbox); bool visitReturn(MReturn *ret); bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins); + bool visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins); bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins); bool visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins); diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 15b8cb243bb..4e6794f48a1 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -1108,6 +1108,10 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared cvtsq2sd(src, dest); } + void convertUInt32ToFloat32(const Register &src, const FloatRegister &dest) { + cvtsq2ss(src, dest); + } + void inc64(AbsoluteAddress dest) { if (JSC::X86Assembler::isAddressImmediate(dest.addr)) { addPtr(Imm32(1), Operand(dest)); diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index 53960eac5ee..50b9d900158 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -401,6 +401,21 @@ CodeGeneratorX86::visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir) return true; } +bool +CodeGeneratorX86::visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir) +{ + Register input = ToRegister(lir->input()); + Register temp = ToRegister(lir->temp()); + FloatRegister output = ToFloatRegister(lir->output()); + + if (input != temp) + masm.mov(input, temp); + + // Beware: convertUInt32ToFloat32 clobbers input. + masm.convertUInt32ToFloat32(temp, output); + return true; +} + // Load a NaN or zero into a register for an out of bounds AsmJS or static // typed array load. class jit::OutOfLineLoadTypedArrayOutOfBounds : public OutOfLineCodeBase diff --git a/js/src/jit/x86/CodeGenerator-x86.h b/js/src/jit/x86/CodeGenerator-x86.h index a422479a19a..b17a3bc6637 100644 --- a/js/src/jit/x86/CodeGenerator-x86.h +++ b/js/src/jit/x86/CodeGenerator-x86.h @@ -64,6 +64,7 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared bool visitCompareV(LCompareV *lir); bool visitCompareVAndBranch(LCompareVAndBranch *lir); bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); + bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); bool visitTruncateDToInt32(LTruncateDToInt32 *ins); bool visitTruncateFToInt32(LTruncateFToInt32 *ins); bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); diff --git a/js/src/jit/x86/LIR-x86.h b/js/src/jit/x86/LIR-x86.h index 6ff8a5c7700..6cf6bf7ad9e 100644 --- a/js/src/jit/x86/LIR-x86.h +++ b/js/src/jit/x86/LIR-x86.h @@ -110,6 +110,21 @@ class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 1> } }; +// Convert a 32-bit unsigned integer to a float32. +class LAsmJSUInt32ToFloat32: public LInstructionHelper<1, 1, 1> +{ + public: + LIR_HEADER(AsmJSUInt32ToFloat32) + + LAsmJSUInt32ToFloat32(const LAllocation &input, const LDefinition &temp) { + setOperand(0, input); + setTemp(0, temp); + } + const LDefinition *temp() { + return getTemp(0); + } +}; + class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 0> { public: diff --git a/js/src/jit/x86/LOpcodes-x86.h b/js/src/jit/x86/LOpcodes-x86.h index ec39c45e958..bf59eca21f1 100644 --- a/js/src/jit/x86/LOpcodes-x86.h +++ b/js/src/jit/x86/LOpcodes-x86.h @@ -19,6 +19,7 @@ _(ModPowTwoI) \ _(PowHalfD) \ _(AsmJSUInt32ToDouble) \ + _(AsmJSUInt32ToFloat32) \ _(AsmJSLoadFuncPtr) \ _(UDivOrMod) diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp index 1db75963f01..ff138f5c40d 100644 --- a/js/src/jit/x86/Lowering-x86.cpp +++ b/js/src/jit/x86/Lowering-x86.cpp @@ -204,6 +204,14 @@ LIRGeneratorX86::visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins) return define(lir, ins); } +bool +LIRGeneratorX86::visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins) +{ + JS_ASSERT(ins->input()->type() == MIRType_Int32); + LAsmJSUInt32ToFloat32 *lir = new LAsmJSUInt32ToFloat32(useRegisterAtStart(ins->input()), temp()); + return define(lir, ins); +} + bool LIRGeneratorX86::visitAsmJSLoadHeap(MAsmJSLoadHeap *ins) { diff --git a/js/src/jit/x86/Lowering-x86.h b/js/src/jit/x86/Lowering-x86.h index 674b43e1491..1062e28cab2 100644 --- a/js/src/jit/x86/Lowering-x86.h +++ b/js/src/jit/x86/Lowering-x86.h @@ -48,6 +48,7 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared bool visitUnbox(MUnbox *unbox); bool visitReturn(MReturn *ret); bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins); + bool visitAsmJSUnsignedToFloat32(MAsmJSUnsignedToFloat32 *ins); bool visitAsmJSLoadHeap(MAsmJSLoadHeap *ins); bool visitAsmJSStoreHeap(MAsmJSStoreHeap *ins); bool visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins); From c0769ccdbdfa22e5cbbbb3331aa48987dbf40e21 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:58:21 +0200 Subject: [PATCH 28/75] Bug 913282: Tests --- .../tests/ion/testFloat32-correctness.js | 171 ++++++++++++++++++ js/src/jit-test/tests/ion/testFloat32.js | 30 ++- 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/ion/testFloat32-correctness.js diff --git a/js/src/jit-test/tests/ion/testFloat32-correctness.js b/js/src/jit-test/tests/ion/testFloat32-correctness.js new file mode 100644 index 00000000000..26234b9b28f --- /dev/null +++ b/js/src/jit-test/tests/ion/testFloat32-correctness.js @@ -0,0 +1,171 @@ +setJitCompilerOption("ion.usecount.trigger", 50); + +var f32 = new Float32Array(10); + +function test(setup, f) { + if (f === undefined) { + f = setup; + setup = function(){}; + } + setup(); + for(var n = 200; n; --n) { + f(); + } +} + +// Basic arithmetic +function setupBasicArith() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0; + f32[3] = 0; + f32[4] = 1.337; + f32[5] = 42; + f32[6] = Infinity; + f32[7] = NaN; +} +function basicArith() { + for (var i = 0; i < 7; ++i) { + var opf = Math.fround(f32[i] + f32[i+1]); + var opd = (1 / (1 / f32[i])) + f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] - f32[i+1]); + opd = (1 / (1 / f32[i])) - f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] * f32[i+1]); + opd = (1 / (1 / f32[i])) * f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] / f32[i+1]); + opd = (1 / (1 / f32[i])) / f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + } +} +test(setupBasicArith, basicArith); + +// MAbs +function setupAbs() { + f32[0] = -0; + f32[1] = 0; + f32[2] = -3.14159; + f32[3] = 3.14159; + f32[4] = -Infinity; + f32[5] = Infinity; + f32[6] = NaN; +} +function abs() { + for(var i = 0; i < 7; ++i) { + assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) ); + } +} +test(setupAbs, abs); + +// MSqrt +function setupSqrt() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 4; + f32[3] = -1; + f32[4] = Infinity; + f32[5] = NaN; + f32[6] = 13.37; +} +function sqrt() { + for(var i = 0; i < 7; ++i) { + var sqrtf = Math.fround(Math.sqrt(f32[i])); + var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops + assertEq( sqrtf, Math.fround(sqrtd) ); + } +} +test(setupSqrt, sqrt); + +// MTruncateToInt32 +// The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul +function setupTruncateToInt32() { + f32[0] = -1; + f32[1] = 4; + f32[2] = 5.13; +} +function truncateToInt32() { + assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) ); + assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) ); +} +test(setupTruncateToInt32, truncateToInt32); + +// MCompare +function comp() { + for(var i = 0; i < 9; ++i) { + assertEq( f32[i] < f32[i+1], true ); + } +} +function setupComp() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0.01; + f32[3] = 0; + f32[4] = 0.01; + f32[5] = 1; + f32[6] = 10; + f32[7] = 13.37; + f32[8] = 42; + f32[9] = Infinity; +} +test(setupComp, comp); + +// MNot +function setupNot() { + f32[0] = -0; + f32[1] = 0; + f32[2] = 1; + f32[3] = NaN; + f32[4] = Infinity; + f32[5] = 42; + f32[5] = -23; +} +function not() { + assertEq( !f32[0], true ); + assertEq( !f32[1], true ); + assertEq( !f32[2], false ); + assertEq( !f32[3], true ); + assertEq( !f32[4], false ); + assertEq( !f32[5], false ); + assertEq( !f32[6], false ); +} +test(setupNot, not); + +// MToInt32 +var str = "can haz cheezburger? okthxbye;"; +function setupToInt32() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 2; + f32[3] = 4; + f32[4] = 5; +} +function testToInt32() { + assertEq(str[f32[0]], 'c'); + assertEq(str[f32[1]], 'a'); + assertEq(str[f32[2]], 'n'); + assertEq(str[f32[3]], 'h'); + assertEq(str[f32[4]], 'a'); +} +test(setupToInt32, testToInt32); + +function setupBailoutToInt32() { + f32[0] = .5; +} +function testBailoutToInt32() { + assertEq(typeof str[f32[0]], 'undefined'); +} +test(setupBailoutToInt32, testBailoutToInt32); + diff --git a/js/src/jit-test/tests/ion/testFloat32.js b/js/src/jit-test/tests/ion/testFloat32.js index 709ef404351..3b8c7b612f4 100644 --- a/js/src/jit-test/tests/ion/testFloat32.js +++ b/js/src/jit-test/tests/ion/testFloat32.js @@ -55,7 +55,7 @@ setJitCompilerOption("ion.usecount.trigger", 50); function test(f) { - f32[0] = 1; + f32[0] = .5; for(var n = 110; n; n--) f(); } @@ -136,6 +136,34 @@ function refuseAddFunctionCall() { } test(refuseAddFunctionCall); +function acceptSqrt() { + var res = Math.sqrt(f32[0]); + assertFloat32(res, true); + f32[0] = res; +} +test(acceptSqrt); + +function refuseSqrt() { + var res = Math.sqrt(f32[0]); + assertFloat32(res, false); + f32[0] = res + 1; +} +test(refuseSqrt); + +function acceptAbs() { + var res = Math.abs(f32[0]); + assertFloat32(res, true); + f32[0] = res; +} +test(acceptAbs); + +function refuseAbs() { + var res = Math.abs(f32[0]); + assertFloat32(res, false); + f64[0] = res + 1; +} +test(refuseAbs); + function acceptTrigo() { var res = Math.cos(f32[0]); f32[0] = res; From 89ea3bb7cba67e898533dafdeb94e320c9099316 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 22 Oct 2013 14:58:29 +0200 Subject: [PATCH 29/75] Bug 918163: Tests --- .../tests/ion/testFloat32-correctness.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/js/src/jit-test/tests/ion/testFloat32-correctness.js b/js/src/jit-test/tests/ion/testFloat32-correctness.js index 26234b9b28f..4db32c0a5a6 100644 --- a/js/src/jit-test/tests/ion/testFloat32-correctness.js +++ b/js/src/jit-test/tests/ion/testFloat32-correctness.js @@ -169,3 +169,61 @@ function testBailoutToInt32() { } test(setupBailoutToInt32, testBailoutToInt32); +// MMath +function assertNear(a, b) { + return ( a != a && b != b ) || + Math.abs(a-b) < 1e-7; +} +function setupTrigo() { + f32[0] = 0; + f32[1] = Math.PI / 2; + f32[2] = Math.PI; + f32[3] = 3 * Math.PI / 2; +} +function trigo() { + // Cos + assertNear(Math.fround(Math.cos(f32[0])), Math.cos(0)); + assertNear(Math.fround(Math.cos(f32[1])), Math.cos(Math.PI / 2)); + assertNear(Math.fround(Math.cos(f32[2])), Math.cos(Math.PI)); + assertNear(Math.fround(Math.cos(f32[3])), Math.cos(3 * Math.PI / 2)); + + // Sin + assertNear(Math.fround(Math.sin(f32[0])), Math.sin(0)); + assertNear(Math.fround(Math.sin(f32[1])), Math.sin(Math.PI / 2)); + assertNear(Math.fround(Math.sin(f32[2])), Math.sin(Math.PI)); + assertNear(Math.fround(Math.sin(f32[3])), Math.sin(3 * Math.PI / 2)); + + // Tan + assertNear(Math.fround(Math.tan(f32[0])), Math.tan(0)); + assertNear(Math.fround(Math.tan(f32[1])), Math.tan(Math.PI / 2)); + assertNear(Math.fround(Math.tan(f32[2])), Math.tan(Math.PI)); + assertNear(Math.fround(Math.tan(f32[3])), Math.tan(3 * Math.PI / 2)); + + // ACos + assertNear(Math.fround(Math.acos(f32[0])), Math.acos(0)); + assertNear(Math.fround(Math.acos(f32[1])), Math.acos(Math.PI / 2)); + assertNear(Math.fround(Math.acos(f32[2])), Math.acos(Math.PI)); + assertNear(Math.fround(Math.acos(f32[3])), Math.acos(3 * Math.PI / 2)); + + // ASin + assertNear(Math.fround(Math.asin(f32[0])), Math.asin(0)); + assertNear(Math.fround(Math.asin(f32[1])), Math.asin(Math.PI / 2)); + assertNear(Math.fround(Math.asin(f32[2])), Math.asin(Math.PI)); + assertNear(Math.fround(Math.asin(f32[3])), Math.asin(3 * Math.PI / 2)); + + // ATan + assertNear(Math.fround(Math.atan(f32[0])), Math.atan(0)); + assertNear(Math.fround(Math.atan(f32[1])), Math.atan(Math.PI / 2)); + assertNear(Math.fround(Math.atan(f32[2])), Math.atan(Math.PI)); + assertNear(Math.fround(Math.atan(f32[3])), Math.atan(3 * Math.PI / 2)); +} +test(setupTrigo, trigo); + +function otherMath() { + for (var i = 0; i < 10; ++i) { + assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i])); + assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i])); + } +}; +test(setupComp, otherMath); + From 0a28148ebf27442eaf2da1ca48e100dbc87c457f Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 22 Oct 2013 09:06:22 -0400 Subject: [PATCH 30/75] Bug 928231 follow-up - Rename the SIZE_OF_TABLES macro --- intl/uconv/ucvja/nsUnicodeToEUCJP.cpp | 10 +++++----- intl/uconv/ucvja/nsUnicodeToISO2022JP.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/intl/uconv/ucvja/nsUnicodeToEUCJP.cpp b/intl/uconv/ucvja/nsUnicodeToEUCJP.cpp index ebdf36e3636..ad7fdaf8513 100644 --- a/intl/uconv/ucvja/nsUnicodeToEUCJP.cpp +++ b/intl/uconv/ucvja/nsUnicodeToEUCJP.cpp @@ -17,20 +17,20 @@ static const int16_t g0201ShiftOutTable[] = { ShiftOutCell(u1BytePrefix8EChar, 2, 0x00, 0xA1, 0x00, 0xDF) }; -#define SIZE_OF_TABLES 3 -static const uScanClassID gScanClassIDs[SIZE_OF_TABLES] = { +#define SIZE_OF_EUCJP_TABLES 3 +static const uScanClassID gScanClassIDs[SIZE_OF_EUCJP_TABLES] = { u2BytesGRCharset, u2BytesGRCharset, uMultibytesCharset }; -static const int16_t *gShiftTables[SIZE_OF_TABLES] = { +static const int16_t *gShiftTables[SIZE_OF_EUCJP_TABLES] = { 0, 0, g0201ShiftOutTable }; -static const uint16_t *gMappingTables[SIZE_OF_TABLES] = { +static const uint16_t *gMappingTables[SIZE_OF_EUCJP_TABLES] = { g_uf0208Mapping, g_uf0208extMapping, g_uf0201Mapping @@ -40,7 +40,7 @@ nsresult nsUnicodeToEUCJPConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { - return CreateMultiTableEncoder(SIZE_OF_TABLES, + return CreateMultiTableEncoder(SIZE_OF_EUCJP_TABLES, (uScanClassID*) gScanClassIDs, (uShiftOutTable**) gShiftTables, (uMappingTable**) gMappingTables, diff --git a/intl/uconv/ucvja/nsUnicodeToISO2022JP.cpp b/intl/uconv/ucvja/nsUnicodeToISO2022JP.cpp index cd91a70873a..0578ff9c6e6 100644 --- a/intl/uconv/ucvja/nsUnicodeToISO2022JP.cpp +++ b/intl/uconv/ucvja/nsUnicodeToISO2022JP.cpp @@ -49,8 +49,8 @@ static const uint16_t g_ufAsciiMapping [] = { 0x0001, 0x0004, 0x0005, 0x0008, 0x0000, 0x0000, 0x007F, 0x0000 }; -#define SIZE_OF_TABLES 5 -static const uint16_t * g_ufMappingTables[SIZE_OF_TABLES] = { +#define SIZE_OF_ISO2022JP_TABLES 5 +static const uint16_t * g_ufMappingTables[SIZE_OF_ISO2022JP_TABLES] = { g_ufAsciiMapping, // ASCII ISOREG 6 g_uf0201GLMapping, // JIS X 0201-1976 ISOREG 14 g_uf0208Mapping, // JIS X 0208-1983 ISOREG 87 @@ -58,7 +58,7 @@ static const uint16_t * g_ufMappingTables[SIZE_OF_TABLES] = { g_uf0208Mapping, // JIS X 0208-1978 ISOREG 42 }; -static const uScanClassID g_ufScanClassIDs[SIZE_OF_TABLES] = { +static const uScanClassID g_ufScanClassIDs[SIZE_OF_ISO2022JP_TABLES] = { u1ByteCharset, // ASCII ISOREG 6 u1ByteCharset, // JIS X 0201-1976 ISOREG 14 u2BytesCharset, // JIS X 0208-1983 ISOREG 87 @@ -211,7 +211,7 @@ NS_IMETHODIMP nsUnicodeToISO2022JP::ConvertNoBuffNoErr( int32_t i; while (src < srcEnd) { - for (i=0; i< SIZE_OF_TABLES ; i++) { + for (i=0; i< SIZE_OF_ISO2022JP_TABLES ; i++) { bcr = 1; bcw = destEnd - dest; res = nsUnicodeEncodeHelper::ConvertByTable(src, &bcr, dest, &bcw, @@ -220,7 +220,7 @@ NS_IMETHODIMP nsUnicodeToISO2022JP::ConvertNoBuffNoErr( if (res != NS_ERROR_UENC_NOMAPPING) break; } - if ( i>= SIZE_OF_TABLES) { + if ( i>= SIZE_OF_ISO2022JP_TABLES) { if (IS_HANKAKU(*src)) { bcr = srcEnd - src; bcw = destEnd - dest; From 5352c6976e442e9bdff8bdf00f643da496e241ca Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:34 +0900 Subject: [PATCH 31/75] Bug 602787 part.1 Don't implement PresShell::Delayed*Event class in nsPresShell.h r=smaug --- layout/base/nsPresShell.cpp | 59 +++++++++++++++++++++++++++++++++---- layout/base/nsPresShell.h | 59 ++++++++----------------------------- 2 files changed, 67 insertions(+), 51 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 2f9b2cc475b..269a1b29bf7 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6106,8 +6106,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, if (aEvent->message == NS_KEY_DOWN) { mNoDelayedKeyEvents = true; } else if (!mNoDelayedKeyEvents) { - nsDelayedEvent* event = - new nsDelayedKeyEvent(aEvent->AsKeyboardEvent()); + DelayedEvent* event = new DelayedKeyEvent(aEvent->AsKeyboardEvent()); if (!mDelayedEvents.AppendElement(event)) { delete event; } @@ -6335,7 +6334,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, if (aEvent->message == NS_MOUSE_BUTTON_DOWN) { mNoDelayedMouseEvents = true; } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) { - nsDelayedEvent* event = new nsDelayedMouseEvent(aEvent->AsMouseEvent()); + DelayedEvent* event = new DelayedMouseEvent(aEvent->AsMouseEvent()); if (!mDelayedEvents.AppendElement(event)) { delete event; } @@ -7628,9 +7627,9 @@ PresShell::FireOrClearDelayedEvents(bool aFireEvents) nsCOMPtr doc = mDocument; while (!mIsDestroying && mDelayedEvents.Length() && !doc->EventHandlingSuppressed()) { - nsAutoPtr ev(mDelayedEvents[0].forget()); + nsAutoPtr ev(mDelayedEvents[0].forget()); mDelayedEvents.RemoveElementAt(0); - ev->Dispatch(this); + ev->Dispatch(); } if (!doc->EventHandlingSuppressed()) { mDelayedEvents.Clear(); @@ -8341,6 +8340,56 @@ nsIPresShell::RemovePostRefreshObserver(nsAPostRefreshObserver* aObserver) // End of protected and private methods on the PresShell //------------------------------------------------------ +//------------------------------------------------------------------ +//-- Delayed event Classes Impls +//------------------------------------------------------------------ + +PresShell::DelayedInputEvent::DelayedInputEvent() : + DelayedEvent(), + mEvent(nullptr) +{ +} + +PresShell::DelayedInputEvent::~DelayedInputEvent() +{ + delete mEvent; +} + +void +PresShell::DelayedInputEvent::Dispatch() +{ + if (!mEvent || !mEvent->widget) { + return; + } + nsCOMPtr widget = mEvent->widget; + nsEventStatus status; + widget->DispatchEvent(mEvent, status); +} + +PresShell::DelayedMouseEvent::DelayedMouseEvent(WidgetMouseEvent* aEvent) : + DelayedInputEvent() +{ + WidgetMouseEvent* mouseEvent = + new WidgetMouseEvent(aEvent->mFlags.mIsTrusted, + aEvent->message, + aEvent->widget, + aEvent->reason, + aEvent->context); + mouseEvent->AssignMouseEventData(*aEvent, false); + mEvent = mouseEvent; +} + +PresShell::DelayedKeyEvent::DelayedKeyEvent(WidgetKeyboardEvent* aEvent) : + DelayedInputEvent() +{ + WidgetKeyboardEvent* keyEvent = + new WidgetKeyboardEvent(aEvent->mFlags.mIsTrusted, + aEvent->message, + aEvent->widget); + keyEvent->AssignKeyEventData(*aEvent, false); + mEvent = keyEvent; +} + // Start of DEBUG only code #ifdef DEBUG diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index dcb2af38cbc..47e901a34e6 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -34,9 +34,8 @@ #include "nsContentUtils.h" // For AddScriptBlocker(). #include "nsRefreshDriver.h" #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/MouseEvents.h" -#include "mozilla/TextEvents.h" class nsRange; class nsIDragService; @@ -547,67 +546,35 @@ protected: return rv; } - class nsDelayedEvent + class DelayedEvent { public: - virtual ~nsDelayedEvent() {}; - virtual void Dispatch(PresShell* aShell) {} + virtual ~DelayedEvent() { } + virtual void Dispatch() { } }; - class nsDelayedInputEvent : public nsDelayedEvent + class DelayedInputEvent : public DelayedEvent { public: - virtual void Dispatch(PresShell* aShell) - { - if (mEvent && mEvent->widget) { - nsCOMPtr w = mEvent->widget; - nsEventStatus status; - w->DispatchEvent(mEvent, status); - } - } + virtual void Dispatch() MOZ_OVERRIDE; protected: - nsDelayedInputEvent() - : nsDelayedEvent(), mEvent(nullptr) {} - - virtual ~nsDelayedInputEvent() - { - delete mEvent; - } + DelayedInputEvent(); + virtual ~DelayedInputEvent(); mozilla::WidgetInputEvent* mEvent; }; - class nsDelayedMouseEvent : public nsDelayedInputEvent + class DelayedMouseEvent : public DelayedInputEvent { public: - nsDelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent) : - nsDelayedInputEvent() - { - mozilla::WidgetMouseEvent* mouseEvent = - new mozilla::WidgetMouseEvent(aEvent->mFlags.mIsTrusted, - aEvent->message, - aEvent->widget, - aEvent->reason, - aEvent->context); - mouseEvent->AssignMouseEventData(*aEvent, false); - mEvent = mouseEvent; - } + DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent); }; - class nsDelayedKeyEvent : public nsDelayedInputEvent + class DelayedKeyEvent : public DelayedInputEvent { public: - nsDelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent) : - nsDelayedInputEvent() - { - mozilla::WidgetKeyboardEvent* keyEvent = - new mozilla::WidgetKeyboardEvent(aEvent->mFlags.mIsTrusted, - aEvent->message, - aEvent->widget); - keyEvent->AssignKeyEventData(*aEvent, false); - mEvent = keyEvent; - } + DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent); }; // Check if aEvent is a mouse event and record the mouse location for later @@ -759,7 +726,7 @@ protected: // Reflow roots that need to be reflowed. nsTArray mDirtyRoots; - nsTArray > mDelayedEvents; + nsTArray > mDelayedEvents; nsRevocableEventPtr > mResizeEvent; nsCOMPtr mAsyncResizeEventTimer; private: From 5a0241522249f4a2d3c8467e4676aac62c287005 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:34 +0900 Subject: [PATCH 32/75] Bug 602787 part.2 Don't implement nsIWidgetListener in its header file r=roc --- view/public/nsView.h | 1 + widget/nsIWidgetListener.h | 49 +++++----- widget/xpwidgets/moz.build | 1 + widget/xpwidgets/nsIWidgetListener.cpp | 114 +++++++++++++++++++++++ xpfe/appshell/src/nsAppShellService.cpp | 2 + xpfe/appshell/src/nsChromeTreeOwner.cpp | 1 + xpfe/appshell/src/nsContentTreeOwner.cpp | 1 + xpfe/appshell/src/nsWebShellWindow.cpp | 1 + xpfe/appshell/src/nsWebShellWindow.h | 2 + xpfe/appshell/src/nsXULWindow.h | 1 + 10 files changed, 149 insertions(+), 24 deletions(-) create mode 100644 widget/xpwidgets/nsIWidgetListener.cpp diff --git a/view/public/nsView.h b/view/public/nsView.h index 91edc51543c..fdcb52a331d 100644 --- a/view/public/nsView.h +++ b/view/public/nsView.h @@ -11,6 +11,7 @@ #include "nsPoint.h" #include "nsRegion.h" #include "nsCRT.h" +#include "nsWidgetInitData.h" // for nsWindowType #include "nsIWidgetListener.h" #include "mozilla/EventForwards.h" diff --git a/widget/nsIWidgetListener.h b/widget/nsIWidgetListener.h index bafbce35dbc..c5805acb53c 100644 --- a/widget/nsIWidgetListener.h +++ b/widget/nsIWidgetListener.h @@ -5,13 +5,15 @@ #ifndef nsIWidgetListener_h__ #define nsIWidgetListener_h__ -#include "nscore.h" -#include "nsIXULWindow.h" -#include "nsRegion.h" -#include "mozilla/BasicEvents.h" +#include + +#include "mozilla/EventForwards.h" class nsView; +class nsIntRegion; class nsIPresShell; +class nsIWidget; +class nsIXULWindow; /** * sizemode is an adjunct to widget size @@ -43,34 +45,35 @@ public: * this is likely a listener for a view, which can be determined using * GetView. If both methods return null, this will be an nsWebBrowser. */ - virtual nsIXULWindow* GetXULWindow() { return nullptr; } + virtual nsIXULWindow* GetXULWindow(); /** * If this listener is for an nsView, return it. */ - virtual nsView* GetView() { return nullptr; } + virtual nsView* GetView(); /** * Return the presshell for this widget listener. */ - virtual nsIPresShell* GetPresShell() { return nullptr; } + virtual nsIPresShell* GetPresShell(); /** * Called when a window is moved to location (x, y). Returns true if the * notification was handled. Coordinates are outer window screen coordinates. */ - virtual bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY) { return false; } + virtual bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY); /** * Called when a window is resized to (width, height). Returns true if the * notification was handled. Coordinates are outer window screen coordinates. */ - virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) { return false; } + virtual bool WindowResized(nsIWidget* aWidget, + int32_t aWidth, int32_t aHeight); /** * Called when the size mode (minimized, maximized, fullscreen) is changed. */ - virtual void SizeModeChanged(nsSizeMode sizeMode) { } + virtual void SizeModeChanged(nsSizeMode aSizeMode); /** * Called when the z-order of the window is changed. Returns true if the @@ -79,36 +82,37 @@ public: * window to place below. On return, aActualBelow will be set to the * window actually behind. This generally only applies to Windows. */ - virtual bool ZLevelChanged(bool aImmediate, nsWindowZ *aPlacement, - nsIWidget* aRequestBelow, nsIWidget** aActualBelow) { return false; } + virtual bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement, + nsIWidget* aRequestBelow, + nsIWidget** aActualBelow); /** * Called when the window is activated and focused. */ - virtual void WindowActivated() { } + virtual void WindowActivated(); /** * Called when the window is deactivated and no longer focused. */ - virtual void WindowDeactivated() { } + virtual void WindowDeactivated(); /** * Called when the show/hide toolbar button on the Mac titlebar is pressed. */ - virtual void OSToolbarButtonPressed() { } + virtual void OSToolbarButtonPressed(); /** * Called when a request is made to close the window. Returns true if the * notification was handled. Returns true if the notification was handled. */ - virtual bool RequestWindowClose(nsIWidget* aWidget) { return false; } + virtual bool RequestWindowClose(nsIWidget* aWidget); /* * Indicate that a paint is about to occur on this window. This is called * at a time when it's OK to change the geometry of this widget or of * other widgets. Must be called before every call to PaintWindow. */ - virtual void WillPaintWindow(nsIWidget* aWidget) { } + virtual void WillPaintWindow(nsIWidget* aWidget); /** * Paint the specified region of the window. Returns true if the @@ -116,7 +120,7 @@ public: * This is called at a time when it is not OK to change the geometry of * this widget or of other widgets. */ - virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) { return false; } + virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion); /** * Indicates that a paint occurred. @@ -124,21 +128,18 @@ public: * this widget or of other widgets. * Must be called after every call to PaintWindow. */ - virtual void DidPaintWindow() { } + virtual void DidPaintWindow(); /** * Request that layout schedules a repaint on the next refresh driver tick. */ - virtual void RequestRepaint() { } + virtual void RequestRepaint(); /** * Handle an event. */ virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent, - bool aUseAttachedEvents) - { - return nsEventStatus_eIgnore; - } + bool aUseAttachedEvents); }; #endif diff --git a/widget/xpwidgets/moz.build b/widget/xpwidgets/moz.build index 287fac0f460..ec3da93c0bb 100644 --- a/widget/xpwidgets/moz.build +++ b/widget/xpwidgets/moz.build @@ -29,6 +29,7 @@ CPP_SOURCES += [ 'nsFilePickerProxy.cpp', 'nsHTMLFormatConverter.cpp', 'nsIdleService.cpp', + 'nsIWidgetListener.cpp', 'nsPrimitiveHelpers.cpp', 'nsPrintOptionsImpl.cpp', 'nsPrintSession.cpp', diff --git a/widget/xpwidgets/nsIWidgetListener.cpp b/widget/xpwidgets/nsIWidgetListener.cpp new file mode 100644 index 00000000000..a1ad325fc8e --- /dev/null +++ b/widget/xpwidgets/nsIWidgetListener.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIWidgetListener.h" + +#include "nsRegion.h" +#include "nsView.h" +#include "nsIPresShell.h" +#include "nsIWidget.h" +#include "nsIXULWindow.h" + +#include "mozilla/BasicEvents.h" + +using namespace mozilla; + +nsIXULWindow* +nsIWidgetListener::GetXULWindow() +{ + return nullptr; +} + +nsView* +nsIWidgetListener::GetView() +{ + return nullptr; +} + +nsIPresShell* +nsIWidgetListener::GetPresShell() +{ + return nullptr; +} + +bool +nsIWidgetListener::WindowMoved(nsIWidget* aWidget, + int32_t aX, + int32_t aY) +{ + return false; +} + +bool +nsIWidgetListener::WindowResized(nsIWidget* aWidget, + int32_t aWidth, + int32_t aHeight) +{ + return false; +} + +void +nsIWidgetListener::SizeModeChanged(nsSizeMode aSizeMode) +{ +} + +bool +nsIWidgetListener::ZLevelChanged(bool aImmediate, + nsWindowZ* aPlacement, + nsIWidget* aRequestBelow, + nsIWidget** aActualBelow) +{ + return false; +} + +void +nsIWidgetListener::WindowActivated() +{ +} + +void +nsIWidgetListener::WindowDeactivated() +{ +} + +void +nsIWidgetListener::OSToolbarButtonPressed() +{ +} + +bool +nsIWidgetListener::RequestWindowClose(nsIWidget* aWidget) +{ + return false; +} + +void +nsIWidgetListener::WillPaintWindow(nsIWidget* aWidget) +{ +} + +bool +nsIWidgetListener::PaintWindow(nsIWidget* aWidget, + nsIntRegion aRegion) +{ + return false; +} + +void +nsIWidgetListener::DidPaintWindow() +{ +} + +void +nsIWidgetListener::RequestRepaint() +{ +} + +nsEventStatus +nsIWidgetListener::HandleEvent(WidgetGUIEvent* aEvent, + bool aUseAttachedEvents) +{ + return nsEventStatus_eIgnore; +} diff --git a/xpfe/appshell/src/nsAppShellService.cpp b/xpfe/appshell/src/nsAppShellService.cpp index 9b65479a810..c7ca8ee1644 100644 --- a/xpfe/appshell/src/nsAppShellService.cpp +++ b/xpfe/appshell/src/nsAppShellService.cpp @@ -23,7 +23,9 @@ #include "nsCRT.h" #include "prprf.h" +#include "nsWidgetInitData.h" #include "nsWidgetsCID.h" +#include "nsIWidget.h" #include "nsIRequestObserver.h" /* For implementing GetHiddenWindowAndJSContext */ diff --git a/xpfe/appshell/src/nsChromeTreeOwner.cpp b/xpfe/appshell/src/nsChromeTreeOwner.cpp index c5dabe5d875..83002cfd79a 100644 --- a/xpfe/appshell/src/nsChromeTreeOwner.cpp +++ b/xpfe/appshell/src/nsChromeTreeOwner.cpp @@ -19,6 +19,7 @@ #include "nsIAuthPrompt.h" #include "nsIBrowserDOMWindow.h" #include "nsIWebProgress.h" +#include "nsIWidget.h" #include "nsIWindowMediator.h" #include "nsIDOMChromeWindow.h" #include "nsIDOMNode.h" diff --git a/xpfe/appshell/src/nsContentTreeOwner.cpp b/xpfe/appshell/src/nsContentTreeOwner.cpp index e55604fcc61..7e28e3c5c2a 100644 --- a/xpfe/appshell/src/nsContentTreeOwner.cpp +++ b/xpfe/appshell/src/nsContentTreeOwner.cpp @@ -34,6 +34,7 @@ #include "nsDocShellCID.h" #include "nsIExternalURLHandlerService.h" #include "nsIMIMEInfo.h" +#include "nsIWidget.h" #include "mozilla/BrowserElementParent.h" #include "nsIDOMDocument.h" diff --git a/xpfe/appshell/src/nsWebShellWindow.cpp b/xpfe/appshell/src/nsWebShellWindow.cpp index 89b88762477..4e7132042bf 100644 --- a/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/xpfe/appshell/src/nsWebShellWindow.cpp @@ -26,6 +26,7 @@ #include "nsIDOMXULElement.h" +#include "nsWidgetInitData.h" #include "nsWidgetsCID.h" #include "nsIWidget.h" #include "nsIWidgetListener.h" diff --git a/xpfe/appshell/src/nsWebShellWindow.h b/xpfe/appshell/src/nsWebShellWindow.h index 89f0fc9eacb..88281bb96ba 100644 --- a/xpfe/appshell/src/nsWebShellWindow.h +++ b/xpfe/appshell/src/nsWebShellWindow.h @@ -16,6 +16,8 @@ /* Forward declarations.... */ class nsIURI; +struct nsWidgetInitData; + namespace mozilla { class WebShellWindowTimerCallback; } // namespace mozilla diff --git a/xpfe/appshell/src/nsXULWindow.h b/xpfe/appshell/src/nsXULWindow.h index cd1f4d978c0..3fc09dec556 100644 --- a/xpfe/appshell/src/nsXULWindow.h +++ b/xpfe/appshell/src/nsXULWindow.h @@ -17,6 +17,7 @@ #include "nsString.h" #include "nsWeakReference.h" #include "nsCOMArray.h" +#include "nsRect.h" // Interfaces needed #include "nsIBaseWindow.h" From 9be37695285b5ec29499e35d499162954543a32c Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:35 +0900 Subject: [PATCH 33/75] Bug 602787 part.4 Don't implement nsAutoHandlingUserInputStatePusher class in nsEventStateManager.h r=smaug --- content/events/src/nsEventStateManager.cpp | 50 ++++++++++++++++++- content/events/src/nsEventStateManager.h | 51 ++++---------------- content/html/content/src/HTMLFormElement.cpp | 6 +-- layout/base/nsPresShell.cpp | 4 +- layout/xul/base/src/nsXULPopupManager.cpp | 4 +- view/src/nsViewManager.cpp | 1 + 6 files changed, 67 insertions(+), 49 deletions(-) diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 23db60d8cdc..ca9a22a1785 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -14,6 +14,7 @@ #include "nsCOMPtr.h" #include "nsEventStateManager.h" +#include "nsFocusManager.h" #include "nsIMEStateManager.h" #include "nsContentEventHandler.h" #include "nsIContent.h" @@ -1955,7 +1956,7 @@ nsEventStateManager::FireContextClick() } nsIDocument* doc = mGestureDownContent->GetCurrentDoc(); - nsAutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc); + AutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc); // dispatch to DOM nsEventDispatcher::Dispatch(mGestureDownContent, mPresContext, &event, @@ -5848,4 +5849,51 @@ nsEventStateManager::Prefs::GetAccessModifierMask(int32_t aItemType) } } +/******************************************************************/ +/* mozilla::AutoHandlingUserInputStatePusher */ +/******************************************************************/ + +AutoHandlingUserInputStatePusher::AutoHandlingUserInputStatePusher( + bool aIsHandlingUserInput, + WidgetEvent* aEvent, + nsIDocument* aDocument) : + mIsHandlingUserInput(aIsHandlingUserInput), + mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN), + mResetFMMouseDownState(false) +{ + if (!aIsHandlingUserInput) { + return; + } + nsEventStateManager::StartHandlingUserInput(); + if (!mIsMouseDown) { + return; + } + nsIPresShell::SetCapturingContent(nullptr, 0); + nsIPresShell::AllowMouseCapture(true); + if (!aDocument || !aEvent->mFlags.mIsTrusted) { + return; + } + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + NS_ENSURE_TRUE_VOID(fm); + fm->SetMouseButtonDownHandlingDocument(aDocument); + mResetFMMouseDownState = true; +} + +AutoHandlingUserInputStatePusher::~AutoHandlingUserInputStatePusher() +{ + if (!mIsHandlingUserInput) { + return; + } + nsEventStateManager::StopHandlingUserInput(); + if (!mIsMouseDown) { + return; + } + nsIPresShell::AllowMouseCapture(false); + if (!mResetFMMouseDownState) { + return; + } + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + NS_ENSURE_TRUE_VOID(fm); + fm->SetMouseButtonDownHandlingDocument(nullptr); +} diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index f8ea957d115..8128cb48af2 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -6,7 +6,6 @@ #ifndef nsEventStateManager_h__ #define nsEventStateManager_h__ -#include "mozilla/BasicEvents.h" #include "mozilla/EventForwards.h" #include "mozilla/TypedEnum.h" @@ -15,11 +14,11 @@ #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsCycleCollectionParticipant.h" -#include "nsFocusManager.h" #include "mozilla/TimeStamp.h" #include "nsIFrame.h" #include "Units.h" +class nsFrameLoader; class nsIContent; class nsIDocument; class nsIDocShell; @@ -847,51 +846,19 @@ public: static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ; }; +namespace mozilla { + /** * This class is used while processing real user input. During this time, popups * are allowed. For mousedown events, mouse capturing is also permitted. */ -class nsAutoHandlingUserInputStatePusher +class AutoHandlingUserInputStatePusher { public: - nsAutoHandlingUserInputStatePusher(bool aIsHandlingUserInput, - mozilla::WidgetEvent* aEvent, - nsIDocument* aDocument) - : mIsHandlingUserInput(aIsHandlingUserInput), - mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN), - mResetFMMouseDownState(false) - { - if (aIsHandlingUserInput) { - nsEventStateManager::StartHandlingUserInput(); - if (mIsMouseDown) { - nsIPresShell::SetCapturingContent(nullptr, 0); - nsIPresShell::AllowMouseCapture(true); - if (aDocument && aEvent->mFlags.mIsTrusted) { - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - fm->SetMouseButtonDownHandlingDocument(aDocument); - mResetFMMouseDownState = true; - } - } - } - } - } - - ~nsAutoHandlingUserInputStatePusher() - { - if (mIsHandlingUserInput) { - nsEventStateManager::StopHandlingUserInput(); - if (mIsMouseDown) { - nsIPresShell::AllowMouseCapture(false); - if (mResetFMMouseDownState) { - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - fm->SetMouseButtonDownHandlingDocument(nullptr); - } - } - } - } - } + AutoHandlingUserInputStatePusher(bool aIsHandlingUserInput, + WidgetEvent* aEvent, + nsIDocument* aDocument); + ~AutoHandlingUserInputStatePusher(); protected: bool mIsHandlingUserInput; @@ -904,6 +871,8 @@ private: static void operator delete(void* /*memory*/) {} }; +} // namespace mozilla + // Click and double-click events need to be handled even for content that // has no frame. This is required for Web compatibility. #define NS_EVENT_NEEDS_FRAME(event) \ diff --git a/content/html/content/src/HTMLFormElement.cpp b/content/html/content/src/HTMLFormElement.cpp index fe85fa24b2b..4ae6ca35a72 100644 --- a/content/html/content/src/HTMLFormElement.cpp +++ b/content/html/content/src/HTMLFormElement.cpp @@ -807,9 +807,9 @@ HTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission) { nsAutoPopupStatePusher popupStatePusher(mSubmitPopupState); - nsAutoHandlingUserInputStatePusher userInpStatePusher( - mSubmitInitiatedFromUserInput, - nullptr, doc); + AutoHandlingUserInputStatePusher userInpStatePusher( + mSubmitInitiatedFromUserInput, + nullptr, doc); nsCOMPtr postDataStream; rv = aFormSubmission->GetEncodedSubmission(actionURI, diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 269a1b29bf7..3a02cca687d 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6867,8 +6867,8 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus) } } - nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput, - aEvent, mDocument); + AutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput, + aEvent, mDocument); if (aEvent->mFlags.mIsTrusted && aEvent->message == NS_MOUSE_MOVE) { nsIPresShell::AllowMouseCapture( diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp index d77021eaf65..fe417a45f97 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -2354,8 +2354,8 @@ nsXULMenuCommandEvent::Run() if (mCloseMenuMode != CloseMenuMode_None) menuFrame->SelectMenu(false); - nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, - shell->GetDocument()); + AutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, + shell->GetDocument()); nsContentUtils::DispatchXULCommand(mMenu, mIsTrusted, nullptr, shell, mControl, mAlt, mShift, mMeta); } diff --git a/view/src/nsViewManager.cpp b/view/src/nsViewManager.cpp index 6d3ffcdedcc..490c6b14732 100644 --- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -27,6 +27,7 @@ #include "nsLayoutUtils.h" #include "Layers.h" #include "gfxPlatform.h" +#include "nsIDocument.h" /** XXX TODO XXX From 0c81660b16b321a1d03debe04a3e5246fd9ed609 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:35 +0900 Subject: [PATCH 34/75] Bug 602787 part.5 Use EventForwards.h in TabParent.h r=smaug --- dom/ipc/TabParent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 96e01920b55..a6a7e7ec615 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -7,10 +7,10 @@ #ifndef mozilla_tabs_TabParent_h #define mozilla_tabs_TabParent_h +#include "mozilla/EventForwards.h" #include "mozilla/dom/PBrowserParent.h" #include "mozilla/dom/PContentDialogParent.h" #include "mozilla/dom/TabContext.h" -#include "mozilla/TouchEvents.h" #include "nsCOMPtr.h" #include "nsIAuthPromptProvider.h" #include "nsIBrowserDOMWindow.h" From 23f88649628b62ebdc181062fe573c92b42c0458 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:35 +0900 Subject: [PATCH 35/75] Bug 602787 part.6 Use EventForwards.h in gtk/nsWindow.h r=karlt --- widget/gtk/nsDragService.cpp | 1 + widget/gtk/nsWindow.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index 480a89e3f76..40997d7a9f0 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -22,6 +22,7 @@ #include #include #include "nsCRT.h" +#include "mozilla/BasicEvents.h" #include "mozilla/Services.h" #include "gfxASurface.h" diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index f4a2e5d4f78..0b92bfa97d3 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -30,7 +30,7 @@ #ifdef ACCESSIBILITY #include "mozilla/a11y/Accessible.h" #endif -#include "mozilla/MouseEvents.h" +#include "mozilla/EventForwards.h" #include "nsGtkIMModule.h" From 79096b1388ab1f454abbba6e58131b4a7528cd83 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:35 +0900 Subject: [PATCH 36/75] Bug 602787 part.7 Don't implement methods which use Widget*Event in qt/nsWindow.h r=romaxa --- widget/qt/nsWindow.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ widget/qt/nsWindow.h | 39 +++------------------------------------ 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 26f2dd3e6ed..864b4d0d7e0 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -2808,6 +2808,14 @@ nsWindow::GetDPI() return float(rootWindow->height()/heightInches); } +nsEventStatus +nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) +{ + nsEventStatus status; + DispatchEvent(aEvent, status); + return status; +} + void nsWindow::DispatchActivateEvent(void) { @@ -3170,3 +3178,37 @@ nsWindow::GetGLFrameBufferFormat() return LOCAL_GL_NONE; } +void +nsWindow::ProcessMotionEvent() +{ + if (mPinchEvent.needDispatch) { + double distance = DistanceBetweenPoints(mPinchEvent.centerPoint, + mPinchEvent.touchPoint); + distance *= 2; + mPinchEvent.delta = distance - mPinchEvent.prevDistance; + nsIntPoint centerPoint(mPinchEvent.centerPoint.x(), + mPinchEvent.centerPoint.y()); + DispatchGestureEvent(NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, + 0, mPinchEvent.delta, centerPoint); + mPinchEvent.prevDistance = distance; + } + if (mMoveEvent.needDispatch) { + WidgetMouseEvent event(true, NS_MOUSE_MOVE, this, + WidgetMouseEvent::eReal); + + event.refPoint.x = nscoord(mMoveEvent.pos.x()); + event.refPoint.y = nscoord(mMoveEvent.pos.y()); + + event.InitBasicModifiers(mMoveEvent.modifiers & Qt::ControlModifier, + mMoveEvent.modifiers & Qt::AltModifier, + mMoveEvent.modifiers & Qt::ShiftModifier, + mMoveEvent.modifiers & Qt::MetaModifier); + event.clickCount = 0; + + DispatchEvent(&event); + mMoveEvent.needDispatch = false; + } + + mTimerStarted = false; +} + diff --git a/widget/qt/nsWindow.h b/widget/qt/nsWindow.h index 98ebaef8136..8d247cf1793 100644 --- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -16,7 +16,7 @@ #include "nsAutoPtr.h" #include "nsBaseWidget.h" -#include "mozilla/MouseEvents.h" +#include "mozilla/EventForwards.h" #include "nsWeakReference.h" @@ -183,12 +183,7 @@ public: void DispatchDeactivateEventOnTopLevelWindow(void); void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus); - nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent) - { - nsEventStatus status; - DispatchEvent(aEvent, status); - return status; - } + nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); // Some of the nsIWidget methods virtual bool IsEnabled() const; @@ -378,35 +373,7 @@ private: // event (like a keypress or mouse click). void UserActivity(); - inline void ProcessMotionEvent() { - if (mPinchEvent.needDispatch) { - double distance = DistanceBetweenPoints(mPinchEvent.centerPoint, mPinchEvent.touchPoint); - distance *= 2; - mPinchEvent.delta = distance - mPinchEvent.prevDistance; - nsIntPoint centerPoint(mPinchEvent.centerPoint.x(), mPinchEvent.centerPoint.y()); - DispatchGestureEvent(NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, - 0, mPinchEvent.delta, centerPoint); - mPinchEvent.prevDistance = distance; - } - if (mMoveEvent.needDispatch) { - WidgetMouseEvent event(true, NS_MOUSE_MOVE, this, - WidgetMouseEvent::eReal); - - event.refPoint.x = nscoord(mMoveEvent.pos.x()); - event.refPoint.y = nscoord(mMoveEvent.pos.y()); - - event.InitBasicModifiers(mMoveEvent.modifiers & Qt::ControlModifier, - mMoveEvent.modifiers & Qt::AltModifier, - mMoveEvent.modifiers & Qt::ShiftModifier, - mMoveEvent.modifiers & Qt::MetaModifier); - event.clickCount = 0; - - DispatchEvent(&event); - mMoveEvent.needDispatch = false; - } - - mTimerStarted = false; - } + inline void ProcessMotionEvent(); void DispatchMotionToMainThread() { if (!mTimerStarted) { From 117b70ba727a21b84aefe3133462512867e081b9 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:35 +0900 Subject: [PATCH 37/75] Bug 602787 part.8 Don't implement nsWindowBase::DispatchPluginEvent() in windows/nsWindowBase.h r=jimm --- widget/windows/KeyboardLayout.h | 2 +- widget/windows/moz.build | 1 + widget/windows/nsWindow.cpp | 2 ++ widget/windows/nsWindowBase.cpp | 29 +++++++++++++++++++++++++++++ widget/windows/nsWindowBase.h | 20 ++------------------ 5 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 widget/windows/nsWindowBase.cpp diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index 6543a3ffaa2..ce70b2a5537 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -11,7 +11,7 @@ #include "nsString.h" #include "nsWindowBase.h" #include "nsWindowDefs.h" -#include "mozilla/EventForwards.h" +#include "mozilla/BasicEvents.h" #include #define NS_NUM_OF_KEYS 70 diff --git a/widget/windows/moz.build b/widget/windows/moz.build index b4ac7a80ac8..af6befe87f6 100644 --- a/widget/windows/moz.build +++ b/widget/windows/moz.build @@ -61,6 +61,7 @@ CPP_SOURCES += [ 'nsWidgetFactory.cpp', 'nsWinGesture.cpp', 'nsWindow.cpp', + 'nsWindowBase.cpp', 'nsWindowDbg.cpp', 'nsWindowGfx.cpp', ] diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index aa4b3e0dfba..cc1eba9bcd7 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -172,6 +172,8 @@ #include "mozilla/HangMonitor.h" #include "WinIMEHandler.h" +#include "npapi.h" + using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::layers; diff --git a/widget/windows/nsWindowBase.cpp b/widget/windows/nsWindowBase.cpp new file mode 100644 index 00000000000..695769e5dab --- /dev/null +++ b/widget/windows/nsWindowBase.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsWindowBase.h" + +#include "mozilla/MiscEvents.h" +#include "npapi.h" + +using namespace mozilla; + +bool +nsWindowBase::DispatchPluginEvent(const MSG& aMsg) +{ + if (!PluginHasFocus()) { + return false; + } + WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this); + nsIntPoint point(0, 0); + InitEvent(pluginEvent, &point); + NPEvent npEvent; + npEvent.event = aMsg.message; + npEvent.wParam = aMsg.wParam; + npEvent.lParam = aMsg.lParam; + pluginEvent.pluginEvent = &npEvent; + pluginEvent.retargetToFocusedDocument = true; + return DispatchWindowEvent(&pluginEvent); +} diff --git a/widget/windows/nsWindowBase.h b/widget/windows/nsWindowBase.h index 6b3c2f58996..59892e7cf53 100644 --- a/widget/windows/nsWindowBase.h +++ b/widget/windows/nsWindowBase.h @@ -6,9 +6,8 @@ #ifndef nsWindowBase_h_ #define nsWindowBase_h_ -#include "mozilla/MiscEvents.h" +#include "mozilla/EventForwards.h" #include "nsBaseWidget.h" -#include "npapi.h" #include /* @@ -59,22 +58,7 @@ public: /* * Default dispatch of a plugin event. */ - virtual bool DispatchPluginEvent(const MSG &aMsg) - { - if (!PluginHasFocus()) { - return false; - } - mozilla::WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this); - nsIntPoint point(0, 0); - InitEvent(pluginEvent, &point); - NPEvent npEvent; - npEvent.event = aMsg.message; - npEvent.wParam = aMsg.wParam; - npEvent.lParam = aMsg.lParam; - pluginEvent.pluginEvent = (void *)&npEvent; - pluginEvent.retargetToFocusedDocument = true; - return DispatchWindowEvent(&pluginEvent); - } + virtual bool DispatchPluginEvent(const MSG& aMsg); /* * Returns true if a plugin has focus on this widget. Otherwise, false. From 9d5a516f41902c124ce45159c9f8835025d71742 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:36 +0900 Subject: [PATCH 38/75] Bug 602787 part.9 Don't implement methods which need BasicEvents.h or TextEvents.h in windows/KeyboardLayout.h r=jimm --- widget/windows/KeyboardLayout.cpp | 164 ++++++++++++++++++++++++++++++ widget/windows/KeyboardLayout.h | 133 +++++------------------- 2 files changed, 187 insertions(+), 110 deletions(-) diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index 631ac3ee509..282839acc72 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -95,6 +95,38 @@ public: * mozilla::widget::ModifierKeyState *****************************************************************************/ +ModifierKeyState::ModifierKeyState() +{ + Update(); +} + +ModifierKeyState::ModifierKeyState(bool aIsShiftDown, + bool aIsControlDown, + bool aIsAltDown) +{ + Update(); + Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_ALTGRAPH); + Modifiers modifiers = 0; + if (aIsShiftDown) { + modifiers |= MODIFIER_SHIFT; + } + if (aIsControlDown) { + modifiers |= MODIFIER_CONTROL; + } + if (aIsAltDown) { + modifiers |= MODIFIER_ALT; + } + if (modifiers) { + Set(modifiers); + } +} + +ModifierKeyState::ModifierKeyState(Modifiers aModifiers) : + mModifiers(aModifiers) +{ + EnsureAltGr(); +} + void ModifierKeyState::Update() { @@ -124,6 +156,22 @@ ModifierKeyState::Update() EnsureAltGr(); } +void +ModifierKeyState::Unset(Modifiers aRemovingModifiers) +{ + mModifiers &= ~aRemovingModifiers; + // Note that we don't need to unset AltGr flag here automatically. + // For nsEditor, we need to remove Alt and Control flags but AltGr isn't + // checked in nsEditor, so, it can be kept. +} + +void +ModifierKeyState::Set(Modifiers aAddingModifiers) +{ + mModifiers |= aAddingModifiers; + EnsureAltGr(); +} + void ModifierKeyState::InitInputEvent(WidgetInputEvent& aInputEvent) const { @@ -170,6 +218,72 @@ ModifierKeyState::InitMouseEvent(WidgetInputEvent& aMouseEvent) const } } +bool +ModifierKeyState::IsShift() const +{ + return (mModifiers & MODIFIER_SHIFT) != 0; +} + +bool +ModifierKeyState::IsControl() const +{ + return (mModifiers & MODIFIER_CONTROL) != 0; +} + +bool +ModifierKeyState::IsAlt() const +{ + return (mModifiers & MODIFIER_ALT) != 0; +} + +bool +ModifierKeyState::IsAltGr() const +{ + return IsControl() && IsAlt(); +} + +bool +ModifierKeyState::IsWin() const +{ + return (mModifiers & MODIFIER_OS) != 0; +} + +bool +ModifierKeyState::IsCapsLocked() const +{ + return (mModifiers & MODIFIER_CAPSLOCK) != 0; +} + +bool +ModifierKeyState::IsNumLocked() const +{ + return (mModifiers & MODIFIER_NUMLOCK) != 0; +} + +bool +ModifierKeyState::IsScrollLocked() const +{ + return (mModifiers & MODIFIER_SCROLLLOCK) != 0; +} + +Modifiers +ModifierKeyState::GetModifiers() const +{ + return mModifiers; +} + +void +ModifierKeyState::EnsureAltGr() +{ + // If both Control key and Alt key are pressed, it means AltGr is pressed. + // Ideally, we should check whether the current keyboard layout has AltGr + // or not. However, setting AltGr flags for keyboard which doesn't have + // AltGr must not be serious bug. So, it should be OK for now. + if (IsAltGr()) { + mModifiers |= MODIFIER_ALTGRAPH; + } +} + /***************************************************************************** * mozilla::widget::UniCharsAndModifiers *****************************************************************************/ @@ -236,6 +350,50 @@ UniCharsAndModifiers::operator+(const UniCharsAndModifiers& aOther) const * mozilla::widget::VirtualKey *****************************************************************************/ +// static +VirtualKey::ShiftState +VirtualKey::ModifiersToShiftState(Modifiers aModifiers) +{ + ShiftState state = 0; + if (aModifiers & MODIFIER_SHIFT) { + state |= STATE_SHIFT; + } + if (aModifiers & MODIFIER_CONTROL) { + state |= STATE_CONTROL; + } + if (aModifiers & MODIFIER_ALT) { + state |= STATE_ALT; + } + if (aModifiers & MODIFIER_CAPSLOCK) { + state |= STATE_CAPSLOCK; + } + return state; +} + +// static +Modifiers +VirtualKey::ShiftStateToModifiers(ShiftState aShiftState) +{ + Modifiers modifiers = 0; + if (aShiftState & STATE_SHIFT) { + modifiers |= MODIFIER_SHIFT; + } + if (aShiftState & STATE_CONTROL) { + modifiers |= MODIFIER_CONTROL; + } + if (aShiftState & STATE_ALT) { + modifiers |= MODIFIER_ALT; + } + if (aShiftState & STATE_CAPSLOCK) { + modifiers |= MODIFIER_CAPSLOCK; + } + if ((modifiers & (MODIFIER_ALT | MODIFIER_CONTROL)) == + (MODIFIER_ALT | MODIFIER_CONTROL)) { + modifiers |= MODIFIER_ALTGRAPH; + } + return modifiers; +} + inline PRUnichar VirtualKey::GetCompositeChar(ShiftState aShiftState, PRUnichar aBaseChar) const { @@ -752,6 +910,12 @@ NativeKey::ComputeUnicharFromScanCode() const MAPVK_VK_TO_CHAR, mKeyboardLayout)); } +void +NativeKey::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const +{ + InitKeyEvent(aKeyEvent, mModKeyState); +} + void NativeKey::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, const ModifierKeyState& aModKeyState) const diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index ce70b2a5537..560b7867978 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -11,7 +11,8 @@ #include "nsString.h" #include "nsWindowBase.h" #include "nsWindowDefs.h" -#include "mozilla/BasicEvents.h" +#include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include #define NS_NUM_OF_KEYS 70 @@ -54,84 +55,36 @@ static const uint32_t sModifierKeyMap[][3] = { class KeyboardLayout; -class ModifierKeyState { +class ModifierKeyState +{ public: - ModifierKeyState() - { - Update(); - } + ModifierKeyState(); + ModifierKeyState(bool aIsShiftDown, bool aIsControlDown, bool aIsAltDown); + ModifierKeyState(Modifiers aModifiers); - ModifierKeyState(bool aIsShiftDown, bool aIsControlDown, bool aIsAltDown) - { - Update(); - Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_ALTGRAPH); - Modifiers modifiers = 0; - if (aIsShiftDown) { - modifiers |= MODIFIER_SHIFT; - } - if (aIsControlDown) { - modifiers |= MODIFIER_CONTROL; - } - if (aIsAltDown) { - modifiers |= MODIFIER_ALT; - } - if (modifiers) { - Set(modifiers); - } - } + MOZ_ALWAYS_INLINE void Update(); - ModifierKeyState(Modifiers aModifiers) : - mModifiers(aModifiers) - { - EnsureAltGr(); - } - - void Update(); - - void Unset(Modifiers aRemovingModifiers) - { - mModifiers &= ~aRemovingModifiers; - // Note that we don't need to unset AltGr flag here automatically. - // For nsEditor, we need to remove Alt and Control flags but AltGr isn't - // checked in nsEditor, so, it can be kept. - } - - void Set(Modifiers aAddingModifiers) - { - mModifiers |= aAddingModifiers; - EnsureAltGr(); - } + MOZ_ALWAYS_INLINE void Unset(Modifiers aRemovingModifiers); + MOZ_ALWAYS_INLINE void Set(Modifiers aAddingModifiers); void InitInputEvent(WidgetInputEvent& aInputEvent) const; - bool IsShift() const { return (mModifiers & MODIFIER_SHIFT) != 0; } - bool IsControl() const { return (mModifiers & MODIFIER_CONTROL) != 0; } - bool IsAlt() const { return (mModifiers & MODIFIER_ALT) != 0; } - bool IsAltGr() const { return IsControl() && IsAlt(); } - bool IsWin() const { return (mModifiers & MODIFIER_OS) != 0; } + MOZ_ALWAYS_INLINE bool IsShift() const; + MOZ_ALWAYS_INLINE bool IsControl() const; + MOZ_ALWAYS_INLINE bool IsAlt() const; + MOZ_ALWAYS_INLINE bool IsAltGr() const; + MOZ_ALWAYS_INLINE bool IsWin() const; - bool IsCapsLocked() const { return (mModifiers & MODIFIER_CAPSLOCK) != 0; } - bool IsNumLocked() const { return (mModifiers & MODIFIER_NUMLOCK) != 0; } - bool IsScrollLocked() const - { - return (mModifiers & MODIFIER_SCROLLLOCK) != 0; - } + MOZ_ALWAYS_INLINE bool IsCapsLocked() const; + MOZ_ALWAYS_INLINE bool IsNumLocked() const; + MOZ_ALWAYS_INLINE bool IsScrollLocked() const; - Modifiers GetModifiers() const { return mModifiers; } + MOZ_ALWAYS_INLINE Modifiers GetModifiers() const; private: Modifiers mModifiers; - void EnsureAltGr() - { - // If both Control key and Alt key are pressed, it means AltGr is pressed. - // Ideally, we should check whether the current keyboard layout has AltGr - // or not. However, setting AltGr flags for keyboard which doesn't have - // AltGr must not be serious bug. So, it should be OK for now. - if (IsAltGr()) { - mModifiers |= MODIFIER_ALTGRAPH; - } - } + MOZ_ALWAYS_INLINE void EnsureAltGr(); void InitMouseEvent(WidgetInputEvent& aMouseEvent) const; }; @@ -196,45 +149,8 @@ public: typedef uint8_t ShiftState; - static ShiftState ModifiersToShiftState(Modifiers aModifiers) - { - ShiftState state = 0; - if (aModifiers & MODIFIER_SHIFT) { - state |= STATE_SHIFT; - } - if (aModifiers & MODIFIER_CONTROL) { - state |= STATE_CONTROL; - } - if (aModifiers & MODIFIER_ALT) { - state |= STATE_ALT; - } - if (aModifiers & MODIFIER_CAPSLOCK) { - state |= STATE_CAPSLOCK; - } - return state; - } - - static Modifiers ShiftStateToModifiers(ShiftState aShiftState) - { - Modifiers modifiers = 0; - if (aShiftState & STATE_SHIFT) { - modifiers |= MODIFIER_SHIFT; - } - if (aShiftState & STATE_CONTROL) { - modifiers |= MODIFIER_CONTROL; - } - if (aShiftState & STATE_ALT) { - modifiers |= MODIFIER_ALT; - } - if (aShiftState & STATE_CAPSLOCK) { - modifiers |= MODIFIER_CAPSLOCK; - } - if ((modifiers & (MODIFIER_ALT | MODIFIER_CONTROL)) == - (MODIFIER_ALT | MODIFIER_CONTROL)) { - modifiers |= MODIFIER_ALTGRAPH; - } - return modifiers; - } + static ShiftState ModifiersToShiftState(Modifiers aModifiers); + static Modifiers ShiftStateToModifiers(ShiftState aShiftState); private: union KeyShiftState @@ -428,10 +344,7 @@ private: */ void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, const ModifierKeyState& aModKeyState) const; - void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const - { - InitKeyEvent(aKeyEvent, mModKeyState); - } + void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const; /** * Dispatches the key event. Returns true if the event is consumed. From 381b632044848f2402d7a8e0013102987a7050b0 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 22 Oct 2013 22:27:36 +0900 Subject: [PATCH 39/75] Bug 602787 part.10 Create TextRange.h for separating TextEvents.h r=roc --- accessible/src/generic/Accessible.cpp | 1 + content/base/src/nsObjectLoadingContent.cpp | 1 + content/events/src/nsContentEventHandler.cpp | 1 + content/events/src/nsPrivateTextRange.h | 2 +- dom/base/CompositionStringSynthesizer.h | 2 +- editor/libeditor/html/nsHTMLDataTransfer.cpp | 1 + layout/generic/Selection.h | 2 +- layout/generic/nsFrameSelection.h | 2 +- layout/generic/nsObjectFrame.cpp | 3 +- layout/xul/base/src/nsMenuPopupFrame.cpp | 3 +- layout/xul/base/src/nsXULPopupManager.cpp | 3 +- widget/EventForwards.h | 2 + widget/TextEvents.h | 145 +---------------- widget/TextRange.h | 162 +++++++++++++++++++ widget/android/nsWindow.h | 3 +- widget/moz.build | 1 + widget/windows/nsTextStore.h | 2 +- 17 files changed, 182 insertions(+), 154 deletions(-) create mode 100644 widget/TextRange.h diff --git a/accessible/src/generic/Accessible.cpp b/accessible/src/generic/Accessible.cpp index 1adb688479a..6a24f0535c9 100644 --- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -30,6 +30,7 @@ #include "nsIDOMDocument.h" #include "nsIDOMNodeFilter.h" #include "nsIDOMHTMLElement.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMTreeWalker.h" #include "nsIDOMXULButtonElement.h" #include "nsIDOMXULDocument.h" diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index ef13a710f57..cb745c105f5 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -78,6 +78,7 @@ #include "nsWidgetsCID.h" #include "nsContentCID.h" +#include "mozilla/BasicEvents.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/Telemetry.h" diff --git a/content/events/src/nsContentEventHandler.cpp b/content/events/src/nsContentEventHandler.cpp index 67576ece868..2e9f959c81e 100644 --- a/content/events/src/nsContentEventHandler.cpp +++ b/content/events/src/nsContentEventHandler.cpp @@ -26,6 +26,7 @@ #include "nsIMEStateManager.h" #include "nsIObjectFrame.h" #include "mozilla/dom/Element.h" +#include "mozilla/TextEvents.h" #include using namespace mozilla; diff --git a/content/events/src/nsPrivateTextRange.h b/content/events/src/nsPrivateTextRange.h index b38af526534..2e096aff461 100644 --- a/content/events/src/nsPrivateTextRange.h +++ b/content/events/src/nsPrivateTextRange.h @@ -10,7 +10,7 @@ #include "nsTArray.h" #include "nsAutoPtr.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange { diff --git a/dom/base/CompositionStringSynthesizer.h b/dom/base/CompositionStringSynthesizer.h index f4966d6e857..369645ff73e 100644 --- a/dom/base/CompositionStringSynthesizer.h +++ b/dom/base/CompositionStringSynthesizer.h @@ -11,7 +11,7 @@ #include "nsTArray.h" #include "nsWeakReference.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class nsIWidget; class nsPIDOMWindow; diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index 2311565f6c9..6cdd13394f3 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -8,6 +8,7 @@ #include "mozilla/dom/DocumentFragment.h" #include "mozilla/Base64.h" +#include "mozilla/BasicEvents.h" #include "mozilla/Preferences.h" #include "mozilla/Selection.h" #include "mozilla/Util.h" diff --git a/layout/generic/Selection.h b/layout/generic/Selection.h index f3ec3b99ed1..5e1f997257e 100644 --- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -14,7 +14,7 @@ #include "nsISelectionPrivate.h" #include "nsRange.h" #include "nsThreadUtils.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" struct CachedOffsetForFrame; class nsAutoScrollTimer; diff --git a/layout/generic/nsFrameSelection.h b/layout/generic/nsFrameSelection.h index b7c9d746187..03a421b66ad 100644 --- a/layout/generic/nsFrameSelection.h +++ b/layout/generic/nsFrameSelection.h @@ -8,7 +8,7 @@ #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" #include "mozilla/Selection.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" #include "nsIFrame.h" #include "nsIContent.h" #include "nsISelectionController.h" diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 6f2cbb1af2c..cb99b8bb6ab 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -145,7 +145,6 @@ extern "C" { #endif /* #if defined(XP_MACOSX) && !defined(__LP64__) */ using namespace mozilla; -using namespace mozilla::plugins; using namespace mozilla::layers; class PluginBackgroundSink : public ReadbackSink { @@ -1791,7 +1790,7 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder, // double pass render. If this plugin isn't oop, the register window message // will be ignored. NPEvent pluginEvent; - pluginEvent.event = DoublePassRenderingEvent(); + pluginEvent.event = plugins::DoublePassRenderingEvent(); pluginEvent.wParam = 0; pluginEvent.lParam = 0; if (pluginEvent.event) diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index c6c2468d3d9..f5b4e02d214 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -19,6 +19,7 @@ #include "nsPopupSetFrame.h" #include "nsEventDispatcher.h" #include "nsPIDOMWindow.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMScreen.h" #include "nsIPresShell.h" #include "nsFrameManager.h" @@ -1650,7 +1651,7 @@ nsMenuPopupFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent, bool& doAction aKeyEvent->GetTimeStamp(&keyTime); if (charCode == 0) { - if (keyCode == NS_VK_BACK) { + if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) { if (!isMenu && !mIncrementalString.IsEmpty()) { mIncrementalString.SetLength(mIncrementalString.Length() - 1); return nullptr; diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp index fe417a45f97..cbf031efa69 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -1846,7 +1846,8 @@ nsXULPopupManager::HandleKeyboardNavigation(uint32_t aKeyCode) return false; nsNavigationDirection theDirection; - NS_ASSERTION(aKeyCode >= NS_VK_END && aKeyCode <= NS_VK_DOWN, "Illegal key code"); + NS_ASSERTION(aKeyCode >= nsIDOMKeyEvent::DOM_VK_END && + aKeyCode <= nsIDOMKeyEvent::DOM_VK_DOWN, "Illegal key code"); theDirection = NS_DIRECTION_FROM_KEY_CODE(itemFrame, aKeyCode); // if a popup is open, first check for navigation within the popup diff --git a/widget/EventForwards.h b/widget/EventForwards.h index 8b2bfa26aba..04ed9297af8 100644 --- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -64,6 +64,8 @@ struct EventFlags; // TextEvents.h struct AlternativeCharCode; + +// TextRange.h struct TextRangeStyle; struct TextRange; diff --git a/widget/TextEvents.h b/widget/TextEvents.h index b6f72346b6d..ee4283bb9f3 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -11,13 +11,12 @@ #include "mozilla/Assertions.h" #include "mozilla/BasicEvents.h" #include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily -#include "nsColor.h" +#include "mozilla/TextRange.h" #include "nsCOMPtr.h" #include "nsIDOMKeyEvent.h" #include "nsITransferable.h" #include "nsRect.h" #include "nsStringGlue.h" -#include "nsStyleConsts.h" #include "nsTArray.h" /****************************************************************************** @@ -149,148 +148,6 @@ public: } }; -/****************************************************************************** - * mozilla::TextRangeStyle - ******************************************************************************/ - -struct TextRangeStyle -{ - enum { - LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, - LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, - LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, - LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, - LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, - LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY - }; - - enum { - DEFINED_NONE = 0x00, - DEFINED_LINESTYLE = 0x01, - DEFINED_FOREGROUND_COLOR = 0x02, - DEFINED_BACKGROUND_COLOR = 0x04, - DEFINED_UNDERLINE_COLOR = 0x08 - }; - - // Initialize all members, because TextRange instances may be compared by - // memcomp. - TextRangeStyle() - { - Clear(); - } - - void Clear() - { - mDefinedStyles = DEFINED_NONE; - mLineStyle = LINESTYLE_NONE; - mIsBoldLine = false; - mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); - } - - bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } - - bool IsLineStyleDefined() const - { - return (mDefinedStyles & DEFINED_LINESTYLE) != 0; - } - - bool IsForegroundColorDefined() const - { - return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; - } - - bool IsBackgroundColorDefined() const - { - return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; - } - - bool IsUnderlineColorDefined() const - { - return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; - } - - bool IsNoChangeStyle() const - { - return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && - IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; - } - - bool Equals(const TextRangeStyle& aOther) - { - if (mDefinedStyles != aOther.mDefinedStyles) - return false; - if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || - !mIsBoldLine != !aOther.mIsBoldLine)) - return false; - if (IsForegroundColorDefined() && - (mForegroundColor != aOther.mForegroundColor)) - return false; - if (IsBackgroundColorDefined() && - (mBackgroundColor != aOther.mBackgroundColor)) - return false; - if (IsUnderlineColorDefined() && - (mUnderlineColor != aOther.mUnderlineColor)) - return false; - return true; - } - - bool operator !=(const TextRangeStyle &aOther) - { - return !Equals(aOther); - } - - bool operator ==(const TextRangeStyle &aOther) - { - return Equals(aOther); - } - - uint8_t mDefinedStyles; - uint8_t mLineStyle; // DEFINED_LINESTYLE - - bool mIsBoldLine; // DEFINED_LINESTYLE - - nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR - nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR - nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR -}; - -/****************************************************************************** - * mozilla::TextRange - ******************************************************************************/ - -// Sync with nsIPrivateTextRange.h when you change these constants. -#define NS_TEXTRANGE_CARETPOSITION 0x01 -#define NS_TEXTRANGE_RAWINPUT 0x02 -#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 -#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 -#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 - -struct TextRange -{ - TextRange() : - mStartOffset(0), mEndOffset(0), mRangeType(0) - { - } - - uint32_t mStartOffset; - // XXX Storing end offset makes the initializing code very complicated. - // We should replace it with mLength. - uint32_t mEndOffset; - uint32_t mRangeType; - - TextRangeStyle mRangeStyle; - - uint32_t Length() const { return mEndOffset - mStartOffset; } -}; - -/****************************************************************************** - * mozilla::TextRangeArray - * - * XXX This should be replaced with nsTArray. - ******************************************************************************/ - -typedef TextRange* TextRangeArray; - /****************************************************************************** * mozilla::WidgetTextEvent * diff --git a/widget/TextRange.h b/widget/TextRange.h new file mode 100644 index 00000000000..77e3cbd3bc1 --- /dev/null +++ b/widget/TextRange.h @@ -0,0 +1,162 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_TextRage_h_ +#define mozilla_TextRage_h_ + +#include + +#include "nsColor.h" +#include "nsStyleConsts.h" + +namespace mozilla { + +/****************************************************************************** + * mozilla::TextRangeStyle + ******************************************************************************/ + +struct TextRangeStyle +{ + enum + { + LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, + LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, + LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, + LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, + LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, + LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY + }; + + enum + { + DEFINED_NONE = 0x00, + DEFINED_LINESTYLE = 0x01, + DEFINED_FOREGROUND_COLOR = 0x02, + DEFINED_BACKGROUND_COLOR = 0x04, + DEFINED_UNDERLINE_COLOR = 0x08 + }; + + // Initialize all members, because TextRange instances may be compared by + // memcomp. + TextRangeStyle() + { + Clear(); + } + + void Clear() + { + mDefinedStyles = DEFINED_NONE; + mLineStyle = LINESTYLE_NONE; + mIsBoldLine = false; + mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); + } + + bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } + + bool IsLineStyleDefined() const + { + return (mDefinedStyles & DEFINED_LINESTYLE) != 0; + } + + bool IsForegroundColorDefined() const + { + return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; + } + + bool IsBackgroundColorDefined() const + { + return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; + } + + bool IsUnderlineColorDefined() const + { + return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; + } + + bool IsNoChangeStyle() const + { + return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && + IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; + } + + bool Equals(const TextRangeStyle& aOther) + { + if (mDefinedStyles != aOther.mDefinedStyles) + return false; + if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || + !mIsBoldLine != !aOther.mIsBoldLine)) + return false; + if (IsForegroundColorDefined() && + (mForegroundColor != aOther.mForegroundColor)) + return false; + if (IsBackgroundColorDefined() && + (mBackgroundColor != aOther.mBackgroundColor)) + return false; + if (IsUnderlineColorDefined() && + (mUnderlineColor != aOther.mUnderlineColor)) + return false; + return true; + } + + bool operator !=(const TextRangeStyle &aOther) + { + return !Equals(aOther); + } + + bool operator ==(const TextRangeStyle &aOther) + { + return Equals(aOther); + } + + uint8_t mDefinedStyles; + uint8_t mLineStyle; // DEFINED_LINESTYLE + + bool mIsBoldLine; // DEFINED_LINESTYLE + + nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR + nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR + nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR +}; + +/****************************************************************************** + * mozilla::TextRange + ******************************************************************************/ + +// Sync with nsIPrivateTextRange.h when you change these constants. +#define NS_TEXTRANGE_CARETPOSITION 0x01 +#define NS_TEXTRANGE_RAWINPUT 0x02 +#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 +#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 +#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 + +struct TextRange +{ + TextRange() : + mStartOffset(0), mEndOffset(0), mRangeType(0) + { + } + + uint32_t mStartOffset; + // XXX Storing end offset makes the initializing code very complicated. + // We should replace it with mLength. + uint32_t mEndOffset; + uint32_t mRangeType; + + TextRangeStyle mRangeStyle; + + uint32_t Length() const { return mEndOffset - mStartOffset; } +}; + +/****************************************************************************** + * mozilla::TextRangeArray + * + * XXX This should be replaced with nsTArray. + ******************************************************************************/ + +typedef TextRange* TextRangeArray; + +} // namespace mozilla + +#endif // mozilla_TextRage_h_ diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 02b90c1ded8..0baddd5ae3f 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -11,8 +11,9 @@ #include "nsIIdleServiceInternal.h" #include "nsTArray.h" #include "AndroidJavaWrappers.h" +#include "mozilla/EventForwards.h" #include "mozilla/StaticPtr.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class gfxASurface; diff --git a/widget/moz.build b/widget/moz.build index c19e49e205e..76c2ef5bf8e 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -118,6 +118,7 @@ EXPORTS.mozilla += [ 'MiscEvents.h', 'MouseEvents.h', 'TextEvents.h', + 'TextRange.h', 'TouchEvents.h', 'WidgetUtils.h', ] diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 5cea0566ddf..4ddb1dddff4 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -13,7 +13,7 @@ #include "nsIWidget.h" #include "nsWindowBase.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" #include #include From ab56ef38b656c844f2bf752b67ab6dd5976d0701 Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Tue, 22 Oct 2013 08:08:10 -0600 Subject: [PATCH 40/75] Bug 928562 - Remove uses of JSContext for BytecodeAnalysis, BaselineInspector, and constructing bytecode type maps, r=jandem. --- js/src/jit/BaselineCompiler.cpp | 30 ++++++++++++++++++++++--- js/src/jit/BaselineInspector.h | 6 ++--- js/src/jit/BaselineJIT.cpp | 14 ++++++++---- js/src/jit/BaselineJIT.h | 15 ++++++++++++- js/src/jit/BytecodeAnalysis.cpp | 4 ++-- js/src/jit/BytecodeAnalysis.h | 2 +- js/src/jit/Ion.cpp | 6 ++--- js/src/jit/IonAnalysis.cpp | 31 ++++++++++++++++---------- js/src/jit/IonBuilder.cpp | 15 ++++++------- js/src/jscompartment.cpp | 2 ++ js/src/jsinfer.cpp | 39 ++------------------------------- js/src/jsinfer.h | 6 ----- js/src/jsinferinlines.h | 25 +++++++++++---------- js/src/jsscript.h | 4 ---- 14 files changed, 103 insertions(+), 96 deletions(-) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index aada54cb2f0..e7511ddeff9 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -33,7 +33,7 @@ BaselineCompiler::BaselineCompiler(JSContext *cx, HandleScript script) bool BaselineCompiler::init() { - if (!analysis_.init(cx)) + if (!analysis_.init(cx->runtime()->gsnCache)) return false; if (!labels_.init(script->length)) @@ -74,7 +74,7 @@ BaselineCompiler::compile() IonSpew(IonSpew_Codegen, "# Emitting baseline code for script %s:%d", script->filename(), script->lineno); - if (cx->typeInferenceEnabled() && !script->ensureHasBytecodeTypeMap(cx)) + if (cx->typeInferenceEnabled() && !script->ensureHasTypes(cx)) return Method_Error; // Only need to analyze scripts which are marked |argumensHasVarBinding|, to @@ -155,11 +155,15 @@ BaselineCompiler::compile() prologueOffset_.fixup(&masm); spsPushToggleOffset_.fixup(&masm); + // Note: There is an extra entry in the bytecode type map for the search hint, see below. + size_t bytecodeTypeMapEntries = cx->typeInferenceEnabled() ? script->nTypeSets + 1 : 0; + BaselineScript *baselineScript = BaselineScript::New(cx, prologueOffset_.offset(), spsPushToggleOffset_.offset(), icEntries_.length(), pcMappingIndexEntries.length(), - pcEntries.length()); + pcEntries.length(), + bytecodeTypeMapEntries); if (!baselineScript) return Method_Error; @@ -210,6 +214,26 @@ BaselineCompiler::compile() if (cx->runtime()->spsProfiler.enabled()) baselineScript->toggleSPS(true); + if (cx->typeInferenceEnabled()) { + uint32_t *bytecodeMap = baselineScript->bytecodeTypeMap(); + + uint32_t added = 0; + for (jsbytecode *pc = script->code; pc < script->code + script->length; pc += GetBytecodeLength(pc)) { + JSOp op = JSOp(*pc); + if (js_CodeSpec[op].format & JOF_TYPESET) { + bytecodeMap[added++] = pc - script->code; + if (added == script->nTypeSets) + break; + } + } + + JS_ASSERT(added == script->nTypeSets); + + // The last entry in the last index found, and is used to avoid binary + // searches for the sought entry when queries are in linear order. + bytecodeMap[script->nTypeSets] = 0; + } + return Method_Compiled; } diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index a4367ba6e37..ae4bff7a509 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -46,12 +46,12 @@ class SetElemICInspector : public ICInspector class BaselineInspector { private: - RootedScript script; + JSScript *script; ICEntry *prevLookedUpEntry; public: - BaselineInspector(JSContext *cx, JSScript *rawScript) - : script(cx, rawScript), prevLookedUpEntry(nullptr) + BaselineInspector(JSScript *script) + : script(script), prevLookedUpEntry(nullptr) { JS_ASSERT(script); } diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 3da8a5a761c..471edc9a8b7 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -211,8 +211,8 @@ jit::EnterBaselineAtBranch(JSContext *cx, StackFrame *fp, jsbytecode *pc) return IonExec_Ok; } -static MethodStatus -BaselineCompile(JSContext *cx, HandleScript script) +MethodStatus +jit::BaselineCompile(JSContext *cx, HandleScript script) { JS_ASSERT(!script->hasBaselineScript()); JS_ASSERT(script->canBaselineCompile()); @@ -361,21 +361,25 @@ static const unsigned DataAlignment = sizeof(uintptr_t); BaselineScript * BaselineScript::New(JSContext *cx, uint32_t prologueOffset, uint32_t spsPushToggleOffset, size_t icEntries, - size_t pcMappingIndexEntries, size_t pcMappingSize) + size_t pcMappingIndexEntries, size_t pcMappingSize, + size_t bytecodeTypeMapEntries) { size_t paddedBaselineScriptSize = AlignBytes(sizeof(BaselineScript), DataAlignment); size_t icEntriesSize = icEntries * sizeof(ICEntry); size_t pcMappingIndexEntriesSize = pcMappingIndexEntries * sizeof(PCMappingIndexEntry); + size_t bytecodeTypeMapSize = bytecodeTypeMapEntries * sizeof(uint32_t); size_t paddedICEntriesSize = AlignBytes(icEntriesSize, DataAlignment); size_t paddedPCMappingIndexEntriesSize = AlignBytes(pcMappingIndexEntriesSize, DataAlignment); size_t paddedPCMappingSize = AlignBytes(pcMappingSize, DataAlignment); + size_t paddedBytecodeTypesMapSize = AlignBytes(bytecodeTypeMapSize, DataAlignment); size_t allocBytes = paddedBaselineScriptSize + paddedICEntriesSize + paddedPCMappingIndexEntriesSize + - paddedPCMappingSize; + paddedPCMappingSize + + paddedBytecodeTypesMapSize; uint8_t *buffer = (uint8_t *)cx->malloc_(allocBytes); if (!buffer) @@ -398,6 +402,8 @@ BaselineScript::New(JSContext *cx, uint32_t prologueOffset, script->pcMappingSize_ = pcMappingSize; offsetCursor += paddedPCMappingSize; + script->bytecodeTypeMapOffset_ = bytecodeTypeMapEntries ? offsetCursor : 0; + return script; } diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 5b85295441f..16be67f7a25 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -146,13 +146,18 @@ struct BaselineScript uint32_t pcMappingOffset_; uint32_t pcMappingSize_; + // List mapping indexes of bytecode type sets to the offset of the opcode + // they correspond to, for use by TypeScript::BytecodeTypes. + uint32_t bytecodeTypeMapOffset_; + public: // Do not call directly, use BaselineScript::New. This is public for cx->new_. BaselineScript(uint32_t prologueOffset, uint32_t spsPushToggleOffset); static BaselineScript *New(JSContext *cx, uint32_t prologueOffset, uint32_t spsPushToggleOffset, size_t icEntries, - size_t pcMappingIndexEntries, size_t pcMappingSize); + size_t pcMappingIndexEntries, size_t pcMappingSize, + size_t bytecodeTypeMapEntries); static void Trace(JSTracer *trc, BaselineScript *script); static void Destroy(FreeOp *fop, BaselineScript *script); @@ -269,6 +274,11 @@ struct BaselineScript } static void writeBarrierPre(Zone *zone, BaselineScript *script); + + uint32_t *bytecodeTypeMap() { + JS_ASSERT(bytecodeTypeMapOffset_); + return reinterpret_cast(reinterpret_cast(this) + bytecodeTypeMapOffset_); + } }; inline bool @@ -348,6 +358,9 @@ BailoutIonToBaseline(JSContext *cx, JitActivation *activation, IonBailoutIterato void MarkActiveBaselineScripts(Zone *zone); +MethodStatus +BaselineCompile(JSContext *cx, HandleScript script); + } // namespace jit } // namespace js diff --git a/js/src/jit/BytecodeAnalysis.cpp b/js/src/jit/BytecodeAnalysis.cpp index 95ebef14132..ae6fa86f172 100644 --- a/js/src/jit/BytecodeAnalysis.cpp +++ b/js/src/jit/BytecodeAnalysis.cpp @@ -39,7 +39,7 @@ struct CatchFinallyRange }; bool -BytecodeAnalysis::init(JSContext *cx) +BytecodeAnalysis::init(GSNCache &gsn) { if (!infos_.growByUninitialized(script_->length)) return false; @@ -120,7 +120,7 @@ BytecodeAnalysis::init(JSContext *cx) // Get the pc of the last instruction in the try block. It's a JSOP_GOTO to // jump over the catch/finally blocks. - jssrcnote *sn = js_GetSrcNote(cx, script_, pc); + jssrcnote *sn = GetSrcNote(gsn, script_, pc); JS_ASSERT(SN_TYPE(sn) == SRC_TRY); jsbytecode *endOfTry = pc + js_GetSrcNoteOffset(sn, 0); diff --git a/js/src/jit/BytecodeAnalysis.h b/js/src/jit/BytecodeAnalysis.h index 168a77d6500..6621d99181d 100644 --- a/js/src/jit/BytecodeAnalysis.h +++ b/js/src/jit/BytecodeAnalysis.h @@ -47,7 +47,7 @@ class BytecodeAnalysis public: explicit BytecodeAnalysis(JSScript *script); - bool init(JSContext *cx); + bool init(GSNCache &gsn); BytecodeInfo &info(jsbytecode *pc) { JS_ASSERT(infos_[pc - script_->code].initialized); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index c9eb461910b..ba3f79b6c32 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -671,7 +671,7 @@ IonCode::finalize(FreeOp *fop) // Buffer can be freed at any time hereafter. Catch use-after-free bugs. // Don't do this if the Ion code is protected, as the signal handler will // deadlock trying to reaqcuire the operation callback lock. - if (!fop->runtime()->ionRuntime()->ionCodeProtected()) + if (fop->runtime()->ionRuntime() && !fop->runtime()->ionRuntime()->ionCodeProtected()) JS_POISON(code_, JS_FREE_PATTERN, bufferSize_); #endif @@ -1594,7 +1594,7 @@ IonCompile(JSContext *cx, JSScript *script, if (!info) return AbortReason_Alloc; - BaselineInspector inspector(cx, script); + BaselineInspector inspector(script); AutoFlushCache afc("IonCompile", cx->runtime()->ionRuntime()); @@ -1762,7 +1762,7 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode JS_ASSERT(jit::IsBaselineEnabled(cx)); JS_ASSERT_IF(osrPc != nullptr, (JSOp)*osrPc == JSOP_LOOPENTRY); - if (executionMode == SequentialExecution && !script->hasBaselineScript()) + if (!script->hasBaselineScript()) return Method_Skipped; if (cx->compartment()->debugMode()) { diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 4ce42f24c78..866ac3b2582 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -9,6 +9,7 @@ #include "jsanalyze.h" #include "jit/BaselineInspector.h" +#include "jit/BaselineJIT.h" #include "jit/Ion.h" #include "jit/IonBuilder.h" #include "jit/LIR.h" @@ -2065,18 +2066,14 @@ jit::AnalyzeNewScriptProperties(JSContext *cx, JSFunction *fun, // which will definitely be added to the created object before it has a // chance to escape and be accessed elsewhere. - if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx)) { + if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx)) return false; - } - if (!fun->nonLazyScript()->compileAndGo) + RootedScript script(cx, fun->nonLazyScript()); + + if (!script->compileAndGo || !script->canBaselineCompile()) return true; - if (!fun->nonLazyScript()->ensureHasTypes(cx)) - return false; - - types::TypeScript::SetThis(cx, fun->nonLazyScript(), types::Type::ObjectType(type)); - Vector accessedProperties(cx); LifoAlloc alloc(types::TypeZone::TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE); @@ -2086,18 +2083,28 @@ jit::AnalyzeNewScriptProperties(JSContext *cx, JSFunction *fun, types::AutoEnterAnalysis enter(cx); - if (!fun->nonLazyScript()->ensureRanAnalysis(cx)) - return false; + if (!cx->compartment()->ensureIonCompartmentExists(cx)) + return Method_Error; + + if (!script->hasBaselineScript()) { + MethodStatus status = BaselineCompile(cx, script); + if (status == Method_Error) + return false; + if (status != Method_Compiled) + return true; + } + + types::TypeScript::SetThis(cx, script, types::Type::ObjectType(type)); MIRGraph graph(&temp); - CompileInfo info(fun->nonLazyScript(), fun, + CompileInfo info(script, fun, /* osrPc = */ nullptr, /* constructing = */ false, DefinitePropertiesAnalysis); AutoTempAllocatorRooter root(cx, &temp); types::CompilerConstraintList *constraints = types::NewCompilerConstraintList(); - BaselineInspector inspector(cx, fun->nonLazyScript()); + BaselineInspector inspector(script); IonBuilder builder(cx, &temp, &graph, constraints, &inspector, &info, /* baselineFrame = */ nullptr); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index ae96fe50890..bbcabdce233 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -66,6 +66,8 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph, { script_.init(info->script()); pc = info->startPC(); + + JS_ASSERT(script()->hasBaselineScript()); } void @@ -279,7 +281,7 @@ IonBuilder::canInlineTarget(JSFunction *target, bool constructing) // Allow constructing lazy scripts when performing the definite properties // analysis, as baseline has not been used to warm the caller up yet. if (target->isInterpretedLazy() && info().executionMode() == DefinitePropertiesAnalysis) { - if (!target->getOrCreateScript(cx)) + if (!target->getOrCreateScript(context())) return false; } @@ -301,8 +303,8 @@ IonBuilder::canInlineTarget(JSFunction *target, bool constructing) return false; } - // Don't inline functions which don't have baseline scripts compiled for them. - if (executionMode == SequentialExecution && !inlineScript->hasBaselineScript()) { + // Don't inline functions which don't have baseline scripts. + if (!inlineScript->hasBaselineScript()) { IonSpew(IonSpew_Inlining, "%s:%d Cannot inline target with no baseline jitcode", inlineScript->filename(), inlineScript->lineno); return false; @@ -513,16 +515,13 @@ IonBuilder::pushLoop(CFGState::State initial, jsbytecode *stopAt, MBasicBlock *e bool IonBuilder::init() { - if (!script()->ensureHasBytecodeTypeMap(cx)) - return false; - if (!types::TypeScript::FreezeTypeSets(constraints(), script(), &thisTypes, &argTypes, &typeArray)) { return false; } - if (!analysis().init(cx)) + if (!analysis().init(gsn)) return false; return true; @@ -3753,7 +3752,7 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target) current->push(callInfo.fun()); JSScript *calleeScript = target->nonLazyScript(); - BaselineInspector inspector(cx, calleeScript); + BaselineInspector inspector(calleeScript); // Improve type information of |this| when not set. if (callInfo.constructing() && diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index cc242e7f14b..802cd89e800 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -138,6 +138,8 @@ JSRuntime::createIonRuntime(JSContext *cx) js_delete(ionRuntime_); ionRuntime_ = nullptr; + AutoLockForExclusiveAccess atomsLock(cx); + JSCompartment *comp = cx->runtime()->atomsCompartment(); if (comp->ionCompartment_) { js_delete(comp->ionCompartment_); diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 8bdc4315ef8..ab85ac88105 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3352,16 +3352,11 @@ types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const if (!(js_CodeSpec[*pc].format & JOF_TYPESET)) return; - if (!script->types) + if (!script->hasBaselineScript()) return; AutoEnterAnalysis enter(cx); - if (!script->ensureHasBytecodeTypeMap(cx)) { - cx->compartment()->types.setPendingNukeTypes(cx); - return; - } - Type type = GetValueType(rval); TypeSet *types = TypeScript::BytecodeTypes(script, pc); if (types->hasType(type)) @@ -3483,36 +3478,6 @@ JSScript::makeTypes(JSContext *cx) return analyzedArgsUsage() || ensureRanAnalysis(cx); } -bool -JSScript::makeBytecodeTypeMap(JSContext *cx) -{ - JS_ASSERT(cx->typeInferenceEnabled()); - JS_ASSERT(types && !types->bytecodeMap); - - types->bytecodeMap = cx->typeLifoAlloc().newArrayUninitialized(nTypeSets + 1); - - if (!types->bytecodeMap) - return false; - - uint32_t added = 0; - for (jsbytecode *pc = code; pc < code + length; pc += GetBytecodeLength(pc)) { - JSOp op = JSOp(*pc); - if (js_CodeSpec[op].format & JOF_TYPESET) { - types->bytecodeMap[added++] = pc - code; - if (added == nTypeSets) - break; - } - } - - JS_ASSERT(added == nTypeSets); - - // The last entry in the last index found, and is used to avoid binary - // searches for the sought entry when queries are in linear order. - types->bytecodeMap[nTypeSets] = 0; - - return true; -} - bool JSScript::makeAnalysis(JSContext *cx) { @@ -4370,7 +4335,7 @@ TypeScript::printTypes(JSContext *cx, HandleScript script) const { JS_ASSERT(script->types == this); - if (!bytecodeMap) + if (!script->hasBaselineScript()) return; AutoEnterAnalysis enter(nullptr, script->compartment()); diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 29f01d22e1a..850f9d89349 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -1150,12 +1150,6 @@ class TypeScript /* Analysis information for the script, cleared on each GC. */ analyze::ScriptAnalysis *analysis; - /* - * List mapping indexes of bytecode type sets to the offset of the opcode - * they correspond to. Cleared on each GC. - */ - uint32_t *bytecodeMap; - public: /* Array of type type sets for variables and JOF_TYPESET ops. */ StackTypeSet *typeArray() const { return (StackTypeSet *) (uintptr_t(this) + sizeof(TypeScript)); } diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 08175923148..23dbf23eaff 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -609,8 +609,12 @@ template TypeScript::BytecodeTypes(JSScript *script, jsbytecode *pc, uint32_t *hint, TYPESET *typeArray) { JS_ASSERT(js_CodeSpec[*pc].format & JOF_TYPESET); - JS_ASSERT(script->types && script->types->bytecodeMap); - uint32_t *bytecodeMap = script->types->bytecodeMap; +#ifdef JS_ION + uint32_t *bytecodeMap = script->baselineScript()->bytecodeTypeMap(); +#else + uint32_t *bytecodeMap = NULL; + MOZ_CRASH(); +#endif uint32_t offset = pc - script->code; JS_ASSERT(offset < script->length); @@ -651,7 +655,12 @@ TypeScript::BytecodeTypes(JSScript *script, jsbytecode *pc, uint32_t *hint, TYPE TypeScript::BytecodeTypes(JSScript *script, jsbytecode *pc) { JS_ASSERT(CurrentThreadCanAccessRuntime(script->runtimeFromMainThread())); - uint32_t *hint = script->types->bytecodeMap + script->nTypeSets; +#ifdef JS_ION + uint32_t *hint = script->baselineScript()->bytecodeTypeMap() + script->nTypeSets; +#else + uint32_t *hint = NULL; + MOZ_CRASH(); +#endif return BytecodeTypes(script, pc, hint, script->types->typeArray()); } @@ -1452,12 +1461,6 @@ JSScript::ensureHasTypes(JSContext *cx) return types || makeTypes(cx); } -inline bool -JSScript::ensureHasBytecodeTypeMap(JSContext *cx) -{ - return ensureHasTypes(cx) && (types->bytecodeMap || makeBytecodeTypeMap(cx)); -} - inline bool JSScript::ensureRanAnalysis(JSContext *cx) { @@ -1487,10 +1490,8 @@ JSScript::analysis() inline void JSScript::clearAnalysis() { - if (types) { + if (types) types->analysis = nullptr; - types->bytecodeMap = nullptr; - } } namespace js { diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 3e5e5f030b2..f30e4af0422 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -833,9 +833,6 @@ class JSScript : public js::gc::BarrieredCell /* Ensure the script has a TypeScript. */ inline bool ensureHasTypes(JSContext *cx); - /* Ensure the script has a TypeScript and map for computing BytecodeTypes. */ - inline bool ensureHasBytecodeTypeMap(JSContext *cx); - /* * Ensure the script has bytecode analysis information. Performed when the * script first runs, or first runs after a TypeScript GC purge. @@ -873,7 +870,6 @@ class JSScript : public js::gc::BarrieredCell private: bool makeTypes(JSContext *cx); - bool makeBytecodeTypeMap(JSContext *cx); bool makeAnalysis(JSContext *cx); public: From df65dbd22025bdec18cd916a988e40359ba0df89 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 22 Oct 2013 07:33:26 -0700 Subject: [PATCH 41/75] Bug 928625 - IonMonkey: Don't emit Unbox operators for values which aren't used. r=bhackett --- js/src/jit-test/tests/ion/bug928625.js | 3 +++ js/src/jit/IonBuilder.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 js/src/jit-test/tests/ion/bug928625.js diff --git a/js/src/jit-test/tests/ion/bug928625.js b/js/src/jit-test/tests/ion/bug928625.js new file mode 100644 index 00000000000..1b5058e33fc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug928625.js @@ -0,0 +1,3 @@ +var summary = true; +evaluate("var summary = 'Array slice when arrays length is assigned';"); +evaluate('var summary;'); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index bbcabdce233..4186e4ec9a9 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6106,7 +6106,7 @@ IonBuilder::pushTypeBarrier(MInstruction *ins, types::TemporaryTypeSet *observed { // Barriers are never needed for instructions whose result will not be used. if (BytecodeIsPopped(pc)) - needsBarrier = false; + return true; // If the instruction has no side effects, we'll resume the entire operation. // The actual type barrier will occur in the interpreter. If the From eebde33be02e387ef23baf92cc1a597adf02cc51 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 22 Oct 2013 17:29:17 +0200 Subject: [PATCH 42/75] Bug 677952: Remove unused public version of Relation::operator=. r=tbsaunde --- accessible/src/base/Relation.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/accessible/src/base/Relation.h b/accessible/src/base/Relation.h index f76750dd108..bb2c0e7beac 100644 --- a/accessible/src/base/Relation.h +++ b/accessible/src/base/Relation.h @@ -56,13 +56,6 @@ public: return *this; } - Relation& operator = (Relation& aRelation) - { - mFirstIter = aRelation.mFirstIter; - mLastIter = aRelation.mLastIter; - return *this; - } - operator RelationCopyHelper() { return RelationCopyHelper(mFirstIter.forget(), mLastIter); From 28e6e2c644ea2e7ab7e38f8ad5e484cc21a740fc Mon Sep 17 00:00:00 2001 From: Arnaud Bienner Date: Wed, 10 Jul 2013 00:25:27 +0200 Subject: [PATCH 43/75] Bug 875275 part 1: Implement layout support for . r=dbaron,dholbert --- content/base/src/nsGkAtomList.h | 1 + content/html/content/src/HTMLInputElement.cpp | 9 ++ layout/base/RestyleManager.cpp | 5 + layout/base/nsCSSFrameConstructor.cpp | 1 + layout/forms/moz.build | 1 + layout/forms/nsColorControlFrame.cpp | 139 ++++++++++++++++++ layout/forms/nsColorControlFrame.h | 65 ++++++++ layout/generic/nsFrame.cpp | 1 + layout/generic/nsFrameIdList.h | 1 + layout/generic/nsHTMLParts.h | 2 + .../input/color/block-invalidate-1-ref.html | 7 + .../forms/input/color/block-invalidate-1.html | 14 ++ .../forms/input/color/custom-style-1-ref.html | 21 +++ .../forms/input/color/custom-style-1.html | 16 ++ .../forms/input/color/input-color-1-ref.html | 33 +++++ .../forms/input/color/input-color-1.html | 9 ++ .../input/color/margin-padding-1-ref.html | 88 +++++++++++ .../forms/input/color/margin-padding-1.html | 39 +++++ .../forms/input/color/reference-style.css | 24 +++ .../reftests/forms/input/color/reftest.list | 7 + .../input/color/transformations-1-ref.html | 78 ++++++++++ .../forms/input/color/transformations-1.html | 35 +++++ layout/reftests/forms/input/reftest.list | 1 + layout/style/forms.css | 14 ++ layout/style/nsCSSPseudoElementList.h | 2 + layout/style/nsCSSPseudoElements.h | 16 +- layout/style/nsHTMLCSSStyleSheet.cpp | 12 ++ layout/style/nsRuleProcessorData.h | 12 +- layout/style/nsStyleSet.cpp | 12 +- layout/style/nsStyleSet.h | 6 +- toolkit/devtools/styleinspector/css-logic.js | 1 + 31 files changed, 662 insertions(+), 10 deletions(-) create mode 100644 layout/forms/nsColorControlFrame.cpp create mode 100644 layout/forms/nsColorControlFrame.h create mode 100644 layout/reftests/forms/input/color/block-invalidate-1-ref.html create mode 100644 layout/reftests/forms/input/color/block-invalidate-1.html create mode 100644 layout/reftests/forms/input/color/custom-style-1-ref.html create mode 100644 layout/reftests/forms/input/color/custom-style-1.html create mode 100644 layout/reftests/forms/input/color/input-color-1-ref.html create mode 100644 layout/reftests/forms/input/color/input-color-1.html create mode 100644 layout/reftests/forms/input/color/margin-padding-1-ref.html create mode 100644 layout/reftests/forms/input/color/margin-padding-1.html create mode 100644 layout/reftests/forms/input/color/reference-style.css create mode 100644 layout/reftests/forms/input/color/reftest.list create mode 100644 layout/reftests/forms/input/color/transformations-1-ref.html create mode 100644 layout/reftests/forms/input/color/transformations-1.html diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 69761a4c3ad..fa8baf98799 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -1782,6 +1782,7 @@ GK_ATOM(blockFrame, "BlockFrame") GK_ATOM(boxFrame, "BoxFrame") GK_ATOM(brFrame, "BRFrame") GK_ATOM(bulletFrame, "BulletFrame") +GK_ATOM(colorControlFrame, "colorControlFrame") GK_ATOM(columnSetFrame, "ColumnSetFrame") GK_ATOM(comboboxControlFrame, "ComboboxControlFrame") GK_ATOM(comboboxDisplayFrame, "ComboboxDisplayFrame") diff --git a/content/html/content/src/HTMLInputElement.cpp b/content/html/content/src/HTMLInputElement.cpp index a3a27ec1243..9a03054fb15 100644 --- a/content/html/content/src/HTMLInputElement.cpp +++ b/content/html/content/src/HTMLInputElement.cpp @@ -2677,6 +2677,14 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue, OnValueChanged(!mParserCreating); } + // Call parent's SetAttr for color input so its control frame is notified + // and updated + if (mType == NS_FORM_INPUT_COLOR) { + return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None, + nsGkAtoms::value, aValue, + true); + } + return NS_OK; } @@ -3530,6 +3538,7 @@ HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) case NS_FORM_INPUT_RESET: case NS_FORM_INPUT_SUBMIT: case NS_FORM_INPUT_IMAGE: // Bug 34418 + case NS_FORM_INPUT_COLOR: { WidgetMouseEvent event(aVisitor.mEvent->mFlags.mIsTrusted, NS_MOUSE_CLICK, nullptr, diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 171c2151c81..a0a52c85e29 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2333,6 +2333,11 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint) // We're reframing anyway; just keep the same context newContext = oldContext; } + } else if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(pseudoTag)) { + newContext = styleSet->ResolvePseudoElementStyle(element, + pseudoType, + parentContext, + aSelf->GetContent()->AsElement()); } else { // Don't expect XUL tree stuff here, since it needs a comparator and // all. diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 4c418dd96fe..69548581923 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3383,6 +3383,7 @@ nsCSSFrameConstructor::FindInputData(Element* aElement, SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame), SIMPLE_INT_CREATE(NS_FORM_INPUT_RANGE, NS_NewRangeFrame), SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame), + SIMPLE_INT_CREATE(NS_FORM_INPUT_COLOR, NS_NewColorControlFrame), // TODO: this is temporary until a frame is written: bug 635240. SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame), // TODO: this is temporary until a frame is written: bug 773205. diff --git a/layout/forms/moz.build b/layout/forms/moz.build index ff06bf9815a..a30fe302134 100644 --- a/layout/forms/moz.build +++ b/layout/forms/moz.build @@ -18,6 +18,7 @@ EXPORTS += [ CPP_SOURCES += [ 'nsButtonFrameRenderer.cpp', + 'nsColorControlFrame.cpp', 'nsComboboxControlFrame.cpp', 'nsFieldSetFrame.cpp', 'nsFileControlFrame.cpp', diff --git a/layout/forms/nsColorControlFrame.cpp b/layout/forms/nsColorControlFrame.cpp new file mode 100644 index 00000000000..9e60fba9be2 --- /dev/null +++ b/layout/forms/nsColorControlFrame.cpp @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsColorControlFrame.h" + +#include "nsContentCreatorFunctions.h" +#include "nsContentList.h" +#include "nsContentUtils.h" +#include "nsFormControlFrame.h" +#include "nsGkAtoms.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMNode.h" +#include "nsStyleSet.h" + +nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext): + nsBlockFrame(aContext) +{ +} + +nsIFrame* +NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) +{ + return new (aPresShell) nsColorControlFrame(aContext); +} + +NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame) + +NS_QUERYFRAME_HEAD(nsColorControlFrame) + NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) +NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame) + + +void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot) +{ + nsFormControlFrame::RegUnRegAccessKey(static_cast(this), false); + nsContentUtils::DestroyAnonymousContent(&mColorContent); + nsBlockFrame::DestroyFrom(aDestructRoot); +} + +nsIAtom* +nsColorControlFrame::GetType() const +{ + return nsGkAtoms::colorControlFrame; +} + +#ifdef DEBUG +NS_IMETHODIMP +nsColorControlFrame::GetFrameName(nsAString& aResult) const +{ + return MakeFrameName(NS_LITERAL_STRING("ColorControl"), aResult); +} +#endif + +// Create the color area for the button. +// The frame will be generated by the frame constructor. +nsresult +nsColorControlFrame::CreateAnonymousContent(nsTArray& aElements) +{ + nsCOMPtr doc = mContent->GetCurrentDoc(); + nsCOMPtr nodeInfo = + doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nullptr, + kNameSpaceID_XHTML, + nsIDOMNode::ELEMENT_NODE); + + nsresult rv = NS_NewHTMLElement(getter_AddRefs(mColorContent), + nodeInfo.forget(), + mozilla::dom::NOT_FROM_PARSER); + NS_ENSURE_SUCCESS(rv, rv); + + // Mark the element to be native anonymous before setting any attributes. + mColorContent->SetIsNativeAnonymousRoot(); + + rv = UpdateColor(); + NS_ENSURE_SUCCESS(rv, rv); + + nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozColorSwatch; + nsRefPtr newStyleContext = PresContext()->StyleSet()-> + ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, + StyleContext(), mColorContent->AsElement()); + if (!aElements.AppendElement(ContentInfo(mColorContent, newStyleContext))) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; +} + +void +nsColorControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, + uint32_t aFilter) +{ + aElements.MaybeAppendElement(mColorContent); +} + +nsresult +nsColorControlFrame::UpdateColor() +{ + // Get the color from the "value" property of our content; it will return the + // default color (through the sanitization algorithm) if there is none. + nsAutoString color; + nsCOMPtr elt = do_QueryInterface(mContent); + elt->GetValue(color); + MOZ_ASSERT(!color.IsEmpty(), + "Content node's GetValue() should return a valid color string " + "(the default color, in case no valid color is set)"); + + // Set the background-color style property of the swatch element to this color + return mColorContent->SetAttr(kNameSpaceID_None, nsGkAtoms::style, + NS_LITERAL_STRING("background-color:") + color, true); +} + +NS_IMETHODIMP +nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) +{ + NS_ASSERTION(mColorContent, "The color div must exist"); + + // If the value attribute is set, update the color box + if (aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) { + UpdateColor(); + } + return nsBlockFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); +} + +nsIFrame* +nsColorControlFrame::GetContentInsertionFrame() +{ + return this; +} + +void +nsColorControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); +} diff --git a/layout/forms/nsColorControlFrame.h b/layout/forms/nsColorControlFrame.h new file mode 100644 index 00000000000..05129d3ab8c --- /dev/null +++ b/layout/forms/nsColorControlFrame.h @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsColorControlFrame_h___ +#define nsColorControlFrame_h___ + +#include "nsBlockFrame.h" +#include "nsCOMPtr.h" +#include "nsIAnonymousContentCreator.h" + +// Class which implements the input type=color + +class nsColorControlFrame MOZ_FINAL : public nsBlockFrame, + public nsIAnonymousContentCreator +{ +public: + friend nsIFrame* NS_NewColorControlFrame(nsIPresShell* aPresShell, + nsStyleContext* aContext); + + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + + NS_DECL_FRAMEARENA_HELPERS + NS_DECL_QUERYFRAME + + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsAString& aResult) const; +#endif + + // nsIAnonymousContentCreator + virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; + virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + uint32_t aFilter) MOZ_OVERRIDE; + + // nsIFrame + NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) MOZ_OVERRIDE; + virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } + virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE; + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) MOZ_OVERRIDE; + + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + { + return nsBlockFrame::IsFrameOfType(aFlags & + ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); + } + +private: + nsColorControlFrame(nsStyleContext* aContext); + + // Update the color swatch + nsresult UpdateColor(); + + nsCOMPtr mColorContent; +}; + + +#endif // nsColorControlFrame_h___ diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index a1634734fb1..02a12c27dc3 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -8893,6 +8893,7 @@ void DR_State::InitFrameTypeTable() AddFrameTypeInfo(nsGkAtoms::blockFrame, "block", "block"); AddFrameTypeInfo(nsGkAtoms::brFrame, "br", "br"); AddFrameTypeInfo(nsGkAtoms::bulletFrame, "bullet", "bullet"); + AddFrameTypeInfo(nsGkAtoms::colorControlFrame, "color", "colorControl"); AddFrameTypeInfo(nsGkAtoms::gfxButtonControlFrame, "button", "gfxButtonControl"); AddFrameTypeInfo(nsGkAtoms::HTMLButtonControlFrame, "HTMLbutton", "HTMLButtonControl"); AddFrameTypeInfo(nsGkAtoms::HTMLCanvasFrame, "HTMLCanvas","HTMLCanvas"); diff --git a/layout/generic/nsFrameIdList.h b/layout/generic/nsFrameIdList.h index e6dd9764b54..2aaee9c721f 100644 --- a/layout/generic/nsFrameIdList.h +++ b/layout/generic/nsFrameIdList.h @@ -11,6 +11,7 @@ FRAME_ID(nsBoxFrame) FRAME_ID(nsBulletFrame) FRAME_ID(nsButtonBoxFrame) FRAME_ID(nsCanvasFrame) +FRAME_ID(nsColorControlFrame) FRAME_ID(nsColumnSetFrame) FRAME_ID(nsComboboxControlFrame) FRAME_ID(nsComboboxDisplayFrame) diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h index e19cb7f0e82..7df6fc10a65 100644 --- a/layout/generic/nsHTMLParts.h +++ b/layout/generic/nsHTMLParts.h @@ -168,6 +168,8 @@ NS_NewFieldSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewFileControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* +NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); +nsIFrame* NS_NewLegendFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewNativeTextControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); diff --git a/layout/reftests/forms/input/color/block-invalidate-1-ref.html b/layout/reftests/forms/input/color/block-invalidate-1-ref.html new file mode 100644 index 00000000000..c10a3fe2276 --- /dev/null +++ b/layout/reftests/forms/input/color/block-invalidate-1-ref.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/layout/reftests/forms/input/color/block-invalidate-1.html b/layout/reftests/forms/input/color/block-invalidate-1.html new file mode 100644 index 00000000000..fb79067ad47 --- /dev/null +++ b/layout/reftests/forms/input/color/block-invalidate-1.html @@ -0,0 +1,14 @@ + + + + + + + diff --git a/layout/reftests/forms/input/color/custom-style-1-ref.html b/layout/reftests/forms/input/color/custom-style-1-ref.html new file mode 100644 index 00000000000..ebb537b1d41 --- /dev/null +++ b/layout/reftests/forms/input/color/custom-style-1-ref.html @@ -0,0 +1,21 @@ + + + + + +
+
+
+
+ + diff --git a/layout/reftests/forms/input/color/custom-style-1.html b/layout/reftests/forms/input/color/custom-style-1.html new file mode 100644 index 00000000000..2f514ae4e2a --- /dev/null +++ b/layout/reftests/forms/input/color/custom-style-1.html @@ -0,0 +1,16 @@ + + + + + + diff --git a/layout/reftests/forms/input/color/input-color-1-ref.html b/layout/reftests/forms/input/color/input-color-1-ref.html new file mode 100644 index 00000000000..698e5f721c7 --- /dev/null +++ b/layout/reftests/forms/input/color/input-color-1-ref.html @@ -0,0 +1,33 @@ + + + + + + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ + diff --git a/layout/reftests/forms/input/color/input-color-1.html b/layout/reftests/forms/input/color/input-color-1.html new file mode 100644 index 00000000000..a351df18fcb --- /dev/null +++ b/layout/reftests/forms/input/color/input-color-1.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/layout/reftests/forms/input/color/margin-padding-1-ref.html b/layout/reftests/forms/input/color/margin-padding-1-ref.html new file mode 100644 index 00000000000..c08e39bac88 --- /dev/null +++ b/layout/reftests/forms/input/color/margin-padding-1-ref.html @@ -0,0 +1,88 @@ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/layout/reftests/forms/input/color/margin-padding-1.html b/layout/reftests/forms/input/color/margin-padding-1.html new file mode 100644 index 00000000000..e394d5d29b7 --- /dev/null +++ b/layout/reftests/forms/input/color/margin-padding-1.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/forms/input/color/reference-style.css b/layout/reftests/forms/input/color/reference-style.css new file mode 100644 index 00000000000..b54a0c05f64 --- /dev/null +++ b/layout/reftests/forms/input/color/reference-style.css @@ -0,0 +1,24 @@ + +div.input-color { + display: inline-block; + -moz-appearance: textfield; + padding: 1px 0px 1px 0px; + color: ButtonText; + text-align: center; + text-shadow: none; + line-height: normal; + font: -moz-button; +} + +div.input-color-swatch { + border-width: 0px; + width: 100%; + height: 100%; + min-width: 50px; + min-height: 1em; + margin-left: auto; + margin-right: auto; + text-align: center; + display: block; + background-color:#000000; /* default color for input type color */ +} diff --git a/layout/reftests/forms/input/color/reftest.list b/layout/reftests/forms/input/color/reftest.list new file mode 100644 index 00000000000..d1652b26db2 --- /dev/null +++ b/layout/reftests/forms/input/color/reftest.list @@ -0,0 +1,7 @@ +default-preferences pref(dom.forms.color,true) + +== input-color-1.html input-color-1-ref.html +== margin-padding-1.html margin-padding-1-ref.html +== block-invalidate-1.html block-invalidate-1-ref.html +== transformations-1.html transformations-1-ref.html +== custom-style-1.html custom-style-1-ref.html diff --git a/layout/reftests/forms/input/color/transformations-1-ref.html b/layout/reftests/forms/input/color/transformations-1-ref.html new file mode 100644 index 00000000000..b8b36e5c433 --- /dev/null +++ b/layout/reftests/forms/input/color/transformations-1-ref.html @@ -0,0 +1,78 @@ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/layout/reftests/forms/input/color/transformations-1.html b/layout/reftests/forms/input/color/transformations-1.html new file mode 100644 index 00000000000..67bb4b3c9f8 --- /dev/null +++ b/layout/reftests/forms/input/color/transformations-1.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/forms/input/reftest.list b/layout/reftests/forms/input/reftest.list index 4287bc4387e..40eb682c286 100644 --- a/layout/reftests/forms/input/reftest.list +++ b/layout/reftests/forms/input/reftest.list @@ -9,3 +9,4 @@ include range/reftest.list include text/reftest.list include percentage/reftest.list include hidden/reftest.list +include color/reftest.list diff --git a/layout/style/forms.css b/layout/style/forms.css index e7ca79e988f..73c370505ac 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -449,6 +449,20 @@ input[type="file"] > button[type="button"] { cursor: inherit; } +/* colored part of the color selector button */ +input[type="color"] > div, +input[type="color"]::-moz-color-swatch { + border-width: 0px; + width: 100%; + height: 100%; + min-width: 50px; + min-height: 1em; + margin-left: auto; + margin-right: auto; + text-align: center; + display: block; +} + /* Try to make RTL look nicer. */ /* TODO: use text-align: match-parent when bug 645642 is fixed. */ input[type="file"]:-moz-dir(rtl) > xul|label { diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h index dccb1eace78..a06b98c62ad 100644 --- a/layout/style/nsCSSPseudoElementList.h +++ b/layout/style/nsCSSPseudoElementList.h @@ -58,3 +58,5 @@ CSS_PSEUDO_ELEMENT(mozRangeProgress, ":-moz-range-progress", 0) CSS_PSEUDO_ELEMENT(mozRangeThumb, ":-moz-range-thumb", 0) CSS_PSEUDO_ELEMENT(mozMeterBar, ":-moz-meter-bar", 0) CSS_PSEUDO_ELEMENT(mozPlaceholder, ":-moz-placeholder", 0) +CSS_PSEUDO_ELEMENT(mozColorSwatch, ":-moz-color-swatch", + CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE) diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 3b8bce1f2ce..5ff9af4221c 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -13,7 +13,7 @@ // Is this pseudo-element a CSS2 pseudo-element that can be specified // with the single colon syntax (in addition to the double-colon syntax, // which can be used for all pseudo-elements)? -#define CSS_PSEUDO_ELEMENT_IS_CSS2 (1<<0) +#define CSS_PSEUDO_ELEMENT_IS_CSS2 (1<<0) // Is this pseudo-element a pseudo-element that can contain other // elements? // (Currently pseudo-elements are either leaves of the tree (relative to @@ -22,7 +22,10 @@ // possible that in the future there might be container pseudo-elements // that form a properly nested tree structure. If that happens, we // should probably split this flag into two.) -#define CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS (1<<1) +#define CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS (1<<1) +// Flag to add the ability to take into account style attribute set for the +// pseudo element (by default it's ignored). +#define CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE (1<<2) // Empty class derived from nsIAtom so that function signatures can // require an atom from this atom list. @@ -67,6 +70,15 @@ public: // Get the atom for a given Type. aType must be < ePseudo_PseudoElementCount static nsIAtom* GetPseudoAtom(Type aType); + static bool PseudoElementSupportsStyleAttribute(nsIAtom *aAtom) { + return PseudoElementHasFlags(aAtom, CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE); + } + + static bool PseudoElementSupportsStyleAttribute(const Type aType) { + MOZ_ASSERT(aType < ePseudo_PseudoElementCount); + return PseudoElementHasFlags(GetPseudoAtom(aType), CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE); + } + private: static uint32_t FlagsForPseudoElement(nsIAtom *aAtom); diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index cad6e7ecbb7..3060132b0be 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -84,6 +84,18 @@ nsHTMLCSSStyleSheet::RulesMatching(ElementRuleProcessorData* aData) /* virtual */ void nsHTMLCSSStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData) { + if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aData->mPseudoType)) { + MOZ_ASSERT(aData->mPseudoElement, + "If pseudo element is supposed to support style attribute, it must " + "have a pseudo element set"); + + // just get the one and only style rule from the content's STYLE attribute + css::StyleRule* rule = aData->mPseudoElement->GetInlineStyleRule(); + if (rule) { + rule->RuleMatched(); + aData->mRuleWalker->Forward(rule); + } + } } /* virtual */ void diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index 4ec7ef88377..d66f83f7483 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -449,19 +449,27 @@ struct MOZ_STACK_CLASS PseudoElementRuleProcessorData : mozilla::dom::Element* aParentElement, nsRuleWalker* aRuleWalker, nsCSSPseudoElements::Type aPseudoType, - TreeMatchContext& aTreeMatchContext) + TreeMatchContext& aTreeMatchContext, + mozilla::dom::Element* aPseudoElement) : ElementDependentRuleProcessorData(aPresContext, aParentElement, aRuleWalker, aTreeMatchContext), - mPseudoType(aPseudoType) + mPseudoType(aPseudoType), + mPseudoElement(aPseudoElement) { NS_PRECONDITION(aPseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount, "invalid aPseudoType value"); NS_PRECONDITION(aTreeMatchContext.mForStyling, "Styling here!"); NS_PRECONDITION(aRuleWalker, "Must have rule walker"); + if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aPseudoType)) { + NS_PRECONDITION(aPseudoElement, + "If pseudo element is supposed to support style attribute, it must " + "have a pseudo element set"); + } } nsCSSPseudoElements::Type mPseudoType; + mozilla::dom::Element* const mPseudoElement; // weak ref }; struct MOZ_STACK_CLASS AnonBoxRuleProcessorData : public RuleProcessorData { diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 071aa864acf..5a3ad898aba 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -1335,7 +1335,8 @@ nsStyleSet::WalkDisableTextZoomRule(Element* aElement, nsRuleWalker* aRuleWalker already_AddRefed nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, nsCSSPseudoElements::Type aType, - nsStyleContext* aParentContext) + nsStyleContext* aParentContext, + Element* aPseudoElement) { NS_ENSURE_FALSE(mInShutdown, nullptr); @@ -1348,7 +1349,8 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement, aParentElement->OwnerDoc()); InitAncestorsIfInStyleScope(treeContext, aParentElement); PseudoElementRuleProcessorData data(PresContext(), aParentElement, - &ruleWalker, aType, treeContext); + &ruleWalker, aType, treeContext, + aPseudoElement); WalkRestrictionRule(aType, &ruleWalker); FileRules(EnumRulesMatching, &data, aParentElement, &ruleWalker); @@ -1399,7 +1401,8 @@ already_AddRefed nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, nsCSSPseudoElements::Type aType, nsStyleContext* aParentContext, - TreeMatchContext& aTreeMatchContext) + TreeMatchContext& aTreeMatchContext, + Element* aPseudoElement) { NS_ENSURE_FALSE(mInShutdown, nullptr); @@ -1411,7 +1414,8 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement, nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled); aTreeMatchContext.ResetForUnvisitedMatching(); PseudoElementRuleProcessorData data(PresContext(), aParentElement, - &ruleWalker, aType, aTreeMatchContext); + &ruleWalker, aType, aTreeMatchContext, + aPseudoElement); WalkRestrictionRule(aType, &ruleWalker); // not the root if there was a restriction rule nsRuleNode *adjustedRoot = ruleWalker.CurrentNode(); diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 772597677f2..85c7d91bc8d 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -133,7 +133,8 @@ class nsStyleSet already_AddRefed ResolvePseudoElementStyle(mozilla::dom::Element* aParentElement, nsCSSPseudoElements::Type aType, - nsStyleContext* aParentContext); + nsStyleContext* aParentContext, + mozilla::dom::Element* aPseudoElement = nullptr); // This functions just like ResolvePseudoElementStyle except that it will // return nullptr if there are no explicit style rules for that @@ -146,7 +147,8 @@ class nsStyleSet ProbePseudoElementStyle(mozilla::dom::Element* aParentElement, nsCSSPseudoElements::Type aType, nsStyleContext* aParentContext, - TreeMatchContext& aTreeMatchContext); + TreeMatchContext& aTreeMatchContext, + mozilla::dom::Element* aPseudoElement = nullptr); // Get a style context for an anonymous box. aPseudoTag is the // pseudo-tag to use and must be non-null. diff --git a/toolkit/devtools/styleinspector/css-logic.js b/toolkit/devtools/styleinspector/css-logic.js index 012d02ced24..168efc1ca00 100644 --- a/toolkit/devtools/styleinspector/css-logic.js +++ b/toolkit/devtools/styleinspector/css-logic.js @@ -1376,6 +1376,7 @@ CssSelector.prototype = { pseudos.add("first-letter"); pseudos.add("first-line"); pseudos.add("selection"); + pseudos.add("-moz-color-swatch"); pseudos.add("-moz-focus-inner"); pseudos.add("-moz-focus-outer"); pseudos.add("-moz-list-bullet"); From 376a58f5a1dad5b61984cbdaac301a4e50013c83 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 22 Oct 2013 17:29:20 +0200 Subject: [PATCH 44/75] Bug 875275 part 2: simplify forms.css for input[type="color"]. r=arnaud.bienner --- layout/style/forms.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/style/forms.css b/layout/style/forms.css index 73c370505ac..e13c1426a30 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -450,16 +450,13 @@ input[type="file"] > button[type="button"] { } /* colored part of the color selector button */ -input[type="color"] > div, input[type="color"]::-moz-color-swatch { - border-width: 0px; width: 100%; height: 100%; min-width: 50px; min-height: 1em; margin-left: auto; margin-right: auto; - text-align: center; display: block; } @@ -538,6 +535,9 @@ input[type="radio"]:hover:active { /* Note: Values in nsNativeTheme IsWidgetStyled function need to match button background/border values here */ +/* TODO: Once we're getting ready to turn on 'dom.forms.color' by default, we + probably want to add input[type="color"] to this selector list, so that it + gets the same styling as other form buttons. */ button, input[type="reset"], input[type="button"], From 4c1ad784d2fc4b7570fd6a77f5c143e0f854ab6b Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 22 Oct 2013 17:29:20 +0200 Subject: [PATCH 45/75] Bug 875275 part 3: Make nsColorControlFrame inherit from nsHTMLButtonControlFrame instead of nsBlockFrame. r=jwatt f=arnaud.bienner --- layout/base/RestyleManager.cpp | 12 ++++++++++++ layout/base/nsCSSFrameConstructor.cpp | 4 +++- layout/forms/nsColorControlFrame.cpp | 17 +++++------------ layout/forms/nsColorControlFrame.h | 18 +++++------------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index a0a52c85e29..2f52c342cbd 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1712,6 +1712,18 @@ ElementForStyleContext(nsIContent* aParentContent, return block->GetContent()->AsElement(); } + if (aPseudoType == nsCSSPseudoElements::ePseudo_mozColorSwatch) { + MOZ_ASSERT(aFrame->GetParent() && + aFrame->GetParent()->GetParent(), + "Color swatch frame should have a parent & grandparent"); + + nsIFrame* grandparentFrame = aFrame->GetParent()->GetParent(); + MOZ_ASSERT(grandparentFrame->GetType() == nsGkAtoms::colorControlFrame, + "Color swatch's grandparent should be nsColorControlFrame"); + + return grandparentFrame->GetContent()->AsElement(); + } + nsIContent* content = aParentContent ? aParentContent : aFrame->GetContent(); return content->AsElement(); } diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 69548581923..ee95ab33f64 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3383,7 +3383,9 @@ nsCSSFrameConstructor::FindInputData(Element* aElement, SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame), SIMPLE_INT_CREATE(NS_FORM_INPUT_RANGE, NS_NewRangeFrame), SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame), - SIMPLE_INT_CREATE(NS_FORM_INPUT_COLOR, NS_NewColorControlFrame), + { NS_FORM_INPUT_COLOR, + FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewColorControlFrame, + nsCSSAnonBoxes::buttonContent) }, // TODO: this is temporary until a frame is written: bug 635240. SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame), // TODO: this is temporary until a frame is written: bug 773205. diff --git a/layout/forms/nsColorControlFrame.cpp b/layout/forms/nsColorControlFrame.cpp index 9e60fba9be2..62e262f0e26 100644 --- a/layout/forms/nsColorControlFrame.cpp +++ b/layout/forms/nsColorControlFrame.cpp @@ -15,7 +15,7 @@ #include "nsStyleSet.h" nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext): - nsBlockFrame(aContext) + nsColorControlFrameSuper(aContext) { } @@ -29,14 +29,14 @@ NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame) NS_QUERYFRAME_HEAD(nsColorControlFrame) NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) -NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsColorControlFrameSuper) void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot) { nsFormControlFrame::RegUnRegAccessKey(static_cast(this), false); nsContentUtils::DestroyAnonymousContent(&mColorContent); - nsBlockFrame::DestroyFrom(aDestructRoot); + nsColorControlFrameSuper::DestroyFrom(aDestructRoot); } nsIAtom* @@ -121,7 +121,8 @@ nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID, if (aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) { UpdateColor(); } - return nsBlockFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); + return nsColorControlFrameSuper::AttributeChanged(aNameSpaceID, aAttribute, + aModType); } nsIFrame* @@ -129,11 +130,3 @@ nsColorControlFrame::GetContentInsertionFrame() { return this; } - -void -nsColorControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) -{ - BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); -} diff --git a/layout/forms/nsColorControlFrame.h b/layout/forms/nsColorControlFrame.h index 05129d3ab8c..cd2ea248d09 100644 --- a/layout/forms/nsColorControlFrame.h +++ b/layout/forms/nsColorControlFrame.h @@ -6,13 +6,15 @@ #ifndef nsColorControlFrame_h___ #define nsColorControlFrame_h___ -#include "nsBlockFrame.h" #include "nsCOMPtr.h" +#include "nsHTMLButtonControlFrame.h" #include "nsIAnonymousContentCreator.h" +typedef nsHTMLButtonControlFrame nsColorControlFrameSuper; + // Class which implements the input type=color -class nsColorControlFrame MOZ_FINAL : public nsBlockFrame, +class nsColorControlFrame MOZ_FINAL : public nsColorControlFrameSuper, public nsIAnonymousContentCreator { public: @@ -27,7 +29,7 @@ public: virtual nsIAtom* GetType() const MOZ_OVERRIDE; #ifdef DEBUG - NS_IMETHOD GetFrameName(nsAString& aResult) const; + NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; #endif // nsIAnonymousContentCreator @@ -42,16 +44,6 @@ public: virtual bool IsLeaf() const MOZ_OVERRIDE { return true; } virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE; - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) MOZ_OVERRIDE; - - virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE - { - return nsBlockFrame::IsFrameOfType(aFlags & - ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); - } - private: nsColorControlFrame(nsStyleContext* aContext); From 6ce735d94af056ae7d3fe8c05f9a50ae032cd4b4 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 22 Oct 2013 17:29:21 +0200 Subject: [PATCH 46/75] Bug 875275 part 4: Fix reftests to adjust for being button-based. r=arnaud.bienner --- .../input/color/block-invalidate-1-ref.html | 1 - .../forms/input/color/custom-style-1-ref.html | 6 +- .../forms/input/color/input-color-1-ref.html | 24 ++--- .../input/color/margin-padding-1-ref.html | 96 +++++++++---------- .../forms/input/color/reference-style.css | 21 ++-- .../input/color/transformations-1-ref.html | 84 ++++++++-------- 6 files changed, 114 insertions(+), 118 deletions(-) diff --git a/layout/reftests/forms/input/color/block-invalidate-1-ref.html b/layout/reftests/forms/input/color/block-invalidate-1-ref.html index c10a3fe2276..027c1e2b577 100644 --- a/layout/reftests/forms/input/color/block-invalidate-1-ref.html +++ b/layout/reftests/forms/input/color/block-invalidate-1-ref.html @@ -1,6 +1,5 @@ - diff --git a/layout/reftests/forms/input/color/custom-style-1-ref.html b/layout/reftests/forms/input/color/custom-style-1-ref.html index ebb537b1d41..13326af59d9 100644 --- a/layout/reftests/forms/input/color/custom-style-1-ref.html +++ b/layout/reftests/forms/input/color/custom-style-1-ref.html @@ -2,7 +2,7 @@ -
+
+ diff --git a/layout/reftests/forms/input/color/input-color-1-ref.html b/layout/reftests/forms/input/color/input-color-1-ref.html index 698e5f721c7..99087c53cc7 100644 --- a/layout/reftests/forms/input/color/input-color-1-ref.html +++ b/layout/reftests/forms/input/color/input-color-1-ref.html @@ -3,31 +3,31 @@ -
+
+ -
+
+ -
+
+ -
+
+ diff --git a/layout/reftests/forms/input/color/margin-padding-1-ref.html b/layout/reftests/forms/input/color/margin-padding-1-ref.html index c08e39bac88..e32ee72ca88 100644 --- a/layout/reftests/forms/input/color/margin-padding-1-ref.html +++ b/layout/reftests/forms/input/color/margin-padding-1-ref.html @@ -2,87 +2,87 @@ -
+
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
+ diff --git a/layout/reftests/forms/input/color/reference-style.css b/layout/reftests/forms/input/color/reference-style.css index b54a0c05f64..6a8274a7dca 100644 --- a/layout/reftests/forms/input/color/reference-style.css +++ b/layout/reftests/forms/input/color/reference-style.css @@ -1,24 +1,21 @@ - -div.input-color { - display: inline-block; +button.input-color { + /* For now, input[type="color"] is styled like a textfield, because it takes + the default 'input' styles in forms.css. Once we're ready to enable it by + default, that will change (and so should these styles here). */ -moz-appearance: textfield; padding: 1px 0px 1px 0px; - color: ButtonText; - text-align: center; - text-shadow: none; - line-height: normal; - font: -moz-button; +} +button.input-color::-moz-focus-inner { + padding: 0; + border: 0; } div.input-color-swatch { - border-width: 0px; + /* This should match the styling for ::-moz-color-swatch in forms.css. */ width: 100%; height: 100%; min-width: 50px; min-height: 1em; - margin-left: auto; - margin-right: auto; - text-align: center; display: block; background-color:#000000; /* default color for input type color */ } diff --git a/layout/reftests/forms/input/color/transformations-1-ref.html b/layout/reftests/forms/input/color/transformations-1-ref.html index b8b36e5c433..fba5093f709 100644 --- a/layout/reftests/forms/input/color/transformations-1-ref.html +++ b/layout/reftests/forms/input/color/transformations-1-ref.html @@ -2,77 +2,77 @@ -
+
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
-
+ +
+ From 78972e3f6643b676556cfb6292bc146092e4a5cf Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Tue, 22 Oct 2013 17:29:21 +0200 Subject: [PATCH 47/75] Bug 875275 part 5: Fix reftests to set padding in author stylesheet in testcase when it's set in reference. r=arnaud.bienner --- .../forms/input/color/custom-style-1-ref.html | 2 -- .../forms/input/color/custom-style-1.html | 3 +-- .../forms/input/color/input-color-1.html | 1 + .../forms/input/color/testcase-style.css | 17 +++++++++++++++++ .../forms/input/color/transformations-1.html | 1 + 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 layout/reftests/forms/input/color/testcase-style.css diff --git a/layout/reftests/forms/input/color/custom-style-1-ref.html b/layout/reftests/forms/input/color/custom-style-1-ref.html index 13326af59d9..fa550d83b6a 100644 --- a/layout/reftests/forms/input/color/custom-style-1-ref.html +++ b/layout/reftests/forms/input/color/custom-style-1-ref.html @@ -4,8 +4,6 @@