From deb2e761b17b4f553e06abde550158337519dec7 Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Fri, 15 Aug 2014 13:56:57 -0400 Subject: [PATCH 001/101] Bug 1042542, Rollup popups when a window is minimized, r=karlt --- widget/gtk/nsWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 789329e3b4c3..80d2deab87b3 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3230,6 +3230,8 @@ nsWindow::OnWindowStateEvent(GtkWidget *aWidget, GdkEventWindowState *aEvent) return; } + CheckForRollup(0, 0, false, true); + if (aEvent->new_window_state & GDK_WINDOW_STATE_ICONIFIED) { LOG(("\tIconified\n")); mSizeState = nsSizeMode_Minimized; From df48ffb1b70adfdf09a19e4a59c6989d41dcf078 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 7 Aug 2014 17:44:08 -0400 Subject: [PATCH 002/101] Bug 1016539. Add support for accelerated a11y filters. r=mwoodrow This adds the ability to render to a temporary surface and use that to apply a filter effect to all of the content. --- gfx/layers/CompositorTypes.h | 1 + gfx/layers/Effects.cpp | 8 +++ gfx/layers/Effects.h | 21 ++++++ gfx/layers/LayersLogging.cpp | 16 +++++ gfx/layers/LayersLogging.h | 4 ++ .../composite/LayerManagerComposite.cpp | 67 +++++++++++++++++++ gfx/layers/composite/LayerManagerComposite.h | 5 ++ .../opengl/CompositingRenderTargetOGL.h | 4 +- gfx/layers/opengl/CompositorOGL.cpp | 14 +++- gfx/layers/opengl/CompositorOGL.h | 3 +- gfx/layers/opengl/OGLShaderProgram.cpp | 2 + gfx/layers/opengl/OGLShaderProgram.h | 10 ++- gfx/thebes/gfxPrefs.h | 2 + 13 files changed, 150 insertions(+), 7 deletions(-) diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index bd07e03cccc2..6e3ca5b0bea0 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -143,6 +143,7 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticFlags) MOZ_BEGIN_ENUM_CLASS(EffectTypes, uint8_t) MASK, BLEND_MODE, + COLOR_MATRIX, MAX_SECONDARY, // sentinel for the count of secondary effect types RGB, YCBCR, diff --git a/gfx/layers/Effects.cpp b/gfx/layers/Effects.cpp index cbea5dc3d0d4..84fef6f7c0db 100644 --- a/gfx/layers/Effects.cpp +++ b/gfx/layers/Effects.cpp @@ -61,3 +61,11 @@ EffectBlendMode::PrintInfo(std::stringstream& aStream, const char* aPrefix) aStream << nsPrintfCString("EffectBlendMode (0x%p) [blendmode=%i]", this, (int)mBlendMode).get(); } +void +EffectColorMatrix::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("EffectColorMatrix (0x%p)", this).get(); + AppendToString(aStream, mColorMatrix, " [matrix=", "]"); +} + diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index 68d9a5dbdae8..e52ecdc41f1b 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -121,8 +121,29 @@ struct EffectRenderTarget : public TexturedEffect virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); RefPtr mRenderTarget; + +protected: + EffectRenderTarget(EffectTypes aType, CompositingRenderTarget *aRenderTarget) + : TexturedEffect(aType, aRenderTarget, true, gfx::Filter::LINEAR) + , mRenderTarget(aRenderTarget) + {} + }; +// Render to a render target rather than the screen. +struct EffectColorMatrix : public Effect +{ + EffectColorMatrix(gfx::Matrix5x4 aMatrix) + : Effect(EffectTypes::COLOR_MATRIX) + , mColorMatrix(aMatrix) + {} + + virtual const char* Name() { return "EffectColorMatrix"; } + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + const gfx::Matrix5x4 mColorMatrix; +}; + + struct EffectRGB : public TexturedEffect { EffectRGB(TextureSource *aTexture, diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index 7e541cf8c2d7..54b4a3966fc5 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -169,6 +169,22 @@ AppendToString(std::stringstream& aStream, const Matrix4x4& m, aStream << sfx; } +void +AppendToString(std::stringstream& aStream, const Matrix5x4& m, + const char* pfx, const char* sfx) +{ + aStream << pfx; + aStream << nsPrintfCString( + "[ %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]", + m._11, m._12, m._13, m._14, + m._21, m._22, m._23, m._24, + m._31, m._32, m._33, m._34, + m._41, m._42, m._43, m._44, + m._51, m._52, m._53, m._54).get(); + aStream << sfx; +} + + void AppendToString(std::stringstream& aStream, const Filter filter, const char* pfx, const char* sfx) diff --git a/gfx/layers/LayersLogging.h b/gfx/layers/LayersLogging.h index 27ed41a4a168..d6517e5d668d 100644 --- a/gfx/layers/LayersLogging.h +++ b/gfx/layers/LayersLogging.h @@ -139,6 +139,10 @@ void AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m, const char* pfx="", const char* sfx=""); +void +AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix5x4& m, + const char* pfx="", const char* sfx=""); + void AppendToString(std::stringstream& aStream, const mozilla::gfx::Filter filter, const char* pfx="", const char* sfx=""); diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index d9c825fd48d4..5523fe59133a 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -410,6 +410,58 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds) } } +RefPtr +LayerManagerComposite::PushGroup() +{ + RefPtr previousTarget = mCompositor->GetCurrentRenderTarget(); + // make our render target the same size as the destination target + // so that we don't have to change size if the drawing area changes. + IntRect rect(previousTarget->GetOrigin(), previousTarget->GetSize()); + // XXX: I'm not sure if this is true or not... + MOZ_ASSERT(rect.x == 0 && rect.y == 0); + if (!mTwoPassTmpTarget || + mTwoPassTmpTarget->GetSize() != previousTarget->GetSize() || + mTwoPassTmpTarget->GetOrigin() != previousTarget->GetOrigin()) { + mTwoPassTmpTarget = mCompositor->CreateRenderTarget(rect, INIT_MODE_NONE); + } + mCompositor->SetRenderTarget(mTwoPassTmpTarget); + return previousTarget; +} +void LayerManagerComposite::PopGroup(RefPtr aPreviousTarget, nsIntRect aClipRect) +{ + mCompositor->SetRenderTarget(aPreviousTarget); + + EffectChain effectChain(RootLayer()); + Matrix5x4 matrix; + if (gfxPrefs::Grayscale()) { + matrix._11 = matrix._12 = matrix._13 = 0.2126f; + matrix._21 = matrix._22 = matrix._23 = 0.7152f; + matrix._31 = matrix._32 = matrix._33 = 0.0722f; + } + + if (gfxPrefs::Invert()) { + matrix._11 = -matrix._11; + matrix._12 = -matrix._12; + matrix._13 = -matrix._13; + matrix._21 = -matrix._21; + matrix._22 = -matrix._22; + matrix._23 = -matrix._23; + matrix._31 = -matrix._31; + matrix._32 = -matrix._32; + matrix._33 = -matrix._33; + matrix._51 = 1; + matrix._52 = 1; + matrix._53 = 1; + } + + effectChain.mPrimaryEffect = new EffectRenderTarget(mTwoPassTmpTarget); + effectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX] = new EffectColorMatrix(matrix); + + gfx::Rect clipRectF(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); + mCompositor->DrawQuad(Rect(Point(0, 0), Size(mTwoPassTmpTarget->GetSize())), clipRectF, effectChain, 1., + Matrix4x4()); +} + void LayerManagerComposite::Render() { @@ -442,6 +494,10 @@ LayerManagerComposite::Render() LayerScope::SendLayerDump(Move(packet)); } + if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) { + composer2D = nullptr; + } + if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) { if (mFPS) { double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now()); @@ -501,6 +557,13 @@ LayerManagerComposite::Render() actualBounds.width, actualBounds.height)); + RefPtr previousTarget; + if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) { + previousTarget = PushGroup(); + } else { + mTwoPassTmpTarget = nullptr; + } + // Render our layers. RootLayer()->Prepare(clipRect); RootLayer()->RenderLayer(clipRect); @@ -513,6 +576,10 @@ LayerManagerComposite::Render() } } + if (mTwoPassTmpTarget) { + PopGroup(previousTarget, clipRect); + } + // Allow widget to render a custom foreground. mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x, actualBounds.y, diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 555b551bdd1e..b7589c635984 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -63,6 +63,7 @@ class SurfaceDescriptor; class ThebesLayerComposite; class TiledLayerComposer; class TextRenderer; +class CompositingRenderTarget; struct FPSState; class LayerManagerComposite : public LayerManager @@ -268,6 +269,9 @@ private: void WorldTransformRect(nsIntRect& aRect); + RefPtr PushGroup(); + void PopGroup(RefPtr aPreviousTarget, nsIntRect aClipRect); + RefPtr mCompositor; nsAutoPtr mClonedLayerTreeProperties; @@ -285,6 +289,7 @@ private: bool mIsCompositorReady; bool mDebugOverlayWantsNextFrame; + RefPtr mTwoPassTmpTarget; RefPtr mTextRenderer; bool mGeometryChanged; }; diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.h b/gfx/layers/opengl/CompositingRenderTargetOGL.h index 647db1127482..485ca39abb29 100644 --- a/gfx/layers/opengl/CompositingRenderTargetOGL.h +++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h @@ -137,9 +137,7 @@ public: } gfx::IntSize GetSize() const MOZ_OVERRIDE { - // XXX - Bug 900770 - MOZ_ASSERT(false, "CompositingRenderTargetOGL should not be used as a TextureSource"); - return gfx::IntSize(0, 0); + return mInitParams.mSize; } gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 60ea8ffbff1d..648e79c45d26 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -897,7 +897,8 @@ CompositorOGL::CreateFBOWithTexture(const IntRect& aRect, bool aCopyFromSource, ShaderConfigOGL CompositorOGL::GetShaderConfigFor(Effect *aEffect, MaskType aMask, - gfx::CompositionOp aOp) const + gfx::CompositionOp aOp, + bool aColorMatrix) const { ShaderConfigOGL config; @@ -944,6 +945,7 @@ CompositorOGL::GetShaderConfigFor(Effect *aEffect, break; } } + config.SetColorMatrix(aColorMatrix); config.SetMask2D(aMask == MaskType::Mask2d); config.SetMask3D(aMask == MaskType::Mask3d); return config; @@ -1091,12 +1093,20 @@ CompositorOGL::DrawQuad(const Rect& aRect, blendMode = blendEffect->mBlendMode; } - ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode); + bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX]; + ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode, colorMatrix); config.SetOpacity(aOpacity != 1.f); ShaderProgramOGL *program = GetShaderProgramFor(config); program->Activate(); program->SetProjectionMatrix(mProjMatrix); program->SetLayerTransform(aTransform); + + if (colorMatrix) { + EffectColorMatrix* effectColorMatrix = + static_cast(aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get()); + program->SetColorMatrix(effectColorMatrix->mColorMatrix); + } + IntPoint offset = mCurrentRenderTarget->GetOrigin(); program->SetRenderOffset(offset.x, offset.y); if (aOpacity != 1.f) diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 86edc0219921..4e959c06fa67 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -333,7 +333,8 @@ private: ShaderConfigOGL GetShaderConfigFor(Effect *aEffect, MaskType aMask = MaskType::MaskNone, - gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER) const; + gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER, + bool aColorMatrix = false) const; ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig); /** diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index 22075b07a4ae..4cf0733f152b 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -47,6 +47,8 @@ AddUniforms(ProgramProfileOGL& aProfile) "uRenderColor", "uTexCoordMultiplier", "uTexturePass2", + "uColorMatrix", + "uColorMatrixVector", nullptr }; diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index c6a9c4ce0f08..51ecaaeed360 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -68,6 +68,8 @@ public: RenderColor, TexCoordMultiplier, TexturePass2, + ColorMatrix, + ColorMatrixVector, KnownUniformCount }; @@ -369,6 +371,12 @@ public: SetUniform(KnownUniform::RenderColor, aColor); } + void SetColorMatrix(const gfx::Matrix5x4& aColorMatrix) + { + SetMatrixUniform(KnownUniform::ColorMatrix, &aColorMatrix._11); + SetUniform(KnownUniform::ColorMatrixVector, 4, &aColorMatrix._51); + } + void SetTexCoordMultiplier(float aWidth, float aHeight) { float f[] = {aWidth, aHeight}; SetUniform(KnownUniform::TexCoordMultiplier, 2, f); @@ -432,7 +440,7 @@ protected: } } - void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues) + void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const float *aFloatValues) { ASSERT_THIS_PROGRAM; NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform"); diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 37a39c22a6ba..ec0a1ecaa818 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -250,6 +250,8 @@ private: DECL_GFX_PREF(Once, "layers.progressive-paint", UseProgressiveTilePainting, bool, false); DECL_GFX_PREF(Once, "layers.scroll-graph", LayersScrollGraph, bool, false); DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false); + DECL_GFX_PREF(Live, "layers.invert", Invert, bool, false); + DECL_GFX_PREF(Live, "layers.grayscale", Grayscale, bool, false); DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f); DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled", ScrollBehaviorEnabled, bool, false); From 93111c8f0e39acd95a3877af64513dd3f9d3aea6 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 15 Aug 2014 11:10:53 -0700 Subject: [PATCH 003/101] Bug 1039633 - Always try to set the ASan symbolizer in gtest runs. r=ted --- testing/gtest/rungtests.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/testing/gtest/rungtests.py b/testing/gtest/rungtests.py index ae06006405bd..9034d4ebeff7 100644 --- a/testing/gtest/rungtests.py +++ b/testing/gtest/rungtests.py @@ -86,6 +86,19 @@ class GTests(object): env[pathvar] = "%s%s%s" % (self.xre_path, os.pathsep, env[pathvar]) else: env[pathvar] = self.xre_path + + # ASan specific environment stuff + # mozinfo is not set up properly to detect if ASan is enabled, so just always set these. + if mozinfo.isLinux or mozinfo.isMac: + # Symbolizer support + llvmsym = os.path.join(self.xre_path, "llvm-symbolizer") + if os.path.isfile(llvmsym): + env["ASAN_SYMBOLIZER_PATH"] = llvmsym + log.info("gtest | ASan using symbolizer at %s", llvmsym) + else: + # This should be |testFail| instead of |info|. See bug 1050891. + log.info("gtest | Failed to find ASan symbolizer at %s", llvmsym) + return env class gtestOptions(OptionParser): From 691dcd68c1fec29ac041b22dd3cffc5a55182e9b Mon Sep 17 00:00:00 2001 From: Garrett Robinson Date: Fri, 15 Aug 2014 11:27:22 -0700 Subject: [PATCH 004/101] Bug 1029155 - Store peer certificate chain from failed connections on TransportSecurityInfo r=keeler --- config/external/nss/nss.def | 1 + netwerk/socket/nsITransportSecurityInfo.idl | 11 ++- .../ssl/src/SSLServerCertVerification.cpp | 53 +++++++++--- .../manager/ssl/src/TransportSecurityInfo.cpp | 47 ++++++++++- .../manager/ssl/src/TransportSecurityInfo.h | 19 +++-- security/manager/ssl/src/nsNSSCertificate.cpp | 82 ++++++++++++++++++- security/manager/ssl/src/nsNSSCertificate.h | 2 + 7 files changed, 192 insertions(+), 23 deletions(-) diff --git a/config/external/nss/nss.def b/config/external/nss/nss.def index 3f432d163eb1..991b7f423f18 100644 --- a/config/external/nss/nss.def +++ b/config/external/nss/nss.def @@ -647,6 +647,7 @@ SSL_NumImplementedCiphers DATA SSL_OptionSet SSL_OptionSetDefault SSL_PeerCertificate +SSL_PeerCertificateChain SSL_PeerStapledOCSPResponses SSL_ResetHandshake SSL_SetCanFalseStartCallback diff --git a/netwerk/socket/nsITransportSecurityInfo.idl b/netwerk/socket/nsITransportSecurityInfo.idl index 96a16233b7f8..1e5c9d0a02df 100644 --- a/netwerk/socket/nsITransportSecurityInfo.idl +++ b/netwerk/socket/nsITransportSecurityInfo.idl @@ -6,9 +6,18 @@ #include "nsISupports.idl" -[scriptable, uuid(8813d03b-e76c-4240-9691-d327d9b91e88)] +interface nsIX509CertList; + +[scriptable, uuid(154898ce-e14f-4981-bfc5-00a41722f44b)] interface nsITransportSecurityInfo : nsISupports { readonly attribute unsigned long securityState; readonly attribute wstring errorMessage; + + /** + * If certificate verification failed, this will be the peer certificate + * chain provided in the handshake, so it can be used for error reporting. + * If verification succeeded, this will be null. + */ + readonly attribute nsIX509CertList failedCertChain; }; diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index 2e76b14c5b33..9f1fab7af7ca 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -621,6 +621,7 @@ public: const void* fdForLogging, TransportSecurityInfo* infoObject, CERTCertificate* serverCert, + ScopedCERTCertList& peerCertChain, SECItem* stapledOCSPResponse, uint32_t providerFlags, Time time, @@ -633,6 +634,7 @@ private: const void* fdForLogging, TransportSecurityInfo* infoObject, CERTCertificate* cert, + CERTCertList* peerCertChain, SECItem* stapledOCSPResponse, uint32_t providerFlags, Time time, @@ -641,6 +643,7 @@ private: const void* const mFdForLogging; const RefPtr mInfoObject; const ScopedCERTCertificate mCert; + ScopedCERTCertList mPeerCertChain; const uint32_t mProviderFlags; const Time mTime; const PRTime mPRTime; @@ -651,12 +654,13 @@ private: SSLServerCertVerificationJob::SSLServerCertVerificationJob( const RefPtr& certVerifier, const void* fdForLogging, TransportSecurityInfo* infoObject, CERTCertificate* cert, - SECItem* stapledOCSPResponse, uint32_t providerFlags, - Time time, PRTime prtime) + CERTCertList* peerCertChain, SECItem* stapledOCSPResponse, + uint32_t providerFlags, Time time, PRTime prtime) : mCertVerifier(certVerifier) , mFdForLogging(fdForLogging) , mInfoObject(infoObject) , mCert(CERT_DupCertificate(cert)) + , mPeerCertChain(peerCertChain) , mProviderFlags(providerFlags) , mTime(time) , mPRTime(prtime) @@ -733,9 +737,13 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject, } SECStatus -AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject, - CERTCertificate* cert, SECItem* stapledOCSPResponse, - uint32_t providerFlags, Time time) +AuthCertificate(CertVerifier& certVerifier, + TransportSecurityInfo* infoObject, + CERTCertificate* cert, + ScopedCERTCertList& peerCertChain, + SECItem* stapledOCSPResponse, + uint32_t providerFlags, + Time time) { MOZ_ASSERT(infoObject); MOZ_ASSERT(cert); @@ -747,7 +755,6 @@ AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject, bool saveIntermediates = !(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE); - ScopedCERTCertList certList; SECOidTag evOidPolicy; rv = certVerifier.VerifySSLServerCert(cert, stapledOCSPResponse, time, infoObject, @@ -799,6 +806,13 @@ AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject, } } + if (rv != SECSuccess) { + // Certificate validation failed; store the peer certificate chain on + // infoObject so it can be used for error reporting. Note: infoObject + // indirectly takes ownership of peerCertChain. + infoObject->SetFailedCertChain(peerCertChain); + } + return rv; } @@ -808,6 +822,7 @@ SSLServerCertVerificationJob::Dispatch( const void* fdForLogging, TransportSecurityInfo* infoObject, CERTCertificate* serverCert, + ScopedCERTCertList& peerCertChain, SECItem* stapledOCSPResponse, uint32_t providerFlags, Time time, @@ -820,10 +835,18 @@ SSLServerCertVerificationJob::Dispatch( return SECFailure; } + // Copy the certificate list so the runnable can take ownership of it in the + // constructor. + // We can safely skip checking if NSS has already shut down here since we're + // in the middle of verifying a certificate. + nsNSSShutDownPreventionLock lock; + CERTCertList* peerCertChainCopy = nsNSSCertList::DupCertList(peerCertChain, lock); + RefPtr job( new SSLServerCertVerificationJob(certVerifier, fdForLogging, infoObject, - serverCert, stapledOCSPResponse, - providerFlags, time, prtime)); + serverCert, peerCertChainCopy, + stapledOCSPResponse, providerFlags, + time, prtime)); nsresult nrv; if (!gCertVerificationThreadPool) { @@ -873,8 +896,8 @@ SSLServerCertVerificationJob::Run() // set the error code if/when it fails. PR_SetError(0, 0); SECStatus rv = AuthCertificate(*mCertVerifier, mInfoObject, mCert.get(), - mStapledOCSPResponse, mProviderFlags, - mTime); + mPeerCertChain, mStapledOCSPResponse, + mProviderFlags, mTime); if (rv == SECSuccess) { uint32_t interval = (uint32_t) ((TimeStamp::Now() - mJobStartTime).ToMilliseconds()); RefPtr restart( @@ -975,6 +998,9 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer) return SECFailure; } + // Get the peer certificate chain for error reporting + ScopedCERTCertList peerCertChain(SSL_PeerCertificateChain(fd)); + socketInfo->SetFullHandshake(); Time now(Now()); @@ -1020,8 +1046,8 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer) socketInfo->SetCertVerificationWaiting(); SECStatus rv = SSLServerCertVerificationJob::Dispatch( certVerifier, static_cast(fd), socketInfo, - serverCert, stapledOCSPResponse, providerFlags, now, - prnow); + serverCert, peerCertChain, stapledOCSPResponse, + providerFlags, now, prnow); return rv; } @@ -1031,7 +1057,8 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer) // a non-blocking socket. SECStatus rv = AuthCertificate(*certVerifier, socketInfo, serverCert, - stapledOCSPResponse, providerFlags, now); + peerCertChain, stapledOCSPResponse, + providerFlags, now); if (rv == SECSuccess) { Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, 1); return SECSuccess; diff --git a/security/manager/ssl/src/TransportSecurityInfo.cpp b/security/manager/ssl/src/TransportSecurityInfo.cpp index 89be54685347..cc9cfbfc9bb3 100644 --- a/security/manager/ssl/src/TransportSecurityInfo.cpp +++ b/security/manager/ssl/src/TransportSecurityInfo.cpp @@ -289,8 +289,8 @@ TransportSecurityInfo::GetInterface(const nsIID & uuid, void * *result) // of the previous value. This is so when older versions attempt to // read a newer serialized TransportSecurityInfo, they will actually // fail and return NS_ERROR_FAILURE instead of silently failing. -#define TRANSPORTSECURITYINFOMAGIC { 0xa9863a23, 0x28ea, 0x45d2, \ - { 0xa2, 0x5a, 0x35, 0x7c, 0xae, 0xfa, 0x7f, 0x82 } } +#define TRANSPORTSECURITYINFOMAGIC { 0xa9863a23, 0xf40a, 0x4060, \ + { 0xb2, 0xe1, 0x62, 0xab, 0x2b, 0x85, 0x26, 0xa9 } } static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC); NS_IMETHODIMP @@ -331,6 +331,15 @@ TransportSecurityInfo::Write(nsIObjectOutputStream* stream) if (NS_FAILED(rv)) { return rv; } + + rv = NS_WriteOptionalCompoundObject(stream, + mFailedCertChain, + NS_GET_IID(nsIX509CertList), + true); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; } @@ -386,6 +395,14 @@ TransportSecurityInfo::Read(nsIObjectInputStream* stream) if (!mSSLStatus) { return NS_ERROR_FAILURE; } + + nsCOMPtr failedCertChainSupports; + rv = NS_ReadOptionalObject(stream, true, getter_AddRefs(failedCertChainSupports)); + if (NS_FAILED(rv)) { + return rv; + } + mFailedCertChain = do_QueryInterface(failedCertChainSupports); + return NS_OK; } @@ -1072,4 +1089,30 @@ TransportSecurityInfo::SetStatusErrorBits(nsIX509Cert & cert, SECFailure); } +NS_IMETHODIMP +TransportSecurityInfo::GetFailedCertChain(nsIX509CertList** _result) +{ + NS_ASSERTION(_result, "non-NULL destination required"); + + *_result = mFailedCertChain; + NS_IF_ADDREF(*_result); + + return NS_OK; +} + +nsresult +TransportSecurityInfo::SetFailedCertChain(ScopedCERTCertList& certList) +{ + nsNSSShutDownPreventionLock lock; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + nsCOMPtr comCertList; + // nsNSSCertList takes ownership of certList + mFailedCertChain = new nsNSSCertList(certList, lock); + + return NS_OK; +} + } } // namespace mozilla::psm diff --git a/security/manager/ssl/src/TransportSecurityInfo.h b/security/manager/ssl/src/TransportSecurityInfo.h index 342408c82703..d32889924f3c 100644 --- a/security/manager/ssl/src/TransportSecurityInfo.h +++ b/security/manager/ssl/src/TransportSecurityInfo.h @@ -7,16 +7,18 @@ #ifndef _MOZILLA_PSM_TRANSPORTSECURITYINFO_H #define _MOZILLA_PSM_TRANSPORTSECURITYINFO_H +#include "ScopedNSSTypes.h" #include "certt.h" #include "mozilla/Mutex.h" #include "mozilla/RefPtr.h" -#include "nsIInterfaceRequestor.h" -#include "nsITransportSecurityInfo.h" -#include "nsSSLStatus.h" -#include "nsISSLStatusProvider.h" -#include "nsIAssociatedContentSecurity.h" -#include "nsNSSShutDown.h" #include "nsDataHashtable.h" +#include "nsIAssociatedContentSecurity.h" +#include "nsIInterfaceRequestor.h" +#include "nsISSLStatusProvider.h" +#include "nsITransportSecurityInfo.h" +#include "nsNSSShutDown.h" +#include "nsSSLStatus.h" +#include "pkix/pkixtypes.h" namespace mozilla { namespace psm { @@ -74,6 +76,8 @@ public: nsSSLStatus* SSLStatus() { return mSSLStatus; } void SetStatusErrorBits(nsIX509Cert & cert, uint32_t collected_errors); + nsresult SetFailedCertChain(ScopedCERTCertList& certList); + private: mutable ::mozilla::Mutex mMutex; @@ -100,6 +104,9 @@ private: /* SSL Status */ mozilla::RefPtr mSSLStatus; + /* Peer cert chain for failed connections (for error reporting) */ + nsCOMPtr mFailedCertChain; + virtual void virtualDestroyNSSReference(); void destructorSafeDestroyNSSReference(); }; diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp index 94b93f6458ad..b886bfe8d0e9 100644 --- a/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/security/manager/ssl/src/nsNSSCertificate.cpp @@ -1545,7 +1545,9 @@ ConstructCERTCertListFromReversedDERArray( } // namespace mozilla -NS_IMPL_ISUPPORTS(nsNSSCertList, nsIX509CertList) +NS_IMPL_ISUPPORTS(nsNSSCertList, + nsIX509CertList, + nsISerializable) nsNSSCertList::nsNSSCertList(ScopedCERTCertList& certList, const nsNSSShutDownPreventionLock& proofOfLock) @@ -1667,6 +1669,84 @@ nsNSSCertList::GetRawCertList() return mCertList.get(); } +NS_IMETHODIMP +nsNSSCertList::Write(nsIObjectOutputStream* aStream) +{ + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + NS_ENSURE_STATE(mCertList); + nsresult rv = NS_OK; + + // First, enumerate the certs to get the length of the list + uint32_t certListLen = 0; + CERTCertListNode* node = nullptr; + for (node = CERT_LIST_HEAD(mCertList); + !CERT_LIST_END(node, mCertList); + node = CERT_LIST_NEXT(node), ++certListLen) { + } + + // Write the length of the list + rv = aStream->Write32(certListLen); + + // Repeat the loop, and serialize each certificate + node = nullptr; + for (node = CERT_LIST_HEAD(mCertList); + !CERT_LIST_END(node, mCertList); + node = CERT_LIST_NEXT(node)) + { + nsCOMPtr cert = nsNSSCertificate::Create(node->cert); + if (!cert) { + rv = NS_ERROR_OUT_OF_MEMORY; + break; + } + + nsCOMPtr serializableCert = do_QueryInterface(cert); + rv = aStream->WriteCompoundObject(serializableCert, NS_GET_IID(nsIX509Cert), true); + if (NS_FAILED(rv)) { + break; + } + } + + return rv; +} + +NS_IMETHODIMP +nsNSSCertList::Read(nsIObjectInputStream* aStream) +{ + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + NS_ENSURE_STATE(mCertList); + nsresult rv = NS_OK; + + uint32_t certListLen; + rv = aStream->Read32(&certListLen); + if (NS_FAILED(rv)) { + return rv; + } + + for(uint32_t i = 0; i < certListLen; ++i) { + nsCOMPtr certSupports; + rv = aStream->ReadObject(true, getter_AddRefs(certSupports)); + if (NS_FAILED(rv)) { + break; + } + + nsCOMPtr cert = do_QueryInterface(certSupports); + rv = AddCert(cert); + if (NS_FAILED(rv)) { + break; + } + } + + return rv; +} + NS_IMETHODIMP nsNSSCertList::GetEnumerator(nsISimpleEnumerator** _retval) { diff --git a/security/manager/ssl/src/nsNSSCertificate.h b/security/manager/ssl/src/nsNSSCertificate.h index 468dec06b8e4..4245b1547f41 100644 --- a/security/manager/ssl/src/nsNSSCertificate.h +++ b/security/manager/ssl/src/nsNSSCertificate.h @@ -82,11 +82,13 @@ SECStatus ConstructCERTCertListFromReversedDERArray( } // namespcae mozilla class nsNSSCertList: public nsIX509CertList, + public nsISerializable, public nsNSSShutDownObject { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIX509CERTLIST + NS_DECL_NSISERIALIZABLE // certList is adopted nsNSSCertList(mozilla::ScopedCERTCertList& certList, From 90fa6beb039658adb585e8d345692afea2812017 Mon Sep 17 00:00:00 2001 From: Garrett Robinson Date: Fri, 15 Aug 2014 11:27:31 -0700 Subject: [PATCH 005/101] Bug 1029155 - Tests for storing failed certificate chains r=keeler --- netwerk/socket/nsITransportSecurityInfo.idl | 2 +- security/manager/boot/src/StaticHPKPins.h | 8 +- .../manager/ssl/public/nsIX509CertList.idl | 8 ++ security/manager/ssl/src/nsNSSCertificate.cpp | 74 +++++++++++++- .../ssl/tests/unit/test_cert_chains.js | 96 ++++++++++++++++++ .../manager/ssl/tests/unit/tlsserver/cert9.db | Bin 294912 -> 294912 bytes .../ssl/tests/unit/tlsserver/default-ee.der | Bin 639 -> 639 bytes .../ssl/tests/unit/tlsserver/expired-ee.der | Bin 0 -> 530 bytes .../tests/unit/tlsserver/generate_certs.sh | 14 ++- .../unit/tlsserver/inadequatekeyusage-ee.der | Bin 0 -> 567 bytes .../manager/ssl/tests/unit/tlsserver/key4.db | Bin 425984 -> 425984 bytes .../tests/unit/tlsserver/other-test-ca.der | Bin 452 -> 452 bytes .../ssl/tests/unit/tlsserver/test-ca.der | Bin 440 -> 440 bytes security/manager/ssl/tests/unit/xpcshell.ini | 4 + 14 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 security/manager/ssl/tests/unit/test_cert_chains.js create mode 100644 security/manager/ssl/tests/unit/tlsserver/expired-ee.der create mode 100644 security/manager/ssl/tests/unit/tlsserver/inadequatekeyusage-ee.der diff --git a/netwerk/socket/nsITransportSecurityInfo.idl b/netwerk/socket/nsITransportSecurityInfo.idl index 1e5c9d0a02df..9a038f00a296 100644 --- a/netwerk/socket/nsITransportSecurityInfo.idl +++ b/netwerk/socket/nsITransportSecurityInfo.idl @@ -8,7 +8,7 @@ interface nsIX509CertList; -[scriptable, uuid(154898ce-e14f-4981-bfc5-00a41722f44b)] +[scriptable, uuid(c754ef58-853f-4870-abf7-98be325d2b97)] interface nsITransportSecurityInfo : nsISupports { readonly attribute unsigned long securityState; readonly attribute wstring errorMessage; diff --git a/security/manager/boot/src/StaticHPKPins.h b/security/manager/boot/src/StaticHPKPins.h index 3ade08dcd7f8..2fa019d1e84a 100644 --- a/security/manager/boot/src/StaticHPKPins.h +++ b/security/manager/boot/src/StaticHPKPins.h @@ -89,7 +89,7 @@ static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[] = /* End Entity Test Cert */ static const char kEnd_Entity_Test_CertFingerprint[] = - "w3a2zMuMdmP9ed7H9HLExM+i+/0UxqHlKszZ5GQpHYM="; + "pVVgLk2kFI2WWRPwDMIX6YmzFhEW4DXQV/U5gP+feGA="; /* Entrust Root Certification Authority */ static const char kEntrust_Root_Certification_AuthorityFingerprint[] = @@ -736,6 +736,7 @@ struct TransportSecurityPreload { /* Sort hostnames for binary search. */ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { + { "2mdn.net", true, false, false, -1, &kPinset_google_root_pems }, { "accounts.firefox.com", true, false, false, 4, &kPinset_mozilla_fxa }, { "accounts.google.com", true, false, false, -1, &kPinset_google_root_pems }, { "addons.mozilla.net", true, false, true, 2, &kPinset_mozilla }, @@ -1060,12 +1061,13 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { { "www.twitter.com", true, false, false, -1, &kPinset_twitterCom }, { "xbrlsuccess.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, { "youtu.be", true, false, false, -1, &kPinset_google_root_pems }, + { "youtube-nocookie.com", true, false, false, -1, &kPinset_google_root_pems }, { "youtube.com", true, false, false, -1, &kPinset_google_root_pems }, { "ytimg.com", true, false, false, -1, &kPinset_google_root_pems }, }; -// Pinning Preload List Length = 326; +// Pinning Preload List Length = 328; static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1416046032356000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1416397232719000); diff --git a/security/manager/ssl/public/nsIX509CertList.idl b/security/manager/ssl/public/nsIX509CertList.idl index f1175efb98d0..af9a66fcc424 100644 --- a/security/manager/ssl/public/nsIX509CertList.idl +++ b/security/manager/ssl/public/nsIX509CertList.idl @@ -18,6 +18,14 @@ interface nsIX509CertList : nsISupports { */ [notxpcom, noscript] voidPtr getRawCertList(); + /** + * Test whether two certificate list instances represent the same + * certificate list. + * + * @return Whether the certificate lists are equal + */ + boolean equals(in nsIX509CertList other); + }; %{C++ diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp index b886bfe8d0e9..34321fbb046a 100644 --- a/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/security/manager/ssl/src/nsNSSCertificate.cpp @@ -21,6 +21,7 @@ #include "nsPKCS12Blob.h" #include "nsPK11TokenDB.h" #include "nsIX509Cert.h" +#include "nsIClassInfoImpl.h" #include "nsNSSASN1Object.h" #include "nsString.h" #include "nsXPIDLString.h" @@ -1545,9 +1546,15 @@ ConstructCERTCertListFromReversedDERArray( } // namespace mozilla -NS_IMPL_ISUPPORTS(nsNSSCertList, - nsIX509CertList, - nsISerializable) +NS_IMPL_CLASSINFO(nsNSSCertList, + nullptr, + // inferred from nsIX509Cert + nsIClassInfo::THREADSAFE, + NS_X509CERTLIST_CID) + +NS_IMPL_ISUPPORTS_CI(nsNSSCertList, + nsIX509CertList, + nsISerializable) nsNSSCertList::nsNSSCertList(ScopedCERTCertList& certList, const nsNSSShutDownPreventionLock& proofOfLock) @@ -1762,6 +1769,67 @@ nsNSSCertList::GetEnumerator(nsISimpleEnumerator** _retval) return NS_OK; } +NS_IMETHODIMP +nsNSSCertList::Equals(nsIX509CertList* other, bool* result) +{ + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + NS_ENSURE_ARG(result); + *result = true; + + nsresult rv; + + nsCOMPtr selfEnumerator; + rv = GetEnumerator(getter_AddRefs(selfEnumerator)); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr otherEnumerator; + rv = other->GetEnumerator(getter_AddRefs(otherEnumerator)); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr selfSupports; + nsCOMPtr otherSupports; + while (NS_SUCCEEDED(selfEnumerator->GetNext(getter_AddRefs(selfSupports)))) { + if (NS_SUCCEEDED(otherEnumerator->GetNext(getter_AddRefs(otherSupports)))) { + nsCOMPtr selfCert = do_QueryInterface(selfSupports); + nsCOMPtr otherCert = do_QueryInterface(otherSupports); + + bool certsEqual = false; + rv = selfCert->Equals(otherCert, &certsEqual); + if (NS_FAILED(rv)) { + return rv; + } + if (!certsEqual) { + *result = false; + break; + } + } else { + // other is shorter than self + *result = false; + break; + } + } + + // Make sure self is the same length as other + bool otherHasMore = false; + rv = otherEnumerator->HasMoreElements(&otherHasMore); + if (NS_FAILED(rv)) { + return rv; + } + if (otherHasMore) { + *result = false; + } + + return NS_OK; +} + NS_IMPL_ISUPPORTS(nsNSSCertListEnumerator, nsISimpleEnumerator) nsNSSCertListEnumerator::nsNSSCertListEnumerator( diff --git a/security/manager/ssl/tests/unit/test_cert_chains.js b/security/manager/ssl/tests/unit/test_cert_chains.js new file mode 100644 index 000000000000..6c08f42c2af4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_chains.js @@ -0,0 +1,96 @@ +// -*- Mode: javascript; 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/. + +"use strict"; + +function build_cert_chain(certNames) { + let certList = Cc["@mozilla.org/security/x509certlist;1"] + .createInstance(Ci.nsIX509CertList); + certNames.forEach(function(certName) { + let cert = constructCertFromFile("tlsserver/" + certName + ".der"); + certList.addCert(cert); + }); + return certList; +} + +function test_cert_equals() { + let certA = constructCertFromFile("tlsserver/default-ee.der"); + let certB = constructCertFromFile("tlsserver/default-ee.der"); + let certC = constructCertFromFile("tlsserver/expired-ee.der"); + + do_check_false(certA == certB); + do_check_true(certA.equals(certB)); + do_check_false(certA.equals(certC)); +} + +function test_cert_list_serialization() { + let certList = build_cert_chain(['default-ee', 'expired-ee']); + + // Serialize the cert list to a string + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"] + .getService(Ci.nsISerializationHelper); + certList.QueryInterface(Ci.nsISerializable); + let serialized = serHelper.serializeToString(certList); + + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsIX509CertList); + do_check_true(certList.equals(deserialized)); +} + +function run_test() { + do_get_profile(); + add_tls_server_setup("BadCertServer"); + + // Test nsIX509Cert.equals + add_test(function() { + test_cert_equals(); + run_next_test(); + }); + + // Test serialization of nsIX509CertList + add_test(function() { + test_cert_list_serialization(); + run_next_test(); + }); + + // Test successful connection (failedCertChain should be null) + add_connection_test( + // re-use pinning certs (keeler) + "good.include-subdomains.pinning.example.com", Cr.NS_OK, null, + function withSecurityInfo(aTransportSecurityInfo) { + aTransportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + do_check_eq(aTransportSecurityInfo.failedCertChain, null); + } + ); + + // Test overrideable connection failure (failedCertChain should be non-null) + add_connection_test( + "expired.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_EXPIRED_CERTIFICATE), + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + do_check_neq(securityInfo.failedCertChain, null); + let originalCertChain = build_cert_chain(["expired-ee", "test-ca"]); + do_check_true(originalCertChain.equals(securityInfo.failedCertChain)); + } + ); + + // Test non-overrideable error (failedCertChain should be non-null) + add_connection_test( + "inadequatekeyusage.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_INADEQUATE_KEY_USAGE), + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + do_check_neq(securityInfo.failedCertChain, null); + let originalCertChain = build_cert_chain(["inadequatekeyusage-ee", "test-ca"]); + do_check_true(originalCertChain.equals(securityInfo.failedCertChain)); + } + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cert9.db b/security/manager/ssl/tests/unit/tlsserver/cert9.db index 26137ebfc33b53056976898c22da098e3bc640db..19bbfdcc82a59d8a8e02d70eeaf77f3f5a641ea0 100644 GIT binary patch delta 20732 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 XgGvrB2O{OiL{cFdu1tO4$t?c|(m?1R literal 294912 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 delta 298 zcmV+_0oDHh1pfq(Iv6%FHZU1*dkSpMApeqW@r|s_TRQ8jP#R6kS zqB$eH`Fhn;W}&iUhg)vZ=A{loIG<_2OQ~zWue*EKwMj3APr-HlLk^dHc7F7Ni339C zQC3JEILn-d!o){T3IVf|3<2|hsFCs-trLexq*j9j{5g2eBQTdWR6J*P?IeXrb`a5d zH-|Nf!^O66O$yEJkT|A30jU+Xl!8Fm_yP4?&&C%xBY4@4PcB&}FFKhqF9Z_Ewh4L> w#)C!=8#ZfK)N=JBqYULo-2I_9^hFt~-OD`w)r=(;-Jp~GwRoiNB{r; diff --git a/security/manager/ssl/tests/unit/tlsserver/expired-ee.der b/security/manager/ssl/tests/unit/tlsserver/expired-ee.der new file mode 100644 index 0000000000000000000000000000000000000000..22b21d6179c61ecbf2e7c0bc9d54fff6d606dea5 GIT binary patch literal 530 zcmXqLV&XGsVk}?4%*4pV#K>mA%f_kI=F#?@mywZ`mBB#BP{4qXjX9KsS(rT}wYWsV z+0j5woY%t8z{Jql(9p!d&@f7z*ASU&pk%0EAP3PS?pjfhS(KWh0M_f8m!g}RSCUy$ zY0x+y*(OF-2Ij_I27|^0qHQkZcI=$jG8*pkkl| z;~OxxiDi_O6j$+z=J!T}3Sl^Q-s@7<>Aj_&iJIj>I{A_8I={b}gz-U8h@k fj2~}*^your1Ghm-$w900TpOxf>w_)@ANUCXp$WK8 literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh index 2d9000ea901f..bdfb86ea7777 100755 --- a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh +++ b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh @@ -65,6 +65,13 @@ $RUN_MOZILLA $CERTUTIL -d $DB_ARGUMENT -N -f $PASSWORD_FILE COMMON_ARGS="-v 360 -w -1 -2 -z $NOISE_FILE" +function export_cert { + NICKNAME="${1}" + DERFILE="${2}" + + $RUN_MOZILLA $CERTUTIL -d $DB_ARGUMENT -L -n $NICKNAME -r > $OUTPUT_DIR/$DERFILE +} + function make_CA { CA_RESPONSES="y\n1\ny" NICKNAME="${1}" @@ -76,7 +83,7 @@ function make_CA { -s "$SUBJECT" \ -t "CT,," \ -x $COMMON_ARGS - $RUN_MOZILLA $CERTUTIL -d $DB_ARGUMENT -L -n $NICKNAME -r > $OUTPUT_DIR/$DERFILE + export_cert $NICKNAME $DERFILE } SERIALNO=1 @@ -146,7 +153,8 @@ make_EE localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example. # Make an EE cert issued by otherCA make_EE otherIssuerEE 'CN=Wrong CA Pin Test End-Entity' otherCA "*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com,*.pinning.example.com" -$RUN_MOZILLA $CERTUTIL -d $DB_ARGUMENT -L -n localhostAndExampleCom -r > $OUTPUT_DIR/default-ee.der +export_cert localhostAndExampleCom default-ee.der + # A cert that is like localhostAndExampleCom, but with a different serial number for # testing the "OCSP response is from the right issuer, but it is for the wrong cert" # case. @@ -155,6 +163,7 @@ make_EE ocspOtherEndEntity 'CN=Other Cert' testCA "localhost,*.example.com" make_INT testINT 'CN=Test Intermediate' testCA make_EE ocspEEWithIntermediate 'CN=Test End-entity with Intermediate' testINT "localhost,*.example.com" make_EE expired 'CN=Expired Test End-entity' testCA "expired.example.com" "-w -400" +export_cert expired expired-ee.der make_EE mismatch 'CN=Mismatch Test End-entity' testCA "doesntmatch.example.com" make_EE selfsigned 'CN=Self-signed Test End-entity' testCA "selfsigned.example.com" "-x" # If the certificate 'CN=Test Intermediate' isn't loaded into memory, @@ -174,6 +183,7 @@ make_EE mismatch-untrusted-expired 'CN=Mismatch-Untrusted-Expired Test End-entit NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE md5signature-expired 'CN=Test MD5Signature-Expired End-entity' testCA "md5signature-expired.example.com" "-Z MD5" "-w -400" make_EE inadequatekeyusage 'CN=Inadequate Key Usage Test End-entity' testCA "inadequatekeyusage.example.com" "--keyUsage crlSigning" +export_cert inadequatekeyusage inadequatekeyusage-ee.der make_EE selfsigned-inadequateEKU 'CN=Self-signed Inadequate EKU Test End-entity' unused "selfsigned-inadequateEKU.example.com" "--keyUsage keyEncipherment,dataEncipherment --extKeyUsage serverAuth" "-x" make_delegated delegatedSigner 'CN=Test Delegated Responder' testCA "--extKeyUsage ocspResponder" diff --git a/security/manager/ssl/tests/unit/tlsserver/inadequatekeyusage-ee.der b/security/manager/ssl/tests/unit/tlsserver/inadequatekeyusage-ee.der new file mode 100644 index 0000000000000000000000000000000000000000..9a992415544a9d6948387527411666148a441434 GIT binary patch literal 567 zcmXqLVlp;pVw|&pnTe5!iBZIWmyJ`a&7D}#ZMp@0D&8*?ZNvoL!|YH^8z zv!j8WIIp3Jfw`fvA&@dOjS}ZILFO9h8|oTpL-eS4<|U@27M3QKq$+r)Rw{%RC#I(= zfDLlZOVLfuE6FUWG-#ZUY%L=z19M|9gF#~_Q)45;nyG54zxO?E`+Wa}1FzYAOVjhQ zvw;@uTWqoMtXYPVT-p3M-re@^;>2zqyfdHp~@#zesWh6SIo$<%oHq zv#vgh?R(2DX|voyGUvWZP5b&O{(JO;mfZ{a^4V^# zS*Oftu{%F6ZF$ec%*epFxW=H$KojUCSwR*h1BE8JOt`nQQ!7hBp3+OLNX#wBN!3fv z&owY&+@oghVa?tZ}iutM_+8Q-NzffSKC5A zai+HSxhqK-QXI~c8}-Uo_%=@y*B2~(7v^Ory(`(VZiC4&?!WUrb4o?FD{?3I|F8OK Gvk3qXWWL7$ literal 0 HcmV?d00001 diff --git a/security/manager/ssl/tests/unit/tlsserver/key4.db b/security/manager/ssl/tests/unit/tlsserver/key4.db index b68debcac9705fe2d424fbc85eab296d2cc48ab6..e33f19881080a4208713fb8c4739e16c8d498eed 100644 GIT binary patch literal 425984 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

Li+DM&Bp@W$osi%tnOy3Q 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 literal 425984 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 Shhkrie}{qe9yy=ym;rvD*N@}? delta 320 zcmV-G0l)sl1H=OqFoFTVFoFRopaTK{0s;j9pUA4ykrXf(HZe9ZF)}eQHd+@AG&C?a zF*YzUGBGeVkz6=`r)=%j=Ba?;wj$91Yz}WPKVe;a8fz46&aG?!`TddKN|t7ckSYG( zx}MY%si2z%$nv~@5*W$mVCR%NjVaZNx%hXW8IiE_z3 z-K*)Om+rt>UehS*JmmjQayfvQFg|vIs%2w#_D_zX7B9^Q;bgW%IU=K7X4!Cew_kY; zHEz$uqLrio diff --git a/security/manager/ssl/tests/unit/tlsserver/test-ca.der b/security/manager/ssl/tests/unit/tlsserver/test-ca.der index d28b99a7d8397b277ca1db434ce3328248ec9423..51fde37e398a42150c38f8d51d0cf4710ef03c33 100644 GIT binary patch delta 320 zcmV-G0l)sZ1GobeFoFTJFoFRcpaTK{0s;j9pb#hnkrXNzH!(9YF*GnSFj^N4G&C?b zF*7kSG%ztRkybK)s*>@%`jf>i^DN|Oy1e#>7kmOXsF`mKQ|%T6CiJl=ZH>|bk8F9L zGF!ZaY!`JVhd7fCzef_`AHF_JWmbwX43SL6c}x*7=~r=n7F~ABh4Gq4XbXAyA{d3I z)+WudhN^LR{R^}6nVvz-Y%875x{;_Q^GQw*P-{0h^%(*I^OFbxFn^yp>2kA7><#|5 z_?}|OV%pxqMVxLctz>>*E+sSBW@}OGwN%H9GhUbe5P z>dyKfuQ_~>lK)v4JnLd5(xSG|TA@To`_CuKo~@UC1(l=U++JGZNwvK9X4s0`QQ4*F zBCS-{-A7cKh}s`p+?X0#InxoFWxRpjuNme?)dSpv?i5{)H->$FH>8rMW`q*O9&V;L SM9tDx!&ukHwnw=869N5sB$u-Q diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini index 512a6e2a65e6..499a831ad8bd 100644 --- a/security/manager/ssl/tests/unit/xpcshell.ini +++ b/security/manager/ssl/tests/unit/xpcshell.ini @@ -95,6 +95,10 @@ run-sequentially = hardcoded ports skip-if = os == "android" [test_add_preexisting_cert.js] [test_keysize.js] +[test_cert_chains.js] +run-sequentially = hardcoded ports +# Bug 1009158: this test times out on Android +skip-if = os == "android" [test_client_cert.js] run-sequentially = hardcoded ports # Bug 1009158: this test times out on Android From d7f0d13fc845abc325740cace36d908865b12da5 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Fri, 15 Aug 2014 13:46:23 -0400 Subject: [PATCH 006/101] Bug 1052751 - Part 1: Cull translated layers on the compositor. r=roc --HG-- extra : rebase_source : 6979b4d41c40ceb808a48ff8a1c038bbcfbed5b0 --- .../composite/ContainerLayerComposite.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 5ef409df39d9..761a10f28d42 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -34,6 +34,9 @@ #include "TextRenderer.h" // for TextRenderer #include +#define CULLING_LOG(...) +// #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__) + namespace mozilla { namespace layers { @@ -321,16 +324,26 @@ ContainerPrepare(ContainerT* aContainer, continue; } + CULLING_LOG("Preparing sublayer %p\n", layerToRender->GetLayer()); + nsIntRegion savedVisibleRegion; bool restoreVisibleRegion = false; + gfx::Matrix matrix; + bool is2D = layerToRender->GetLayer()->GetBaseTransform().Is2D(&matrix); if (i + 1 < children.Length() && - layerToRender->GetLayer()->GetEffectiveTransform().IsIdentity()) { + is2D && !matrix.HasNonIntegerTranslation()) { LayerComposite* nextLayer = static_cast(children.ElementAt(i + 1)->ImplData()); + CULLING_LOG("Culling against %p\n", nextLayer->GetLayer()); nsIntRect nextLayerOpaqueRect; if (nextLayer && nextLayer->GetLayer()) { nextLayerOpaqueRect = GetOpaqueRect(nextLayer->GetLayer()); + gfx::Point point = matrix.GetTranslation(); + nextLayerOpaqueRect.MoveBy(static_cast(-point.x), static_cast(-point.y)); + CULLING_LOG(" point %i, %i\n", static_cast(-point.x), static_cast(-point.y)); + CULLING_LOG(" opaque rect %i, %i, %i, %i\n", nextLayerOpaqueRect.x, nextLayerOpaqueRect.y, nextLayerOpaqueRect.width, nextLayerOpaqueRect.height); } if (!nextLayerOpaqueRect.IsEmpty()) { + CULLING_LOG(" draw\n"); savedVisibleRegion = layerToRender->GetShadowVisibleRegion(); nsIntRegion visibleRegion; visibleRegion.Sub(savedVisibleRegion, nextLayerOpaqueRect); @@ -339,12 +352,16 @@ ContainerPrepare(ContainerT* aContainer, } layerToRender->SetShadowVisibleRegion(visibleRegion); restoreVisibleRegion = true; + } else { + CULLING_LOG(" skip\n"); } } layerToRender->Prepare(clipRect); aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect, restoreVisibleRegion, savedVisibleRegion)); } + CULLING_LOG("Preparing container layer %p\n", aContainer->GetLayer()); + /** * Setup our temporary surface for rendering the contents of this container. */ From 007aa7863019e93d9fb0608b13c49b64ab220d5d Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Fri, 15 Aug 2014 13:28:35 -0600 Subject: [PATCH 007/101] Bug 995696 - Ignore Content:PageShow with tabID of 0 in testNewTab; r=snorp --- mobile/android/base/tests/BaseTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mobile/android/base/tests/BaseTest.java b/mobile/android/base/tests/BaseTest.java index 3beb56fb8ec5..71a8f3bf4e0d 100644 --- a/mobile/android/base/tests/BaseTest.java +++ b/mobile/android/base/tests/BaseTest.java @@ -563,6 +563,10 @@ abstract class BaseTest extends BaseRobocopTest { try { JSONObject data = new JSONObject(pageShowExpecter.blockForEventData()); int tabID = data.getInt("tabID"); + if (tabID == 0) { + mAsserter.dumpLog("addTab ignoring PageShow for tab 0"); + continue; + } if (!mKnownTabIDs.contains(tabID)) { mKnownTabIDs.add(tabID); break; From ecabb3f6d81e16657a4eeda0fc2dc6c343382506 Mon Sep 17 00:00:00 2001 From: Ian Neal Date: Fri, 15 Aug 2014 20:40:19 +0100 Subject: [PATCH 008/101] Bug 1053439 - MOZ_APP_COMPONENT_MODULES and MOZ_APP_EXTRA_LIBS are no longer required r=glandium --- configure.in | 5 ----- toolkit/library/moz.build | 1 - 2 files changed, 6 deletions(-) diff --git a/configure.in b/configure.in index 852f7f3c2ffa..e3709fc24f1b 100644 --- a/configure.in +++ b/configure.in @@ -8340,10 +8340,6 @@ if test "$MOZ_APP_COMPONENT_INCLUDE"; then AC_DEFINE_UNQUOTED(MOZ_APP_COMPONENT_INCLUDE, "$MOZ_APP_COMPONENT_INCLUDE") fi -if test "$MOZ_APP_COMPONENT_MODULES"; then - AC_DEFINE_UNQUOTED(MOZ_APP_COMPONENT_MODULES, $MOZ_APP_COMPONENT_MODULES) -fi - dnl ======================================================== dnl = dnl = Maintainer debug option (no --enable equivalent) @@ -8737,7 +8733,6 @@ AC_SUBST(CC_VERSION) AC_SUBST(CXX_VERSION) AC_SUBST(MSMANIFEST_TOOL) AC_SUBST(NS_ENABLE_TSF) -AC_SUBST_LIST(MOZ_APP_EXTRA_LIBS) AC_SUBST(MOZ_WAVE) AC_SUBST(MOZ_VORBIS) diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index db941241554b..092b08649a7f 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -164,7 +164,6 @@ if CONFIG['OS_ARCH'] == 'Linux' and CONFIG['OS_TARGET'] != 'Android': OS_LIBS += CONFIG['MOZ_CAIRO_OSLIBS'] OS_LIBS += CONFIG['MOZ_WEBRTC_X11_LIBS'] -OS_LIBS += CONFIG['MOZ_APP_EXTRA_LIBS'] if CONFIG['MOZ_NATIVE_JPEG']: OS_LIBS += CONFIG['MOZ_JPEG_LIBS'] From e97daeff0a2dc24f3fc213b61b48e55b507669d4 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 15 Aug 2014 15:44:26 -0400 Subject: [PATCH 009/101] Backed out changeset dd013a36e5d9 (bug 1042542) for Linux mochitest-dt failures. CLOSED TREE --HG-- extra : amend_source : 79952f7653b6cd3e72b2afca2ba7024acfb0218c --- widget/gtk/nsWindow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 80d2deab87b3..789329e3b4c3 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3230,8 +3230,6 @@ nsWindow::OnWindowStateEvent(GtkWidget *aWidget, GdkEventWindowState *aEvent) return; } - CheckForRollup(0, 0, false, true); - if (aEvent->new_window_state & GDK_WINDOW_STATE_ICONIFIED) { LOG(("\tIconified\n")); mSizeState = nsSizeMode_Minimized; From 2cf6bd79bae4be686fb02f371542cec1ac4f7e3b Mon Sep 17 00:00:00 2001 From: "Adam Roach [:abr]" Date: Tue, 12 Aug 2014 16:58:47 -0500 Subject: [PATCH 010/101] Bug 1052850 - Fix VCM receive calls to use local PT rather than remote PT r=jesup --- media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp index 679ecc3158f0..42daafede6a6 100644 --- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp +++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp @@ -1555,7 +1555,7 @@ int vcmRxStart(cc_mcapid_t mcap_id, case CC_AUDIO_1: if ( VcmSIPCCBinding::getAudioTermination() != nullptr ) return VcmSIPCCBinding::getAudioTermination()->rxStart( - group_id, stream_id, payload->remote_rtp_pt, + group_id, stream_id, payload->local_rtp_pt, attrs->audio.packetization_period, port, attrs->audio.avt_payload_type, map_algorithmID(algorithmID), key, key_len, salt, salt_len, attrs->audio.mixing_mode, @@ -1565,7 +1565,7 @@ int vcmRxStart(cc_mcapid_t mcap_id, case CC_VIDEO_1: if ( VcmSIPCCBinding::getVideoTermination() != nullptr ) return VcmSIPCCBinding::getVideoTermination()->rxStart( - group_id, stream_id, payload->remote_rtp_pt, + group_id, stream_id, payload->local_rtp_pt, 0, port, 0, map_algorithmID(algorithmID), key, key_len, salt, salt_len, 0, 0); break; @@ -1740,7 +1740,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, for(int i=0; i Date: Fri, 15 Aug 2014 15:54:05 -0400 Subject: [PATCH 011/101] Bug 1054474. Change FPSCounter to not use ToSecondsSigDigits(). r=BenWa ToSecondsSigDigits is slower and broken on Windows and doesn't really provide any value in this case. --HG-- extra : rebase_source : 889657d9bd1e7a2bc4bd2f8b2da16fac63ece822 --- gfx/layers/composite/FPSCounter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/layers/composite/FPSCounter.cpp b/gfx/layers/composite/FPSCounter.cpp index 57bb6158580a..adb7a2f0ff9c 100644 --- a/gfx/layers/composite/FPSCounter.cpp +++ b/gfx/layers/composite/FPSCounter.cpp @@ -49,7 +49,7 @@ FPSCounter::Init() bool FPSCounter::CapturedFullInterval(TimeStamp aTimestamp) { TimeDuration duration = aTimestamp - mLastInterval; - return duration.ToSecondsSigDigits() >= kFpsDumpInterval; + return duration.ToSeconds() >= kFpsDumpInterval; } void From 311b8a1af5b943b597d80982657deb50d8f1af6f Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Fri, 15 Aug 2014 16:24:22 -0400 Subject: [PATCH 012/101] Bug 1053998 - add few bits for doclifecycle logging, r=tbsaunde --- accessible/base/Logging.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/accessible/base/Logging.cpp b/accessible/base/Logging.cpp index 98a9456adc44..0975307f9b25 100644 --- a/accessible/base/Logging.cpp +++ b/accessible/base/Logging.cpp @@ -196,8 +196,10 @@ static void LogDocParent(nsIDocument* aDocumentNode) { nsIDocument* parentDoc = aDocumentNode->GetParentDocument(); - printf("parent id: %p", static_cast(parentDoc)); + printf("parent DOM document: %p", static_cast(parentDoc)); if (parentDoc) { + printf(", parent acc document: %p", + static_cast(GetExistingDocAccessible(parentDoc))); printf("\n parent "); LogDocURI(parentDoc); printf("\n"); From bace3d73428beb4b874831b2db0d3440da80ba72 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Fri, 15 Aug 2014 11:24:00 -0700 Subject: [PATCH 013/101] Bug 1047486 - Don't crash on null VideoData. r=cpearce Avoid crashing when we can't create a VideoData object for the decoded data MacOS X returns. --- content/media/fmp4/apple/AppleVTDecoder.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/media/fmp4/apple/AppleVTDecoder.cpp b/content/media/fmp4/apple/AppleVTDecoder.cpp index 9a21abf17460..bbd7054734fb 100644 --- a/content/media/fmp4/apple/AppleVTDecoder.cpp +++ b/content/media/fmp4/apple/AppleVTDecoder.cpp @@ -298,6 +298,12 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage, // Unlock the returned image data. CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly); + if (!data) { + NS_ERROR("Couldn't create VideoData for frame"); + mCallback->Error(); + return NS_ERROR_FAILURE; + } + // Frames come out in DTS order but we need to output them // in composition order. mReorderQueue.Push(data.forget()); From 91cf777f5f3a3c85350e653a4833e6e637fe2faf Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Fri, 15 Aug 2014 16:49:02 -0400 Subject: [PATCH 014/101] Bug 1053765 - Putting role=log on a table tag breaks row and cell accessibles, r=tbsaunde --- accessible/base/nsAccessibilityService.cpp | 6 +++--- accessible/generic/Accessible-inl.h | 6 ++++++ accessible/generic/Accessible.h | 1 + accessible/tests/mochitest/tree/test_table.html | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index 520d1b3a7af0..e36a6c5dc55e 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -972,10 +972,10 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, // If table has strong ARIA role then all table descendants shouldn't // expose their native roles. - if (!roleMapEntry && newAcc) { + if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) { if (frame->AccessibleType() == eHTMLTableRowType) { nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); - if (contextRoleMap && !(contextRoleMap->IsOfType(eTable))) + if (!contextRoleMap->IsOfType(eTable)) roleMapEntry = &aria::gEmptyRoleMap; } else if (frame->AccessibleType() == eHTMLTableCellType && @@ -987,7 +987,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, content->Tag() == nsGkAtoms::dd || frame->AccessibleType() == eHTMLLiType) { nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); - if (contextRoleMap && !(contextRoleMap->IsOfType(eList))) + if (!contextRoleMap->IsOfType(eList)) roleMapEntry = &aria::gEmptyRoleMap; } } diff --git a/accessible/generic/Accessible-inl.h b/accessible/generic/Accessible-inl.h index 0cc04872e8d1..09f691ef0c10 100644 --- a/accessible/generic/Accessible-inl.h +++ b/accessible/generic/Accessible-inl.h @@ -28,6 +28,12 @@ Accessible::IsARIARole(nsIAtom* aARIARole) const return mRoleMapEntry && mRoleMapEntry->Is(aARIARole); } +inline bool +Accessible::HasStrongARIARole() const +{ + return mRoleMapEntry && mRoleMapEntry->roleRule == kUseMapRole; +} + inline mozilla::a11y::role Accessible::ARIARole() { diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index 03c6308236f6..9906f11e2ba1 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -219,6 +219,7 @@ public: */ bool HasARIARole() const { return mRoleMapEntry; } bool IsARIARole(nsIAtom* aARIARole) const; + bool HasStrongARIARole() const; /** * Retrun ARIA role map if any. diff --git a/accessible/tests/mochitest/tree/test_table.html b/accessible/tests/mochitest/tree/test_table.html index 8d51b1accfc1..bfbd6ae5a341 100644 --- a/accessible/tests/mochitest/tree/test_table.html +++ b/accessible/tests/mochitest/tree/test_table.html @@ -162,6 +162,18 @@ }; testAccessibleTree("table5", accTree); + ///////////////////////////////////////////////////////////////////////// + // log table + accTree = + { TABLE: [ + { ROW: [ + { CELL: [ + { TEXT_LEAF: [ ] } + ] } + ] } + ] }; + testAccessibleTree("logtable", accTree); + SimpleTest.finish(); } @@ -264,5 +276,7 @@ + +
blah
From 57a41c12a76400170149258c209b0df6f6fd5f92 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 15 Aug 2014 14:00:53 -0700 Subject: [PATCH 015/101] Bug 1023585 - Remove suppression for AllocateArrayBufferContents now that the leak is fixed. r=khuey --- build/sanitizers/lsan_suppressions.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/build/sanitizers/lsan_suppressions.txt b/build/sanitizers/lsan_suppressions.txt index c59655ec5fcb..e5e1e381861f 100644 --- a/build/sanitizers/lsan_suppressions.txt +++ b/build/sanitizers/lsan_suppressions.txt @@ -59,9 +59,6 @@ leak:event_base_once # Bug 1021854 - nsFileStreamBase::DoOpen() leaking fds. bc1, oth leak:nsLocalFile::OpenNSPRFileDesc -# Bug 1023585 - Leak of array buffer in JSStructuredCloneWriter::transferOwnership(). m1 -leak:AllocateArrayBufferContents - # Bug 1022010 - Small leak under _render_glyph_outline. bc1 leak:_render_glyph_outline From b057565fa00f961f7979bef1a592401cc68bbd5f Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Fri, 8 Aug 2014 13:22:39 -0700 Subject: [PATCH 016/101] Bug 1033442 - Remove non-pod malloc from MallocProvider and AllocPolicy; r=jonco --- js/src/builtin/MapObject.cpp | 8 +- js/src/ctypes/CTypes.cpp | 5 +- js/src/ds/LifoAlloc.h | 17 +-- js/src/gc/ForkJoinNursery.cpp | 37 ++---- js/src/gc/ForkJoinNursery.h | 6 +- js/src/gc/Nursery.cpp | 3 +- js/src/jit/BaselineJIT.cpp | 2 +- js/src/jit/Ion.cpp | 2 +- js/src/jit/IonAllocPolicy.h | 29 ++--- js/src/jit/JitcodeMap.cpp | 2 +- js/src/jit/shared/CodeGenerator-shared.cpp | 4 +- js/src/jsalloc.h | 11 +- js/src/jsapi.cpp | 4 +- js/src/jscntxt.h | 16 --- js/src/jsgcinlines.h | 1 + js/src/jsiter.cpp | 14 ++- js/src/jsopcode.cpp | 2 +- js/src/jsscript.cpp | 13 +- js/src/shell/js.cpp | 2 +- js/src/vm/ArgumentsObject.cpp | 7 +- js/src/vm/MallocProvider.h | 134 +++++++++++---------- js/src/vm/Runtime.h | 8 +- js/src/vm/SelfHosting.cpp | 2 +- js/src/vm/String.cpp | 7 +- js/src/vm/StringBuffer.cpp | 6 + js/src/vm/StringBuffer.h | 8 +- js/src/vm/TypedArrayObject.cpp | 2 +- memory/replace/dmd/DMD.cpp | 10 ++ mfbt/AllocPolicy.h | 12 +- mfbt/Vector.h | 8 +- 30 files changed, 193 insertions(+), 189 deletions(-) diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 09bbbc60d424..257a97988bfe 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -108,14 +108,14 @@ class OrderedHashTable MOZ_ASSERT(!hashTable, "init must be called at most once"); uint32_t buckets = initialBuckets(); - Data **tableAlloc = static_cast(alloc.malloc_(buckets * sizeof(Data *))); + Data **tableAlloc = alloc.template pod_malloc(buckets); if (!tableAlloc) return false; for (uint32_t i = 0; i < buckets; i++) tableAlloc[i] = nullptr; uint32_t capacity = uint32_t(buckets * fillFactor()); - Data *dataAlloc = static_cast(alloc.malloc_(capacity * sizeof(Data))); + Data *dataAlloc = alloc.template pod_malloc(capacity); if (!dataAlloc) { alloc.free_(tableAlloc); return false; @@ -625,14 +625,14 @@ class OrderedHashTable } size_t newHashBuckets = 1 << (HashNumberSizeBits - newHashShift); - Data **newHashTable = static_cast(alloc.malloc_(newHashBuckets * sizeof(Data *))); + Data **newHashTable = alloc.template pod_malloc(newHashBuckets); if (!newHashTable) return false; for (uint32_t i = 0; i < newHashBuckets; i++) newHashTable[i] = nullptr; uint32_t newCapacity = uint32_t(newHashBuckets * fillFactor()); - Data *newData = static_cast(alloc.malloc_(newCapacity * sizeof(Data))); + Data *newData = alloc.template pod_malloc(newCapacity); if (!newData) { alloc.free_(newHashTable); return false; diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 2aa3b7a4a622..b0a1905b2716 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -38,6 +38,7 @@ #include "builtin/TypedObject.h" #include "ctypes/Library.h" +#include "gc/Zone.h" using namespace std; using mozilla::NumericLimits; @@ -6097,7 +6098,7 @@ CClosure::Create(JSContext* cx, // Allocate a buffer for the return value. size_t rvSize = CType::GetSize(fninfo->mReturnType); - cinfo->errResult = cx->malloc_(rvSize); + cinfo->errResult = result->zone()->pod_malloc(rvSize); if (!cinfo->errResult) return nullptr; @@ -6382,7 +6383,7 @@ CData::Create(JSContext* cx, } else { // Initialize our own buffer. size_t size = CType::GetSize(typeObj); - data = (char*)cx->malloc_(size); + data = dataObj->zone()->pod_malloc(size); if (!data) { // Report a catchable allocation error. JS_ReportAllocationOverflow(cx); diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index 555d3b256442..2cf329444c85 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -516,25 +516,28 @@ class LifoAllocPolicy MOZ_IMPLICIT LifoAllocPolicy(LifoAlloc &alloc) : alloc_(alloc) {} - void *malloc_(size_t bytes) { - return fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes); + template + T *pod_malloc(size_t numElems) { + if (numElems & mozilla::tl::MulOverflowMask::value) + return nullptr; + size_t bytes = numElems * sizeof(T); + void *p = fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes); + return static_cast(p); } template T *pod_calloc(size_t numElems) { - if (numElems & mozilla::tl::MulOverflowMask::value) - return nullptr; - T *p = (T *)malloc_(numElems * sizeof(T)); + T *p = pod_malloc(numElems); if (fb == Fallible && !p) return nullptr; memset(p, 0, numElems * sizeof(T)); return p; } void *realloc_(void *p, size_t oldBytes, size_t bytes) { - void *n = malloc_(bytes); + uint8_t *n = pod_malloc(bytes); if (fb == Fallible && !n) return nullptr; memcpy(n, p, Min(oldBytes, bytes)); - return n; + return static_cast(n); } void free_(void *p) { } diff --git a/js/src/gc/ForkJoinNursery.cpp b/js/src/gc/ForkJoinNursery.cpp index 2f474437d934..37a6967b9e95 100644 --- a/js/src/gc/ForkJoinNursery.cpp +++ b/js/src/gc/ForkJoinNursery.cpp @@ -139,17 +139,6 @@ // newspace won't be needed (if the parallel section is finished) or // can be created empty (if the gc just needed to evacuate). // -// -// Style note: -// -// - Use js_memcpy, malloc_, realloc_, and js_free uniformly, do not -// use PodCopy or pod_malloc: the type information for the latter is -// not always correct and surrounding code usually operates in terms -// of bytes, anyhow. -// -// With power comes responsibility, etc: code that used pod_malloc -// gets safe size computation built-in; here we must handle that -// manually. namespace js { namespace gc { @@ -563,19 +552,19 @@ ForkJoinNursery::allocateSlots(JSObject *obj, uint32_t nslots) if (nslots & mozilla::tl::MulOverflowMask::value) return nullptr; - size_t size = nslots * sizeof(HeapSlot); if (!isInsideNewspace(obj)) - return reinterpret_cast(cx_->malloc_(size)); + return obj->zone()->pod_malloc(nslots); if (nslots > MaxNurserySlots) - return allocateHugeSlots(nslots); + return allocateHugeSlots(obj, nslots); + size_t size = nslots * sizeof(HeapSlot); HeapSlot *slots = static_cast(allocate(size)); if (slots) return slots; - return allocateHugeSlots(nslots); + return allocateHugeSlots(obj, nslots); } HeapSlot * @@ -634,13 +623,12 @@ ForkJoinNursery::freeSlots(HeapSlot *slots) } HeapSlot * -ForkJoinNursery::allocateHugeSlots(size_t nslots) +ForkJoinNursery::allocateHugeSlots(JSObject *obj, size_t nslots) { if (nslots & mozilla::tl::MulOverflowMask::value) return nullptr; - size_t size = nslots * sizeof(HeapSlot); - HeapSlot *slots = reinterpret_cast(cx_->malloc_(size)); + HeapSlot *slots = obj->zone()->pod_malloc(nslots); if (!slots) return slots; @@ -777,12 +765,13 @@ ForkJoinNursery::allocateInTospace(gc::AllocKind thingKind) return allocateInTospaceInfallible(thingSize); } -void * -ForkJoinNursery::allocateInTospace(size_t nelem, size_t elemSize) +template +T * +ForkJoinNursery::allocateInTospace(size_t nelem) { if (isEvacuating_) - return evacuationZone_->malloc_(nelem * elemSize); - return allocateInTospaceInfallible(nelem * elemSize); + return evacuationZone_->pod_malloc(nelem); + return static_cast(allocateInTospaceInfallible(nelem * sizeof(T))); } MOZ_ALWAYS_INLINE void @@ -850,7 +839,7 @@ ForkJoinNursery::copySlotsToTospace(JSObject *dst, JSObject *src, AllocKind dstK } size_t count = src->numDynamicSlots(); - dst->slots = reinterpret_cast(allocateInTospace(count, sizeof(HeapSlot))); + dst->slots = allocateInTospace(count); if (!dst->slots) CrashAtUnhandlableOOM("Failed to allocate slots while moving object."); js_memcpy(dst->slots, src->slots, count * sizeof(HeapSlot)); @@ -889,7 +878,7 @@ ForkJoinNursery::copyElementsToTospace(JSObject *dst, JSObject *src, AllocKind d } JS_ASSERT(nslots >= 2); - dstHeader = reinterpret_cast(allocateInTospace(nslots, sizeof(HeapSlot))); + dstHeader = reinterpret_cast(allocateInTospace(nslots)); if (!dstHeader) CrashAtUnhandlableOOM("Failed to allocate elements while moving object."); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); diff --git a/js/src/gc/ForkJoinNursery.h b/js/src/gc/ForkJoinNursery.h index f374b5d35a4f..6af73f77bfca 100644 --- a/js/src/gc/ForkJoinNursery.h +++ b/js/src/gc/ForkJoinNursery.h @@ -205,7 +205,7 @@ class ForkJoinNursery void *allocate(size_t size); // Allocate an external slot array and register it with this nursery. - HeapSlot *allocateHugeSlots(size_t nslots); + HeapSlot *allocateHugeSlots(JSObject *obj, size_t nslots); // Reallocate an external slot array, unregister the old array and // register the new array. If the allocation fails then leave @@ -240,9 +240,9 @@ class ForkJoinNursery void computeNurserySizeAfterGC(size_t live, const char **msg); AllocKind getObjectAllocKind(JSObject *src); - void *allocateInTospace(AllocKind thingKind); - void *allocateInTospace(size_t nelem, size_t elemSize); void *allocateInTospaceInfallible(size_t thingSize); + void *allocateInTospace(AllocKind thingKind); + template T *allocateInTospace(size_t nelem); MOZ_ALWAYS_INLINE bool shouldMoveObject(void **thingp); void *moveObjectToTospace(JSObject *src); size_t copyObjectToTospace(JSObject *dst, JSObject *src, gc::AllocKind dstKind); diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 64faf27c1989..b74823505cbe 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -695,8 +695,7 @@ js::Nursery::moveElementsToTenured(JSObject *dst, JSObject *src, AllocKind dstKi } JS_ASSERT(nslots >= 2); - size_t nbytes = nslots * sizeof(HeapValue); - dstHeader = static_cast(zone->malloc_(nbytes)); + dstHeader = reinterpret_cast(zone->pod_malloc(nslots)); if (!dstHeader) CrashAtUnhandlableOOM("Failed to allocate elements while tenuring."); js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot)); diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 3b08c35b12e6..4e4bd667abd4 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -373,7 +373,7 @@ BaselineScript::New(JSContext *cx, uint32_t prologueOffset, uint32_t epilogueOff paddedPCMappingSize + paddedBytecodeTypesMapSize; - uint8_t *buffer = (uint8_t *)cx->malloc_(allocBytes); + uint8_t *buffer = cx->zone()->pod_malloc(allocBytes); if (!buffer) return nullptr; diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index a5d8c44f1849..8e6ebd60b19f 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -900,7 +900,7 @@ IonScript::New(JSContext *cx, types::RecompileInfo recompileInfo, paddedSafepointSize + paddedCallTargetSize + paddedBackedgeSize; - uint8_t *buffer = (uint8_t *)cx->malloc_(sizeof(IonScript) + bytes); + uint8_t *buffer = cx->zone()->pod_malloc(sizeof(IonScript) + bytes); if (!buffer) return nullptr; diff --git a/js/src/jit/IonAllocPolicy.h b/js/src/jit/IonAllocPolicy.h index 831851c1999e..612c23318042 100644 --- a/js/src/jit/IonAllocPolicy.h +++ b/js/src/jit/IonAllocPolicy.h @@ -100,20 +100,21 @@ class IonAllocPolicy MOZ_IMPLICIT IonAllocPolicy(TempAllocator &alloc) : alloc_(alloc) {} - void *malloc_(size_t bytes) { - return alloc_.allocate(bytes); + template + T *pod_malloc(size_t numElems) { + if (numElems & mozilla::tl::MulOverflowMask::value) + return nullptr; + return static_cast(alloc_.allocate(numElems * sizeof(T))); } template T *pod_calloc(size_t numElems) { - if (numElems & mozilla::tl::MulOverflowMask::value) - return nullptr; - T *p = (T *)alloc_.allocate(numElems * sizeof(T)); + T *p = pod_malloc(numElems); if (p) memset(p, 0, numElems * sizeof(T)); return p; } void *realloc_(void *p, size_t oldBytes, size_t bytes) { - void *n = malloc_(bytes); + void *n = static_cast(pod_malloc(bytes)); if (!n) return n; memcpy(n, p, Min(oldBytes, bytes)); @@ -125,22 +126,16 @@ class IonAllocPolicy } }; -// Deprecated. Don't use this. Will be removed after everything has been -// converted to IonAllocPolicy. class OldIonAllocPolicy { public: OldIonAllocPolicy() {} - void *malloc_(size_t bytes) { - return GetIonContext()->temp->allocate(bytes); - } - void *realloc_(void *p, size_t oldBytes, size_t bytes) { - void *n = malloc_(bytes); - if (!n) - return n; - memcpy(n, p, Min(oldBytes, bytes)); - return n; + template + T *pod_malloc(size_t numElems) { + if (numElems & mozilla::tl::MulOverflowMask::value) + return nullptr; + return static_cast(GetIonContext()->temp->allocate(numElems * sizeof(T))); } void free_(void *p) { } diff --git a/js/src/jit/JitcodeMap.cpp b/js/src/jit/JitcodeMap.cpp index f6348a221603..21bf5974000f 100644 --- a/js/src/jit/JitcodeMap.cpp +++ b/js/src/jit/JitcodeMap.cpp @@ -552,7 +552,7 @@ JitcodeIonTable::makeIonEntry(JSContext *cx, JitCode *code, } // Create SizedScriptList - void *mem = cx->malloc_(SizedScriptList::AllocSizeFor(numScripts)); + void *mem = (void *)cx->pod_malloc(SizedScriptList::AllocSizeFor(numScripts)); if (!mem) return false; SizedScriptList *scriptList = new (mem) SizedScriptList(numScripts, scripts); diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 62eb529e99ab..3adea610ccb6 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -588,7 +588,7 @@ CodeGeneratorShared::createNativeToBytecodeScriptList(JSContext *cx) } // Allocate array for list. - JSScript **data = (JSScript **) cx->malloc_(scriptList.length() * sizeof(JSScript **)); + JSScript **data = cx->runtime()->pod_malloc(scriptList.length()); if (!data) return false; @@ -642,7 +642,7 @@ CodeGeneratorShared::generateCompactNativeToBytecodeMap(JSContext *cx, JitCode * JS_ASSERT(numRegions > 0); // Writer is done, copy it to sized buffer. - uint8_t *data = (uint8_t *) cx->malloc_(writer.length()); + uint8_t *data = cx->runtime()->pod_malloc(writer.length()); if (!data) return false; diff --git a/js/src/jsalloc.h b/js/src/jsalloc.h index a026e7bd0393..0459ca53a657 100644 --- a/js/src/jsalloc.h +++ b/js/src/jsalloc.h @@ -25,7 +25,7 @@ struct ContextFriendFields; class SystemAllocPolicy { public: - void *malloc_(size_t bytes) { return js_malloc(bytes); } + template T *pod_malloc(size_t numElems) { return js_pod_malloc(numElems); } template T *pod_calloc(size_t numElems) { return js_pod_calloc(numElems); } void *realloc_(void *p, size_t oldBytes, size_t bytes) { return js_realloc(p, bytes); } void free_(void *p) { js_free(p); } @@ -55,10 +55,11 @@ class TempAllocPolicy MOZ_IMPLICIT TempAllocPolicy(JSContext *cx) : cx_((ContextFriendFields *) cx) {} // :( MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields *cx) : cx_(cx) {} - void *malloc_(size_t bytes) { - void *p = js_malloc(bytes); + template + T *pod_malloc(size_t numElems) { + T *p = js_pod_malloc(numElems); if (MOZ_UNLIKELY(!p)) - p = onOutOfMemory(nullptr, bytes); + p = static_cast(onOutOfMemory(nullptr, numElems * sizeof(T))); return p; } @@ -66,7 +67,7 @@ class TempAllocPolicy T *pod_calloc(size_t numElems) { T *p = js_pod_calloc(numElems); if (MOZ_UNLIKELY(!p)) - p = (T *)onOutOfMemory(reinterpret_cast(1), numElems * sizeof(T)); + p = static_cast(onOutOfMemory(reinterpret_cast(1), numElems * sizeof(T))); return p; } diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index fc2c9b33ad81..f0c6002bc5ed 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1411,7 +1411,7 @@ JS_malloc(JSContext *cx, size_t nbytes) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - return cx->malloc_(nbytes); + return static_cast(cx->runtime()->pod_malloc(nbytes)); } JS_PUBLIC_API(void *) @@ -1458,7 +1458,7 @@ JS_strdup(JSRuntime *rt, const char *s) { AssertHeapIsIdle(rt); size_t n = strlen(s) + 1; - void *p = rt->malloc_(n); + char *p = rt->pod_malloc(n); if (!p) return nullptr; return static_cast(js_memcpy(p, s, n)); diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 93bb160c8e34..b770fbb666e3 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -993,22 +993,6 @@ class AutoAssertNoException } }; -/* - * FIXME bug 647103 - replace these *AllocPolicy names. - */ -class ContextAllocPolicy -{ - ThreadSafeContext *const cx_; - - public: - MOZ_IMPLICIT ContextAllocPolicy(ThreadSafeContext *cx) : cx_(cx) {} - ThreadSafeContext *context() const { return cx_; } - void *malloc_(size_t bytes) { return cx_->malloc_(bytes); } - void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx_->realloc_(p, oldBytes, bytes); } - void free_(void *p) { js_free(p); } - void reportAllocOverflow() const { js_ReportAllocationOverflow(cx_); } -}; - /* Exposed intrinsics so that Ion may inline them. */ bool intrinsic_ToObject(JSContext *cx, unsigned argc, Value *vp); bool intrinsic_IsObject(JSContext *cx, unsigned argc, Value *vp); diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index 384b2a0af4a2..88fefd2d4422 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -195,6 +195,7 @@ class ArenaCellIterImpl ArenaCellIterImpl() : firstThingOffset(0) // Squelch , thingSize(0) // warnings + , limit(0) { } diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index d9688403f955..c14cca43b0d5 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -381,7 +381,7 @@ js::VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap) size_t len = props.length(); size_t idsz = len * sizeof(jsid); size_t sz = (sizeof(JSIdArray) - sizeof(jsid)) + idsz; - JSIdArray *ida = static_cast(cx->malloc_(sz)); + JSIdArray *ida = reinterpret_cast(cx->zone()->pod_malloc(sz)); if (!ida) return false; @@ -499,12 +499,14 @@ NativeIterator * NativeIterator::allocateIterator(JSContext *cx, uint32_t slength, const AutoIdVector &props) { size_t plength = props.length(); - NativeIterator *ni = (NativeIterator *) - cx->malloc_(sizeof(NativeIterator) - + plength * sizeof(JSString *) - + slength * sizeof(Shape *)); - if (!ni) + size_t nbytes = sizeof(NativeIterator) + + plength * sizeof(JSString *) + + slength * sizeof(Shape *); + uint8_t *bytes = cx->zone()->pod_malloc(nbytes); + if (!bytes) return nullptr; + + NativeIterator *ni = (NativeIterator *)bytes; AutoValueVector strings(cx); ni->props_array = ni->props_cursor = (HeapPtrFlatString *) (ni + 1); ni->props_end = ni->props_array + plength; diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 19455a439b3f..ea18d5e0ff31 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -2080,7 +2080,7 @@ js::GetPCCountScriptSummary(JSContext *cx, size_t index) /* * OOM on buffer appends here will not be caught immediately, but since - * StringBuffer uses a ContextAllocPolicy will trigger an exception on the + * StringBuffer uses a TempAllocPolicy will trigger an exception on the * context if they occur, which we'll catch before returning. */ StringBuffer buf(cx); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index d7978e07345b..10369212c11d 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1608,7 +1608,7 @@ ScriptSource::ensureOwnsSource(ExclusiveContext *cx) if (ownsUncompressedChars()) return true; - jschar *uncompressed = (jschar *) cx->malloc_(sizeof(jschar) * Max(length_, 1)); + jschar *uncompressed = cx->zone()->pod_malloc(Max(length_, 1)); if (!uncompressed) return false; PodCopy(uncompressed, uncompressedChars(), length_); @@ -1818,7 +1818,7 @@ ScriptSource::performXDR(XDRState *xdr) size_t byteLen = compressedLength ? compressedLength : (length_ * sizeof(jschar)); if (mode == XDR_DECODE) { - void *p = xdr->cx()->malloc_(Max(byteLen, 1)); + uint8_t *p = xdr->cx()->template pod_malloc(Max(byteLen, 1)); if (!p || !xdr->codeBytes(p, byteLen)) { js_free(p); return false; @@ -1908,7 +1908,7 @@ ScriptSource::performXDR(XDRState *xdr) return true; } -// Format and return a cx->malloc_'ed URL for a generated script like: +// Format and return a cx->zone()->pod_malloc'ed URL for a generated script like: // {filename} line {lineno} > {introducer} // For example: // foo.js line 7 > eval @@ -1933,7 +1933,7 @@ FormatIntroducedFilename(ExclusiveContext *cx, const char *filename, unsigned li 3 /* == strlen(" > ") */ + introducerLen + 1 /* \0 */; - char *formatted = cx->pod_malloc(len); + char *formatted = cx->zone()->pod_malloc(len); if (!formatted) return nullptr; mozilla::DebugOnly checkLen = JS_snprintf(formatted, len, "%s line %s > %s", @@ -2061,7 +2061,8 @@ js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength, uint32_t padding = (pointerSize - ((baseLength + dataOffset) & pointerMask)) & pointerMask; uint32_t length = baseLength + padding + pointerSize * natoms; - SharedScriptData *entry = (SharedScriptData *)cx->malloc_(length + dataOffset); + SharedScriptData *entry = reinterpret_cast( + cx->zone()->pod_malloc(length + dataOffset)); if (!entry) return nullptr; @@ -3654,7 +3655,7 @@ LazyScript::CreateRaw(ExclusiveContext *cx, HandleFunction fun, size_t bytes = (p.numFreeVariables * sizeof(HeapPtrAtom)) + (p.numInnerFunctions * sizeof(HeapPtrFunction)); - ScopedJSFreePtr table(bytes ? cx->malloc_(bytes) : nullptr); + ScopedJSFreePtr table(bytes ? fun->zone()->pod_malloc(bytes) : nullptr); if (bytes && !table) return nullptr; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index cd01d4e9bc8d..f75008e52732 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -499,7 +499,7 @@ ReadEvalPrintLoop(JSContext *cx, Handle global, FILE *in, FILE *out, * coincides with the end of a line. */ int startline = lineno; - typedef Vector CharBuffer; + typedef Vector CharBuffer; CharBuffer buffer(cx); do { ScheduleWatchdog(cx->runtime(), -1); diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp index 1c5b4a456aa9..9022a5dca97b 100644 --- a/js/src/vm/ArgumentsObject.cpp +++ b/js/src/vm/ArgumentsObject.cpp @@ -157,8 +157,8 @@ struct CopyScriptFrameIterArgs template /* static */ ArgumentsObject * -ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction callee, unsigned numActuals, - CopyArgs ©) +ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction callee, + unsigned numActuals, CopyArgs ©) { RootedObject proto(cx, callee->global().getOrCreateObjectPrototype(cx)); if (!proto) @@ -188,7 +188,8 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle numDeletedWords * sizeof(size_t) + numArgs * sizeof(Value); - ArgumentsData *data = (ArgumentsData *)cx->malloc_(numBytes); + ArgumentsData *data = reinterpret_cast( + cx->zone()->pod_malloc(numBytes)); if (!data) return nullptr; diff --git a/js/src/vm/MallocProvider.h b/js/src/vm/MallocProvider.h index a9ef261bbbd6..6897edd0b6ae 100644 --- a/js/src/vm/MallocProvider.h +++ b/js/src/vm/MallocProvider.h @@ -52,11 +52,70 @@ namespace js { template struct MallocProvider { - void *malloc_(size_t bytes) { - Client *client = static_cast(this); - client->updateMallocCounter(bytes); - void *p = js_malloc(bytes); - return MOZ_LIKELY(!!p) ? p : client->onOutOfMemory(nullptr, bytes); + template + T *pod_malloc() { + T *p = js_pod_malloc(); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(sizeof(T)); + return p; + } + client()->onOutOfMemory(nullptr, sizeof(T)); + return nullptr; + } + + template + T *pod_malloc(size_t numElems) { + T *p = js_pod_malloc(numElems); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(numElems * sizeof(T)); + return p; + } + if (numElems & mozilla::tl::MulOverflowMask::value) { + client()->reportAllocationOverflow(); + return nullptr; + } + client()->onOutOfMemory(nullptr, numElems * sizeof(T)); + return nullptr; + } + + template + mozilla::UniquePtr + make_pod_array(size_t numElems) { + return mozilla::UniquePtr(pod_malloc(numElems)); + } + + template + T *pod_calloc() { + T *p = js_pod_calloc(); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(sizeof(T)); + return p; + } + client()->onOutOfMemory(reinterpret_cast(1), sizeof(T)); + return nullptr; + } + + template + T * + pod_calloc(size_t numElems) { + T *p = js_pod_calloc(numElems); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(numElems * sizeof(T)); + return p; + } + if (numElems & mozilla::tl::MulOverflowMask::value) { + client()->reportAllocationOverflow(); + return nullptr; + } + client()->onOutOfMemory(reinterpret_cast(1), sizeof(T)); + return nullptr; + } + + template + mozilla::UniquePtr + make_zeroed_pod_array(size_t numElems) + { + return mozilla::UniquePtr(pod_calloc(numElems)); } void *realloc_(void *p, size_t oldBytes, size_t newBytes) { @@ -83,73 +142,16 @@ struct MallocProvider return MOZ_LIKELY(!!p2) ? p2 : client->onOutOfMemory(p, bytes); } - template - T *pod_malloc() { - return (T *)malloc_(sizeof(T)); - } - - template - T *pod_calloc() { - Client *client = static_cast(this); - client->updateMallocCounter(sizeof(T)); - T *p = js_pod_calloc(); - if (MOZ_UNLIKELY(!p)) { - client->onOutOfMemory(reinterpret_cast(1), sizeof(T)); - return nullptr; - } - return p; - } - - template - T *pod_malloc(size_t numElems) { - if (numElems & mozilla::tl::MulOverflowMask::value) { - Client *client = static_cast(this); - client->reportAllocationOverflow(); - return nullptr; - } - return (T *)malloc_(numElems * sizeof(T)); - } - - template - mozilla::UniquePtr - make_pod_array(size_t numElems) { - return mozilla::UniquePtr(pod_malloc(numElems)); - } - - template - T * - pod_calloc(size_t numElems, JSCompartment *comp = nullptr, JSContext *cx = nullptr) { - if (numElems & mozilla::tl::MulOverflowMask::value) { - Client *client = static_cast(this); - client->reportAllocationOverflow(); - return nullptr; - } - Client *client = static_cast(this); - client->updateMallocCounter(numElems * sizeof(T)); - T *p = js_pod_calloc(numElems); - if (MOZ_UNLIKELY(!p)) { - client->onOutOfMemory(reinterpret_cast(1), sizeof(T)); - return nullptr; - } - return p; - } - - template - mozilla::UniquePtr - make_zeroed_pod_array(size_t numElems, - JSCompartment *comp = nullptr, - JSContext *cx = nullptr) - { - return mozilla::UniquePtr(pod_calloc(numElems, comp, cx)); - } - template T *pod_realloc(T *prior, size_t oldSize, size_t newSize) { return (T *)realloc_(prior, oldSize * sizeof(T), newSize * sizeof(T)); } - JS_DECLARE_NEW_METHODS(new_, malloc_, MOZ_ALWAYS_INLINE) + JS_DECLARE_NEW_METHODS(new_, pod_malloc, MOZ_ALWAYS_INLINE) JS_DECLARE_MAKE_METHODS(make_unique, new_, MOZ_ALWAYS_INLINE) + + private: + Client *client() { return static_cast(this); } }; } /* namespace js */ diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index a6441186694f..d0b61503a65e 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1649,7 +1649,7 @@ SetValueRangeToNull(Value *vec, size_t len) } /* - * Allocation policy that uses JSRuntime::malloc_ and friends, so that + * Allocation policy that uses JSRuntime::pod_malloc and friends, so that * memory pressure is properly accounted for. This is suitable for * long-lived objects owned by the JSRuntime. * @@ -1665,7 +1665,11 @@ class RuntimeAllocPolicy public: MOZ_IMPLICIT RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {} - void *malloc_(size_t bytes) { return runtime->malloc_(bytes); } + + template + T *pod_malloc(size_t numElems) { + return runtime->pod_malloc(numElems); + } template T *pod_calloc(size_t numElems) { diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 7752634d5e1f..f7b53026e83b 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -1023,7 +1023,7 @@ JSRuntime::initSelfHosting(JSContext *cx) const unsigned char *compressed = compressedSources; uint32_t compressedLen = GetCompressedSize(); - ScopedJSFreePtr src(reinterpret_cast(cx->malloc_(srcLen))); + ScopedJSFreePtr src(selfHostingGlobal_->zone()->pod_malloc(srcLen)); if (!src || !DecompressString(compressed, compressedLen, reinterpret_cast(src.get()), srcLen)) { diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 98f29d153b43..c9d64de633de 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -152,7 +152,7 @@ JSString::equals(const char *s) template static MOZ_ALWAYS_INLINE bool -AllocChars(ThreadSafeContext *maybecx, size_t length, CharT **chars, size_t *capacity) +AllocChars(JSString *str, size_t length, CharT **chars, size_t *capacity) { /* * String length doesn't include the null char, so include it here before @@ -173,8 +173,7 @@ AllocChars(ThreadSafeContext *maybecx, size_t length, CharT **chars, size_t *cap *capacity = numChars - 1; JS_STATIC_ASSERT(JSString::MAX_LENGTH * sizeof(CharT) < UINT32_MAX); - size_t bytes = numChars * sizeof(CharT); - *chars = (CharT *)(maybecx ? maybecx->malloc_(bytes) : js_malloc(bytes)); + *chars = str->zone()->pod_malloc(numChars); return *chars != nullptr; } @@ -379,7 +378,7 @@ JSRope::flattenInternal(ExclusiveContext *maybecx) } } - if (!AllocChars(maybecx, wholeLength, &wholeChars, &wholeCapacity)) + if (!AllocChars(this, wholeLength, &wholeChars, &wholeCapacity)) return nullptr; pos = wholeChars; diff --git a/js/src/vm/StringBuffer.cpp b/js/src/vm/StringBuffer.cpp index 6e25208f9bfa..72a97518f104 100644 --- a/js/src/vm/StringBuffer.cpp +++ b/js/src/vm/StringBuffer.cpp @@ -88,6 +88,12 @@ FinishStringFlat(ExclusiveContext *cx, StringBuffer &sb, Buffer &cb) if (!str) return nullptr; + /* + * The allocation was made on a TempAllocPolicy, so account for the string + * data on the string's zone. + */ + str->zone()->updateMallocCounter(sizeof(CharT) * len); + buf.forget(); return str; } diff --git a/js/src/vm/StringBuffer.h b/js/src/vm/StringBuffer.h index 13799d54925e..81238092f36f 100644 --- a/js/src/vm/StringBuffer.h +++ b/js/src/vm/StringBuffer.h @@ -30,11 +30,11 @@ namespace js { class StringBuffer { /* - * The Vector's buffer is taken by the new string so use - * ContextAllocPolicy. + * The Vector's buffer may be either stolen or copied, so we need to use + * TempAllocPolicy and account for the memory manually when stealing. */ - typedef Vector Latin1CharBuffer; - typedef Vector TwoByteCharBuffer; + typedef Vector Latin1CharBuffer; + typedef Vector TwoByteCharBuffer; ExclusiveContext *cx; diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index eb1e67d7da22..46478af0b1d9 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1066,7 +1066,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject // We have to make a copy of the source array here, since // there's overlap, and we have to convert types. - void *srcbuf = cx->malloc_(byteLength); + uint8_t *srcbuf = self->zone()->pod_malloc(byteLength); if (!srcbuf) return false; js_memcpy(srcbuf, tarray->viewData(), byteLength); diff --git a/memory/replace/dmd/DMD.cpp b/memory/replace/dmd/DMD.cpp index 91dd23daedd5..38f56e775b6f 100644 --- a/memory/replace/dmd/DMD.cpp +++ b/memory/replace/dmd/DMD.cpp @@ -102,6 +102,16 @@ public: return p; } + template + static T* pod_malloc(size_t aNumElems) + { + if (aNumElems & mozilla::tl::MulOverflowMask::value) + return nullptr; + void* p = gMallocTable->malloc(aNumElems * sizeof(T)); + ExitOnFailure(p); + return (T*)p; + } + static void* calloc_(size_t aSize) { void* p = gMallocTable->calloc(1, aSize); diff --git a/mfbt/AllocPolicy.h b/mfbt/AllocPolicy.h index c2fcd83d4fc5..124e7023364a 100644 --- a/mfbt/AllocPolicy.h +++ b/mfbt/AllocPolicy.h @@ -12,6 +12,9 @@ #ifndef mozilla_AllocPolicy_h #define mozilla_AllocPolicy_h +#include "mozilla/NullPtr.h" +#include "mozilla/TemplateLib.h" + #include #include @@ -24,7 +27,7 @@ namespace mozilla { * mechanism when OOM occurs. The concept modeled here is as follows: * * - public copy constructor, assignment, destructor - * - void* malloc_(size_t) + * - template T* pod_malloc(size_t) * Responsible for OOM reporting when null is returned. * - template T* pod_calloc(size_t) * Responsible for OOM reporting when null is returned. @@ -50,9 +53,12 @@ namespace mozilla { class MallocAllocPolicy { public: - void* malloc_(size_t aBytes) + template + T* pod_malloc(size_t aNumElems) { - return malloc(aBytes); + if (aNumElems & mozilla::tl::MulOverflowMask::value) + return nullptr; + return static_cast(malloc(aNumElems * sizeof(T))); } template diff --git a/mfbt/Vector.h b/mfbt/Vector.h index 8540caf476f4..99c06112d39e 100644 --- a/mfbt/Vector.h +++ b/mfbt/Vector.h @@ -124,7 +124,7 @@ struct VectorImpl { MOZ_ASSERT(!aV.usingInlineStorage()); MOZ_ASSERT(!CapacityHasExcessSpace(aNewCap)); - T* newbuf = reinterpret_cast(aV.malloc_(aNewCap * sizeof(T))); + T* newbuf = aV.template pod_malloc(aNewCap); if (!newbuf) { return false; } @@ -704,7 +704,7 @@ VectorBase::convertToHeapStorage(size_t aNewCap) /* Allocate buffer. */ MOZ_ASSERT(!detail::CapacityHasExcessSpace(aNewCap)); - T* newBuf = reinterpret_cast(this->malloc_(aNewCap * sizeof(T))); + T* newBuf = this->template pod_malloc(aNewCap); if (!newBuf) { return false; } @@ -813,7 +813,7 @@ VectorBase::initCapacity(size_t aRequest) if (aRequest == 0) { return true; } - T* newbuf = reinterpret_cast(this->malloc_(aRequest * sizeof(T))); + T* newbuf = this->template pod_malloc(aRequest); if (!newbuf) { return false; } @@ -1137,7 +1137,7 @@ VectorBase::extractRawBuffer() { T* ret; if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc_(mLength * sizeof(T))); + ret = this->template pod_malloc(mLength); if (!ret) { return nullptr; } From 6cf995b7709cf55d428043dcf89f08887cacff71 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 15 Aug 2014 17:15:26 -0400 Subject: [PATCH 017/101] Backed out changeset 926c83cd24f0 (bug 1052751) for B2G reftest failures. --- .../composite/ContainerLayerComposite.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 761a10f28d42..5ef409df39d9 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -34,9 +34,6 @@ #include "TextRenderer.h" // for TextRenderer #include -#define CULLING_LOG(...) -// #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__) - namespace mozilla { namespace layers { @@ -324,26 +321,16 @@ ContainerPrepare(ContainerT* aContainer, continue; } - CULLING_LOG("Preparing sublayer %p\n", layerToRender->GetLayer()); - nsIntRegion savedVisibleRegion; bool restoreVisibleRegion = false; - gfx::Matrix matrix; - bool is2D = layerToRender->GetLayer()->GetBaseTransform().Is2D(&matrix); if (i + 1 < children.Length() && - is2D && !matrix.HasNonIntegerTranslation()) { + layerToRender->GetLayer()->GetEffectiveTransform().IsIdentity()) { LayerComposite* nextLayer = static_cast(children.ElementAt(i + 1)->ImplData()); - CULLING_LOG("Culling against %p\n", nextLayer->GetLayer()); nsIntRect nextLayerOpaqueRect; if (nextLayer && nextLayer->GetLayer()) { nextLayerOpaqueRect = GetOpaqueRect(nextLayer->GetLayer()); - gfx::Point point = matrix.GetTranslation(); - nextLayerOpaqueRect.MoveBy(static_cast(-point.x), static_cast(-point.y)); - CULLING_LOG(" point %i, %i\n", static_cast(-point.x), static_cast(-point.y)); - CULLING_LOG(" opaque rect %i, %i, %i, %i\n", nextLayerOpaqueRect.x, nextLayerOpaqueRect.y, nextLayerOpaqueRect.width, nextLayerOpaqueRect.height); } if (!nextLayerOpaqueRect.IsEmpty()) { - CULLING_LOG(" draw\n"); savedVisibleRegion = layerToRender->GetShadowVisibleRegion(); nsIntRegion visibleRegion; visibleRegion.Sub(savedVisibleRegion, nextLayerOpaqueRect); @@ -352,16 +339,12 @@ ContainerPrepare(ContainerT* aContainer, } layerToRender->SetShadowVisibleRegion(visibleRegion); restoreVisibleRegion = true; - } else { - CULLING_LOG(" skip\n"); } } layerToRender->Prepare(clipRect); aContainer->mPrepared->mLayers.AppendElement(PreparedLayer(layerToRender, clipRect, restoreVisibleRegion, savedVisibleRegion)); } - CULLING_LOG("Preparing container layer %p\n", aContainer->GetLayer()); - /** * Setup our temporary surface for rendering the contents of this container. */ From 53911e168c0cd8c156a4b17e949226ea5a87199c Mon Sep 17 00:00:00 2001 From: Catalin Badea Date: Fri, 15 Aug 2014 14:17:35 -0700 Subject: [PATCH 018/101] Bug 853995 - Move plugin parameters array from nsPluginInstanceOwner to content. r=johns,jst --- content/base/src/nsObjectLoadingContent.cpp | 228 ++++++++--- content/base/src/nsObjectLoadingContent.h | 36 ++ dom/plugins/base/nsNPAPIPluginInstance.cpp | 175 ++++----- dom/plugins/base/nsNPAPIPluginInstance.h | 10 +- dom/plugins/base/nsPluginInstanceOwner.cpp | 402 +------------------- dom/plugins/base/nsPluginInstanceOwner.h | 64 +--- dom/webidl/HTMLObjectElement.webidl | 16 + 7 files changed, 331 insertions(+), 600 deletions(-) diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index c7a14d260c7f..09b3673034c4 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -12,6 +12,7 @@ // Interface headers #include "imgLoader.h" #include "nsIContent.h" +#include "nsIContentInlines.h" #include "nsIDocShell.h" #include "nsIDocument.h" #include "nsIDOMCustomEvent.h" @@ -82,6 +83,7 @@ #include "mozilla/EventDispatcher.h" #include "mozilla/EventStates.h" #include "mozilla/Telemetry.h" +#include "mozilla/dom/HTMLObjectElementBinding.h" #ifdef XP_WIN // Thanks so much, Microsoft! :( @@ -915,6 +917,167 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading) return NS_OK; } +void +nsObjectLoadingContent::GetPluginAttributes(nsTArray& aAttributes) +{ + aAttributes = mCachedAttributes; +} + +void +nsObjectLoadingContent::GetPluginParameters(nsTArray& aParameters) +{ + aParameters = mCachedParameters; +} + +void +nsObjectLoadingContent::GetNestedParams(nsTArray& aParams, + bool aIgnoreCodebase) +{ + nsCOMPtr domElement = + do_QueryInterface(static_cast(this)); + + nsCOMPtr allParams; + NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml"); + domElement->GetElementsByTagNameNS(xhtml_ns, + NS_LITERAL_STRING("param"), getter_AddRefs(allParams)); + + if (!allParams) + return; + + uint32_t numAllParams; + allParams->GetLength(&numAllParams); + for (uint32_t i = 0; i < numAllParams; i++) { + nsCOMPtr pNode; + allParams->Item(i, getter_AddRefs(pNode)); + nsCOMPtr element = do_QueryInterface(pNode); + + if (!element) + continue; + + nsAutoString name; + element->GetAttribute(NS_LITERAL_STRING("name"), name); + + if (name.IsEmpty()) + continue; + + nsCOMPtr parent; + nsCOMPtr domObject; + nsCOMPtr domApplet; + pNode->GetParentNode(getter_AddRefs(parent)); + while (!(domObject || domApplet) && parent) { + domObject = do_QueryInterface(parent); + domApplet = do_QueryInterface(parent); + nsCOMPtr temp; + parent->GetParentNode(getter_AddRefs(temp)); + parent = temp; + } + + if (domApplet) { + parent = do_QueryInterface(domApplet); + } else if (domObject) { + parent = do_QueryInterface(domObject); + } else { + continue; + } + + nsCOMPtr domNode = do_QueryInterface(domElement); + if (parent == domNode) { + MozPluginParameter param; + element->GetAttribute(NS_LITERAL_STRING("name"), param.mName); + element->GetAttribute(NS_LITERAL_STRING("value"), param.mValue); + + param.mName.Trim(" \n\r\t\b", true, true, false); + param.mValue.Trim(" \n\r\t\b", true, true, false); + + // ignore codebase param if it was already added in the attributes array. + if (aIgnoreCodebase && param.mName.EqualsIgnoreCase("codebase")) { + continue; + } + + aParams.AppendElement(param); + } + } +} + +void +nsObjectLoadingContent::BuildParametersArray() +{ + if (mCachedAttributes.Length() || mCachedParameters.Length()) { + MOZ_ASSERT(false, "Parameters array should be empty."); + return; + } + + nsCOMPtr content = + do_QueryInterface(static_cast(this)); + + int32_t start = 0, end = content->GetAttrCount(), step = 1; + // HTML attributes are stored in reverse order. + if (content->IsHTML() && content->IsInHTMLDocument()) { + start = end - 1; + end = -1; + step = -1; + } + + for (int32_t i = start; i != end; i += step) { + MozPluginParameter param; + const nsAttrName* attrName = content->GetAttrNameAt(i); + nsIAtom* atom = attrName->LocalName(); + content->GetAttr(attrName->NamespaceID(), atom, param.mValue); + atom->ToString(param.mName); + mCachedAttributes.AppendElement(param); + } + + bool isJava = nsPluginHost::IsJavaMIMEType(mContentType.get()); + + nsCString codebase; + if (isJava) { + mBaseURI->GetSpec(codebase); + } + + nsAdoptingCString wmodeOverride = Preferences::GetCString("plugins.force.wmode"); + + for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) { + if (!wmodeOverride.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("wmode")) { + CopyASCIItoUTF16(wmodeOverride, mCachedAttributes[i].mValue); + wmodeOverride.Truncate(); + } else if (!codebase.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("codebase")) { + CopyASCIItoUTF16(codebase, mCachedAttributes[i].mValue); + codebase.Truncate(); + } + } + + if (!wmodeOverride.IsEmpty()) { + MozPluginParameter param; + param.mName = NS_LITERAL_STRING("wmode"); + CopyASCIItoUTF16(wmodeOverride, param.mValue); + mCachedAttributes.AppendElement(param); + } + + if (!codebase.IsEmpty()) { + MozPluginParameter param; + param.mName = NS_LITERAL_STRING("codebase"); + CopyASCIItoUTF16(codebase, param.mValue); + mCachedAttributes.AppendElement(param); + } + + // Some plugins were never written to understand the "data" attribute of the OBJECT tag. + // Real and WMP will not play unless they find a "src" attribute, see bug 152334. + // Nav 4.x would simply replace the "data" with "src". Because some plugins correctly + // look for "data", lets instead copy the "data" attribute and add another entry + // to the bottom of the array if there isn't already a "src" specified. + if (content->Tag() == nsGkAtoms::object && + !content->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) { + MozPluginParameter param; + content->GetAttr(kNameSpaceID_None, nsGkAtoms::data, param.mValue); + if (!param.mValue.IsEmpty()) { + param.mName = NS_LITERAL_STRING("SRC"); + mCachedAttributes.AppendElement(param); + } + } + + GetNestedParams(mCachedParameters, isJava); +} + void nsObjectLoadingContent::NotifyOwnerDocumentActivityChanged() { @@ -1502,59 +1665,15 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI) // Java wants the codebase attribute even if it occurs in tags - // XXX(johns): This duplicates a chunk of code from nsInstanceOwner, see - // bug 853995 if (isJava) { // Find all tags that are nested beneath us, but not beneath another // object/applet tag. - nsCOMArray ourParams; - nsCOMPtr mydomElement = do_QueryInterface(thisContent); - - nsCOMPtr allParams; - NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml"); - mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"), - getter_AddRefs(allParams)); - if (allParams) { - uint32_t numAllParams; - allParams->GetLength(&numAllParams); - for (uint32_t i = 0; i < numAllParams; i++) { - nsCOMPtr pnode; - allParams->Item(i, getter_AddRefs(pnode)); - nsCOMPtr domelement = do_QueryInterface(pnode); - if (domelement) { - nsAutoString name; - domelement->GetAttribute(NS_LITERAL_STRING("name"), name); - name.Trim(" \n\r\t\b", true, true, false); - if (name.EqualsIgnoreCase("codebase")) { - // Find the first plugin element parent - nsCOMPtr parent; - nsCOMPtr domobject; - nsCOMPtr domapplet; - pnode->GetParentNode(getter_AddRefs(parent)); - while (!(domobject || domapplet) && parent) { - domobject = do_QueryInterface(parent); - domapplet = do_QueryInterface(parent); - nsCOMPtr temp; - parent->GetParentNode(getter_AddRefs(temp)); - parent = temp; - } - if (domapplet || domobject) { - if (domapplet) { - parent = do_QueryInterface(domapplet); - } - else { - parent = do_QueryInterface(domobject); - } - nsCOMPtr mydomNode = do_QueryInterface(mydomElement); - if (parent == mydomNode) { - hasCodebase = true; - domelement->GetAttribute(NS_LITERAL_STRING("value"), - codebaseStr); - codebaseStr.Trim(" \n\r\t\b", true, true, false); - } - } - } - } + nsTArray params; + GetNestedParams(params, false); + for (uint32_t i = 0; i < params.Length(); i++) { + if (params[i].mName.EqualsIgnoreCase("codebase")) { + hasCodebase = true; + codebaseStr = params[i].mValue; } } } @@ -2121,6 +2240,12 @@ nsObjectLoadingContent::LoadObject(bool aNotify, /// Attempt to load new type /// + + // Cache the current attributes and parameters. + if (mType == eType_Plugin || mType == eType_Null) { + BuildParametersArray(); + } + // We don't set mFinalListener until OnStartRequest has been called, to // prevent re-entry ugliness with CloseChannel() nsCOMPtr finalListener; @@ -2477,6 +2602,9 @@ nsObjectLoadingContent::UnloadObject(bool aResetState) mIsStopping = false; } + mCachedAttributes.Clear(); + mCachedParameters.Clear(); + // This call should be last as it may re-enter StopPluginInstance(); } diff --git a/content/base/src/nsObjectLoadingContent.h b/content/base/src/nsObjectLoadingContent.h index 375f645ddc51..52e5d0dba21e 100644 --- a/content/base/src/nsObjectLoadingContent.h +++ b/content/base/src/nsObjectLoadingContent.h @@ -34,6 +34,7 @@ class nsPluginInstanceOwner; namespace mozilla { namespace dom { template class Sequence; +struct MozPluginParameter; } } @@ -119,6 +120,19 @@ class nsObjectLoadingContent : public nsImageLoadingContent mNetworkCreated = aNetworkCreated; } + /** + * When the object is loaded, the attributes and all nested + * elements are cached as name:value string pairs to be passed as + * parameters when instantiating the plugin. + * + * Note: these cached values can be overriden for different quirk cases. + */ + // Returns the cached attributes array. + void GetPluginAttributes(nsTArray& aAttributes); + + // Returns the cached array. + void GetPluginParameters(nsTArray& aParameters); + /** * Immediately instantiate a plugin instance. This is a no-op if mType != * eType_Plugin or a plugin is already running. @@ -322,6 +336,26 @@ class nsObjectLoadingContent : public nsImageLoadingContent eParamContentTypeChanged = 1u << 2 }; + /** + * Getter for child elements that are not nested in another plugin + * dom element. + * This is an internal helper function and should not be used directly for + * passing parameters to the plugin instance. + * + * See GetPluginParameters and GetPluginAttributes, which also handle + * quirk-overrides. + * + * @param aParameters The array containing pairs of name/value strings + * from nested objects. + * @param aIgnoreCodebase Flag for ignoring the "codebase" param when + * building the array. This is useful when loading + * java. + */ + void GetNestedParams(nsTArray& aParameters, + bool aIgnoreCodebase); + + void BuildParametersArray(); + /** * Loads fallback content with the specified FallbackType * @@ -579,6 +613,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent nsWeakFrame mPrintFrame; nsRefPtr mInstanceOwner; + nsTArray mCachedAttributes; + nsTArray mCachedParameters; }; #endif diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index b6742c2284c0..366cc6ca78d3 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -39,8 +39,10 @@ #include "mozilla/Preferences.h" #include "mozilla/unused.h" #include "nsILoadContext.h" +#include "mozilla/dom/HTMLObjectElementBinding.h" using namespace mozilla; +using namespace mozilla::dom; #ifdef MOZ_WIDGET_ANDROID #include "ANPBase.h" @@ -196,6 +198,9 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance() , mOnScreen(true) #endif , mHaveJavaC2PJSObjectQuirk(false) + , mCachedParamLength(0) + , mCachedParamNames(nullptr) + , mCachedParamValues(nullptr) { mNPP.pdata = nullptr; mNPP.ndata = this; @@ -219,6 +224,28 @@ nsNPAPIPluginInstance::~nsNPAPIPluginInstance() PR_Free((void *)mMIMEType); mMIMEType = nullptr; } + + if (!mCachedParamValues || !mCachedParamNames) { + return; + } + MOZ_ASSERT(mCachedParamValues && mCachedParamNames); + + for (uint32_t i = 0; i < mCachedParamLength; i++) { + if (mCachedParamNames[i]) { + NS_Free(mCachedParamNames[i]); + mCachedParamNames[i] = nullptr; + } + if (mCachedParamValues[i]) { + NS_Free(mCachedParamValues[i]); + mCachedParamValues[i] = nullptr; + } + } + + NS_Free(mCachedParamNames); + mCachedParamNames = nullptr; + + NS_Free(mCachedParamValues); + mCachedParamValues = nullptr; } uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0; @@ -377,28 +404,6 @@ nsNPAPIPluginInstance::GetTagType(nsPluginTagType *result) return mOwner->GetTagType(result); } -nsresult -nsNPAPIPluginInstance::GetAttributes(uint16_t& n, const char*const*& names, - const char*const*& values) -{ - if (!mOwner) { - return NS_ERROR_FAILURE; - } - - return mOwner->GetAttributes(n, names, values); -} - -nsresult -nsNPAPIPluginInstance::GetParameters(uint16_t& n, const char*const*& names, - const char*const*& values) -{ - if (!mOwner) { - return NS_ERROR_FAILURE; - } - - return mOwner->GetParameters(n, names, values); -} - nsresult nsNPAPIPluginInstance::GetMode(int32_t *result) { @@ -427,39 +432,53 @@ nsNPAPIPluginInstance::Start() return NS_OK; } + if (!mOwner) { + MOZ_ASSERT(false, "Should not be calling Start() on unowned plugin."); + return NS_ERROR_FAILURE; + } + PluginDestructionGuard guard(this); - uint16_t count = 0; - const char* const* names = nullptr; - const char* const* values = nullptr; + nsTArray attributes; + nsTArray params; + nsPluginTagType tagtype; nsresult rv = GetTagType(&tagtype); if (NS_SUCCEEDED(rv)) { - // Note: If we failed to get the tag type, we may be a full page plugin, so no arguments - rv = GetAttributes(count, names, values); - NS_ENSURE_SUCCESS(rv, rv); + mOwner->GetAttributes(attributes); + mOwner->GetParameters(params); + } else { + MOZ_ASSERT(false, "Failed to get tag type."); + } - // nsPluginTagType_Object or Applet may also have PARAM tags - // Note: The arrays handed back by GetParameters() are - // crafted specially to be directly behind the arrays from GetAttributes() - // with a null entry as a separator. This is for 4.x backwards compatibility! - // see bug 111008 for details - if (tagtype != nsPluginTagType_Embed) { - uint16_t pcount = 0; - const char* const* pnames = nullptr; - const char* const* pvalues = nullptr; - if (NS_SUCCEEDED(GetParameters(pcount, pnames, pvalues))) { - // Android expects an empty string as the separator instead of null -#ifdef MOZ_WIDGET_ANDROID - NS_ASSERTION(PL_strcmp(values[count], "") == 0, "attribute/parameter array not setup correctly for Android NPAPI plugins"); -#else - NS_ASSERTION(!values[count], "attribute/parameter array not setup correctly for NPAPI plugins"); -#endif - if (pcount) - count += ++pcount; // if it's all setup correctly, then all we need is to - // change the count (attrs + PARAM/blank + params) - } - } + mCachedParamLength = attributes.Length() + 1 + params.Length(); + + // We add an extra entry "PARAM" as a separator between the attribute + // and param values, but we don't count it if there are no entries. + // Legacy behavior quirk. + uint32_t quirkParamLength = params.Length() ? + mCachedParamLength : attributes.Length(); + + mCachedParamNames = (char**)NS_Alloc(sizeof(char*) * mCachedParamLength); + mCachedParamValues = (char**)NS_Alloc(sizeof(char*) * mCachedParamLength); + + for (uint32_t i = 0; i < attributes.Length(); i++) { + mCachedParamNames[i] = ToNewUTF8String(attributes[i].mName); + mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue); + } + + // Android expects and empty string instead of null. + mCachedParamNames[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("PARAM")); + #ifdef MOZ_WIDGET_ANDROID + mCachedParamValues[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("")); + #else + mCachedParamValues[attributes.Length()] = nullptr; + #endif + + for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length(); i ++) { + mCachedParamNames[pos] = ToNewUTF8String(params[i].mName); + mCachedParamValues[pos] = ToNewUTF8String(params[i].mValue); + pos++; } int32_t mode; @@ -469,57 +488,7 @@ nsNPAPIPluginInstance::Start() GetMode(&mode); GetMIMEType(&mimetype); - CheckJavaC2PJSObjectQuirk(count, names, values); - - // Some older versions of Flash have a bug in them - // that causes the stack to become currupt if we - // pass swliveconnect=1 in the NPP_NewProc arrays. - // See bug 149336 (UNIX), bug 186287 (Mac) - // - // The code below disables the attribute unless - // the environment variable: - // MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK - // is set. - // - // It is okay to disable this attribute because - // back in 4.x, scripting required liveconnect to - // start Java which was slow. Scripting no longer - // requires starting Java and is quick plus controled - // from the browser, so Flash now ignores this attribute. - // - // This code can not be put at the time of creating - // the array because we may need to examine the - // stream header to determine we want Flash. - - static const char flashMimeType[] = "application/x-shockwave-flash"; - static const char blockedParam[] = "swliveconnect"; - if (count && !PL_strcasecmp(mimetype, flashMimeType)) { - static int cachedDisableHack = 0; - if (!cachedDisableHack) { - if (PR_GetEnv("MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK")) - cachedDisableHack = -1; - else - cachedDisableHack = 1; - } - if (cachedDisableHack > 0) { - for (uint16_t i=0; iNPP_New((char*)mimetype, &mNPP, (uint16_t)mode, - count, (char**)names, (char**)values, - nullptr, &error); + quirkParamLength, mCachedParamNames, + mCachedParamValues, nullptr, &error); mInPluginInitCall = oldVal; NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP New called: this=%p, npp=%p, mime=%s, mode=%d, argc=%d, return=%d\n", - this, &mNPP, mimetype, mode, count, error)); + this, &mNPP, mimetype, mode, quirkParamLength, error)); if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) { mRunning = DESTROYED; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index f916b5716b71..e99843e1e7f8 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -305,10 +305,6 @@ protected: virtual ~nsNPAPIPluginInstance(); nsresult GetTagType(nsPluginTagType *result); - nsresult GetAttributes(uint16_t& n, const char*const*& names, - const char*const*& values); - nsresult GetParameters(uint16_t& n, const char*const*& names, - const char*const*& values); nsresult GetMode(int32_t *result); // check if this is a Java applet and affected by bug 750480 @@ -398,6 +394,12 @@ private: bool mHaveJavaC2PJSObjectQuirk; static uint32_t gInUnsafePluginCalls; + + // The arrays can only be released when the plugin instance is destroyed, + // because the plugin, in in-process mode, might keep a reference to them. + uint32_t mCachedParamLength; + char **mCachedParamNames; + char **mCachedParamValues; }; // On Android, we need to guard against plugin code leaking entries in the local diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index cb105212681f..98d56d562e52 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -39,6 +39,7 @@ using mozilla::DefaultXDisplay; #include "nsIAppShell.h" #include "nsIDOMHTMLAppletElement.h" #include "nsIObjectLoadingContent.h" +#include "nsObjectLoadingContent.h" #include "nsAttrName.h" #include "nsIFocusManager.h" #include "nsFocusManager.h" @@ -53,6 +54,7 @@ using mozilla::DefaultXDisplay; #include "mozilla/MiscEvents.h" #include "mozilla/MouseEvents.h" #include "mozilla/TextEvents.h" +#include "mozilla/dom/HTMLObjectElementBinding.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" @@ -88,6 +90,7 @@ using namespace mozilla::dom; #endif using namespace mozilla; +using namespace mozilla::dom; using namespace mozilla::layers; // special class for handeling DOM context menu events because for @@ -280,10 +283,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() mWidgetVisible = true; mPluginWindowVisible = false; mPluginDocumentActiveState = true; - mNumCachedAttrs = 0; - mNumCachedParams = 0; - mCachedAttrParamNames = nullptr; - mCachedAttrParamValues = nullptr; mLastMouseDownButtonType = -1; #ifdef XP_MACOSX @@ -306,8 +305,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() nsPluginInstanceOwner::~nsPluginInstanceOwner() { - int32_t cnt; - if (mWaitingForPaint) { // We don't care when the event is dispatched as long as it's "soon", // since whoever needs it will be waiting for it. @@ -317,28 +314,6 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner() mObjectFrame = nullptr; - for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) { - if (mCachedAttrParamNames && mCachedAttrParamNames[cnt]) { - NS_Free(mCachedAttrParamNames[cnt]); - mCachedAttrParamNames[cnt] = nullptr; - } - - if (mCachedAttrParamValues && mCachedAttrParamValues[cnt]) { - NS_Free(mCachedAttrParamValues[cnt]); - mCachedAttrParamValues[cnt] = nullptr; - } - } - - if (mCachedAttrParamNames) { - NS_Free(mCachedAttrParamNames); - mCachedAttrParamNames = nullptr; - } - - if (mCachedAttrParamValues) { - NS_Free(mCachedAttrParamValues); - mCachedAttrParamValues = nullptr; - } - PLUG_DeletePluginNativeWindow(mPluginWindow); mPluginWindow = nullptr; @@ -411,38 +386,13 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetMode(int32_t *aMode) return rv; } -NS_IMETHODIMP nsPluginInstanceOwner::GetAttributes(uint16_t& n, - const char*const*& names, - const char*const*& values) +void nsPluginInstanceOwner::GetAttributes(nsTArray& attributes) { - nsresult rv = EnsureCachedAttrParamArrays(); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr content = do_QueryInterface(mContent); + nsObjectLoadingContent *loadingContent = + static_cast(content.get()); - n = mNumCachedAttrs; - names = (const char **)mCachedAttrParamNames; - values = (const char **)mCachedAttrParamValues; - - return rv; -} - -NS_IMETHODIMP nsPluginInstanceOwner::GetAttribute(const char* name, const char* *result) -{ - NS_ENSURE_ARG_POINTER(name); - NS_ENSURE_ARG_POINTER(result); - - nsresult rv = EnsureCachedAttrParamArrays(); - NS_ENSURE_SUCCESS(rv, rv); - - *result = nullptr; - - for (int i = 0; i < mNumCachedAttrs; i++) { - if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) { - *result = mCachedAttrParamValues[i]; - return NS_OK; - } - } - - return NS_ERROR_FAILURE; + loadingContent->GetPluginAttributes(attributes); } NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result) @@ -789,326 +739,13 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetTagType(nsPluginTagType *result) return NS_OK; } -NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(uint16_t& n, const char*const*& names, const char*const*& values) +void nsPluginInstanceOwner::GetParameters(nsTArray& parameters) { - nsresult rv = EnsureCachedAttrParamArrays(); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr content = do_QueryInterface(mContent); + nsObjectLoadingContent *loadingContent = + static_cast(content.get()); - n = mNumCachedParams; - if (n) { - names = (const char **)(mCachedAttrParamNames + mNumCachedAttrs + 1); - values = (const char **)(mCachedAttrParamValues + mNumCachedAttrs + 1); - } else - names = values = nullptr; - - return rv; -} - -NS_IMETHODIMP nsPluginInstanceOwner::GetParameter(const char* name, const char* *result) -{ - NS_ENSURE_ARG_POINTER(name); - NS_ENSURE_ARG_POINTER(result); - - nsresult rv = EnsureCachedAttrParamArrays(); - NS_ENSURE_SUCCESS(rv, rv); - - *result = nullptr; - - for (int i = mNumCachedAttrs + 1; i < (mNumCachedParams + 1 + mNumCachedAttrs); i++) { - if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) { - *result = mCachedAttrParamValues[i]; - return NS_OK; - } - } - - return NS_ERROR_FAILURE; -} - - -// Cache the attributes and/or parameters of our tag into a single set -// of arrays to be compatible with Netscape 4.x. The attributes go first, -// followed by a PARAM/null and then any PARAM tags. Also, hold the -// cached array around for the duration of the life of the instance -// because Netscape 4.x did. See bug 111008. -nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays() -{ - if (mCachedAttrParamValues) - return NS_OK; - - NS_PRECONDITION(((mNumCachedAttrs + mNumCachedParams) == 0) && - !mCachedAttrParamNames, - "re-cache of attrs/params not implemented! use the DOM " - "node directy instead"); - - // Convert to a 16-bit count. Subtract 3 in case we add an extra - // "src", "wmode", or "codebase" entry below. - uint32_t cattrs = mContent->GetAttrCount(); - if (cattrs < 0x0000FFFC) { - mNumCachedAttrs = static_cast(cattrs); - } else { - mNumCachedAttrs = 0xFFFC; - } - - // Check if we are java for special codebase handling - const char* mime = nullptr; - bool isJava = NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime && - nsPluginHost::IsJavaMIMEType(mime); - - // now, we need to find all the PARAM tags that are children of us - // however, be careful not to include any PARAMs that don't have us - // as a direct parent. For nested object (or applet) tags, be sure - // to only round up the param tags that coorespond with THIS - // instance. And also, weed out any bogus tags that may get in the - // way, see bug 39609. Then, with any param tag that meet our - // qualification, temporarly cache them in an nsCOMArray until - // we can figure out what size to make our fixed char* array. - nsCOMArray ourParams; - - // Get all dependent PARAM tags, even if they are not direct children. - nsCOMPtr mydomElement = do_QueryInterface(mContent); - NS_ENSURE_TRUE(mydomElement, NS_ERROR_NO_INTERFACE); - - // Making DOM method calls can cause our frame to go away. - nsCOMPtr kungFuDeathGrip(this); - - nsCOMPtr allParams; - NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml"); - mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"), - getter_AddRefs(allParams)); - if (allParams) { - uint32_t numAllParams; - allParams->GetLength(&numAllParams); - for (uint32_t i = 0; i < numAllParams; i++) { - nsCOMPtr pnode; - allParams->Item(i, getter_AddRefs(pnode)); - nsCOMPtr domelement = do_QueryInterface(pnode); - if (domelement) { - // Ignore params without a name attribute. - nsAutoString name; - domelement->GetAttribute(NS_LITERAL_STRING("name"), name); - if (!name.IsEmpty()) { - // Find the first object or applet parent. - nsCOMPtr parent; - nsCOMPtr domobject; - nsCOMPtr domapplet; - pnode->GetParentNode(getter_AddRefs(parent)); - while (!(domobject || domapplet) && parent) { - domobject = do_QueryInterface(parent); - domapplet = do_QueryInterface(parent); - nsCOMPtr temp; - parent->GetParentNode(getter_AddRefs(temp)); - parent = temp; - } - if (domapplet || domobject) { - if (domapplet) { - parent = do_QueryInterface(domapplet); - } - else { - parent = do_QueryInterface(domobject); - } - nsCOMPtr mydomNode = do_QueryInterface(mydomElement); - if (parent == mydomNode) { - ourParams.AppendObject(domelement); - } - } - } - } - } - } - - // Convert to a 16-bit count. - uint32_t cparams = ourParams.Count(); - if (cparams < 0x0000FFFF) { - mNumCachedParams = static_cast(cparams); - } else { - mNumCachedParams = 0xFFFF; - } - - uint16_t numRealAttrs = mNumCachedAttrs; - - // Some plugins were never written to understand the "data" attribute of the OBJECT tag. - // Real and WMP will not play unless they find a "src" attribute, see bug 152334. - // Nav 4.x would simply replace the "data" with "src". Because some plugins correctly - // look for "data", lets instead copy the "data" attribute and add another entry - // to the bottom of the array if there isn't already a "src" specified. - nsAutoString data; - if (mContent->Tag() == nsGkAtoms::object && - !mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src) && - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, data) && - !data.IsEmpty()) { - mNumCachedAttrs++; - } - - // "plugins.force.wmode" forces us to send a specific "wmode" parameter, - // used by flash to select a rendering mode. Common values include - // "opaque", "transparent", "windowed", "direct" - nsCString wmodeType; - nsAdoptingCString wmodePref = Preferences::GetCString("plugins.force.wmode"); - if (!wmodePref.IsEmpty()) { - mNumCachedAttrs++; - wmodeType = wmodePref; - } -#if defined(XP_WIN) || defined(XP_LINUX) - // Bug 923745 - Until we support windowed mode plugins in content processes, - // force flash to use a windowless rendering mode. This hack should go away - // when bug 923746 lands. (OS X plugins always use some native widgets, so - // unfortunately this does not help there) - else if (XRE_GetProcessType() == GeckoProcessType_Content) { - mNumCachedAttrs++; - wmodeType.AssignLiteral("transparent"); - } -#endif - - // (Bug 738396) java has quirks in its codebase parsing, pass the - // absolute codebase URI as content sees it. - bool addCodebase = false; - nsAutoCString codebaseStr; - if (isJava) { - nsCOMPtr objlc = do_QueryInterface(mContent); - NS_ENSURE_TRUE(objlc, NS_ERROR_UNEXPECTED); - nsCOMPtr codebaseURI; - nsresult rv = objlc->GetBaseURI(getter_AddRefs(codebaseURI)); - NS_ENSURE_SUCCESS(rv, rv); - codebaseURI->GetSpec(codebaseStr); - if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::codebase)) { - mNumCachedAttrs++; - addCodebase = true; - } - } - - mCachedAttrParamNames = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams)); - NS_ENSURE_TRUE(mCachedAttrParamNames, NS_ERROR_OUT_OF_MEMORY); - mCachedAttrParamValues = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams)); - NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY); - - // Some plugins (eg Flash, see bug 234675.) are actually sensitive to the - // attribute order. So we want to make sure we give the plugin the - // attributes in the order they came in in the source, to be compatible with - // other browsers. Now in HTML, the storage order is the reverse of the - // source order, while in XML and XHTML it's the same as the source order - // (see the AddAttributes functions in the HTML and XML content sinks). - int32_t start, end, increment; - if (mContent->IsHTML() && - mContent->IsInHTMLDocument()) { - // HTML. Walk attributes in reverse order. - start = numRealAttrs - 1; - end = -1; - increment = -1; - } else { - // XHTML or XML. Walk attributes in forward order. - start = 0; - end = numRealAttrs; - increment = 1; - } - - // Set to the next slot to fill in name and value cache arrays. - uint32_t nextAttrParamIndex = 0; - - // Whether or not we force the wmode below while traversing - // the name/value pairs. - bool wmodeSet = false; - - // Add attribute name/value pairs. - for (int32_t index = start; index != end; index += increment) { - const nsAttrName* attrName = mContent->GetAttrNameAt(index); - nsIAtom* atom = attrName->LocalName(); - nsAutoString value; - mContent->GetAttr(attrName->NamespaceID(), atom, value); - nsAutoString name; - atom->ToString(name); - - FixUpURLS(name, value); - - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name); - if (!wmodeType.IsEmpty() && - 0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "wmode")) { - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType)); - - if (!wmodeSet) { - // We allocated space to add a wmode attr, but we don't need it now. - mNumCachedAttrs--; - wmodeSet = true; - } - } else if (isJava && 0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "codebase")) { - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseStr)); - } else { - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value); - } - nextAttrParamIndex++; - } - - // Potentially add CODEBASE attribute - if (addCodebase) { - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("codebase")); - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseStr)); - nextAttrParamIndex++; - } - - // Potentially add WMODE attribute. - if (!wmodeType.IsEmpty() && !wmodeSet) { - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("wmode")); - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType)); - nextAttrParamIndex++; - } - - // Potentially add SRC attribute. - if (!data.IsEmpty()) { - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("SRC")); - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(data); - nextAttrParamIndex++; - } - - // Add PARAM and null separator. - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("PARAM")); -#ifdef MOZ_WIDGET_ANDROID - // Flash expects an empty string on android - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("")); -#else - mCachedAttrParamValues[nextAttrParamIndex] = nullptr; -#endif - nextAttrParamIndex++; - - // Add PARAM name/value pairs. - - // We may decrement mNumCachedParams below - uint16_t totalParams = mNumCachedParams; - for (uint16_t i = 0; i < totalParams; i++) { - nsIDOMElement* param = ourParams.ObjectAt(i); - if (!param) { - continue; - } - - nsAutoString name; - nsAutoString value; - param->GetAttribute(NS_LITERAL_STRING("name"), name); // check for empty done above - param->GetAttribute(NS_LITERAL_STRING("value"), value); - - FixUpURLS(name, value); - - /* - * According to the HTML 4.01 spec, at - * http://www.w3.org/TR/html4/types.html#type-cdata - * ''User agents may ignore leading and trailing - * white space in CDATA attribute values (e.g., " - * myval " may be interpreted as "myval"). Authors - * should not declare attribute values with - * leading or trailing white space.'' - * However, do not trim consecutive spaces as in bug 122119 - */ - name.Trim(" \n\r\t\b", true, true, false); - value.Trim(" \n\r\t\b", true, true, false); - if (isJava && name.EqualsIgnoreCase("codebase")) { - // We inserted normalized codebase above, don't include other versions in - // params - mNumCachedParams--; - continue; - } - mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name); - mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value); - nextAttrParamIndex++; - } - - return NS_OK; + loadingContent->GetPluginParameters(parameters); } #ifdef XP_MACOSX @@ -3168,19 +2805,6 @@ nsObjectFrame* nsPluginInstanceOwner::GetFrame() return mObjectFrame; } -// Little helper function to resolve relative URL in -// |value| for certain inputs of |name| -void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value) -{ - if (name.LowerCaseEqualsLiteral("pluginspage")) { - nsCOMPtr baseURI = GetBaseURI(); - nsAutoString newURL; - NS_MakeAbsoluteURI(newURL, value, baseURI); - if (!newURL.IsEmpty()) - value = newURL; - } -} - NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled) { return mInstance ? mInstance->PrivateModeStateChanged(aEnabled) : NS_OK; diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 5522b32081e2..6970b584ff95 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -29,6 +29,12 @@ class nsPluginDOMContextMenuListener; class nsObjectFrame; class nsDisplayListBuilder; +namespace mozilla { +namespace dom { +struct MozPluginParameter; +} +} + #ifdef MOZ_X11 class gfxXlibSurface; #ifdef MOZ_WIDGET_QT @@ -72,50 +78,8 @@ public: */ NS_IMETHOD GetTagType(nsPluginTagType *aResult); - /** - * Get a ptr to the paired list of parameter names and values, - * returns the length of the array. - * - * Each name or value is a null-terminated string. - */ - NS_IMETHOD GetParameters(uint16_t& aCount, - const char*const*& aNames, - const char*const*& aValues); - - /** - * Get the value for the named parameter. Returns null - * if the parameter was not set. - * - * @param aName - name of the parameter - * @param aResult - parameter value - * @result - NS_OK if this operation was successful - */ - NS_IMETHOD GetParameter(const char* aName, const char* *aResult); - - /** - * QueryInterface on nsIPluginInstancePeer to get this. - * - * (Corresponds to NPP_New's argc, argn, and argv arguments.) - * Get a ptr to the paired list of attribute names and values, - * returns the length of the array. - * - * Each name or value is a null-terminated string. - */ - NS_IMETHOD GetAttributes(uint16_t& aCount, - const char*const*& aNames, - const char*const*& aValues); - - - /** - * Gets the value for the named attribute. - * - * @param aName - the name of the attribute to find - * @param aResult - the resulting attribute - * @result - NS_OK if this operation was successful, NS_ERROR_FAILURE if - * this operation failed. result is set to NULL if the attribute is not found - * else to the found value. - */ - NS_IMETHOD GetAttribute(const char* aName, const char* *aResult); + void GetParameters(nsTArray& parameters); + void GetAttributes(nsTArray& attributes); /** * Returns the DOM element corresponding to the tag which references @@ -300,8 +264,7 @@ private: return NS_SUCCEEDED(mInstance->GetImageSize(&size)) && size == nsIntSize(mPluginWindow->width, mPluginWindow->height); } - - void FixUpURLS(const nsString &name, nsAString &value); + #ifdef MOZ_WIDGET_ANDROID mozilla::LayoutDeviceRect GetPluginRect(); bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0)); @@ -347,11 +310,6 @@ private: bool mPluginWindowVisible; bool mPluginDocumentActiveState; - uint16_t mNumCachedAttrs; - uint16_t mNumCachedParams; - char **mCachedAttrParamNames; - char **mCachedAttrParamValues; - #ifdef XP_MACOSX NPEventModel mEventModel; // This is a hack! UseAsyncRendering() can incorrectly return false @@ -370,9 +328,7 @@ private: nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent); int mLastMouseDownButtonType; - - nsresult EnsureCachedAttrParamArrays(); - + #ifdef MOZ_X11 class Renderer #if defined(MOZ_WIDGET_QT) diff --git a/dom/webidl/HTMLObjectElement.webidl b/dom/webidl/HTMLObjectElement.webidl index b75a3cfddf24..93b3fa03ba02 100644 --- a/dom/webidl/HTMLObjectElement.webidl +++ b/dom/webidl/HTMLObjectElement.webidl @@ -155,6 +155,13 @@ interface MozObjectLoadingContent { [ChromeOnly] unsigned long getContentTypeForMIMEType(DOMString aMimeType); + + [ChromeOnly] + sequence getPluginAttributes(); + + [ChromeOnly] + sequence getPluginParameters(); + /** * This method will play a plugin that has been stopped by the * click-to-play plugins or play-preview features. @@ -206,6 +213,15 @@ interface MozObjectLoadingContent { void cancelPlayPreview(); }; +/** + * Name:Value pair type used for passing parameters to NPAPI or javascript + * plugins. + */ +dictionary MozPluginParameter { + DOMString name = ""; + DOMString value = ""; +}; + HTMLObjectElement implements MozImageLoadingContent; HTMLObjectElement implements MozFrameLoaderOwner; HTMLObjectElement implements MozObjectLoadingContent; From 9647357b1fb9059f14988185a56ebd1019c977e5 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 15 Aug 2014 17:41:29 -0400 Subject: [PATCH 019/101] Bug 1053792 - Fix some bad implicit constructors in the mtransport code; r=jesup --- media/mtransport/nr_socket_prsock.h | 2 +- media/mtransport/nricectx.h | 2 +- media/mtransport/runnable_utils.py | 10 +++++++++- media/mtransport/runnable_utils_generated.h | 2 +- media/mtransport/sigslot.h | 2 +- media/mtransport/stun_udp_socket_filter.cpp | 5 +++-- media/mtransport/transportflow.h | 2 +- media/mtransport/transportlayerdtls.h | 2 +- media/mtransport/transportlayerloopback.h | 2 +- 9 files changed, 19 insertions(+), 10 deletions(-) diff --git a/media/mtransport/nr_socket_prsock.h b/media/mtransport/nr_socket_prsock.h index 30949b45fd34..533c4c65f7dd 100644 --- a/media/mtransport/nr_socket_prsock.h +++ b/media/mtransport/nr_socket_prsock.h @@ -202,7 +202,7 @@ public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIUDPSOCKETINTERNAL - NrSocketIpc(const nsCOMPtr &main_thread); + explicit NrSocketIpc(const nsCOMPtr &main_thread); // Implementations of the NrSocketBase APIs virtual int create(nr_transport_addr *addr); diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h index 315a91aedd73..d0be5ca9de99 100644 --- a/media/mtransport/nricectx.h +++ b/media/mtransport/nricectx.h @@ -93,7 +93,7 @@ extern const char kNrIceTransportTcp[]; class NrIceStunServer { public: - NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) { + explicit NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) { memcpy(&addr_, &addr, sizeof(addr)); } diff --git a/media/mtransport/runnable_utils.py b/media/mtransport/runnable_utils.py index 9ef23f11764d..50c599475372 100644 --- a/media/mtransport/runnable_utils.py +++ b/media/mtransport/runnable_utils.py @@ -7,6 +7,11 @@ boilerplate = "/* This Source Code Form is subject to the terms of the Mozilla P * License, v. 2.0. If a copy of the MPL was not distributed with this\n\ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n" +def get_args_count(args, member): + if member: + return args + 2 + return args + 1 + def gen_args_type(args, member): if member: ret = ["C o"] @@ -98,7 +103,10 @@ def generate_class_template(args, ret = False, member = True): print " public:" if not ret: - print " %s(" % class_name + gen_args_type(args, member) + ") :" + explicit = "" + if get_args_count(args, member) == 1: + explicit = "explicit " + print " %s%s(" % (explicit, class_name) + gen_args_type(args, member) + ") :" print " " + gen_init(args, False, member) + " {}" else: print " %s(" % class_name + gen_args_type(args, member) + ", R *r) :" diff --git a/media/mtransport/runnable_utils_generated.h b/media/mtransport/runnable_utils_generated.h index 5a45d82f4e35..d349827dc920 100644 --- a/media/mtransport/runnable_utils_generated.h +++ b/media/mtransport/runnable_utils_generated.h @@ -6,7 +6,7 @@ // 0 arguments -- template class runnable_args_nm_0 : public detail::runnable_args_base { public: - runnable_args_nm_0(M m) : + explicit runnable_args_nm_0(M m) : m_(m) {} NS_IMETHOD Run() { diff --git a/media/mtransport/sigslot.h b/media/mtransport/sigslot.h index 5d7fc9d67981..91cd76f25293 100644 --- a/media/mtransport/sigslot.h +++ b/media/mtransport/sigslot.h @@ -307,7 +307,7 @@ namespace sigslot { public: mt_policy *m_mutex; - lock_block(mt_policy *mtx) + explicit lock_block(mt_policy *mtx) : m_mutex(mtx) { m_mutex->lock(); diff --git a/media/mtransport/stun_udp_socket_filter.cpp b/media/mtransport/stun_udp_socket_filter.cpp index 2d0e1aef0a5f..9b530e1e0144 100644 --- a/media/mtransport/stun_udp_socket_filter.cpp +++ b/media/mtransport/stun_udp_socket_filter.cpp @@ -10,6 +10,7 @@ extern "C" { #include "stun.h" } +#include "mozilla/Attributes.h" #include "mozilla/net/DNS.h" #include "stun_udp_socket_filter.h" #include "nr_socket_prsock.h" @@ -18,7 +19,7 @@ namespace { class NetAddressAdapter { public: - NetAddressAdapter(const mozilla::net::NetAddr& netaddr) + MOZ_IMPLICIT NetAddressAdapter(const mozilla::net::NetAddr& netaddr) : addr_(ntohl(netaddr.inet.ip)), port_(ntohs(netaddr.inet.port)) { MOZ_ASSERT(netaddr.raw.family == AF_INET); @@ -44,7 +45,7 @@ class PendingSTUNRequest { net_addr_(netaddr), is_id_set_(true) {} - PendingSTUNRequest(const NetAddressAdapter& netaddr) + MOZ_IMPLICIT PendingSTUNRequest(const NetAddressAdapter& netaddr) : id_(), net_addr_(netaddr), is_id_set_(false) {} diff --git a/media/mtransport/transportflow.h b/media/mtransport/transportflow.h index 151f82fe9864..eddff571659d 100644 --- a/media/mtransport/transportflow.h +++ b/media/mtransport/transportflow.h @@ -56,7 +56,7 @@ class TransportFlow : public nsISupports, : id_("(anonymous)"), state_(TransportLayer::TS_NONE), layers_(new std::deque) {} - TransportFlow(const std::string id) + explicit TransportFlow(const std::string id) : id_(id), state_(TransportLayer::TS_NONE), layers_(new std::deque) {} diff --git a/media/mtransport/transportlayerdtls.h b/media/mtransport/transportlayerdtls.h index 725ddb768b2e..999b420d7b32 100644 --- a/media/mtransport/transportlayerdtls.h +++ b/media/mtransport/transportlayerdtls.h @@ -30,7 +30,7 @@ struct Packet; class TransportLayerNSPRAdapter { public: - TransportLayerNSPRAdapter(TransportLayer *output) : + explicit TransportLayerNSPRAdapter(TransportLayer *output) : output_(output), input_() {} diff --git a/media/mtransport/transportlayerloopback.h b/media/mtransport/transportlayerloopback.h index b24ccf1f7b39..2790834dad01 100644 --- a/media/mtransport/transportlayerloopback.h +++ b/media/mtransport/transportlayerloopback.h @@ -107,7 +107,7 @@ class TransportLayerLoopback : public TransportLayer { // Fires every 100 ms class Deliverer : public nsITimerCallback { public: - Deliverer(TransportLayerLoopback *layer) : + explicit Deliverer(TransportLayerLoopback *layer) : layer_(layer) {} void Detach() { layer_ = nullptr; From 48af23d3d197bae883b9fa74aebebd7b1080853c Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 15 Aug 2014 23:19:34 +0100 Subject: [PATCH 020/101] Bug 1023371 - Refactor mozcrash to seperate out the IO from the stack inspection, r=ted.mielczarek This makes it compatible with structured logging. --- testing/mozbase/mozcrash/mozcrash/mozcrash.py | 318 ++++++++++++------ .../structured/formatters/machformatter.py | 37 ++ .../structured/formatters/tbplformatter.py | 27 ++ .../mozlog/mozlog/structured/structuredlog.py | 18 +- 4 files changed, 302 insertions(+), 98 deletions(-) diff --git a/testing/mozbase/mozcrash/mozcrash/mozcrash.py b/testing/mozbase/mozcrash/mozcrash/mozcrash.py index 7d8a183330e0..80972325fe35 100644 --- a/testing/mozbase/mozcrash/mozcrash/mozcrash.py +++ b/testing/mozbase/mozcrash/mozcrash/mozcrash.py @@ -14,12 +14,32 @@ import sys import tempfile import urllib2 import zipfile +from collections import namedtuple import mozfile import mozlog +from mozlog.structured import structuredlog -def check_for_crashes(dump_directory, symbols_path, +StackInfo = namedtuple("StackInfo", + ["minidump_path", + "signature", + "stackwalk_stdout", + "stackwalk_stderr", + "stackwalk_retcode", + "stackwalk_errors", + "extra"]) + + +def get_logger(): + structured_logger = structuredlog.get_default_logger("mozcrash") + if structured_logger is None: + return mozlog.getLogger('mozcrash') + return structured_logger + + +def check_for_crashes(dump_directory, + symbols_path, stackwalk_binary=None, dump_save_path=None, test_name=None, @@ -51,12 +71,6 @@ def check_for_crashes(dump_directory, symbols_path, Returns True if any minidumps were found, False otherwise. """ - dumps = glob.glob(os.path.join(dump_directory, '*.dmp')) - if not dumps: - return False - - if stackwalk_binary is None: - stackwalk_binary = os.environ.get('MINIDUMP_STACKWALK', None) # try to get the caller's filename if no test name is given if test_name is None: @@ -65,102 +79,212 @@ def check_for_crashes(dump_directory, symbols_path, except: test_name = "unknown" - try: - log = mozlog.getLogger('mozcrash') - remove_symbols = False - # If our symbols are at a remote URL, download them now - # We want to download URLs like http://... but not Windows paths like c:\... - if symbols_path and mozfile.is_url(symbols_path): - log.info("Downloading symbols from: %s", symbols_path) - remove_symbols = True - # Get the symbols and write them to a temporary zipfile - data = urllib2.urlopen(symbols_path) - symbols_file = tempfile.TemporaryFile() - symbols_file.write(data.read()) - # extract symbols to a temporary directory (which we'll delete after - # processing all crashes) - symbols_path = tempfile.mkdtemp() - zfile = zipfile.ZipFile(symbols_file, 'r') - mozfile.extract_zip(zfile, symbols_path) - zfile.close() + crash_info = CrashInfo(dump_directory, symbols_path, dump_save_path=dump_save_path, + stackwalk_binary=stackwalk_binary) - for d in dumps: - extra = os.path.splitext(d)[0] + '.extra' + if not crash_info.has_dumps: + return False - stackwalk_output = [] - stackwalk_output.append("Crash dump filename: " + d) - top_frame = None - if symbols_path and stackwalk_binary and os.path.exists(stackwalk_binary): - # run minidump_stackwalk - p = subprocess.Popen([stackwalk_binary, d, symbols_path], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - if len(out) > 3: - # minidump_stackwalk is chatty, - # so ignore stderr when it succeeds. - stackwalk_output.append(out) - # The top frame of the crash is always the line after "Thread N (crashed)" - # Examples: - # 0 libc.so + 0xa888 - # 0 libnss3.so!nssCertificate_Destroy [certificate.c : 102 + 0x0] - # 0 mozjs.dll!js::GlobalObject::getDebuggers() [GlobalObject.cpp:89df18f9b6da : 580 + 0x0] - # 0 libxul.so!void js::gc::MarkInternal(JSTracer*, JSObject**) [Marking.cpp : 92 + 0x28] - lines = out.splitlines() - for i, line in enumerate(lines): - if "(crashed)" in line: - match = re.search(r"^ 0 (?:.*!)?(?:void )?([^\[]+)", lines[i+1]) - if match: - top_frame = "@ %s" % match.group(1).strip() - break - else: - stackwalk_output.append("stderr from minidump_stackwalk:") - stackwalk_output.append(err) - if p.returncode != 0: - stackwalk_output.append("minidump_stackwalk exited with return code %d" % p.returncode) - else: - if not symbols_path: - stackwalk_output.append("No symbols path given, can't process dump.") - if not stackwalk_binary: - stackwalk_output.append("MINIDUMP_STACKWALK not set, can't process dump.") - elif stackwalk_binary and not os.path.exists(stackwalk_binary): - stackwalk_output.append("MINIDUMP_STACKWALK binary not found: %s" % stackwalk_binary) - if not top_frame: - top_frame = "Unknown top frame" - if not quiet: - print "PROCESS-CRASH | %s | application crashed [%s]" % (test_name, top_frame) - print '\n'.join(stackwalk_output) - if dump_save_path is None: - dump_save_path = os.environ.get('MINIDUMP_SAVE_PATH', None) - if dump_save_path: - # This code did not previously create the directory, - # so there may be a file hanging out with its name. - if os.path.isfile(dump_save_path): - os.unlink(dump_save_path) - if not os.path.isdir(dump_save_path): - try: - os.makedirs(dump_save_path) - except OSError: - pass - - shutil.move(d, dump_save_path) - log.info("Saved minidump as %s", - os.path.join(dump_save_path, os.path.basename(d))) - - if os.path.isfile(extra): - shutil.move(extra, dump_save_path) - log.info("Saved app info as %s", - os.path.join(dump_save_path, os.path.basename(extra))) - else: - mozfile.remove(d) - mozfile.remove(extra) - finally: - if remove_symbols: - mozfile.remove(symbols_path) + for info in crash_info: + if not quiet: + stackwalk_output = ["Crash dump filename: %s" % info.minidump_path] + if info.stackwalk_stderr: + stackwalk_output.append("stderr from minidump_stackwalk:") + stackwalk_output.append(info.stackwalk_stderr) + elif info.stackwalk_stdout is not None: + stackwalk_output.append(info.stackwalk_stdout) + if info.stackwalk_retcode is not None and info.stackwalk_retcode != 0: + stackwalk_output.append("minidump_stackwalk exited with return code %d" % + info.stackwalk_retcode) + signature = info.signature if info.signature else "unknown top frame" + print "PROCESS-CRASH | %s | application crashed [%s]" % (test_name, + signature) + print '\n'.join(stackwalk_output) + print '\n'.join(info.stackwalk_errors) return True +def log_crashes(logger, + dump_directory, + symbols_path, + process=None, + test=None, + stackwalk_binary=None, + dump_save_path=None): + """Log crashes using a structured logger""" + for info in CrashInfo(dump_directory, symbols_path, dump_save_path=dump_save_path, + stackwalk_binary=stackwalk_binary): + kwargs = info._asdict() + kwargs.pop("extra") + logger.crash(process=process, test=test, **kwargs) + + +class CrashInfo(object): + """Get information about a crash based on dump files. + + Typical usage is to iterate over the CrashInfo object. This returns StackInfo + objects, one for each crash dump file that is found in the dump_directory. + + :param dump_directory: Path to search for minidump files + :param symbols_path: Path to a path to a directory containing symbols to use for + dump processing. This can either be a path to a directory + containing Breakpad-format symbols, or a URL to a zip file + containing a set of symbols. + :param dump_save_path: Path to which to save the dump files. If this is None, + the MINIDUMP_SAVE_PATH environment variable will be used. + :param stackwalk_binary: Path to the minidump_stackwalk binary. If this is None, + the MINIDUMP_STACKWALK environment variable will be used + as the path to the minidump binary.""" + + def __init__(self, dump_directory, symbols_path, dump_save_path=None, + stackwalk_binary=None): + self.dump_directory = dump_directory + self.symbols_path = symbols_path + self.remove_symbols = False + + if dump_save_path is None: + dump_save_path = os.environ.get('MINIDUMP_SAVE_PATH', None) + self.dump_save_path = dump_save_path + + if stackwalk_binary is None: + stackwalk_binary = os.environ.get('MINIDUMP_STACKWALK', None) + self.stackwalk_binary = stackwalk_binary + + self.logger = get_logger() + self._dump_files = None + + def _get_symbols(self): + # This updates self.symbols_path so we only download once + if self.symbols_path and mozfile.is_url(self.symbols_path): + self.remove_symbols = True + self.logger.info("Downloading symbols from: %s" % self.symbols_path) + # Get the symbols and write them to a temporary zipfile + data = urllib2.urlopen(self.symbols_path) + with tempfile.TemporaryFile() as symbols_file: + symbols_file.write(data.read()) + # extract symbols to a temporary directory (which we'll delete after + # processing all crashes) + self.symbols_path = tempfile.mkdtemp() + with zipfile.ZipFile(symbols_file, 'r') as zfile: + mozfile.extract_zip(zfile, self.symbols_path) + + @property + def dump_files(self): + """List of tuple (path_to_dump_file, path_to_extra_file) for each dump + file in self.dump_directory. The extra files may not exist.""" + if self._dump_files is None: + self._dump_files = [(path, os.path.splitext(path)[0] + '.extra') for path in + glob.glob(os.path.join(self.dump_directory, '*.dmp'))] + return self._dump_files + + @property + def has_dumps(self): + """Boolean indicating whether any crash dump files were found in the + current directory""" + return len(self.dump_files) > 0 + + def __iter__(self): + for path, extra in self.dump_files: + rv = self._process_dump_file(path, extra) + yield rv + + if self.remove_symbols: + mozfile.remove(self.symbols_path) + + def _process_dump_file(self, path, extra): + """Process a single dump file using self.stackwalk_binary, and return a + tuple containing properties of the crash dump. + + :param path: Path to the minidump file to analyse + :return: A StackInfo tuple with the fields:: + minidump_path: Path of the dump file + signature: The top frame of the stack trace, or None if it + could not be determined. + stackwalk_stdout: String of stdout data from stackwalk + stackwalk_stderr: String of stderr data from stackwalk or + None if it succeeded + stackwalk_retcode: Return code from stackwalk + stackwalk_errors: List of errors in human-readable form that prevented + stackwalk being launched. + """ + self._get_symbols() + + errors = [] + signature = None + include_stderr = False + out = None + err = None + retcode = None + if (self.symbols_path and self.stackwalk_binary and + os.path.exists(self.stackwalk_binary)): + # run minidump_stackwalk + p = subprocess.Popen([self.stackwalk_binary, path, self.symbols_path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (out, err) = p.communicate() + retcode = p.returncode + if len(out) > 3: + # minidump_stackwalk is chatty, + # so ignore stderr when it succeeds. + # The top frame of the crash is always the line after "Thread N (crashed)" + # Examples: + # 0 libc.so + 0xa888 + # 0 libnss3.so!nssCertificate_Destroy [certificate.c : 102 + 0x0] + # 0 mozjs.dll!js::GlobalObject::getDebuggers() [GlobalObject.cpp:89df18f9b6da : 580 + 0x0] + # 0 libxul.so!void js::gc::MarkInternal(JSTracer*, JSObject**) [Marking.cpp : 92 + 0x28] + lines = out.splitlines() + for i, line in enumerate(lines): + if "(crashed)" in line: + match = re.search(r"^ 0 (?:.*!)?(?:void )?([^\[]+)", lines[i+1]) + if match: + signature = "@ %s" % match.group(1).strip() + break + else: + include_stderr = True + else: + if not self.symbols_path: + errors.append("No symbols path given, can't process dump.") + if not self.stackwalk_binary: + errors.append("MINIDUMP_STACKWALK not set, can't process dump.") + elif self.stackwalk_binary and not os.path.exists(self.stackwalk_binary): + errors.append("MINIDUMP_STACKWALK binary not found: %s" % self.stackwalk_binary) + + if self.dump_save_path: + self._save_dump_file(path, extra) + + if os.path.exists(path): + mozfile.remove(path) + if os.path.exists(extra): + mozfile.remove(extra) + + return StackInfo(path, + signature, + out, + err if include_stderr else None, + retcode, + errors, + extra) + + def _save_dump_file(self, path, extra): + if os.path.isfile(self.dump_save_path): + os.unlink(self.dump_save_path) + if not os.path.isdir(self.dump_save_path): + try: + os.makedirs(self.dump_save_path) + except OSError: + pass + + shutil.move(path, self.dump_save_path) + self.logger.info("Saved minidump as %s" % + os.path.join(self.dump_save_path, os.path.basename(path))) + + if os.path.isfile(extra): + shutil.move(extra, self.dump_save_path) + self.logger.info("Saved app info as %s" % + os.path.join(self.dump_save_path, os.path.basename(extra))) + + def check_for_java_exception(logcat, quiet=False): """ Print a summary of a fatal Java exception, if present in the provided diff --git a/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py b/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py index 5536e3a1b738..448f5e84359f 100644 --- a/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py +++ b/testing/mozbase/mozlog/mozlog/structured/formatters/machformatter.py @@ -76,6 +76,8 @@ class MachFormatter(base.BaseFormatter): color = self.terminal.red elif data["action"] in ("suite_start", "suite_end", "test_start"): color = self.terminal.yellow + elif data["action"] == "crash": + color = self.terminal.red if color is not None: action = color(action) @@ -244,6 +246,41 @@ class MachFormatter(base.BaseFormatter): data["process"], data.get("command", "")) + def crash(self, data): + test = self._get_test_id(data) + + if data.get("stackwalk_returncode", 0) != 0 and not data.get("stackwalk_stderr"): + success = True + else: + success = False + + rv = ["pid:%s. Test:%s. Minidump anaylsed:%s. Signature:[%s]" % + (data.get("pid", None), test, success, data["signature"])] + + if data.get("minidump_path"): + rv.append("Crash dump filename: %s" % data["minidump_path"]) + + if data.get("stackwalk_returncode", 0) != 0: + rv.append("minidump_stackwalk exited with return code %d" % + data["stackwalk_returncode"]) + + if data.get("stackwalk_stderr"): + rv.append("stderr from minidump_stackwalk:") + rv.append(data["stackwalk_stderr"]) + elif data.get("stackwalk_stdout"): + rv.append(data["stackwalk_stdout"]) + + if data.get("stackwalk_errors"): + rv.extend(data.get("stackwalk_errors")) + + rv = "\n".join(rv) + if not rv[-1] == "\n": + rv += "\n" + + return rv + + + def log(self, data): level = data.get("level").upper() diff --git a/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py b/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py index eb13f9f63509..4658422b370e 100644 --- a/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py +++ b/testing/mozbase/mozlog/mozlog/structured/formatters/tbplformatter.py @@ -30,6 +30,33 @@ class TbplFormatter(BaseFormatter): def process_output(self, data): return "PROCESS | %(process)s | %(data)s\n" % data + def crash(self, data): + id = self.id_str(data["test"]) if "test" in data else "pid: " % data["process"] + + rv = ["PROCESS-CRASH | %s | application crashed [%s]" % (id, + data["signature"])] + if data.get("minidump_path"): + rv.append("Crash dump filename: %s" % data["minidump_path"]) + + if data.get("stackwalk_stderr"): + rv.append("stderr from minidump_stackwalk:") + rv.append(data["stackwalk_stderr"]) + elif data.get("stackwalk_stdout"): + rv.append(data["stackwalk_stdout"]) + + if data.get("stackwalk_returncode", 0) != 0: + rv.append("minidump_stackwalk exited with return code %d" % + data["stackwalk_returncode"]) + + if data.get("stackwalk_errors"): + rv.extend(data.get("stackwalk_errors")) + + rv = "\n".join(rv) + if not rv[-1] == "\n": + rv += "\n" + + return rv + def suite_start(self, data): self.suite_start_time = data["time"] return "SUITE-START | Running %i tests\n" % len(data["tests"]) diff --git a/testing/mozbase/mozlog/mozlog/structured/structuredlog.py b/testing/mozbase/mozlog/mozlog/structured/structuredlog.py index 411a1d2d2bfb..81f6a719115d 100644 --- a/testing/mozbase/mozlog/mozlog/structured/structuredlog.py +++ b/testing/mozbase/mozlog/mozlog/structured/structuredlog.py @@ -11,7 +11,8 @@ import sys import time import traceback -from logtypes import Unicode, TestId, Status, SubStatus, Dict, List, Any, log_action, convertor_registry +from logtypes import Unicode, TestId, Status, SubStatus, Dict, List, Int, Any +from logtypes import log_action, convertor_registry """Structured Logging for recording test results. @@ -94,6 +95,7 @@ class LoggerState(object): self.running_tests = set() self.suite_started = False + class StructuredLogger(object): _lock = Lock() _logger_states = {} @@ -297,6 +299,20 @@ class StructuredLogger(object): """ self._log_data("process_output", data) + @log_action(Unicode("process", default=None), + Unicode("signature", default="[Unknown]"), + TestId("test", default=None, optional=True), + Unicode("minidump_path", default=None, optional=True), + Unicode("minidump_extra", default=None, optional=True), + Int("stackwalk_retcode", default=None, optional=True), + Unicode("stackwalk_stdout", default=None, optional=True), + Unicode("stackwalk_stderr", default=None, optional=True), + List("stackwalk_errors", Unicode, default=None)) + def crash(self, data): + if data["stackwalk_errors"] is None: + data["stackwalk_errors"] = [] + + self._log_data("crash", data) def _log_func(level_name): @log_action(Unicode("message"), From 5ea1c8dfad50d6e3c459f3873e922d70144f71e5 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Fri, 15 Aug 2014 16:14:50 -0700 Subject: [PATCH 021/101] Bug 1046964 - Remove some dead code (r=Waldo) --- js/src/frontend/Parser.cpp | 133 ------------------------------------- 1 file changed, 133 deletions(-) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 1086f3317915..83d5d57b32bc 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -639,139 +639,6 @@ Parser::parse(JSObject *chain) return pn; } -/* - * Insist on a final return before control flows out of pn. Try to be a bit - * smart about loops: do {...; return e2;} while(0) at the end of a function - * that contains an early return e1 will get a strict warning. Similarly for - * iloops: while (true){...} is treated as though ... returns. - */ -enum { - ENDS_IN_OTHER = 0, - ENDS_IN_RETURN = 1, - ENDS_IN_BREAK = 2 -}; - -static int -HasFinalReturn(ParseNode *pn) -{ - ParseNode *pn2, *pn3; - unsigned rv, rv2, hasDefault; - - switch (pn->getKind()) { - case PNK_STATEMENTLIST: - if (!pn->pn_head) - return ENDS_IN_OTHER; - return HasFinalReturn(pn->last()); - - case PNK_IF: - if (!pn->pn_kid3) - return ENDS_IN_OTHER; - return HasFinalReturn(pn->pn_kid2) & HasFinalReturn(pn->pn_kid3); - - case PNK_WHILE: - pn2 = pn->pn_left; - if (pn2->isKind(PNK_TRUE)) - return ENDS_IN_RETURN; - if (pn2->isKind(PNK_NUMBER) && pn2->pn_dval) - return ENDS_IN_RETURN; - return ENDS_IN_OTHER; - - case PNK_DOWHILE: - pn2 = pn->pn_right; - if (pn2->isKind(PNK_FALSE)) - return HasFinalReturn(pn->pn_left); - if (pn2->isKind(PNK_TRUE)) - return ENDS_IN_RETURN; - if (pn2->isKind(PNK_NUMBER)) { - if (pn2->pn_dval == 0) - return HasFinalReturn(pn->pn_left); - return ENDS_IN_RETURN; - } - return ENDS_IN_OTHER; - - case PNK_FOR: - pn2 = pn->pn_left; - if (pn2->isArity(PN_TERNARY) && !pn2->pn_kid2) - return ENDS_IN_RETURN; - return ENDS_IN_OTHER; - - case PNK_SWITCH: - rv = ENDS_IN_RETURN; - hasDefault = ENDS_IN_OTHER; - pn2 = pn->pn_right; - if (pn2->isKind(PNK_LEXICALSCOPE)) - pn2 = pn2->expr(); - for (pn2 = pn2->pn_head; rv && pn2; pn2 = pn2->pn_next) { - if (pn2->isKind(PNK_DEFAULT)) - hasDefault = ENDS_IN_RETURN; - pn3 = pn2->pn_right; - JS_ASSERT(pn3->isKind(PNK_STATEMENTLIST)); - if (pn3->pn_head) { - rv2 = HasFinalReturn(pn3->last()); - if (rv2 == ENDS_IN_OTHER && pn2->pn_next) - /* Falling through to next case or default. */; - else - rv &= rv2; - } - } - /* If a final switch has no default case, we judge it harshly. */ - rv &= hasDefault; - return rv; - - case PNK_BREAK: - return ENDS_IN_BREAK; - - case PNK_WITH: - return HasFinalReturn(pn->pn_right); - - case PNK_RETURN: - return ENDS_IN_RETURN; - - case PNK_LABEL: - case PNK_LEXICALSCOPE: - return HasFinalReturn(pn->expr()); - - case PNK_THROW: - return ENDS_IN_RETURN; - - case PNK_TRY: - /* If we have a finally block that returns, we are done. */ - if (pn->pn_kid3) { - rv = HasFinalReturn(pn->pn_kid3); - if (rv == ENDS_IN_RETURN) - return rv; - } - - /* Else check the try block and any and all catch statements. */ - rv = HasFinalReturn(pn->pn_kid1); - if (pn->pn_kid2) { - JS_ASSERT(pn->pn_kid2->isArity(PN_LIST)); - for (pn2 = pn->pn_kid2->pn_head; pn2; pn2 = pn2->pn_next) - rv &= HasFinalReturn(pn2); - } - return rv; - - case PNK_CATCH: - /* Check this catch block's body. */ - return HasFinalReturn(pn->pn_kid3); - - case PNK_LET: - /* Non-binary let statements are let declarations. */ - if (!pn->isArity(PN_BINARY)) - return ENDS_IN_OTHER; - return HasFinalReturn(pn->pn_right); - - default: - return ENDS_IN_OTHER; - } -} - -static int -HasFinalReturn(SyntaxParseHandler::Node pn) -{ - return ENDS_IN_RETURN; -} - template bool Parser::reportBadReturn(Node pn, ParseReportKind kind, From 55952e99b72206a88845e94cf074638c4fad93a5 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Fri, 15 Aug 2014 16:16:42 -0700 Subject: [PATCH 022/101] Bug 950745 - Back out assertions that are triggering too often --- dom/events/EventDispatcher.cpp | 4 ---- js/ipc/JavaScriptChild.cpp | 14 -------------- 2 files changed, 18 deletions(-) diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index 263d75ab8b47..540e03e31a2b 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -401,10 +401,6 @@ EventDispatcher::Dispatch(nsISupports* aTarget, NS_ERROR_DOM_INVALID_STATE_ERR); NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!"); -#ifdef NIGHTLY_BUILD - MOZ_RELEASE_ASSERT(!mozilla::ipc::ProcessingUrgentMessages()); -#endif - // If we're dispatching an already created DOMEvent object, make // sure it is initialized! // If aTargets is non-null, the event isn't going to be dispatched. diff --git a/js/ipc/JavaScriptChild.cpp b/js/ipc/JavaScriptChild.cpp index 02c936471847..4e609ad2a5b5 100644 --- a/js/ipc/JavaScriptChild.cpp +++ b/js/ipc/JavaScriptChild.cpp @@ -20,17 +20,6 @@ using namespace mozilla::jsipc; using mozilla::AutoSafeJSContext; -#ifdef NIGHTLY_BUILD -static void -UrgentMessageCheck(JSContext *cx, HandleScript script) -{ - // We're only allowed to enter chrome JS code while processing urgent - // messages. - if (ipc::ProcessingUrgentMessages()) - MOZ_RELEASE_ASSERT(xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))); -} -#endif - static void FinalizeChild(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data) { @@ -43,9 +32,6 @@ JavaScriptChild::JavaScriptChild(JSRuntime *rt) : JavaScriptShared(rt), JavaScriptBase(rt) { -#ifdef NIGHTLY_BUILD - js::SetAssertOnScriptEntryHook(rt, UrgentMessageCheck); -#endif } JavaScriptChild::~JavaScriptChild() From f872500ed5ae5a15963ab1120b72e83bc7147070 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:06 -0700 Subject: [PATCH 023/101] Bug 1049957 - Increase MakeUnique max params to 8. - r=waldo --- mfbt/UniquePtr.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/mfbt/UniquePtr.h b/mfbt/UniquePtr.h index 45a8e80565a0..c288ee664ca1 100644 --- a/mfbt/UniquePtr.h +++ b/mfbt/UniquePtr.h @@ -662,7 +662,7 @@ struct UniqueSelector */ // We don't have variadic template support everywhere, so just hard-code arities -// 0-5 for now. If you need more arguments, feel free to add the extra +// 0-8 for now. If you need more arguments, feel free to add the extra // overloads (and deletions for the T = E[N] case). // // Beware! Due to lack of true nullptr support in gcc 4.4 and 4.5, passing @@ -716,6 +716,39 @@ MakeUnique(A1&& aA1, A2&& aA2, A3&& aA3, A4&& aA4, A5&& aA5) Forward(aA5))); } +template +typename detail::UniqueSelector::SingleObject +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6) +{ + return UniquePtr(new T(Forward(a1), Forward(a2), + Forward(a3), Forward(a4), + Forward(a5), Forward(a6))); +} + +template +typename detail::UniqueSelector::SingleObject +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7) +{ + return UniquePtr(new T(Forward(a1), Forward(a2), + Forward(a3), Forward(a4), + Forward(a5), Forward(a6), + Forward(a7))); +} + +template +typename detail::UniqueSelector::SingleObject +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, + A8&& a8) +{ + return UniquePtr(new T(Forward(a1), Forward(a2), + Forward(a3), Forward(a4), + Forward(a5), Forward(a6), + Forward(a7), Forward(a8))); +} + template typename detail::UniqueSelector::UnknownBound MakeUnique(decltype(sizeof(int)) aN) @@ -749,6 +782,24 @@ template::KnownBound MakeUnique(A1&& aA1, A2&& aA2, A3&& aA3, A4&& aA4, A5&& aA5) MOZ_DELETE; +template +typename detail::UniqueSelector::KnownBound +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, + A6&& a6) MOZ_DELETE; + +template +typename detail::UniqueSelector::KnownBound +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, + A7&& a7) MOZ_DELETE; + +template +typename detail::UniqueSelector::KnownBound +MakeUnique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, + A7&& a7, A8&& a8) MOZ_DELETE; + } // namespace mozilla #endif /* mozilla_UniquePtr_h */ From 2879380ef6dc6c70374cb7a32044e353624cb1c1 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:07 -0700 Subject: [PATCH 024/101] Bug 1049957 - Use UniquePtr for GLScreenBuffer. - r=kamidphish --- gfx/gl/GLContext.cpp | 6 ++-- gfx/gl/GLContext.h | 4 +-- gfx/gl/GLScreenBuffer.cpp | 65 ++++++++++++++++++--------------------- gfx/gl/GLScreenBuffer.h | 30 +++++++++--------- 4 files changed, 49 insertions(+), 56 deletions(-) diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 230f81add85a..5e8ff97da908 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -2035,12 +2035,11 @@ GLContext::OffscreenSize() const bool GLContext::CreateScreenBufferImpl(const IntSize& size, const SurfaceCaps& caps) { - GLScreenBuffer* newScreen = GLScreenBuffer::Create(this, size, caps); + UniquePtr newScreen = GLScreenBuffer::Create(this, size, caps); if (!newScreen) return false; if (!newScreen->Resize(size)) { - delete newScreen; return false; } @@ -2050,7 +2049,7 @@ GLContext::CreateScreenBufferImpl(const IntSize& size, const SurfaceCaps& caps) // it falls out of scope. ScopedBindFramebuffer autoFB(this); - mScreen = newScreen; + mScreen = Move(newScreen); return true; } @@ -2068,7 +2067,6 @@ GLContext::ResizeScreenBuffer(const IntSize& size) void GLContext::DestroyScreenBuffer() { - delete mScreen; mScreen = nullptr; } diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 0b5905faf346..c0563b1c9364 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -2920,7 +2920,7 @@ public: protected: friend class GLScreenBuffer; - GLScreenBuffer* mScreen; + UniquePtr mScreen; void DestroyScreenBuffer(); @@ -2946,7 +2946,7 @@ public: } GLScreenBuffer* Screen() const { - return mScreen; + return mScreen.get(); } bool PublishFrame(); diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 74fc127979ac..89bdfbbdf646 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -26,7 +26,7 @@ namespace gl { using gfx::SurfaceFormat; -GLScreenBuffer* +UniquePtr GLScreenBuffer::Create(GLContext* gl, const gfx::IntSize& size, const SurfaceCaps& caps) @@ -64,13 +64,16 @@ GLScreenBuffer::Create(GLContext* gl, gl, nullptr); - return new GLScreenBuffer(gl, caps, factory, stream); + UniquePtr ret( new GLScreenBuffer(gl, caps, + Move(factory), + stream) ); + return Move(ret); } GLScreenBuffer::~GLScreenBuffer() { - delete mDraw; - delete mRead; + mDraw = nullptr; + mRead = nullptr; // bug 914823: it is crucial to destroy the Factory _after_ we destroy // the SharedSurfaces around here! Reason: the shared surfaces will want @@ -408,26 +411,20 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size) mRead->Attach(surf); } else { // Else something changed, so resize: - DrawBuffer* draw = nullptr; + UniquePtr draw; bool drawOk = CreateDraw(size, &draw); // Can be null. - ReadBuffer* read = CreateRead(surf); + UniquePtr read = CreateRead(surf); bool readOk = !!read; if (!drawOk || !readOk) { - delete draw; - delete read; - surf->UnlockProd(); return false; } - delete mDraw; - delete mRead; - - mDraw = draw; - mRead = read; + mDraw = Move(draw); + mRead = Move(read); } // Check that we're all set up. @@ -477,7 +474,8 @@ GLScreenBuffer::Resize(const gfx::IntSize& size) } bool -GLScreenBuffer::CreateDraw(const gfx::IntSize& size, DrawBuffer** out_buffer) +GLScreenBuffer::CreateDraw(const gfx::IntSize& size, + UniquePtr* out_buffer) { GLContext* gl = mFactory->mGL; const GLFormats& formats = mFactory->mFormats; @@ -486,7 +484,7 @@ GLScreenBuffer::CreateDraw(const gfx::IntSize& size, DrawBuffer** out_buffer) return DrawBuffer::Create(gl, caps, formats, size, out_buffer); } -ReadBuffer* +UniquePtr GLScreenBuffer::CreateRead(SharedSurface* surf) { GLContext* gl = mFactory->mGL; @@ -512,13 +510,14 @@ GLScreenBuffer::Readback(SharedSurface* src, gfx::DataSourceSurface* dest) src->LockProd(); } - ReadBuffer* buffer = CreateRead(src); - MOZ_ASSERT(buffer); - ScopedBindFramebuffer autoFB(mGL, buffer->mFB); - ReadPixelsIntoDataSurface(mGL, dest); + { + UniquePtr buffer = CreateRead(src); + MOZ_ASSERT(buffer); - delete buffer; + ScopedBindFramebuffer autoFB(mGL, buffer->mFB); + ReadPixelsIntoDataSurface(mGL, dest); + } if (needsSwap) { src->UnlockProd(); @@ -534,7 +533,7 @@ DrawBuffer::Create(GLContext* const gl, const SurfaceCaps& caps, const GLFormats& formats, const gfx::IntSize& size, - DrawBuffer** out_buffer) + UniquePtr* out_buffer) { MOZ_ASSERT(out_buffer); *out_buffer = nullptr; @@ -578,13 +577,13 @@ DrawBuffer::Create(GLContext* const gl, gl->fGenFramebuffers(1, &fb); gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb); - ScopedDeletePtr buffer; - buffer = new DrawBuffer(gl, size, fb, colorMSRB, depthRB, stencilRB); + UniquePtr ret( new DrawBuffer(gl, size, fb, colorMSRB, + depthRB, stencilRB) ); if (!gl->IsFramebufferComplete(fb)) return false; - *out_buffer = buffer.forget(); + *out_buffer = Move(ret); return true; } @@ -606,7 +605,7 @@ DrawBuffer::~DrawBuffer() //////////////////////////////////////////////////////////////////////// // ReadBuffer -ReadBuffer* +UniquePtr ReadBuffer::Create(GLContext* gl, const SurfaceCaps& caps, const GLFormats& formats, @@ -617,9 +616,8 @@ ReadBuffer::Create(GLContext* gl, if (surf->mAttachType == AttachmentType::Screen) { // Don't need anything. Our read buffer will be the 'screen'. - return new ReadBuffer(gl, - 0, 0, 0, - surf); + return UniquePtr( new ReadBuffer(gl, 0, 0, 0, + surf) ); } GLuint depthRB = 0; @@ -653,15 +651,12 @@ ReadBuffer::Create(GLContext* gl, gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb, target); gl->mFBOMapping[fb] = surf; - - ScopedDeletePtr buffer; - buffer = new ReadBuffer(gl, - fb, depthRB, stencilRB, - surf); + UniquePtr ret( new ReadBuffer(gl, fb, depthRB, + stencilRB, surf) ); if (!gl->IsFramebufferComplete(fb)) return nullptr; - return buffer.forget(); + return Move(ret); } ReadBuffer::~ReadBuffer() diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index 5f39512a58ab..1aad1bdfb018 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -38,7 +38,7 @@ public: const SurfaceCaps& caps, const GLFormats& formats, const gfx::IntSize& size, - DrawBuffer** out_buffer); + UniquePtr* out_buffer); protected: GLContext* const mGL; @@ -72,10 +72,10 @@ class ReadBuffer { public: // Infallible, always non-null. - static ReadBuffer* Create(GLContext* gl, - const SurfaceCaps& caps, - const GLFormats& formats, - SharedSurface* surf); + static UniquePtr Create(GLContext* gl, + const SurfaceCaps& caps, + const GLFormats& formats, + SharedSurface* surf); protected: GLContext* const mGL; @@ -118,20 +118,20 @@ class GLScreenBuffer { public: // Infallible. - static GLScreenBuffer* Create(GLContext* gl, - const gfx::IntSize& size, - const SurfaceCaps& caps); + static UniquePtr Create(GLContext* gl, + const gfx::IntSize& size, + const SurfaceCaps& caps); protected: - GLContext* const mGL; // Owns us. + GLContext* const mGL; // Owns us. public: const SurfaceCaps mCaps; protected: - SurfaceFactory* mFactory; // Owned by us. + SurfaceFactory* mFactory; // Owned by us. RefPtr mStream; - DrawBuffer* mDraw; // Owned by us. - ReadBuffer* mRead; // Owned by us. + UniquePtr mDraw; // Owned by us. + UniquePtr mRead; // Owned by us. bool mNeedsBlit; @@ -249,10 +249,10 @@ public: void Readback(SharedSurface* src, gfx::DataSourceSurface* dest); protected: - bool Attach(SharedSurface* surface, const gfx::IntSize& size); + bool Attach(SharedSurface* surf, const gfx::IntSize& size); - bool CreateDraw(const gfx::IntSize& size, DrawBuffer** out_buffer); - ReadBuffer* CreateRead(SharedSurface* surf); + bool CreateDraw(const gfx::IntSize& size, UniquePtr* out_buffer); + UniquePtr CreateRead(SharedSurface* surf); public: /* `fb` in these functions is the framebuffer the GLContext is hoping to From d10b4934b4a243789f0fe5412e3bcc018a7547b6 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:07 -0700 Subject: [PATCH 025/101] Bug 1049957 - Use RefPtr for SurfaceStream. - r=kamidphish --- gfx/gl/GLScreenBuffer.cpp | 15 ++++++--------- gfx/gl/GLScreenBuffer.h | 2 +- gfx/gl/SurfaceStream.cpp | 7 ++++--- gfx/gl/SurfaceStream.h | 6 +++--- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 89bdfbbdf646..57ce7ae89988 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -58,11 +58,10 @@ GLScreenBuffer::Create(GLContext* gl, if (!factory) factory = new SurfaceFactory_Basic(gl, caps); - SurfaceStream* stream = SurfaceStream::CreateForType( - SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread, - caps.preserve), - gl, - nullptr); + auto streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread, + caps.preserve); + RefPtr stream; + stream = SurfaceStream::CreateForType(streamType, gl, nullptr); UniquePtr ret( new GLScreenBuffer(gl, caps, Move(factory), @@ -387,10 +386,8 @@ GLScreenBuffer::Morph(SurfaceFactory* newFactory, SurfaceStreamType streamType) if (mStream->mType == streamType) return; - SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream); - MOZ_ASSERT(newStream); - - mStream = newStream; + mStream = SurfaceStream::CreateForType(streamType, mGL, mStream); + MOZ_ASSERT(mStream); } bool diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index 1aad1bdfb018..a3571c81e80f 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -149,7 +149,7 @@ protected: GLScreenBuffer(GLContext* gl, const SurfaceCaps& caps, SurfaceFactory* factory, - SurfaceStream* stream) + const RefPtr& stream) : mGL(gl) , mCaps(caps) , mFactory(factory) diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp index b05705745b99..cd5a46324168 100644 --- a/gfx/gl/SurfaceStream.cpp +++ b/gfx/gl/SurfaceStream.cpp @@ -30,10 +30,10 @@ SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc, } } -SurfaceStream* +TemporaryRef SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glContext, SurfaceStream* prevStream) { - SurfaceStream* result = nullptr; + RefPtr result; switch (type) { case SurfaceStreamType::SingleBuffer: @@ -53,7 +53,8 @@ SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glC } result->mGLContext = glContext; - return result; + + return result.forget(); } bool diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index 023c0cd6ed45..24c9e764249e 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -34,9 +34,9 @@ public: static SurfaceStreamType ChooseGLStreamType(OMTC omtc, bool preserveBuffer); - static SurfaceStream* CreateForType(SurfaceStreamType type, - mozilla::gl::GLContext* glContext, - SurfaceStream* prevStream = nullptr); + static TemporaryRef CreateForType(SurfaceStreamType type, + mozilla::gl::GLContext* glContext, + SurfaceStream* prevStream = nullptr); const SurfaceStreamType mType; From ebe1200d76444f67aeb44ad4da556145c8b2327d Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:08 -0700 Subject: [PATCH 026/101] Bug 1049957 - Use UniquePtr for SharedSurface, SurfaceFactory. - r=kamidphish --- gfx/gl/GLScreenBuffer.cpp | 25 +- gfx/gl/GLScreenBuffer.h | 15 +- gfx/gl/SharedSurface.cpp | 38 ++- gfx/gl/SharedSurface.h | 9 +- gfx/gl/SharedSurfaceANGLE.cpp | 43 ++-- gfx/gl/SharedSurfaceANGLE.h | 15 +- gfx/gl/SharedSurfaceEGL.cpp | 16 +- gfx/gl/SharedSurfaceEGL.h | 16 +- gfx/gl/SharedSurfaceGL.cpp | 15 +- gfx/gl/SharedSurfaceGL.h | 24 +- gfx/gl/SharedSurfaceGralloc.cpp | 9 +- gfx/gl/SharedSurfaceGralloc.h | 12 +- gfx/gl/SharedSurfaceIO.cpp | 33 ++- gfx/gl/SharedSurfaceIO.h | 15 +- gfx/gl/SurfaceStream.cpp | 305 +++++++++++++++--------- gfx/gl/SurfaceStream.h | 82 +++---- gfx/layers/client/CanvasClient.cpp | 6 +- gfx/layers/client/ClientCanvasLayer.cpp | 25 +- gfx/layers/client/ClientCanvasLayer.h | 4 +- gfx/layers/d3d10/CanvasLayerD3D10.cpp | 4 +- 20 files changed, 401 insertions(+), 310 deletions(-) diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 57ce7ae89988..1b7e2990178a 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -37,7 +37,7 @@ GLScreenBuffer::Create(GLContext* gl, return nullptr; } - SurfaceFactory* factory = nullptr; + UniquePtr factory; #ifdef MOZ_WIDGET_GONK /* On B2G, we want a Gralloc factory, and we want one right at the start */ @@ -45,7 +45,7 @@ GLScreenBuffer::Create(GLContext* gl, caps.surfaceAllocator && XRE_GetProcessType() != GeckoProcessType_Default) { - factory = new SurfaceFactory_Gralloc(gl, caps); + factory = MakeUnique(gl, caps); } #endif #ifdef XP_MACOSX @@ -55,8 +55,9 @@ GLScreenBuffer::Create(GLContext* gl, } #endif - if (!factory) - factory = new SurfaceFactory_Basic(gl, caps); + if (!factory) { + factory = MakeUnique(gl, caps); + } auto streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread, caps.preserve); @@ -80,7 +81,7 @@ GLScreenBuffer::~GLScreenBuffer() // buffers, but that Allocator may be kept alive by the Factory, // as it currently the case in SurfaceFactory_Gralloc holding a nsRefPtr // to the Allocator! - delete mFactory; + mFactory = nullptr; } @@ -374,13 +375,13 @@ GLScreenBuffer::AssureBlitted() } void -GLScreenBuffer::Morph(SurfaceFactory* newFactory, SurfaceStreamType streamType) +GLScreenBuffer::Morph(UniquePtr newFactory, + SurfaceStreamType streamType) { MOZ_ASSERT(mStream); if (newFactory) { - delete mFactory; - mFactory = newFactory; + mFactory = Move(newFactory); } if (mStream->mType == streamType) @@ -437,7 +438,7 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size) bool GLScreenBuffer::Swap(const gfx::IntSize& size) { - SharedSurface* nextSurf = mStream->SwapProducer(mFactory, size); + SharedSurface* nextSurf = mStream->SwapProducer(mFactory.get(), size); if (!nextSurf) { SurfaceFactory_Basic basicFactory(mGL, mFactory->mCaps); nextSurf = mStream->SwapProducer(&basicFactory, size); @@ -463,11 +464,11 @@ GLScreenBuffer::PublishFrame(const gfx::IntSize& size) bool GLScreenBuffer::Resize(const gfx::IntSize& size) { - SharedSurface* surface = mStream->Resize(mFactory, size); - if (!surface) + SharedSurface* surf = mStream->Resize(mFactory.get(), size); + if (!surf) return false; - return Attach(surface, size); + return Attach(surf, size); } bool diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index a3571c81e80f..ab53281b438b 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -127,11 +127,11 @@ protected: public: const SurfaceCaps mCaps; protected: - SurfaceFactory* mFactory; // Owned by us. + UniquePtr mFactory; RefPtr mStream; - UniquePtr mDraw; // Owned by us. - UniquePtr mRead; // Owned by us. + UniquePtr mDraw; + UniquePtr mRead; bool mNeedsBlit; @@ -148,11 +148,11 @@ protected: GLScreenBuffer(GLContext* gl, const SurfaceCaps& caps, - SurfaceFactory* factory, + UniquePtr factory, const RefPtr& stream) : mGL(gl) , mCaps(caps) - , mFactory(factory) + , mFactory(Move(factory)) , mStream(stream) , mDraw(nullptr) , mRead(nullptr) @@ -175,7 +175,7 @@ public: } SurfaceFactory* Factory() const { - return mFactory; + return mFactory.get(); } SharedSurface* SharedSurf() const { @@ -235,7 +235,8 @@ public: * Once you pass newFactory into Morph, newFactory will be owned by * GLScreenBuffer, so `forget` any references to it that still exist. */ - void Morph(SurfaceFactory* newFactory, SurfaceStreamType streamType); + void Morph(UniquePtr newFactory, + SurfaceStreamType streamType); protected: // Returns false on error or inability to resize. diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index 27743607fce7..1f7a864a29d1 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -29,15 +29,15 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, dest->mAttachType == AttachmentType::Screen) { // Here, we actually need to blit through a temp surface, so let's make one. - nsAutoPtr tempSurf; + UniquePtr tempSurf; tempSurf = SharedSurface_GLTexture::Create(gl, gl, factory->mFormats, src->mSize, factory->mCaps.alpha); - ProdCopy(src, tempSurf, factory); - ProdCopy(tempSurf, dest, factory); + ProdCopy(src, tempSurf.get(), factory); + ProdCopy(tempSurf.get(), dest, factory); return; } @@ -269,46 +269,38 @@ SurfaceFactory::SurfaceFactory(GLContext* gl, SurfaceFactory::~SurfaceFactory() { while (!mScraps.empty()) { - SharedSurface* cur = mScraps.front(); + UniquePtr cur = Move(mScraps.front()); mScraps.pop(); - - delete cur; } } -SharedSurface* +UniquePtr SurfaceFactory::NewSharedSurface(const gfx::IntSize& size) { // Attempt to reuse an old surface. while (!mScraps.empty()) { - SharedSurface* cur = mScraps.front(); + UniquePtr cur = Move(mScraps.front()); mScraps.pop(); - if (cur->mSize == size) - return cur; - // Destroy old surfaces of the wrong size. - delete cur; + if (cur->mSize == size) + return Move(cur); + + // Let `cur` be destroyed as it falls out of scope, if it wasn't + // moved. } - SharedSurface* ret = CreateShared(size); - - return ret; + return CreateShared(size); } // Auto-deletes surfs of the wrong type. void -SurfaceFactory::Recycle(SharedSurface*& surf) +SurfaceFactory::Recycle(UniquePtr surf) { - if (!surf) - return; + MOZ_ASSERT(surf); if (surf->mType == mType) { - mScraps.push(surf); - } else { - delete surf; + mScraps.push(Move(surf)); } - - surf = nullptr; } } /* namespace gfx */ diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 6557ea53dc12..821a8729c66a 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -22,6 +22,7 @@ #include "GLDefs.h" #include "mozilla/Attributes.h" #include "mozilla/gfx/Point.h" +#include "mozilla/WeakPtr.h" #include "SurfaceTypes.h" namespace mozilla { @@ -140,15 +141,15 @@ public: } protected: - virtual SharedSurface* CreateShared(const gfx::IntSize& size) = 0; + virtual UniquePtr CreateShared(const gfx::IntSize& size) = 0; - std::queue mScraps; + std::queue< UniquePtr > mScraps; public: - SharedSurface* NewSharedSurface(const gfx::IntSize& size); + UniquePtr NewSharedSurface(const gfx::IntSize& size); // Auto-deletes surfs of the wrong type. - void Recycle(SharedSurface*& surf); + void Recycle(UniquePtr surf); }; } // namespace gl diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp index 16e4e2d3c2aa..d8727a61fe10 100644 --- a/gfx/gl/SharedSurfaceANGLE.cpp +++ b/gfx/gl/SharedSurfaceANGLE.cpp @@ -11,23 +11,6 @@ namespace mozilla { namespace gl { -SurfaceFactory_ANGLEShareHandle* -SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, - const SurfaceCaps& caps) -{ - GLLibraryEGL* egl = &sEGLLibrary; - if (!egl) - return nullptr; - - if (!egl->IsExtensionSupported( - GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle)) - { - return nullptr; - } - - return new SurfaceFactory_ANGLEShareHandle(gl, egl, caps); -} - EGLDisplay SharedSurface_ANGLEShareHandle::Display() { @@ -179,7 +162,7 @@ CreatePBufferSurface(GLLibraryEGL* egl, return surface; } -SharedSurface_ANGLEShareHandle* +/*static*/ UniquePtr SharedSurface_ANGLEShareHandle::Create(GLContext* gl, EGLContext context, EGLConfig config, const gfx::IntSize& size, bool hasAlpha) @@ -208,12 +191,28 @@ SharedSurface_ANGLEShareHandle::Create(GLContext* gl, return nullptr; } - return new SharedSurface_ANGLEShareHandle(gl, egl, - size, hasAlpha, - context, pbuffer, - shareHandle); + typedef SharedSurface_ANGLEShareHandle ptrT; + return UniquePtr( new ptrT(gl, egl, size, hasAlpha, context, + pbuffer, shareHandle) ); } +/*static*/ UniquePtr +SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, + const SurfaceCaps& caps) +{ + GLLibraryEGL* egl = &sEGLLibrary; + if (!egl) + return nullptr; + + if (!egl->IsExtensionSupported( + GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle)) + { + return nullptr; + } + + typedef SurfaceFactory_ANGLEShareHandle ptrT; + return UniquePtr( new ptrT(gl, egl, caps) ); +} SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl, GLLibraryEGL* egl, diff --git a/gfx/gl/SharedSurfaceANGLE.h b/gfx/gl/SharedSurfaceANGLE.h index 5658843bda16..d2273071115d 100644 --- a/gfx/gl/SharedSurfaceANGLE.h +++ b/gfx/gl/SharedSurfaceANGLE.h @@ -20,10 +20,11 @@ class SharedSurface_ANGLEShareHandle : public SharedSurface { public: - static SharedSurface_ANGLEShareHandle* Create(GLContext* gl, - EGLContext context, EGLConfig config, - const gfx::IntSize& size, - bool hasAlpha); + static UniquePtr Create(GLContext* gl, + EGLContext context, + EGLConfig config, + const gfx::IntSize& size, + bool hasAlpha); static SharedSurface_ANGLEShareHandle* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLSurfaceANGLE); @@ -85,15 +86,15 @@ protected: EGLConfig mConfig; public: - static SurfaceFactory_ANGLEShareHandle* Create(GLContext* gl, - const SurfaceCaps& caps); + static UniquePtr Create(GLContext* gl, + const SurfaceCaps& caps); protected: SurfaceFactory_ANGLEShareHandle(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps); - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; return SharedSurface_ANGLEShareHandle::Create(mProdGL, mContext, mConfig, diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp index 4a9e6eddf51b..e34660924575 100644 --- a/gfx/gl/SharedSurfaceEGL.cpp +++ b/gfx/gl/SharedSurfaceEGL.cpp @@ -16,7 +16,7 @@ namespace mozilla { namespace gl { -SharedSurface_EGLImage* +/*static*/ UniquePtr SharedSurface_EGLImage::Create(GLContext* prodGL, const GLFormats& formats, const gfx::IntSize& size, @@ -46,12 +46,11 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, return nullptr; } - return new SharedSurface_EGLImage(prodGL, egl, - size, hasAlpha, - formats, prodTex, image); + typedef SharedSurface_EGLImage ptrT; + return UniquePtr( new ptrT(prodGL, egl, size, hasAlpha, + formats, prodTex, image) ); } - bool SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl) { @@ -216,9 +215,9 @@ SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_te } -SurfaceFactory_EGLImage* +/*static*/ UniquePtr SurfaceFactory_EGLImage::Create(GLContext* prodGL, - const SurfaceCaps& caps) + const SurfaceCaps& caps) { EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext(); @@ -227,7 +226,8 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, return nullptr; } - return new SurfaceFactory_EGLImage(prodGL, context, caps); + typedef SurfaceFactory_EGLImage ptrT; + return UniquePtr( new ptrT(prodGL, context, caps) ); } } /* namespace gfx */ diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h index f50578758ae8..7c845ba7e152 100644 --- a/gfx/gl/SharedSurfaceEGL.h +++ b/gfx/gl/SharedSurfaceEGL.h @@ -22,11 +22,11 @@ class SharedSurface_EGLImage : public SharedSurface { public: - static SharedSurface_EGLImage* Create(GLContext* prodGL, - const GLFormats& formats, - const gfx::IntSize& size, - bool hasAlpha, - EGLContext context); + static UniquePtr Create(GLContext* prodGL, + const GLFormats& formats, + const gfx::IntSize& size, + bool hasAlpha, + EGLContext context); static SharedSurface_EGLImage* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLImageShare); @@ -84,8 +84,8 @@ class SurfaceFactory_EGLImage { public: // Fallible: - static SurfaceFactory_EGLImage* Create(GLContext* prodGL, - const SurfaceCaps& caps); + static UniquePtr Create(GLContext* prodGL, + const SurfaceCaps& caps); protected: const EGLContext mContext; @@ -98,7 +98,7 @@ protected: {} public: - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext); } diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp index 35c2e8b13359..c68ab0c555be 100644 --- a/gfx/gl/SharedSurfaceGL.cpp +++ b/gfx/gl/SharedSurfaceGL.cpp @@ -17,7 +17,7 @@ namespace gl { using gfx::IntSize; using gfx::SurfaceFormat; -SharedSurface_Basic* +/*static*/ UniquePtr SharedSurface_Basic::Create(GLContext* gl, const GLFormats& formats, const IntSize& size, @@ -45,7 +45,9 @@ SharedSurface_Basic::Create(GLContext* gl, default: MOZ_CRASH("Unhandled Tex format."); } - return new SharedSurface_Basic(gl, size, hasAlpha, format, tex); + + typedef SharedSurface_Basic ptrT; + return UniquePtr( new ptrT(gl, size, hasAlpha, format, tex) ); } SharedSurface_Basic::SharedSurface_Basic(GLContext* gl, @@ -100,9 +102,10 @@ SharedSurface_Basic::Fence() ReadPixelsIntoDataSurface(mGL, mData); } +//////////////////////////////////////////////////////////////////////// +// SharedSurface_GLTexture - -SharedSurface_GLTexture* +/*static*/ UniquePtr SharedSurface_GLTexture::Create(GLContext* prodGL, GLContext* consGL, const GLFormats& formats, @@ -124,7 +127,9 @@ SharedSurface_GLTexture::Create(GLContext* prodGL, ownsTex = true; } - return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex, ownsTex); + typedef SharedSurface_GLTexture ptrT; + return UniquePtr( new ptrT(prodGL, consGL, size, hasAlpha, + tex, ownsTex) ); } SharedSurface_GLTexture::~SharedSurface_GLTexture() diff --git a/gfx/gl/SharedSurfaceGL.h b/gfx/gl/SharedSurfaceGL.h index 5c0ecb0cf2a8..4ce14fdfc78a 100644 --- a/gfx/gl/SharedSurfaceGL.h +++ b/gfx/gl/SharedSurfaceGL.h @@ -34,10 +34,10 @@ class SharedSurface_Basic : public SharedSurface { public: - static SharedSurface_Basic* Create(GLContext* gl, - const GLFormats& formats, - const gfx::IntSize& size, - bool hasAlpha); + static UniquePtr Create(GLContext* gl, + const GLFormats& formats, + const gfx::IntSize& size, + bool hasAlpha); static SharedSurface_Basic* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic); @@ -90,7 +90,7 @@ public: : SurfaceFactory(gl, SharedSurfaceType::Basic, caps) {} - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; return SharedSurface_Basic::Create(mGL, mFormats, size, hasAlpha); } @@ -102,12 +102,12 @@ class SharedSurface_GLTexture : public SharedSurface { public: - static SharedSurface_GLTexture* Create(GLContext* prodGL, - GLContext* consGL, - const GLFormats& formats, - const gfx::IntSize& size, - bool hasAlpha, - GLuint texture = 0); + static UniquePtr Create(GLContext* prodGL, + GLContext* consGL, + const GLFormats& formats, + const gfx::IntSize& size, + bool hasAlpha, + GLuint texture = 0); static SharedSurface_GLTexture* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::GLTextureShare); @@ -183,7 +183,7 @@ public: MOZ_ASSERT(consGL != prodGL); } - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha); } diff --git a/gfx/gl/SharedSurfaceGralloc.cpp b/gfx/gl/SharedSurfaceGralloc.cpp index e8b4cde8e8fd..56c6f5885f67 100644 --- a/gfx/gl/SharedSurfaceGralloc.cpp +++ b/gfx/gl/SharedSurfaceGralloc.cpp @@ -49,7 +49,7 @@ SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, mAllocator = allocator; } -SharedSurface_Gralloc* +/*static*/ UniquePtr SharedSurface_Gralloc::Create(GLContext* prodGL, const GLFormats& formats, const gfx::IntSize& size, @@ -110,11 +110,14 @@ SharedSurface_Gralloc::Create(GLContext* prodGL, egl->fDestroyImage(display, image); - SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, grallocTC, prodTex); + + typedef SharedSurface_Gralloc ptrT; + UniquePtr surf( new ptrT(prodGL, size, hasAlpha, egl, + allocator, grallocTC, prodTex) ); DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get()); - return surf; + return Move(surf); } diff --git a/gfx/gl/SharedSurfaceGralloc.h b/gfx/gl/SharedSurfaceGralloc.h index dc10f259f5a8..e7ac988e0735 100644 --- a/gfx/gl/SharedSurfaceGralloc.h +++ b/gfx/gl/SharedSurfaceGralloc.h @@ -23,11 +23,11 @@ class SharedSurface_Gralloc : public SharedSurface { public: - static SharedSurface_Gralloc* Create(GLContext* prodGL, - const GLFormats& formats, - const gfx::IntSize& size, - bool hasAlpha, - layers::ISurfaceAllocator* allocator); + static UniquePtr Create(GLContext* prodGL, + const GLFormats& formats, + const gfx::IntSize& size, + bool hasAlpha, + layers::ISurfaceAllocator* allocator); static SharedSurface_Gralloc* Cast(SharedSurface* surf) { MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc); @@ -84,7 +84,7 @@ public: const SurfaceCaps& caps, layers::ISurfaceAllocator* allocator = nullptr); - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; if (!mAllocator) { return nullptr; diff --git a/gfx/gl/SharedSurfaceIO.cpp b/gfx/gl/SharedSurfaceIO.cpp index efcf62a991b3..a8c7184f9808 100644 --- a/gfx/gl/SharedSurfaceIO.cpp +++ b/gfx/gl/SharedSurfaceIO.cpp @@ -13,14 +13,18 @@ namespace mozilla { namespace gl { -/* static */ SharedSurface_IOSurface* -SharedSurface_IOSurface::Create(MacIOSurface* surface, GLContext* gl, bool hasAlpha) +/*static*/ UniquePtr +SharedSurface_IOSurface::Create(const RefPtr& ioSurf, + GLContext* gl, + bool hasAlpha) { MOZ_ASSERT(surface); MOZ_ASSERT(gl); gfx::IntSize size(surface->GetWidth(), surface->GetHeight()); - return new SharedSurface_IOSurface(surface, gl, size, hasAlpha); + + typedef SharedSurface_IOSurface ptrT; + return UniquePtr( new ptrT(ioSurf, gl, size, hasAlpha) ); } void @@ -87,7 +91,7 @@ BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf) ioSurf->CGLTexImageIOSurface2D(cgl); } -SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface, +SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr& ioSurf, GLContext* gl, const gfx::IntSize& size, bool hasAlpha) @@ -96,7 +100,7 @@ SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface, gl, size, hasAlpha) - , mSurface(surface) + , mIOSurf(ioSurf) , mCurConsGL(nullptr) , mConsTex(0) { @@ -118,7 +122,7 @@ SharedSurface_IOSurface::ConsTexture(GLContext* consGL) consGL->MakeCurrent(); mConsTex = 0; consGL->fGenTextures(1, &mConsTex); - BackTextureWithIOSurf(consGL, mConsTex, mSurface); + BackTextureWithIOSurf(consGL, mConsTex, mIOSurf); } return mConsTex; @@ -134,17 +138,21 @@ SharedSurface_IOSurface::~SharedSurface_IOSurface() } } +//////////////////////////////////////////////////////////////////////// +// SurfaceFactory_IOSurface -/*static*/ SurfaceFactory_IOSurface* +/*static*/ UniquePtr SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps) { gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(), MacIOSurface::GetMaxHeight()); - return new SurfaceFactory_IOSurface(gl, caps, maxDims); + + typedef SurfaceFactory_IOSurface ptrT; + return UniquePtr( new ptrT(gl, caps, maxDims) ); } -SharedSurface* +UniquePtr SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size) { if (size.width > mMaxDims.width || @@ -154,15 +162,16 @@ SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size) } bool hasAlpha = mReadCaps.alpha; - RefPtr surf = - MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha); + RefPtr ioSurf; + ioSurf = MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, + hasAlpha); if (!surf) { NS_WARNING("Failed to create MacIOSurface."); return nullptr; } - return SharedSurface_IOSurface::Create(surf, mGL, hasAlpha); + return SharedSurface_IOSurface::Create(ioSurf, mGL, hasAlpha); } } diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h index 59af20210b9c..288931bc0542 100644 --- a/gfx/gl/SharedSurfaceIO.h +++ b/gfx/gl/SharedSurfaceIO.h @@ -17,7 +17,9 @@ namespace gl { class SharedSurface_IOSurface : public SharedSurface { public: - static SharedSurface_IOSurface* Create(MacIOSurface* surface, GLContext* gl, bool hasAlpha); + static UniquePtr Create(MacIOSurface* surface, + GLContext* gl, + bool hasAlpha); ~SharedSurface_IOSurface(); @@ -55,9 +57,10 @@ public: } private: - SharedSurface_IOSurface(MacIOSurface* surface, GLContext* gl, const gfx::IntSize& size, bool hasAlpha); + SharedSurface_IOSurface(MacIOSurface* ioSurf, GLContext* gl, + const gfx::IntSize& size, bool hasAlpha); - RefPtr mSurface; + RefPtr mIOSurf; GLuint mProdTex; const GLContext* mCurConsGL; GLuint mConsTex; @@ -67,8 +70,8 @@ class SurfaceFactory_IOSurface : public SurfaceFactory { public: // Infallible. - static SurfaceFactory_IOSurface* Create(GLContext* gl, - const SurfaceCaps& caps); + static UniquePtr Create(GLContext* gl, + const SurfaceCaps& caps); protected: const gfx::IntSize mMaxDims; @@ -80,7 +83,7 @@ protected: { } - virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE; + virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE; }; } /* namespace gfx */ diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp index cd5a46324168..e293f731675f 100644 --- a/gfx/gl/SurfaceStream.cpp +++ b/gfx/gl/SurfaceStream.cpp @@ -9,6 +9,7 @@ #include "SharedSurface.h" #include "SharedSurfaceGL.h" #include "GeckoProfiler.h" +#include "mozilla/Move.h" namespace mozilla { namespace gl { @@ -61,7 +62,7 @@ bool SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { if (!mProducer) { - New(factory, src->mSize, mProducer); + New(factory, src->mSize, &mProducer); if (!mProducer) { return false; } @@ -69,14 +70,17 @@ SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFac MOZ_ASSERT(src->mSize == mProducer->mSize, "Size mismatch"); - SharedSurface::ProdCopy(src, mProducer, factory); + SharedSurface::ProdCopy(src, mProducer.get(), factory); return true; } void SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size, - SharedSurface*& surf) + UniquePtr* surfSlot) { + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; + MOZ_ASSERT(!surf); surf = factory->NewSharedSurface(size); @@ -84,91 +88,145 @@ SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size, // Before next use, wait until SharedSurface's buffer // is no longer being used. surf->WaitForBufferOwnership(); - mSurfaces.insert(surf); +#ifdef DEBUG + mSurfaces.insert(surf.get()); +#endif } } void -SurfaceStream::Recycle(SurfaceFactory* factory, SharedSurface*& surf) +SurfaceStream::MoveTo(UniquePtr* slotFrom, + UniquePtr* slotTo) { - if (surf) { - mSurfaces.erase(surf); - factory->Recycle(surf); - } - MOZ_ASSERT(!surf); + MOZ_ASSERT(slotFrom); + UniquePtr& from = *slotFrom; + + MOZ_ASSERT(slotTo); + UniquePtr& to = *slotTo; + + MOZ_ASSERT(!to); + to = Move(from); + from = nullptr; } void -SurfaceStream::Delete(SharedSurface*& surf) +SurfaceStream::Recycle(SurfaceFactory* factory, UniquePtr* surfSlot) { + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; + if (surf) { - mSurfaces.erase(surf); - delete surf; +#ifdef DEBUG + mSurfaces.erase(surf.get()); +#endif + factory->Recycle(Move(surf)); surf = nullptr; } MOZ_ASSERT(!surf); } -SharedSurface* -SurfaceStream::Surrender(SharedSurface*& surf) +void +SurfaceStream::Delete(UniquePtr* surfSlot) { - SharedSurface* ret = surf; + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; if (surf) { - mSurfaces.erase(surf); +#ifdef DEBUG + mSurfaces.erase(surf.get()); +#endif surf = nullptr; } MOZ_ASSERT(!surf); - - return ret; } -SharedSurface* -SurfaceStream::Absorb(SharedSurface*& surf) +UniquePtr +SurfaceStream::Surrender(UniquePtr* surfSlot) { - SharedSurface* ret = surf; + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; +#ifdef DEBUG if (surf) { - mSurfaces.insert(surf); - surf = nullptr; + mSurfaces.erase(surf.get()); } - MOZ_ASSERT(!surf); +#endif - return ret; + UniquePtr ret = Move(surf); + surf = nullptr; + + return Move(ret); +} + +// Move `surfSlot` to `return`, but record that the surf is now part of +// this stream. +UniquePtr +SurfaceStream::Absorb(UniquePtr* surfSlot) +{ + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; + +#ifdef DEBUG + if (surf) { + mSurfaces.insert(surf.get()); + } +#endif + + UniquePtr ret = Move(surf); + surf = nullptr; + + return Move(ret); } void -SurfaceStream::Scrap(SharedSurface*& scrap) +SurfaceStream::Scrap(UniquePtr* surfSlot) { - if (scrap) { - mScraps.push(scrap); - scrap = nullptr; + MOZ_ASSERT(surfSlot); + UniquePtr& surf = *surfSlot; + + if (surf) { + mScraps.push(Move(surf)); + surf = nullptr; } - MOZ_ASSERT(!scrap); + MOZ_ASSERT(!surf); + } void SurfaceStream::RecycleScraps(SurfaceFactory* factory) { while (!mScraps.empty()) { - SharedSurface* cur = mScraps.top(); + UniquePtr cur = Move(mScraps.top()); mScraps.pop(); - Recycle(factory, cur); + Recycle(factory, &cur); } } +//////////////////////////////////////////////////////////////////////// +// SurfaceStream +SurfaceStream::SurfaceStream(SurfaceStreamType type, + SurfaceStream* prevStream) + : mType(type) + , mProducer(nullptr) + , mMonitor("SurfaceStream monitor") + , mIsAlive(true) +{ + MOZ_ASSERT(!prevStream || mType != prevStream->mType, + "We should not need to create a SurfaceStream from another " + "of the same type."); +} SurfaceStream::~SurfaceStream() { - Delete(mProducer); + Delete(&mProducer); while (!mScraps.empty()) { - SharedSurface* cur = mScraps.top(); + UniquePtr cur = Move(mScraps.top()); mScraps.pop(); - Delete(cur); + Delete(&cur); } MOZ_ASSERT(mSurfaces.empty()); @@ -196,13 +254,16 @@ SurfaceStream::Resize(SurfaceFactory* factory, const gfx::IntSize& size) MonitorAutoLock lock(mMonitor); if (mProducer) { - Scrap(mProducer); + Scrap(&mProducer); } - New(factory, size, mProducer); - return mProducer; + New(factory, size, &mProducer); + return mProducer.get(); } +//////////////////////////////////////////////////////////////////////// +// SurfaceStream_SingleBuffer + SurfaceStream_SingleBuffer::SurfaceStream_SingleBuffer(SurfaceStream* prevStream) : SurfaceStream(SurfaceStreamType::SingleBuffer, prevStream) , mConsumer(nullptr) @@ -210,33 +271,30 @@ SurfaceStream_SingleBuffer::SurfaceStream_SingleBuffer(SurfaceStream* prevStream if (!prevStream) return; - SharedSurface* prevProducer = nullptr; - SharedSurface* prevConsumer = nullptr; - prevStream->SurrenderSurfaces(prevProducer, prevConsumer); + UniquePtr prevProducer; + UniquePtr prevConsumer; + prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer); - if (prevConsumer == prevProducer) - prevConsumer = nullptr; - - mProducer = Absorb(prevProducer); - mConsumer = Absorb(prevConsumer); + mProducer = Absorb(&prevProducer); + mConsumer = Absorb(&prevConsumer); } SurfaceStream_SingleBuffer::~SurfaceStream_SingleBuffer() { - Delete(mConsumer); + Delete(&mConsumer); } void -SurfaceStream_SingleBuffer::SurrenderSurfaces(SharedSurface*& producer, - SharedSurface*& consumer) +SurfaceStream_SingleBuffer::SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) { + MOZ_ASSERT(out_producer); + MOZ_ASSERT(out_consumer); + mIsAlive = false; - producer = Surrender(mProducer); - consumer = Surrender(mConsumer); - - if (!consumer) - consumer = producer; + *out_producer = Surrender(&mProducer); + *out_consumer = Surrender(&mConsumer); } SharedSurface* @@ -245,7 +303,7 @@ SurfaceStream_SingleBuffer::SwapProducer(SurfaceFactory* factory, { MonitorAutoLock lock(mMonitor); if (mConsumer) { - Recycle(factory, mConsumer); + Recycle(factory, &mConsumer); } if (mProducer) { @@ -265,17 +323,17 @@ SurfaceStream_SingleBuffer::SwapProducer(SurfaceFactory* factory, } if (needsNewBuffer) { - Move(mProducer, mConsumer); + MoveTo(&mProducer, &mConsumer); } } // The old Prod (if there every was one) was invalid, // so we need a new one. if (!mProducer) { - New(factory, size, mProducer); + New(factory, size, &mProducer); } - return mProducer; + return mProducer.get(); } SharedSurface* @@ -285,14 +343,15 @@ SurfaceStream_SingleBuffer::SwapConsumer_NoWait() // Use Cons, if present. // Otherwise, just use Prod directly. - SharedSurface* toConsume = mConsumer; + SharedSurface* toConsume = mConsumer.get(); if (!toConsume) - toConsume = mProducer; + toConsume = mProducer.get(); return toConsume; } - +//////////////////////////////////////////////////////////////////////// +// SurfaceStream_TripleBuffer_Copy SurfaceStream_TripleBuffer_Copy::SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream) : SurfaceStream(SurfaceStreamType::TripleBuffer_Copy, prevStream) @@ -302,34 +361,34 @@ SurfaceStream_TripleBuffer_Copy::SurfaceStream_TripleBuffer_Copy(SurfaceStream* if (!prevStream) return; - SharedSurface* prevProducer = nullptr; - SharedSurface* prevConsumer = nullptr; - prevStream->SurrenderSurfaces(prevProducer, prevConsumer); + UniquePtr prevProducer; + UniquePtr prevConsumer; + prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer); - if (prevConsumer == prevProducer) - prevConsumer = nullptr; - - mProducer = Absorb(prevProducer); - mConsumer = Absorb(prevConsumer); + mProducer = Absorb(&prevProducer); + mConsumer = Absorb(&prevConsumer); } SurfaceStream_TripleBuffer_Copy::~SurfaceStream_TripleBuffer_Copy() { - Delete(mStaging); - Delete(mConsumer); + Delete(&mStaging); + Delete(&mConsumer); } void -SurfaceStream_TripleBuffer_Copy::SurrenderSurfaces(SharedSurface*& producer, - SharedSurface*& consumer) +SurfaceStream_TripleBuffer_Copy::SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) { + MOZ_ASSERT(out_producer); + MOZ_ASSERT(out_consumer); + mIsAlive = false; - producer = Surrender(mProducer); - consumer = Surrender(mConsumer); + *out_producer = Surrender(&mProducer); + *out_consumer = Surrender(&mConsumer); - if (!consumer) - consumer = Surrender(mStaging); + if (!*out_consumer) + *out_consumer = Surrender(&mStaging); } SharedSurface* @@ -343,55 +402,57 @@ SurfaceStream_TripleBuffer_Copy::SwapProducer(SurfaceFactory* factory, if (mStaging) { // We'll re-use this for a new mProducer later on if // the size remains the same - Recycle(factory, mStaging); + Recycle(factory, &mStaging); } - Move(mProducer, mStaging); + MoveTo(&mProducer, &mStaging); mStaging->Fence(); - New(factory, size, mProducer); + New(factory, size, &mProducer); - if (mProducer && mStaging->mSize == mProducer->mSize) - SharedSurface::ProdCopy(mStaging, mProducer, factory); + if (mProducer && + mStaging->mSize == mProducer->mSize) + { + SharedSurface::ProdCopy(mStaging.get(), mProducer.get(), factory); + } } else { - New(factory, size, mProducer); + New(factory, size, &mProducer); } - return mProducer; + return mProducer.get(); } - SharedSurface* SurfaceStream_TripleBuffer_Copy::SwapConsumer_NoWait() { MonitorAutoLock lock(mMonitor); if (mStaging) { - Scrap(mConsumer); - Move(mStaging, mConsumer); + Scrap(&mConsumer); + MoveTo(&mStaging, &mConsumer); } - return mConsumer; + return mConsumer.get(); } +//////////////////////////////////////////////////////////////////////// +// SurfaceStream_TripleBuffer + void SurfaceStream_TripleBuffer::Init(SurfaceStream* prevStream) { if (!prevStream) return; - SharedSurface* prevProducer = nullptr; - SharedSurface* prevConsumer = nullptr; - prevStream->SurrenderSurfaces(prevProducer, prevConsumer); + UniquePtr prevProducer; + UniquePtr prevConsumer; + prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer); - if (prevConsumer == prevProducer) - prevConsumer = nullptr; - - mProducer = Absorb(prevProducer); - mConsumer = Absorb(prevConsumer); + mProducer = Absorb(&prevProducer); + mConsumer = Absorb(&prevConsumer); } - -SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream) +SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStreamType type, + SurfaceStream* prevStream) : SurfaceStream(type, prevStream) , mStaging(nullptr) , mConsumer(nullptr) @@ -409,21 +470,24 @@ SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStream* prevStream SurfaceStream_TripleBuffer::~SurfaceStream_TripleBuffer() { - Delete(mStaging); - Delete(mConsumer); + Delete(&mStaging); + Delete(&mConsumer); } void -SurfaceStream_TripleBuffer::SurrenderSurfaces(SharedSurface*& producer, - SharedSurface*& consumer) +SurfaceStream_TripleBuffer::SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) { + MOZ_ASSERT(out_producer); + MOZ_ASSERT(out_consumer); + mIsAlive = false; - producer = Surrender(mProducer); - consumer = Surrender(mConsumer); + *out_producer = Surrender(&mProducer); + *out_consumer = Surrender(&mConsumer); - if (!consumer) - consumer = Surrender(mStaging); + if (!*out_consumer) + *out_consumer = Surrender(&mStaging); } SharedSurface* @@ -431,7 +495,7 @@ SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory, const gfx::IntSize& size) { PROFILER_LABEL("SurfaceStream_TripleBuffer", "SwapProducer", - js::ProfileEntry::Category::GRAPHICS); + js::ProfileEntry::Category::GRAPHICS); MonitorAutoLock lock(mMonitor); if (mProducer) { @@ -443,17 +507,17 @@ SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory, WaitForCompositor(); } if (mStaging) { - Scrap(mStaging); + Scrap(&mStaging); } - Move(mProducer, mStaging); + MoveTo(&mProducer, &mStaging); mStaging->Fence(); } MOZ_ASSERT(!mProducer); - New(factory, size, mProducer); + New(factory, size, &mProducer); - return mProducer; + return mProducer.get(); } SharedSurface* @@ -461,16 +525,20 @@ SurfaceStream_TripleBuffer::SwapConsumer_NoWait() { MonitorAutoLock lock(mMonitor); if (mStaging) { - Scrap(mConsumer); - Move(mStaging, mConsumer); + Scrap(&mConsumer); + MoveTo(&mStaging, &mConsumer); mMonitor.NotifyAll(); } - return mConsumer; + return mConsumer.get(); } +//////////////////////////////////////////////////////////////////////// +// SurfaceStream_TripleBuffer_Async + SurfaceStream_TripleBuffer_Async::SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream) - : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async, prevStream) + : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async, + prevStream) { } @@ -481,8 +549,9 @@ SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async() void SurfaceStream_TripleBuffer_Async::WaitForCompositor() { - PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", "WaitForCompositor", - js::ProfileEntry::Category::GRAPHICS); + PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", + "WaitForCompositor", + js::ProfileEntry::Category::GRAPHICS); // If we haven't be notified within 100ms, then // something must have happened and it will never arrive. diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index 24c9e764249e..4c3042e6a06d 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -13,6 +13,7 @@ #include "mozilla/gfx/Point.h" #include "mozilla/GenericRefCounted.h" #include "SurfaceTypes.h" +#include "SharedSurface.h" namespace mozilla { @@ -46,9 +47,11 @@ public: protected: // |mProd| is owned by us, but can be ripped away when // creating a new GLStream from this one. - SharedSurface* mProducer; + UniquePtr mProducer; +#ifdef DEBUG std::set mSurfaces; - std::stack mScraps; +#endif + std::stack< UniquePtr > mScraps; mutable Monitor mMonitor; bool mIsAlive; @@ -58,16 +61,7 @@ protected: // |previous| can be null, indicating this is the first one. // Otherwise, we pull in |mProd| from |previous| an our initial surface. - SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream) - : mType(type) - , mProducer(nullptr) - , mMonitor("SurfaceStream monitor") - , mIsAlive(true) - { - MOZ_ASSERT(!prevStream || mType != prevStream->mType, - "We should not need to create a SurfaceStream from another " - "of the same type."); - } + SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream); public: virtual ~SurfaceStream(); @@ -76,26 +70,23 @@ protected: // These functions below are helpers to make trading buffers around easier. // For instance, using Move(a,b) instead of normal assignment assures that // we are never leaving anything hanging around, keeping things very safe. - static void Move(SharedSurface*& from, SharedSurface*& to) { - MOZ_ASSERT(!to); - to = from; - from = nullptr; - } - + void MoveTo(UniquePtr* slotFrom, + UniquePtr* slotTo); void New(SurfaceFactory* factory, const gfx::IntSize& size, - SharedSurface*& surf); - void Delete(SharedSurface*& surf); - void Recycle(SurfaceFactory* factory, SharedSurface*& surf); + UniquePtr* surfSlot); + void Delete(UniquePtr* surfSlot); + void Recycle(SurfaceFactory* factory, + UniquePtr* surfSlot); // Surrender control of a surface, and return it for use elsewhere. - SharedSurface* Surrender(SharedSurface*& surf); + UniquePtr Surrender(UniquePtr* surfSlot); // Absorb control of a surface from elsewhere, clears its old location. - SharedSurface* Absorb(SharedSurface*& surf); + UniquePtr Absorb(UniquePtr* surfSlot); // For holding on to surfaces we don't need until we can return them to the // Producer's factory via SurfaceFactory::Recycle. // Not thread-safe. - void Scrap(SharedSurface*& scrap); + void Scrap(UniquePtr* surfSlot); // Not thread-safe. void RecycleScraps(SurfaceFactory* factory); @@ -124,7 +115,8 @@ protected: public: virtual SharedSurface* SwapConsumer(); - virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer) = 0; + virtual void SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) = 0; }; // Not thread-safe. Don't use cross-threads. @@ -132,10 +124,11 @@ class SurfaceStream_SingleBuffer : public SurfaceStream { protected: - SharedSurface* mConsumer; // Only present after resize-swap. + UniquePtr mConsumer; // Only present after resize-swap. public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer) + explicit SurfaceStream_SingleBuffer(SurfaceStream* prevStream); virtual ~SurfaceStream_SingleBuffer(); @@ -144,11 +137,12 @@ public: * SwapCons being called in Render. */ virtual SharedSurface* SwapProducer(SurfaceFactory* factory, - const gfx::IntSize& size); + const gfx::IntSize& size) MOZ_OVERRIDE; - virtual SharedSurface* SwapConsumer_NoWait(); + virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE; - virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); + virtual void SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) MOZ_OVERRIDE; }; // Our hero for preserveDrawingBuffer=true. @@ -156,20 +150,22 @@ class SurfaceStream_TripleBuffer_Copy : public SurfaceStream { protected: - SharedSurface* mStaging; - SharedSurface* mConsumer; + UniquePtr mStaging; + UniquePtr mConsumer; public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy) + explicit SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream); virtual ~SurfaceStream_TripleBuffer_Copy(); virtual SharedSurface* SwapProducer(SurfaceFactory* factory, - const gfx::IntSize& size); + const gfx::IntSize& size) MOZ_OVERRIDE; - virtual SharedSurface* SwapConsumer_NoWait(); + virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE; - virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); + virtual void SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) MOZ_OVERRIDE; }; @@ -177,8 +173,8 @@ class SurfaceStream_TripleBuffer : public SurfaceStream { protected: - SharedSurface* mStaging; - SharedSurface* mConsumer; + UniquePtr mStaging; + UniquePtr mConsumer; // Returns true if we were able to wait, false if not virtual void WaitForCompositor() {} @@ -188,9 +184,12 @@ protected: public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer) + explicit SurfaceStream_TripleBuffer(SurfaceStream* prevStream); virtual ~SurfaceStream_TripleBuffer(); - virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory); + + virtual bool CopySurfaceToProducer(SharedSurface* src, + SurfaceFactory* factory) MOZ_OVERRIDE; private: // Common constructor code. @@ -199,11 +198,12 @@ private: public: // Done writing to prod, swap prod and staging virtual SharedSurface* SwapProducer(SurfaceFactory* factory, - const gfx::IntSize& size); + const gfx::IntSize& size) MOZ_OVERRIDE; - virtual SharedSurface* SwapConsumer_NoWait(); + virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE; - virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); + virtual void SurrenderSurfaces(UniquePtr* out_producer, + UniquePtr* out_consumer) MOZ_OVERRIDE; }; class SurfaceStream_TripleBuffer_Async @@ -213,6 +213,8 @@ protected: virtual void WaitForCompositor() MOZ_OVERRIDE; public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Async) + explicit SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream); virtual ~SurfaceStream_TripleBuffer_Async(); }; diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index ecc6d0eb830e..87f56be0e55b 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -157,8 +157,10 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) // Copy our current surface to the current producer surface in our stream, then // call SwapProducer to make a new buffer ready. - stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory); - stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height)); + stream->CopySurfaceToProducer(aLayer->mTextureSurface.get(), + aLayer->mFactory.get()); + stream->SwapProducer(aLayer->mFactory.get(), + gfx::IntSize(aSize.width, aSize.height)); } else { stream = screen->Stream(); } diff --git a/gfx/layers/client/ClientCanvasLayer.cpp b/gfx/layers/client/ClientCanvasLayer.cpp index 8cfb78fae295..781d3160e3a5 100644 --- a/gfx/layers/client/ClientCanvasLayer.cpp +++ b/gfx/layers/client/ClientCanvasLayer.cpp @@ -47,7 +47,7 @@ ClientCanvasLayer::~ClientCanvasLayer() mCanvasClient = nullptr; } if (mTextureSurface) { - delete mTextureSurface; + mTextureSurface = nullptr; } } @@ -73,13 +73,16 @@ ClientCanvasLayer::Initialize(const Data& aData) SurfaceStreamType streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread, screen->PreserveBuffer()); - SurfaceFactory* factory = nullptr; + UniquePtr factory = nullptr; + if (!gfxPrefs::WebGLForceLayersReadback()) { switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) { case mozilla::layers::LayersBackend::LAYERS_OPENGL: { if (mGLContext->GetContextType() == GLContextType::EGL) { #ifdef MOZ_WIDGET_GONK - factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder()); + factory = MakeUnique(mGLContext, + caps, + ClientManager()->AsShadowForwarder()); #else bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); if (!isCrossProcess) { @@ -96,7 +99,8 @@ ClientCanvasLayer::Initialize(const Data& aData) #ifdef XP_MACOSX factory = SurfaceFactory_IOSurface::Create(mGLContext, caps); #else - factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps); + GLContext* nullConsGL = nullptr; // Bug 1050044. + factory = MakeUnique(mGLContext, nullConsGL, caps); #endif } break; @@ -117,26 +121,25 @@ ClientCanvasLayer::Initialize(const Data& aData) if (mStream) { // We're using a stream other than the one in the default screen - mFactory = factory; + mFactory = Move(factory); if (!mFactory) { // Absolutely must have a factory here, so create a basic one - mFactory = new SurfaceFactory_Basic(mGLContext, caps); + mFactory = MakeUnique(mGLContext, caps); } gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height); mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext, mGLContext->GetGLFormats(), size, caps.alpha, aData.mTexID); - SharedSurface* producer = mStream->SwapProducer(mFactory, size); + SharedSurface* producer = mStream->SwapProducer(mFactory.get(), size); if (!producer) { // Fallback to basic factory - delete mFactory; - mFactory = new SurfaceFactory_Basic(mGLContext, caps); - producer = mStream->SwapProducer(mFactory, size); + mFactory = MakeUnique(mGLContext, caps); + producer = mStream->SwapProducer(mFactory.get(), size); MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory"); } } else if (factory) { - screen->Morph(factory, streamType); + screen->Morph(Move(factory), streamType); } } } diff --git a/gfx/layers/client/ClientCanvasLayer.h b/gfx/layers/client/ClientCanvasLayer.h index 70a84051bcd1..591319f4bce0 100644 --- a/gfx/layers/client/ClientCanvasLayer.h +++ b/gfx/layers/client/ClientCanvasLayer.h @@ -101,8 +101,8 @@ protected: RefPtr mCanvasClient; - gl::SharedSurface* mTextureSurface; - gl::SurfaceFactory* mFactory; + UniquePtr mTextureSurface; + UniquePtr mFactory; friend class DeprecatedCanvasClient2D; friend class CanvasClient2D; diff --git a/gfx/layers/d3d10/CanvasLayerD3D10.cpp b/gfx/layers/d3d10/CanvasLayerD3D10.cpp index 2f9ca3038585..65930ae1d243 100644 --- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp +++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp @@ -51,7 +51,7 @@ CanvasLayerD3D10::Initialize(const Data& aData) SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread, screen->PreserveBuffer()); - SurfaceFactory* factory = nullptr; + UniquePtr factory = nullptr; if (!gfxPrefs::WebGLForceLayersReadback()) { if (mGLContext->IsANGLE()) { factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, @@ -60,7 +60,7 @@ CanvasLayerD3D10::Initialize(const Data& aData) } if (factory) { - screen->Morph(factory, streamType); + screen->Morph(Move(factory), streamType); } } else if (aData.mDrawTarget) { mDrawTarget = aData.mDrawTarget; From 462da9f9df3ddc8a6575059bbbbf98d0d0cdd6d1 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:08 -0700 Subject: [PATCH 027/101] Bug 1049957 - Fix compilation errors. - r=kamidphish --- gfx/gl/GLScreenBuffer.cpp | 13 +++++++------ gfx/gl/GLScreenBuffer.h | 1 + gfx/gl/SharedSurface.h | 1 + gfx/gl/SharedSurfaceANGLE.cpp | 12 +++++++----- gfx/gl/SharedSurfaceEGL.cpp | 24 ++++++++++++++---------- gfx/gl/SharedSurfaceGL.cpp | 8 +++++--- gfx/gl/SharedSurfaceGralloc.cpp | 21 ++++++++++++--------- gfx/gl/SharedSurfaceGralloc.h | 9 ++++++--- gfx/gl/SharedSurfaceIO.cpp | 14 ++++++++------ gfx/gl/SharedSurfaceIO.h | 9 +++++---- gfx/gl/SurfaceStream.h | 1 + gfx/layers/client/ClientCanvasLayer.cpp | 2 +- 12 files changed, 68 insertions(+), 47 deletions(-) diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 1b7e2990178a..1d1bf91f8c6d 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -20,6 +20,7 @@ #endif #include "ScopedGLHelpers.h" #include "gfx2DGlue.h" +#include "../layers/ipc/ShadowLayers.h" namespace mozilla { namespace gl { @@ -31,10 +32,11 @@ GLScreenBuffer::Create(GLContext* gl, const gfx::IntSize& size, const SurfaceCaps& caps) { + UniquePtr ret; if (caps.antialias && !gl->IsSupported(GLFeature::framebuffer_multisample)) { - return nullptr; + return Move(ret); } UniquePtr factory; @@ -64,9 +66,7 @@ GLScreenBuffer::Create(GLContext* gl, RefPtr stream; stream = SurfaceStream::CreateForType(streamType, gl, nullptr); - UniquePtr ret( new GLScreenBuffer(gl, caps, - Move(factory), - stream) ); + ret.reset( new GLScreenBuffer(gl, caps, Move(factory), stream) ); return Move(ret); } @@ -651,8 +651,9 @@ ReadBuffer::Create(GLContext* gl, UniquePtr ret( new ReadBuffer(gl, fb, depthRB, stencilRB, surf) ); - if (!gl->IsFramebufferComplete(fb)) - return nullptr; + if (!gl->IsFramebufferComplete(fb)) { + ret = nullptr; + } return Move(ret); } diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index ab53281b438b..9eab5fb020ad 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -21,6 +21,7 @@ #include "GLDefs.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Point.h" +#include "mozilla/UniquePtr.h" namespace mozilla { namespace gl { diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 821a8729c66a..33a52807c081 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -22,6 +22,7 @@ #include "GLDefs.h" #include "mozilla/Attributes.h" #include "mozilla/gfx/Point.h" +#include "mozilla/UniquePtr.h" #include "mozilla/WeakPtr.h" #include "SurfaceTypes.h" diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp index d8727a61fe10..904a506d71f1 100644 --- a/gfx/gl/SharedSurfaceANGLE.cpp +++ b/gfx/gl/SharedSurfaceANGLE.cpp @@ -192,8 +192,9 @@ SharedSurface_ANGLEShareHandle::Create(GLContext* gl, } typedef SharedSurface_ANGLEShareHandle ptrT; - return UniquePtr( new ptrT(gl, egl, size, hasAlpha, context, - pbuffer, shareHandle) ); + UniquePtr ret( new ptrT(gl, egl, size, hasAlpha, context, + pbuffer, shareHandle) ); + return Move(ret); } /*static*/ UniquePtr @@ -204,14 +205,15 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, if (!egl) return nullptr; - if (!egl->IsExtensionSupported( - GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle)) + auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle; + if (!egl->IsExtensionSupported(ext)) { return nullptr; } typedef SurfaceFactory_ANGLEShareHandle ptrT; - return UniquePtr( new ptrT(gl, egl, caps) ); + UniquePtr ret( new ptrT(gl, egl, caps) ); + return Move(ret); } SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl, diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp index e34660924575..a16e4a7a0d09 100644 --- a/gfx/gl/SharedSurfaceEGL.cpp +++ b/gfx/gl/SharedSurfaceEGL.cpp @@ -27,14 +27,16 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, MOZ_ASSERT(egl); MOZ_ASSERT(context); + UniquePtr ret; + if (!HasExtensions(egl, prodGL)) { - return nullptr; + return Move(ret); } MOZ_ALWAYS_TRUE(prodGL->MakeCurrent()); GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size); if (!prodTex) { - return nullptr; + return Move(ret); } EGLClientBuffer buffer = reinterpret_cast(prodTex); @@ -43,12 +45,12 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, nullptr); if (!image) { prodGL->fDeleteTextures(1, &prodTex); - return nullptr; + return Move(ret); } - typedef SharedSurface_EGLImage ptrT; - return UniquePtr( new ptrT(prodGL, egl, size, hasAlpha, - formats, prodTex, image) ); + ret.reset( new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha, + formats, prodTex, image) ); + return Move(ret); } bool @@ -221,13 +223,15 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, { EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext(); + typedef SurfaceFactory_EGLImage ptrT; + UniquePtr ret; + GLLibraryEGL* egl = &sEGLLibrary; - if (!SharedSurface_EGLImage::HasExtensions(egl, prodGL)) { - return nullptr; + if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) { + ret.reset( new ptrT(prodGL, context, caps) ); } - typedef SurfaceFactory_EGLImage ptrT; - return UniquePtr( new ptrT(prodGL, context, caps) ); + return Move(ret); } } /* namespace gfx */ diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp index c68ab0c555be..dc5cc7011ad2 100644 --- a/gfx/gl/SharedSurfaceGL.cpp +++ b/gfx/gl/SharedSurfaceGL.cpp @@ -47,7 +47,8 @@ SharedSurface_Basic::Create(GLContext* gl, } typedef SharedSurface_Basic ptrT; - return UniquePtr( new ptrT(gl, size, hasAlpha, format, tex) ); + UniquePtr ret( new ptrT(gl, size, hasAlpha, format, tex) ); + return Move(ret); } SharedSurface_Basic::SharedSurface_Basic(GLContext* gl, @@ -128,8 +129,9 @@ SharedSurface_GLTexture::Create(GLContext* prodGL, } typedef SharedSurface_GLTexture ptrT; - return UniquePtr( new ptrT(prodGL, consGL, size, hasAlpha, - tex, ownsTex) ); + UniquePtr ret( new ptrT(prodGL, consGL, size, hasAlpha, tex, + ownsTex) ); + return Move(ret); } SharedSurface_GLTexture::~SharedSurface_GLTexture() diff --git a/gfx/gl/SharedSurfaceGralloc.cpp b/gfx/gl/SharedSurfaceGralloc.cpp index 56c6f5885f67..0ece2ab1dcf0 100644 --- a/gfx/gl/SharedSurfaceGralloc.cpp +++ b/gfx/gl/SharedSurfaceGralloc.cpp @@ -59,10 +59,12 @@ SharedSurface_Gralloc::Create(GLContext* prodGL, GLLibraryEGL* egl = &sEGLLibrary; MOZ_ASSERT(egl); + UniquePtr ret; + DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n"); if (!HasExtensions(egl, prodGL)) - return nullptr; + return Move(ret); gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA : gfxContentType::COLOR; @@ -78,7 +80,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL, layers::TextureFlags::DEFAULT); if (!grallocTC->AllocateForGLRendering(size)) { - return nullptr; + return Move(ret); } sp buffer = grallocTC->GetGraphicBuffer(); @@ -93,7 +95,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL, LOCAL_EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs); if (!image) { - return nullptr; + return Move(ret); } prodGL->MakeCurrent(); @@ -110,14 +112,15 @@ SharedSurface_Gralloc::Create(GLContext* prodGL, egl->fDestroyImage(display, image); + ret.reset( new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, + allocator, grallocTC, + prodTex) ); - typedef SharedSurface_Gralloc ptrT; - UniquePtr surf( new ptrT(prodGL, size, hasAlpha, egl, - allocator, grallocTC, prodTex) ); + DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p," + " GraphicBuffer %p.\n", + ret.get(), buffer.get()); - DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get()); - - return Move(surf); + return Move(ret); } diff --git a/gfx/gl/SharedSurfaceGralloc.h b/gfx/gl/SharedSurfaceGralloc.h index e7ac988e0735..e32b5e3e2420 100644 --- a/gfx/gl/SharedSurfaceGralloc.h +++ b/gfx/gl/SharedSurfaceGralloc.h @@ -86,10 +86,13 @@ public: virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; - if (!mAllocator) { - return nullptr; + + UniquePtr ret; + if (mAllocator) { + ret = SharedSurface_Gralloc::Create(mGL, mFormats, size, + hasAlpha, mAllocator); } - return SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha, mAllocator); + return Move(ret); } }; diff --git a/gfx/gl/SharedSurfaceIO.cpp b/gfx/gl/SharedSurfaceIO.cpp index a8c7184f9808..5a16c07ccc50 100644 --- a/gfx/gl/SharedSurfaceIO.cpp +++ b/gfx/gl/SharedSurfaceIO.cpp @@ -18,13 +18,14 @@ SharedSurface_IOSurface::Create(const RefPtr& ioSurf, GLContext* gl, bool hasAlpha) { - MOZ_ASSERT(surface); + MOZ_ASSERT(ioSurf); MOZ_ASSERT(gl); - gfx::IntSize size(surface->GetWidth(), surface->GetHeight()); + gfx::IntSize size(ioSurf->GetWidth(), ioSurf->GetHeight()); typedef SharedSurface_IOSurface ptrT; - return UniquePtr( new ptrT(ioSurf, gl, size, hasAlpha) ); + UniquePtr ret( new ptrT(ioSurf, gl, size, hasAlpha) ); + return Move(ret); } void @@ -107,7 +108,7 @@ SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr& ioS gl->MakeCurrent(); mProdTex = 0; gl->fGenTextures(1, &mProdTex); - BackTextureWithIOSurf(gl, mProdTex, surface); + BackTextureWithIOSurf(gl, mProdTex, mIOSurf); } GLuint @@ -149,7 +150,8 @@ SurfaceFactory_IOSurface::Create(GLContext* gl, MacIOSurface::GetMaxHeight()); typedef SurfaceFactory_IOSurface ptrT; - return UniquePtr( new ptrT(gl, caps, maxDims) ); + UniquePtr ret( new ptrT(gl, caps, maxDims) ); + return Move(ret); } UniquePtr @@ -166,7 +168,7 @@ SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size) ioSurf = MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha); - if (!surf) { + if (!ioSurf) { NS_WARNING("Failed to create MacIOSurface."); return nullptr; } diff --git a/gfx/gl/SharedSurfaceIO.h b/gfx/gl/SharedSurfaceIO.h index 288931bc0542..8dff33a397d9 100644 --- a/gfx/gl/SharedSurfaceIO.h +++ b/gfx/gl/SharedSurfaceIO.h @@ -17,7 +17,7 @@ namespace gl { class SharedSurface_IOSurface : public SharedSurface { public: - static UniquePtr Create(MacIOSurface* surface, + static UniquePtr Create(const RefPtr& ioSurf, GLContext* gl, bool hasAlpha); @@ -53,12 +53,13 @@ public: } MacIOSurface* GetIOSurface() const { - return mSurface; + return mIOSurf; } private: - SharedSurface_IOSurface(MacIOSurface* ioSurf, GLContext* gl, - const gfx::IntSize& size, bool hasAlpha); + SharedSurface_IOSurface(const RefPtr& ioSurf, + GLContext* gl, const gfx::IntSize& size, + bool hasAlpha); RefPtr mIOSurf; GLuint mProdTex; diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index 4c3042e6a06d..0d69c09356e3 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -12,6 +12,7 @@ #include "mozilla/Attributes.h" #include "mozilla/gfx/Point.h" #include "mozilla/GenericRefCounted.h" +#include "mozilla/UniquePtr.h" #include "SurfaceTypes.h" #include "SharedSurface.h" diff --git a/gfx/layers/client/ClientCanvasLayer.cpp b/gfx/layers/client/ClientCanvasLayer.cpp index 781d3160e3a5..c874f6f2980f 100644 --- a/gfx/layers/client/ClientCanvasLayer.cpp +++ b/gfx/layers/client/ClientCanvasLayer.cpp @@ -73,7 +73,7 @@ ClientCanvasLayer::Initialize(const Data& aData) SurfaceStreamType streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread, screen->PreserveBuffer()); - UniquePtr factory = nullptr; + UniquePtr factory; if (!gfxPrefs::WebGLForceLayersReadback()) { switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) { From 00cbda0f585b69bcf0450768ff2a4d564809b31f Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:08 -0700 Subject: [PATCH 028/101] Bug 1049957 - Use custom std::queue wrapper instead of std::queue>. - r=kamidphish --- gfx/gl/SharedSurface.cpp | 12 +++++------- gfx/gl/SharedSurface.h | 34 +++++++++++++++++++++++++++++++++- gfx/gl/SurfaceStream.cpp | 12 +++++------- gfx/gl/SurfaceStream.h | 2 +- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index 1f7a864a29d1..215ae8bf5a8d 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -268,9 +268,8 @@ SurfaceFactory::SurfaceFactory(GLContext* gl, SurfaceFactory::~SurfaceFactory() { - while (!mScraps.empty()) { - UniquePtr cur = Move(mScraps.front()); - mScraps.pop(); + while (!mScraps.Empty()) { + UniquePtr cur = mScraps.Pop(); } } @@ -278,9 +277,8 @@ UniquePtr SurfaceFactory::NewSharedSurface(const gfx::IntSize& size) { // Attempt to reuse an old surface. - while (!mScraps.empty()) { - UniquePtr cur = Move(mScraps.front()); - mScraps.pop(); + while (!mScraps.Empty()) { + UniquePtr cur = mScraps.Pop(); if (cur->mSize == size) return Move(cur); @@ -299,7 +297,7 @@ SurfaceFactory::Recycle(UniquePtr surf) MOZ_ASSERT(surf); if (surf->mType == mType) { - mScraps.push(Move(surf)); + mScraps.Push(Move(surf)); } } diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 33a52807c081..7f3611102826 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -114,6 +114,38 @@ public: } }; +template +class UniquePtrQueue +{ + std::queue mQueue; + +public: + ~UniquePtrQueue() { + MOZ_ASSERT(Empty()); + } + + bool Empty() const { + return mQueue.empty(); + } + + void Push(UniquePtr up) { + T* p = up.release(); + mQueue.push(p); + } + + UniquePtr Pop() { + UniquePtr ret; + if (mQueue.empty()) + return Move(ret); + + T* p = mQueue.front(); + mQueue.pop(); + + ret.reset(p); + return Move(ret); + } +}; + class SurfaceFactory { public: @@ -144,7 +176,7 @@ public: protected: virtual UniquePtr CreateShared(const gfx::IntSize& size) = 0; - std::queue< UniquePtr > mScraps; + UniquePtrQueue mScraps; public: UniquePtr NewSharedSurface(const gfx::IntSize& size); diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp index e293f731675f..dadeb660334a 100644 --- a/gfx/gl/SurfaceStream.cpp +++ b/gfx/gl/SurfaceStream.cpp @@ -185,7 +185,7 @@ SurfaceStream::Scrap(UniquePtr* surfSlot) UniquePtr& surf = *surfSlot; if (surf) { - mScraps.push(Move(surf)); + mScraps.Push(Move(surf)); surf = nullptr; } MOZ_ASSERT(!surf); @@ -195,9 +195,8 @@ SurfaceStream::Scrap(UniquePtr* surfSlot) void SurfaceStream::RecycleScraps(SurfaceFactory* factory) { - while (!mScraps.empty()) { - UniquePtr cur = Move(mScraps.top()); - mScraps.pop(); + while (!mScraps.Empty()) { + UniquePtr cur = mScraps.Pop(); Recycle(factory, &cur); } @@ -222,9 +221,8 @@ SurfaceStream::~SurfaceStream() { Delete(&mProducer); - while (!mScraps.empty()) { - UniquePtr cur = Move(mScraps.top()); - mScraps.pop(); + while (!mScraps.Empty()) { + UniquePtr cur = mScraps.Pop(); Delete(&cur); } diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index 0d69c09356e3..f443e1f1aacd 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -52,7 +52,7 @@ protected: #ifdef DEBUG std::set mSurfaces; #endif - std::stack< UniquePtr > mScraps; + UniquePtrQueue mScraps; mutable Monitor mMonitor; bool mIsAlive; From fb6a85846462e71a8400776f78ebcdd9ce1304ee Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 15 Aug 2014 17:38:09 -0700 Subject: [PATCH 029/101] Bug 1049957 - Fixes from reviews. - r=kamidphish --- gfx/gl/GLScreenBuffer.cpp | 2 +- gfx/gl/SharedSurface.cpp | 2 +- gfx/gl/SharedSurface.h | 11 +++++------ gfx/gl/SurfaceStream.cpp | 8 +++----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 1d1bf91f8c6d..de408f7180ea 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -652,7 +652,7 @@ ReadBuffer::Create(GLContext* gl, UniquePtr ret( new ReadBuffer(gl, fb, depthRB, stencilRB, surf) ); if (!gl->IsFramebufferComplete(fb)) { - ret = nullptr; + ret = nullptr; } return Move(ret); diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index 215ae8bf5a8d..42d83b9bc4b8 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -269,7 +269,7 @@ SurfaceFactory::SurfaceFactory(GLContext* gl, SurfaceFactory::~SurfaceFactory() { while (!mScraps.Empty()) { - UniquePtr cur = mScraps.Pop(); + mScraps.Pop(); } } diff --git a/gfx/gl/SharedSurface.h b/gfx/gl/SharedSurface.h index 7f3611102826..5c13c7f58a32 100644 --- a/gfx/gl/SharedSurface.h +++ b/gfx/gl/SharedSurface.h @@ -123,7 +123,7 @@ public: ~UniquePtrQueue() { MOZ_ASSERT(Empty()); } - + bool Empty() const { return mQueue.empty(); } @@ -135,13 +135,12 @@ public: UniquePtr Pop() { UniquePtr ret; - if (mQueue.empty()) - return Move(ret); - T* p = mQueue.front(); - mQueue.pop(); + if (!mQueue.empty()) { + ret.reset(mQueue.front()); + mQueue.pop(); + } - ret.reset(p); return Move(ret); } }; diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp index dadeb660334a..af2abf82356f 100644 --- a/gfx/gl/SurfaceStream.cpp +++ b/gfx/gl/SurfaceStream.cpp @@ -106,7 +106,7 @@ SurfaceStream::MoveTo(UniquePtr* slotFrom, MOZ_ASSERT(!to); to = Move(from); - from = nullptr; + MOZ_ASSERT(!from); } void @@ -120,7 +120,6 @@ SurfaceStream::Recycle(SurfaceFactory* factory, UniquePtr* surfSl mSurfaces.erase(surf.get()); #endif factory->Recycle(Move(surf)); - surf = nullptr; } MOZ_ASSERT(!surf); } @@ -153,7 +152,7 @@ SurfaceStream::Surrender(UniquePtr* surfSlot) #endif UniquePtr ret = Move(surf); - surf = nullptr; + MOZ_ASSERT(!surf); return Move(ret); } @@ -173,7 +172,7 @@ SurfaceStream::Absorb(UniquePtr* surfSlot) #endif UniquePtr ret = Move(surf); - surf = nullptr; + MOZ_ASSERT(!surf); return Move(ret); } @@ -186,7 +185,6 @@ SurfaceStream::Scrap(UniquePtr* surfSlot) if (surf) { mScraps.Push(Move(surf)); - surf = nullptr; } MOZ_ASSERT(!surf); From bdc41d899e92a6224077da5caf689ef14e1ca4c3 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Fri, 15 Aug 2014 21:55:24 -0400 Subject: [PATCH 030/101] bug 1032055 - fix ordering of static xul component constants with LTO r=glandium --- toolkit/library/StaticXULComponentsEnd/moz.build | 1 + toolkit/library/moz.build | 3 +++ 2 files changed, 4 insertions(+) diff --git a/toolkit/library/StaticXULComponentsEnd/moz.build b/toolkit/library/StaticXULComponentsEnd/moz.build index ed4291e5ed7f..0d432c343cd0 100644 --- a/toolkit/library/StaticXULComponentsEnd/moz.build +++ b/toolkit/library/StaticXULComponentsEnd/moz.build @@ -6,6 +6,7 @@ SOURCES += [ 'StaticXULComponentsEnd.cpp', ] +SOURCES['StaticXULComponentsEnd.cpp'].flags += ['-fno-lto'] LIBRARY_NAME = 'StaticXULComponentsEnd' DEFINES['MOZILLA_INTERNAL_API'] = True diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index 092b08649a7f..4454c934cd47 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -22,6 +22,9 @@ MSVC_ENABLE_PGO = True # it contains first in Windows PGO builds. SOURCES['StaticXULComponentsStart.cpp'].no_pgo = True +# Don't let LTO reorder this. +SOURCES['StaticXULComponentsStart.cpp'].flags += ['-fno-lto'] + if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'nsDllMain.cpp', From c33a664a92bb90eec90a02aafc8a6cf621421fc1 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 15 Aug 2014 23:14:30 -0400 Subject: [PATCH 031/101] Backed out changeset 3ad9f60f1972 (bug 1032055) for B2G ICS bustage. --- toolkit/library/StaticXULComponentsEnd/moz.build | 1 - toolkit/library/moz.build | 3 --- 2 files changed, 4 deletions(-) diff --git a/toolkit/library/StaticXULComponentsEnd/moz.build b/toolkit/library/StaticXULComponentsEnd/moz.build index 0d432c343cd0..ed4291e5ed7f 100644 --- a/toolkit/library/StaticXULComponentsEnd/moz.build +++ b/toolkit/library/StaticXULComponentsEnd/moz.build @@ -6,7 +6,6 @@ SOURCES += [ 'StaticXULComponentsEnd.cpp', ] -SOURCES['StaticXULComponentsEnd.cpp'].flags += ['-fno-lto'] LIBRARY_NAME = 'StaticXULComponentsEnd' DEFINES['MOZILLA_INTERNAL_API'] = True diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index 4454c934cd47..092b08649a7f 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -22,9 +22,6 @@ MSVC_ENABLE_PGO = True # it contains first in Windows PGO builds. SOURCES['StaticXULComponentsStart.cpp'].no_pgo = True -# Don't let LTO reorder this. -SOURCES['StaticXULComponentsStart.cpp'].flags += ['-fno-lto'] - if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'nsDllMain.cpp', From 171665617d546427cd1b48a4f90ee13f6f1e19b4 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 15 Aug 2014 20:22:09 -0700 Subject: [PATCH 032/101] Bug 1054563: Remove unnecessary nsresult return value from BuildScrollFrame, and de-indent it. r=tn --- layout/base/nsCSSFrameConstructor.cpp | 17 ++++++++--------- layout/base/nsCSSFrameConstructor.h | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index bdc9a4f18b89..33ab80c65761 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -4470,7 +4470,7 @@ nsCSSFrameConstructor::FinishBuildingScrollFrame(nsContainerFrame* aScrollFrame, * If this is not null, we'll just use it * @param aScrolledContentStyle the style that was resolved for the scrolled frame. (returned) */ -nsresult +void nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState, nsIContent* aContent, nsStyleContext* aContentStyle, @@ -4478,16 +4478,15 @@ nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState, nsContainerFrame* aParentFrame, nsContainerFrame*& aNewFrame) { - nsRefPtr scrolledContentStyle = - BeginBuildingScrollFrame(aState, aContent, aContentStyle, aParentFrame, - nsCSSAnonBoxes::scrolledContent, - false, aNewFrame); + nsRefPtr scrolledContentStyle = + BeginBuildingScrollFrame(aState, aContent, aContentStyle, aParentFrame, + nsCSSAnonBoxes::scrolledContent, + false, aNewFrame); - aScrolledFrame->SetStyleContextWithoutNotification(scrolledContentStyle); - InitAndRestoreFrame(aState, aContent, aNewFrame, aScrolledFrame); + aScrolledFrame->SetStyleContextWithoutNotification(scrolledContentStyle); + InitAndRestoreFrame(aState, aContent, aNewFrame, aScrolledFrame); - FinishBuildingScrollFrame(aNewFrame, aScrolledFrame); - return NS_OK; + FinishBuildingScrollFrame(aNewFrame, aScrolledFrame); } const nsCSSFrameConstructor::FrameConstructionData* diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 0e1b0edc3486..1c2d42038372 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1425,7 +1425,7 @@ private: // Calls BeginBuildingScrollFrame, InitAndRestoreFrame, and then FinishBuildingScrollFrame. // @param aNewFrame the created scrollframe --- output only // @param aParentFrame the geometric parent that the scrollframe will have. - nsresult + void BuildScrollFrame(nsFrameConstructorState& aState, nsIContent* aContent, nsStyleContext* aContentStyle, From c39cb67ced299cfab10302a250187203040ce0bd Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:23 +1200 Subject: [PATCH 033/101] Bug 1048752. Part 1: Remove GetCaretReadOnly (unused). r=tn --HG-- extra : rebase_source : 86c27ad506440199fe623a083a2b4cb7eca98e47 --- layout/base/nsCaret.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index b1b904fd070f..e08fb9f8cb70 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -62,15 +62,6 @@ class nsCaret : public nsISelectionListener */ void SetCaretReadOnly(bool inMakeReadonly); - /** GetCaretReadOnly get the appearance of the caret - * @return true if the caret is in 'read only' state, otherwise, - * returns false - */ - bool GetCaretReadOnly() - { - return mReadOnly; - } - /** * Gets the position and size of the caret that would be drawn for * the focus node/offset of aSelection (assuming it would be drawn, From d085b972a2ff09ab44652832335b98c5baead006 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:23 +1200 Subject: [PATCH 034/101] Bug 1048752. Part 2: Remove InvalidateOutsideCaret and MaybeInvalidateCaretPosition. r=tn I'm quite sure DLBI means we don't need these anymore. --HG-- extra : rebase_source : 6cb6cd7c160a46688793c6ab1cdded333aecdd61 --- editor/libeditor/text/nsPlaintextEditor.cpp | 6 --- layout/base/nsCaret.cpp | 10 ----- layout/base/nsCaret.h | 7 ---- layout/base/nsIPresShell.h | 12 +----- layout/base/nsPresShell.cpp | 44 --------------------- layout/base/nsPresShell.h | 2 - 6 files changed, 2 insertions(+), 79 deletions(-) diff --git a/editor/libeditor/text/nsPlaintextEditor.cpp b/editor/libeditor/text/nsPlaintextEditor.cpp index ed113b555323..0365649b81fb 100644 --- a/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/editor/libeditor/text/nsPlaintextEditor.cpp @@ -762,12 +762,6 @@ NS_IMETHODIMP nsPlaintextEditor::InsertLineBreak() nsRefPtr selection = GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - // Batching the selection and moving nodes out from under the caret causes - // caret turds. Ask the shell to invalidate the caret now to avoid the turds. - nsCOMPtr shell = GetPresShell(); - NS_ENSURE_TRUE(shell, NS_ERROR_NOT_INITIALIZED); - shell->MaybeInvalidateCaretPosition(); - nsTextRulesInfo ruleInfo(EditAction::insertBreak); ruleInfo.maxLength = mMaxTextLength; bool cancel, handled; diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 24e8d53bb573..24fa95edc7e7 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -457,16 +457,6 @@ nsIFrame * nsCaret::GetCaretFrame(int32_t *aOffset) return frame; } -void nsCaret::InvalidateOutsideCaret() -{ - nsIFrame *frame = GetCaretFrame(); - - // Only invalidate if we are not fully contained by our frame's rect. - if (frame && !frame->GetVisualOverflowRect().Contains(GetCaretRect())) { - frame->SchedulePaint(); - } -} - void nsCaret::UpdateCaretPosition() { // We'll recalculate anyway if we're not drawn right now. diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index e08fb9f8cb70..8d9c59bd864c 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -111,13 +111,6 @@ class nsCaret : public nsISelectionListener return r; } - /** InvalidateOutsideCaret - * Invalidate the area that the caret currently occupies if the caret is - * outside of its frame's overflow area. This is used when the content that - * the caret is currently drawn is is being deleted or reflowed. - */ - void InvalidateOutsideCaret(); - /** UpdateCaretPosition * Update the caret's current frame and rect, but don't draw yet. This is * useful for flickerless moving of the caret (e.g., when the frame the diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 10df929885f3..23fc0a818dcc 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -137,10 +137,9 @@ typedef struct CapturingContentInfo { nsIContent* mContent; } CapturingContentInfo; -//a4e5ff3a-dc5c-4b3a-a625-d164a9e50619 #define NS_IPRESSHELL_IID \ -{ 0xa4e5ff3a, 0xdc5c, 0x4b3a, \ - {0xa6, 0x25, 0xd1, 0x64, 0xa9, 0xe5, 0x06, 0x19}} + { 0x42e9a352, 0x76f3, 0x4ba3, \ + { 0x94, 0x0b, 0x78, 0x9e, 0x58, 0x38, 0x73, 0x4f } } // debug VerifyReflow flags #define VERIFY_REFLOW_ON 0x01 @@ -789,13 +788,6 @@ public: */ virtual already_AddRefed GetCaret() const = 0; - /** - * Invalidate the caret's current position if it's outside of its frame's - * boundaries. This function is useful if you're batching selection - * notifications and might remove the caret's frame out from under it. - */ - virtual void MaybeInvalidateCaretPosition() = 0; - /** * Set the current caret to a new caret. To undo this, call RestoreCaret. */ diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 03610aad425f..d5eb5043edbc 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2209,13 +2209,6 @@ already_AddRefed PresShell::GetSelectionCarets() const return selectionCaret.forget(); } -void PresShell::MaybeInvalidateCaretPosition() -{ - if (mCaret) { - mCaret->InvalidateOutsideCaret(); - } -} - void PresShell::SetCaret(nsCaret *aNewCaret) { mCaret = aNewCaret; @@ -4287,29 +4280,6 @@ PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush) } } -void -PresShell::CharacterDataWillChange(nsIDocument *aDocument, - nsIContent* aContent, - CharacterDataChangeInfo* aInfo) -{ - NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged"); - NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); - - if (mCaret) { - // Invalidate the caret's current location before we call into the frame - // constructor. It is important to do this now, and not wait until the - // resulting reflow, because this call causes continuation frames of the - // text frame the caret is in to forget what part of the content they - // refer to, making it hard for them to return the correct continuation - // frame to the caret. - // - // It's also important to do this before the content actually changes, since - // in bidi text the caret needs to look at the content to determine its - // position and shape. - mCaret->InvalidateOutsideCaret(); - } -} - void PresShell::CharacterDataChanged(nsIDocument *aDocument, nsIContent* aContent, @@ -4504,11 +4474,6 @@ PresShell::ContentRemoved(nsIDocument *aDocument, NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentRemoved"); NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); - // Make sure that the caret doesn't leave a turd where the child used to be. - if (mCaret) { - mCaret->InvalidateOutsideCaret(); - } - // Notify the ESM that the content has been removed, so that // it can clean up any state related to the content. @@ -8633,12 +8598,6 @@ PresShell::DidCauseReflow() void PresShell::WillDoReflow() { - // We just reflowed, tell the caret that its frame might have moved. - // XXXbz that comment makes no sense - if (mCaret) { - mCaret->InvalidateOutsideCaret(); - } - mPresContext->FlushUserFontSet(); mPresContext->FlushCounterStyles(); @@ -8666,9 +8625,6 @@ PresShell::DidDoReflow(bool aInterruptible, bool aWasInterrupted) } if (mCaret) { - // Update the caret's position now to account for any changes created by - // the reflow. - mCaret->InvalidateOutsideCaret(); mCaret->UpdateCaretPosition(); } diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 87cd5a537a17..d73339bd4def 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -229,7 +229,6 @@ public: virtual mozilla::dom::Element* GetSelectionCaretsEndElement() const MOZ_OVERRIDE; // caret handling virtual already_AddRefed GetCaret() const MOZ_OVERRIDE; - virtual void MaybeInvalidateCaretPosition() MOZ_OVERRIDE; NS_IMETHOD SetCaretEnabled(bool aInEnable) MOZ_OVERRIDE; NS_IMETHOD SetCaretReadOnly(bool aReadOnly) MOZ_OVERRIDE; NS_IMETHOD GetCaretEnabled(bool *aOutEnabled) MOZ_OVERRIDE; @@ -276,7 +275,6 @@ public: NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED // nsIMutationObserver - NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED From 787f2f51a51c69ed8983d0218deca0d170f53028 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:24 +1200 Subject: [PATCH 035/101] Bug 1048752. Part 3: Make GetCaretFrameForNodeOffset static. r=tn GetCaretFrameForNodeOffset only uses the nsFrameSelection and mBidiUI from its nsCaret. For mBidiUI we can just get the pref directly whenever we need it. By modifying GetCaretFrameForNodeOffset to take nsFrameSelection as a parameter, we can make it static to make it clear it isn't really related to the state of the nsCaret. This may also fix a bug in Selection::GetPrimaryFrameForFocusNode where things would go unexpectedly wrong if mCaret is temporarily observing a different selection to the Selection. --HG-- extra : rebase_source : cdd59f6e20cd1060bc5d2325cb3adb5e5c4a1d2c --- layout/base/nsCaret.cpp | 64 ++++++++++++++++++++-------------- layout/base/nsCaret.h | 14 ++++---- layout/generic/nsSelection.cpp | 12 ++----- 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 24fa95edc7e7..1685ccd9ec74 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -176,7 +176,6 @@ nsresult nsCaret::Init(nsIPresShell *inPresShell) { StartBlinking(); } - mBidiUI = Preferences::GetBool("bidi.browser.ui"); return NS_OK; } @@ -369,7 +368,7 @@ nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect, uint8_t bidiLevel = frameSelection->GetCaretBidiLevel(); nsIFrame* frame; int32_t frameOffset; - rv = GetCaretFrameForNodeOffset(contentNode, focusOffset, + rv = GetCaretFrameForNodeOffset(frameSelection, contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, &frame, &frameOffset); if (NS_FAILED(rv) || !frame) @@ -441,11 +440,16 @@ nsIFrame * nsCaret::GetCaretFrame(int32_t *aOffset) if (!mDrawn) return nullptr; + nsRefPtr frameSelection = GetFrameSelection(); + if (!frameSelection) + return nullptr; + // Recompute the frame that we're supposed to draw in to guarantee that // we're not going to try to draw into a stale (dead) frame. int32_t offset; nsIFrame *frame = nullptr; - nsresult rv = GetCaretFrameForNodeOffset(mLastContent, mLastContentOffset, + nsresult rv = GetCaretFrameForNodeOffset(frameSelection, + mLastContent, mLastContentOffset, mLastHint, mLastBidiLevel, &frame, &offset); if (NS_FAILED(rv)) @@ -607,11 +611,16 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNode* aNode, if (!contentNode) return false; + nsRefPtr frameSelection = GetFrameSelection(); + if (!frameSelection) + return nullptr; + nsIFrame* theFrame = nullptr; int32_t theFrameOffset = 0; - nsresult rv = GetCaretFrameForNodeOffset(contentNode, aOffset, aFrameHint, aBidiLevel, - &theFrame, &theFrameOffset); + nsresult rv = + GetCaretFrameForNodeOffset(frameSelection, contentNode, aOffset, aFrameHint, + aBidiLevel, &theFrame, &theFrameOffset); if (NS_FAILED(rv) || !theFrame) return false; @@ -652,17 +661,24 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNode* aNode, return true; } -nsresult -nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, - int32_t aOffset, - nsFrameSelection::HINT aFrameHint, - uint8_t aBidiLevel, - nsIFrame** aReturnFrame, - int32_t* aReturnOffset) +static bool +IsBidiUI() { + return Preferences::GetBool("bidi.browser.ui"); +} - //get frame selection and find out what frame to use... - nsCOMPtr presShell = do_QueryReferent(mPresShell); +nsresult +nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection, + nsIContent* aContentNode, + int32_t aOffset, + nsFrameSelection::HINT aFrameHint, + uint8_t aBidiLevel, + nsIFrame** aReturnFrame, + int32_t* aReturnOffset) +{ + if (!aFrameSelection) + return NS_ERROR_FAILURE; + nsIPresShell* presShell = aFrameSelection->GetShell(); if (!presShell) return NS_ERROR_FAILURE; @@ -670,15 +686,11 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, presShell->GetDocument() != aContentNode->GetComposedDoc()) return NS_ERROR_FAILURE; - nsRefPtr frameSelection = GetFrameSelection(); - if (!frameSelection) - return NS_ERROR_FAILURE; - nsIFrame* theFrame = nullptr; int32_t theFrameOffset = 0; - theFrame = frameSelection->GetFrameForNodeOffset(aContentNode, aOffset, - aFrameHint, &theFrameOffset); + theFrame = aFrameSelection->GetFrameForNodeOffset( + aContentNode, aOffset, aFrameHint, &theFrameOffset); if (!theFrame) return NS_ERROR_FAILURE; @@ -695,7 +707,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, // NS_STYLE_DIRECTION_LTR : LTR or Default // NS_STYLE_DIRECTION_RTL // NS_STYLE_DIRECTION_INHERIT - if (mBidiUI) + if (IsBidiUI()) { // If there has been a reflow, take the caret Bidi level to be the level of the current frame if (aBidiLevel & BIDI_LEVEL_UNDEFINED) @@ -711,7 +723,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, theFrame->GetOffsets(start, end); if (start == 0 || end == 0 || start == theFrameOffset || end == theFrameOffset) { - nsPrevNextBidiLevels levels = frameSelection-> + nsPrevNextBidiLevels levels = aFrameSelection-> GetPrevNextBidiLevels(aContentNode, aOffset, false); /* Boundary condition, we need to know the Bidi levels of the characters before and after the caret */ @@ -791,7 +803,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, && !((levelBefore ^ levelAfter) & 1) // before and after have the same parity && ((aBidiLevel ^ levelAfter) & 1)) // caret has different parity { - if (NS_SUCCEEDED(frameSelection->GetFrameFromLevel(frameAfter, eDirNext, aBidiLevel, &theFrame))) + if (NS_SUCCEEDED(aFrameSelection->GetFrameFromLevel(frameAfter, eDirNext, aBidiLevel, &theFrame))) { theFrame->GetOffsets(start, end); levelAfter = NS_GET_EMBEDDING_LEVEL(theFrame); @@ -805,7 +817,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, && !((levelBefore ^ levelAfter) & 1) // before and after have the same parity && ((aBidiLevel ^ levelAfter) & 1)) // caret has different parity { - if (NS_SUCCEEDED(frameSelection->GetFrameFromLevel(frameBefore, eDirPrevious, aBidiLevel, &theFrame))) + if (NS_SUCCEEDED(aFrameSelection->GetFrameFromLevel(frameBefore, eDirPrevious, aBidiLevel, &theFrame))) { theFrame->GetOffsets(start, end); levelBefore = NS_GET_EMBEDDING_LEVEL(theFrame); @@ -820,8 +832,6 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, } } - NS_ASSERTION(!theFrame || theFrame->PresContext()->PresShell() == presShell, - "caret frame is in wrong document"); *aReturnFrame = theFrame; *aReturnOffset = theFrameOffset; return NS_OK; @@ -1051,7 +1061,7 @@ nsCaret::UpdateCaretRects(nsIFrame* aFrame, int32_t aFrameOffset) // keyboard direction, or the user has no right-to-left keyboard // installed, so we never draw the hook. if (bidiKeyboard && NS_SUCCEEDED(bidiKeyboard->IsLangRTL(&isCaretRTL)) && - mBidiUI) { + IsBidiUI()) { if (isCaretRTL != mKeyboardRTL) { /* if the caret bidi level and the keyboard language direction are not in * synch, the keyboard language must have been changed by the diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 8d9c59bd864c..a8f626dd4e8c 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -141,12 +141,13 @@ class nsCaret : public nsISelectionListener static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); - nsresult GetCaretFrameForNodeOffset(nsIContent* aContentNode, - int32_t aOffset, - nsFrameSelection::HINT aFrameHint, - uint8_t aBidiLevel, - nsIFrame** aReturnFrame, - int32_t* aReturnOffset); + static nsresult GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection, + nsIContent* aContentNode, + int32_t aOffset, + nsFrameSelection::HINT aFrameHint, + uint8_t aBidiLevel, + nsIFrame** aReturnFrame, + int32_t* aReturnOffset); void CheckCaretDrawingState(); @@ -228,7 +229,6 @@ protected: bool mIgnoreUserModify; bool mKeyboardRTL; // is the keyboard language right-to-left - bool mBidiUI; // is bidi UI turned on nsRect mHookRect; // directional hook on the caret uint8_t mLastBidiLevel; // saved bidi level of the last draw request, to use when we erase nsRect mCaretRect; // the last caret rect, in the coodinates of the last frame. diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 68411fd38a5f..869ea94725e1 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -3923,18 +3923,10 @@ Selection::GetPrimaryFrameForFocusNode(nsIFrame** aReturnFrame, nsFrameSelection::HINT hint = mFrameSelection->GetHint(); if (aVisual) { - nsIPresShell *presShell = mFrameSelection->GetShell(); - if (!presShell) - return NS_ERROR_FAILURE; - - nsRefPtr caret = presShell->GetCaret(); - if (!caret) - return NS_ERROR_FAILURE; - uint8_t caretBidiLevel = mFrameSelection->GetCaretBidiLevel(); - return caret->GetCaretFrameForNodeOffset(content, FocusOffset(), - hint, caretBidiLevel, aReturnFrame, aOffsetUsed); + return nsCaret::GetCaretFrameForNodeOffset(mFrameSelection, + content, FocusOffset(), hint, caretBidiLevel, aReturnFrame, aOffsetUsed); } *aReturnFrame = mFrameSelection-> From 82492566631682a7411af454379e61e9404f9f04 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:24 +1200 Subject: [PATCH 036/101] Bug 1048752. Part 4: Make EViewCoordinates (unused). r=tn --HG-- extra : rebase_source : 571ba155fb5741fdd26d0391ef4a029a7383b34a --- layout/base/nsCaret.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index a8f626dd4e8c..2904012888f4 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -29,12 +29,6 @@ class nsCaret : public nsISelectionListener virtual ~nsCaret(); public: - enum EViewCoordinates { - eTopLevelWindowCoordinates, - eRenderingViewCoordinates, - eClosestViewCoordinates - }; - NS_DECL_ISUPPORTS nsresult Init(nsIPresShell *inPresShell); From d967df6e74d57e95e8d6e76beb3b2db6d9936efb Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:24 +1200 Subject: [PATCH 037/101] Bug 1048752. Part 5: Reorder API declarations. r=tn To make it more clear what's going on, make CaretBlinkCallback protected and reorder the public methods to put the state-changing "API" methods first. --HG-- extra : rebase_source : fddf0ea4b9269b2d431d0b75c40f99a9140138a1 --- layout/base/nsCaret.h | 111 ++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 2904012888f4..da73dcb598a1 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -31,30 +31,62 @@ class nsCaret : public nsISelectionListener public: NS_DECL_ISUPPORTS - nsresult Init(nsIPresShell *inPresShell); - void Terminate(); - - nsISelection* GetCaretDOMSelection(); - nsresult SetCaretDOMSelection(nsISelection *inDOMSel); + nsresult Init(nsIPresShell *inPresShell); + void Terminate(); + nsresult SetCaretDOMSelection(nsISelection *inDOMSel); + nsISelection* GetCaretDOMSelection(); + /** + * Sets whether the caret should only be visible in nodes that are not + * user-modify: read-only, or whether it should be visible in all nodes. + * + * @param aIgnoreUserModify true to have the cursor visible in all nodes, + * false to have it visible in all nodes except + * those with user-modify: read-only + */ + void SetIgnoreUserModify(bool aIgnoreUserModify); + void CheckCaretDrawingState(); + /** SetCaretVisible will set the visibility of the caret + * @param inMakeVisible true to show the caret, false to hide it + */ + void SetCaretVisible(bool intMakeVisible); /** GetCaretVisible will get the visibility of the caret * This function is virtual so that it can be used by nsCaretAccessible * without linking * @param outMakeVisible true if it is shown, false if it is hidden * @return NS_OK */ - virtual nsresult GetCaretVisible(bool *outMakeVisible); - - /** SetCaretVisible will set the visibility of the caret - * @param inMakeVisible true to show the caret, false to hide it - */ - void SetCaretVisible(bool intMakeVisible); - + virtual nsresult GetCaretVisible(bool *outMakeVisible); /** SetCaretReadOnly set the appearance of the caret * @param inMakeReadonly true to show the caret in a 'read only' state, * false to show the caret in normal, editing state */ - void SetCaretReadOnly(bool inMakeReadonly); + void SetCaretReadOnly(bool inMakeReadonly); + /** + * @param aVisibility true if the caret should be visible even when the + * selection is not collapsed. + */ + void SetVisibilityDuringSelection(bool aVisibility); + + /** EraseCaret + * this will erase the caret if its drawn and reset drawn status + */ + void EraseCaret(); + /** UpdateCaretPosition + * Update the caret's current frame and rect, but don't draw yet. This is + * useful for flickerless moving of the caret (e.g., when the frame the + * caret is in reflows and is moved). + */ + void UpdateCaretPosition(); + /** DrawAtPosition + * + * Draw the caret explicitly, at the specified node and offset. + * To avoid drawing glitches, you should call EraseCaret() + * after each call to DrawAtPosition(). + * + * Note: This call breaks the caret's ability to blink at all. + **/ + nsresult DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset); /** * Gets the position and size of the caret that would be drawn for @@ -67,24 +99,6 @@ class nsCaret : public nsISelectionListener virtual nsIFrame* GetGeometry(nsISelection* aSelection, nsRect* aRect, nscoord* aBidiIndicatorSize = nullptr); - - /** EraseCaret - * this will erase the caret if its drawn and reset drawn status - */ - void EraseCaret(); - - void SetVisibilityDuringSelection(bool aVisibility); - - /** DrawAtPosition - * - * Draw the caret explicitly, at the specified node and offset. - * To avoid drawing glitches, you should call EraseCaret() - * after each call to DrawAtPosition(). - * - * Note: This call breaks the caret's ability to blink at all. - **/ - nsresult DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset); - /** GetCaretFrame * Get the current frame that the caret should be drawn in. If the caret is * not currently visible (i.e., it is between blinks), then this will @@ -92,49 +106,29 @@ class nsCaret : public nsISelectionListener * * @param aOffset is result of the caret offset in the content. */ - nsIFrame* GetCaretFrame(int32_t *aOffset = nullptr); - + nsIFrame* GetCaretFrame(int32_t *aOffset = nullptr); /** GetCaretRect * Get the current caret rect. Only call this when GetCaretFrame returns * non-null. */ - nsRect GetCaretRect() + nsRect GetCaretRect() { nsRect r; r.UnionRect(mCaretRect, GetHookRect()); return r; } - /** UpdateCaretPosition - * Update the caret's current frame and rect, but don't draw yet. This is - * useful for flickerless moving of the caret (e.g., when the frame the - * caret is in reflows and is moved). - */ - void UpdateCaretPosition(); - /** PaintCaret * Actually paint the caret onto the given rendering context. */ - void PaintCaret(nsDisplayListBuilder *aBuilder, - nsRenderingContext *aCtx, - nsIFrame *aForFrame, - const nsPoint &aOffset); - /** - * Sets whether the caret should only be visible in nodes that are not - * user-modify: read-only, or whether it should be visible in all nodes. - * - * @param aIgnoreUserModify true to have the cursor visible in all nodes, - * false to have it visible in all nodes except - * those with user-modify: read-only - */ - - void SetIgnoreUserModify(bool aIgnoreUserModify); + void PaintCaret(nsDisplayListBuilder *aBuilder, + nsRenderingContext *aCtx, + nsIFrame *aForFrame, + const nsPoint &aOffset); //nsISelectionListener interface NS_DECL_NSISELECTIONLISTENER - static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); - static nsresult GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection, nsIContent* aContentNode, int32_t aOffset, @@ -143,11 +137,10 @@ class nsCaret : public nsISelectionListener nsIFrame** aReturnFrame, int32_t* aReturnOffset); - void CheckCaretDrawingState(); - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; protected: + static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); void KillTimer(); nsresult PrimeTimer(); From 3b04ddd57df535cdee6726d6a3d69ac9d5e17508 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:24 +1200 Subject: [PATCH 038/101] Bug 1048752. Part 6: Remove 'virtual' declarations. r=tn These used to be needed for linking with non-libxul builds, but are no longer needed. The obsolete comment is fixed in a later patch. --HG-- extra : rebase_source : 034f69b647bd64d4353e51a15e166094b7b2e638 --- layout/base/nsCaret.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index da73dcb598a1..9be1821ba5c9 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -56,7 +56,7 @@ class nsCaret : public nsISelectionListener * @param outMakeVisible true if it is shown, false if it is hidden * @return NS_OK */ - virtual nsresult GetCaretVisible(bool *outMakeVisible); + nsresult GetCaretVisible(bool *outMakeVisible); /** SetCaretReadOnly set the appearance of the caret * @param inMakeReadonly true to show the caret in a 'read only' state, * false to show the caret in normal, editing state @@ -96,9 +96,9 @@ class nsCaret : public nsISelectionListener * @param aRect must be non-null * @param aBidiIndicatorSize if non-null, set to the bidi indicator size. */ - virtual nsIFrame* GetGeometry(nsISelection* aSelection, - nsRect* aRect, - nscoord* aBidiIndicatorSize = nullptr); + nsIFrame* GetGeometry(nsISelection* aSelection, + nsRect* aRect, + nscoord* aBidiIndicatorSize = nullptr); /** GetCaretFrame * Get the current frame that the caret should be drawn in. If the caret is * not currently visible (i.e., it is between blinks), then this will From fb59918a6c01ad7afcdf55ae79b17e2ce8d66b8e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:25 +1200 Subject: [PATCH 039/101] Bug 1048752. Part 7: Remove mCaretWidthCSSPx. r=tn mCaretWidthCSSPx doesn't need to be stored. We can just recompute it whenever we need it. --HG-- extra : rebase_source : 850b556651afade0da543e281e5fa54235969ab4 --- layout/base/nsCaret.cpp | 4 ++-- layout/base/nsCaret.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 1685ccd9ec74..39dec45a9b03 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -141,7 +141,6 @@ nsresult nsCaret::Init(nsIPresShell *inPresShell) // XXX we should just do this LookAndFeel consultation every time // we need these values. - mCaretWidthCSSPx = LookAndFeel::GetInt(LookAndFeel::eIntID_CaretWidth, 1); mCaretAspectRatio = LookAndFeel::GetFloat(LookAndFeel::eFloatID_CaretAspectRatio, 0.0f); @@ -197,7 +196,8 @@ nsCaret::Metrics nsCaret::ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nsco { // Compute nominal sizes in appunits nscoord caretWidth = (aCaretHeight * mCaretAspectRatio) + - nsPresContext::CSSPixelsToAppUnits(mCaretWidthCSSPx); + nsPresContext::CSSPixelsToAppUnits( + LookAndFeel::GetInt(LookAndFeel::eIntID_CaretWidth, 1)); if (DrawCJKCaret(aFrame, aOffset)) { caretWidth += nsPresContext::CSSPixelsToAppUnits(1); diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 9be1821ba5c9..5cd397bf2684 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -202,7 +202,6 @@ protected: // XXX these fields should go away and the values be acquired as needed, // probably by ComputeMetrics. uint32_t mBlinkRate; // time for one cyle (on then off), in milliseconds - nscoord mCaretWidthCSSPx; // caret width in CSS pixels float mCaretAspectRatio; // caret width/height aspect ratio bool mVisible; // is the caret blinking From 84b6888d629ad6c025e192ec81f34e130b4bd0ca Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:25 +1200 Subject: [PATCH 040/101] Bug 1048752. Part 8: Remove mCaretAspectRatio. r=tn mCaretAspectRatio doesn't need to be stored. We can recompute it whenever we need it. --HG-- extra : rebase_source : 065a6996e920800edf5cbcc7f072f0439ef84553 --- layout/base/nsCaret.cpp | 8 ++------ layout/base/nsCaret.h | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 39dec45a9b03..a5c9c3bd3702 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -139,11 +139,6 @@ nsresult nsCaret::Init(nsIPresShell *inPresShell) mPresShell = do_GetWeakReference(inPresShell); // the presshell owns us, so no addref NS_ASSERTION(mPresShell, "Hey, pres shell should support weak refs"); - // XXX we should just do this LookAndFeel consultation every time - // we need these values. - mCaretAspectRatio = - LookAndFeel::GetFloat(LookAndFeel::eFloatID_CaretAspectRatio, 0.0f); - mBlinkRate = static_cast( LookAndFeel::GetInt(LookAndFeel::eIntID_CaretBlinkTime, mBlinkRate)); mShowDuringSelection = @@ -195,7 +190,8 @@ DrawCJKCaret(nsIFrame* aFrame, int32_t aOffset) nsCaret::Metrics nsCaret::ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight) { // Compute nominal sizes in appunits - nscoord caretWidth = (aCaretHeight * mCaretAspectRatio) + + nscoord caretWidth = + (aCaretHeight * LookAndFeel::GetFloat(LookAndFeel::eFloatID_CaretAspectRatio, 0.0f)) + nsPresContext::CSSPixelsToAppUnits( LookAndFeel::GetInt(LookAndFeel::eIntID_CaretWidth, 1)); diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 5cd397bf2684..759c9fc81dd4 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -202,7 +202,6 @@ protected: // XXX these fields should go away and the values be acquired as needed, // probably by ComputeMetrics. uint32_t mBlinkRate; // time for one cyle (on then off), in milliseconds - float mCaretAspectRatio; // caret width/height aspect ratio bool mVisible; // is the caret blinking From b8bd1730f32388f36c8a6c838ec17812f166f475 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:25 +1200 Subject: [PATCH 041/101] Bug 1048752. Part 9: Remove nsCaret.h from nsDisplayList.h. r=tn I got tired of slow build turnarounds every time I modified nsCaret.h. --HG-- extra : rebase_source : 0c4598c4881ab8de0a636b08c70fb801bb912247 --- dom/base/nsGlobalWindow.cpp | 1 + layout/base/TouchCaret.cpp | 4 +++- layout/base/TouchCaret.h | 3 +++ layout/base/nsDisplayList.cpp | 24 ++++++++++++++++++++++ layout/base/nsDisplayList.h | 17 ++++----------- layout/build/nsLayoutStatics.cpp | 1 + layout/forms/nsFormControlFrame.cpp | 2 ++ layout/generic/nsImageFrame.cpp | 15 ++++++++++++++ layout/generic/nsImageFrame.h | 10 ++------- layout/generic/nsTextFrame.h | 2 ++ layout/tables/BasicTableLayoutStrategy.cpp | 5 ++++- 11 files changed, 61 insertions(+), 23 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 62cfef6397a7..cea15c8e38b6 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -39,6 +39,7 @@ #include "nsISlowScriptDebug.h" #include "nsWindowMemoryReporter.h" #include "WindowNamedPropertiesHandler.h" +#include "nsFrameSelection.h" // Helper Classes #include "nsJSUtils.h" diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index efe87aecdd6a..0a9ad432cf3b 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -6,6 +6,8 @@ #include "TouchCaret.h" +#include + #include "nsCOMPtr.h" #include "nsFrameSelection.h" #include "nsIFrame.h" @@ -27,7 +29,7 @@ #include "nsIInterfaceRequestorUtils.h" #include "nsView.h" #include "nsDOMTokenList.h" -#include +#include "nsCaret.h" using namespace mozilla; diff --git a/layout/base/TouchCaret.h b/layout/base/TouchCaret.h index 36baeb54d891..0474041c5a67 100644 --- a/layout/base/TouchCaret.h +++ b/layout/base/TouchCaret.h @@ -16,6 +16,9 @@ #include "mozilla/TouchEvents.h" #include "Units.h" +class nsIFrame; +class nsIPresShell; + namespace mozilla { /** diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 2b27ca8affbd..271918fd12fc 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2724,6 +2724,30 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder, } } +nsDisplayCaret::nsDisplayCaret(nsDisplayListBuilder* aBuilder, + nsIFrame* aCaretFrame, + nsCaret *aCaret) + : nsDisplayItem(aBuilder, aCaretFrame) + , mCaret(aCaret) +{ + MOZ_COUNT_CTOR(nsDisplayCaret); +} + +#ifdef NS_BUILD_REFCNT_LOGGING +nsDisplayCaret::~nsDisplayCaret() +{ + MOZ_COUNT_DTOR(nsDisplayCaret); +} +#endif + +nsRect +nsDisplayCaret::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) +{ + *aSnap = false; + // The caret returns a rect in the coordinates of mFrame. + return mCaret->GetCaretRect() + ToReferenceFrame(); +} + void nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 9914e4fa08ca..d8072b72bd86 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -18,7 +18,6 @@ #include "nsContainerFrame.h" #include "nsPoint.h" #include "nsRect.h" -#include "nsCaret.h" #include "plarena.h" #include "nsRegion.h" #include "FrameLayerBuilder.h" @@ -36,6 +35,7 @@ class nsRenderingContext; class nsDisplayTableItem; class nsISelection; class nsDisplayLayerEventRegions; +class nsCaret; namespace mozilla { namespace layers { @@ -1951,21 +1951,12 @@ protected: class nsDisplayCaret : public nsDisplayItem { public: nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame, - nsCaret *aCaret) - : nsDisplayItem(aBuilder, aCaretFrame), mCaret(aCaret) { - MOZ_COUNT_CTOR(nsDisplayCaret); - } + nsCaret *aCaret); #ifdef NS_BUILD_REFCNT_LOGGING - virtual ~nsDisplayCaret() { - MOZ_COUNT_DTOR(nsDisplayCaret); - } + virtual ~nsDisplayCaret(); #endif - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE { - *aSnap = false; - // The caret returns a rect in the coordinates of mFrame. - return mCaret->GetCaretRect() + ToReferenceFrame(); - } + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET) protected: diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 16499ed9ad12..a585317c9857 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -63,6 +63,7 @@ #include "DisplayItemClip.h" #include "ActiveLayerTracker.h" #include "CounterStyleManager.h" +#include "FrameLayerBuilder.h" #include "AudioChannelService.h" #include "mozilla/dom/DataStoreService.h" diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp index 2de83b387ec2..2e42ccdaaa66 100644 --- a/layout/forms/nsFormControlFrame.cpp +++ b/layout/forms/nsFormControlFrame.cpp @@ -4,12 +4,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsFormControlFrame.h" + #include "nsGkAtoms.h" #include "nsLayoutUtils.h" #include "nsIDOMHTMLInputElement.h" #include "mozilla/EventStateManager.h" #include "mozilla/LookAndFeel.h" #include "nsDeviceContext.h" +#include "nsIContent.h" using namespace mozilla; diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 444defdfabe7..839bc4d8e4e0 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -41,6 +41,11 @@ #include "nsIDOMNode.h" #include "nsLayoutUtils.h" #include "nsDisplayList.h" +#include "nsIContent.h" +#include "nsIDocument.h" +#include "FrameLayerBuilder.h" +#include "nsISelectionController.h" +#include "nsISelection.h" #include "imgIContainer.h" #include "imgLoader.h" @@ -804,6 +809,16 @@ nsImageFrame::GetInnerArea() const return GetContentRect() - GetPosition(); } +Element* +nsImageFrame::GetMapElement() const +{ + nsAutoString usemap; + if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, usemap)) { + return mContent->OwnerDoc()->FindImageMap(usemap); + } + return nullptr; +} + // get the offset into the content area of the image where aImg starts if it is a continuation. nscoord nsImageFrame::GetContinuationOffset() const diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index d0ebaecb7644..39822d808c4d 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -19,6 +19,7 @@ #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "nsIReflowCallback.h" +#include "nsTObserverArray.h" class nsImageMap; class nsIURI; @@ -150,14 +151,7 @@ public: /** * Return a map element associated with this image. */ - mozilla::dom::Element* GetMapElement() const - { - nsAutoString usemap; - if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, usemap)) { - return mContent->OwnerDoc()->FindImageMap(usemap); - } - return nullptr; - } + mozilla::dom::Element* GetMapElement() const; /** * Return true if the image has associated image map. diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index a592cf7e4ab3..f2acf18422c0 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -16,6 +16,8 @@ class nsTextPaintStyle; class PropertyProvider; +struct SelectionDetails; +class nsTextFragment; typedef nsFrame nsTextFrameBase; diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index 7c8193208fee..021e1b52e83a 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -10,12 +10,15 @@ */ #include "BasicTableLayoutStrategy.h" + +#include + #include "nsTableFrame.h" #include "nsTableCellFrame.h" #include "nsLayoutUtils.h" #include "nsGkAtoms.h" #include "SpanningCellSorter.h" -#include +#include "nsIContent.h" using namespace mozilla; using namespace mozilla::layout; From 0de1b9e514219095470384c8366f7aa01fede167 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:25 +1200 Subject: [PATCH 042/101] Bug 1048752. Part 10: Remove FrameLayerBuilder.h from nsDisplayList.h. r=tn I was inspired by the previous patch to remove FrameLayerBuilder.h from nsDisplayList.h too. --HG-- extra : rebase_source : b34a01bea5865da4737817e2396b98d54cc6d1bf --- layout/base/FrameLayerBuilder.h | 14 +------------- layout/base/LayerState.h | 26 ++++++++++++++++++++++++++ layout/base/moz.build | 1 + layout/base/nsDisplayList.cpp | 1 + layout/base/nsDisplayList.h | 4 +++- layout/generic/nsFrame.cpp | 6 ++++-- layout/ipc/RenderFrameParent.cpp | 1 + 7 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 layout/base/LayerState.h diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index b0c25a959283..74e3be0a4d95 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -14,6 +14,7 @@ #include "ImageLayers.h" #include "DisplayItemClip.h" #include "mozilla/layers/LayersTypes.h" +#include "LayerState.h" class nsDisplayListBuilder; class nsDisplayList; @@ -38,19 +39,6 @@ class LayerManagerData; class ThebesLayerData; class ContainerState; -enum LayerState { - LAYER_NONE, - LAYER_INACTIVE, - LAYER_ACTIVE, - // Force an active layer even if it causes incorrect rendering, e.g. - // when the layer has rounded rect clips. - LAYER_ACTIVE_FORCE, - // Special layer that is metadata only. - LAYER_ACTIVE_EMPTY, - // Inactive style layer for rendering SVG effects. - LAYER_SVG_EFFECTS -}; - class RefCountedRegion { private: ~RefCountedRegion() {} diff --git a/layout/base/LayerState.h b/layout/base/LayerState.h new file mode 100644 index 000000000000..494fe0ae0d6e --- /dev/null +++ b/layout/base/LayerState.h @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 20; 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 LAYERSTATE_H_ +#define LAYERSTATE_H_ + +namespace mozilla { + +enum LayerState { + LAYER_NONE, + LAYER_INACTIVE, + LAYER_ACTIVE, + // Force an active layer even if it causes incorrect rendering, e.g. + // when the layer has rounded rect clips. + LAYER_ACTIVE_FORCE, + // Special layer that is metadata only. + LAYER_ACTIVE_EMPTY, + // Inactive style layer for rendering SVG effects. + LAYER_SVG_EFFECTS +}; + +} + +#endif diff --git a/layout/base/moz.build b/layout/base/moz.build index c89494e9095c..98af57a820c0 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -21,6 +21,7 @@ EXPORTS += [ 'DisplayListClipState.h', 'FrameLayerBuilder.h', 'FramePropertyTable.h', + 'LayerState.h', 'nsArenaMemoryStats.h', 'nsBidi.h', 'nsBidiPresUtils.h', diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 271918fd12fc..b4168e952923 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -55,6 +55,7 @@ #include "nsPrintfCString.h" #include "UnitTransforms.h" #include "LayersLogging.h" +#include "FrameLayerBuilder.h" #include #include diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index d8072b72bd86..929e310fe93e 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -19,11 +19,12 @@ #include "nsPoint.h" #include "nsRect.h" #include "plarena.h" +#include "Layers.h" #include "nsRegion.h" -#include "FrameLayerBuilder.h" #include "nsLayoutUtils.h" #include "nsDisplayListInvalidation.h" #include "DisplayListClipState.h" +#include "LayerState.h" #include @@ -38,6 +39,7 @@ class nsDisplayLayerEventRegions; class nsCaret; namespace mozilla { +class FrameLayerBuilder; namespace layers { class Layer; class ImageLayer; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 59b919be38cd..65c5c73f4ec1 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -8,6 +8,9 @@ #include "nsFrame.h" +#include +#include + #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" @@ -30,7 +33,6 @@ #include "nsIPresShell.h" #include "prlog.h" #include "prprf.h" -#include #include "nsFrameManager.h" #include "nsLayoutUtils.h" #include "RestyleManager.h" @@ -48,7 +50,7 @@ #include "nsNameSpaceManager.h" #include "nsIPercentHeightObserver.h" #include "nsStyleStructInlines.h" -#include +#include "FrameLayerBuilder.h" #include "nsBidiPresUtils.h" diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 58ac4252b8f1..7c3a2e0e40b6 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -27,6 +27,7 @@ #include "mozilla/layers/LayerManagerComposite.h" #include "mozilla/layers/CompositorChild.h" #include "ClientLayerManager.h" +#include "FrameLayerBuilder.h" typedef nsContentView::ViewConfig ViewConfig; using namespace mozilla::dom; From 075f97aa3732cc41ba7d31ce1ea7fda4df2d53e0 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:25 +1200 Subject: [PATCH 043/101] Bug 1048752. Part 11: Remove nsLayoutUtils.h from nsDisplayList.h. r=tn --HG-- extra : rebase_source : 02251076442a5c4251e8d9484cb428a4c07f3a13 --- layout/base/nsDisplayList.cpp | 16 ++++++++++++++++ layout/base/nsDisplayList.h | 16 +--------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index b4168e952923..ff650b67d2ad 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2003,6 +2003,22 @@ nsDisplayBackgroundImage::IsSingleFixedPositionImage(nsDisplayListBuilder* aBuil return true; } +bool +nsDisplayBackgroundImage::ShouldFixToViewport(LayerManager* aManager) +{ + // APZ doesn't (yet) know how to scroll the visible region for these type of + // items, so don't layerize them if it's enabled. + if (nsLayoutUtils::UsesAsyncScrolling() || + (aManager && aManager->ShouldAvoidComponentAlphaLayers())) { + return false; + } + + // Put background-attachment:fixed background images in their own + // compositing layer, unless we have APZ enabled + return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED && + !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty(); +} + bool nsDisplayBackgroundImage::TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 929e310fe93e..86bbb2e2fded 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -21,7 +21,6 @@ #include "plarena.h" #include "Layers.h" #include "nsRegion.h" -#include "nsLayoutUtils.h" #include "nsDisplayListInvalidation.h" #include "DisplayListClipState.h" #include "LayerState.h" @@ -2150,20 +2149,7 @@ public: static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip, const nsRect& aRect, bool* aSnap); - virtual bool ShouldFixToViewport(LayerManager* aManager) MOZ_OVERRIDE - { - // APZ doesn't (yet) know how to scroll the visible region for these type of - // items, so don't layerize them if it's enabled. - if (nsLayoutUtils::UsesAsyncScrolling() || - (aManager && aManager->ShouldAvoidComponentAlphaLayers())) { - return false; - } - - // Put background-attachment:fixed background images in their own - // compositing layer, unless we have APZ enabled - return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED && - !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty(); - } + virtual bool ShouldFixToViewport(LayerManager* aManager) MOZ_OVERRIDE; protected: typedef class mozilla::layers::ImageContainer ImageContainer; From 224aa3096df57bde17adf230f961c2422f23637b Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:26 +1200 Subject: [PATCH 044/101] Bug 1048752. Part 12: Replace mBlinkRate with mIsBlinking. r=tn We don't need to store the blink rate. Instead we can just fetch it whenever we need it. However we do need a flag to handle the case where nsCaret::DrawAtPosition disables blinking. --HG-- extra : rebase_source : 4f36825a8e22edd3a2e37edb1fae5675c85adadd --- layout/base/nsCaret.cpp | 17 +++++++++-------- layout/base/nsCaret.h | 4 +--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index a5c9c3bd3702..61bab9e8ccbe 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -111,7 +111,7 @@ AdjustCaretFrameForLineEnd(nsIFrame** aFrame, int32_t* aOffset) nsCaret::nsCaret() : mPresShell(nullptr) -, mBlinkRate(500) +, mIsBlinking(true) , mVisible(false) , mDrawn(false) , mPendingDraw(false) @@ -139,8 +139,6 @@ nsresult nsCaret::Init(nsIPresShell *inPresShell) mPresShell = do_GetWeakReference(inPresShell); // the presshell owns us, so no addref NS_ASSERTION(mPresShell, "Hey, pres shell should support weak refs"); - mBlinkRate = static_cast( - LookAndFeel::GetInt(LookAndFeel::eIntID_CaretBlinkTime, mBlinkRate)); mShowDuringSelection = LookAndFeel::GetInt(LookAndFeel::eIntID_ShowCaretDuringSelection, mShowDuringSelection ? 1 : 0) != 0; @@ -392,7 +390,7 @@ void nsCaret::EraseCaret() { if (mDrawn) { DrawCaret(true); - if (mReadOnly && mBlinkRate) { + if (mReadOnly && mIsBlinking) { // If readonly we don't have a blink timer set, so caret won't // be redrawn automatically. We need to force the caret to get // redrawn right after the paint @@ -417,9 +415,9 @@ nsresult nsCaret::DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset) bidiLevel = frameSelection->GetCaretBidiLevel(); // DrawAtPosition is used by consumers who want us to stay drawn where they - // tell us. Setting mBlinkRate to 0 tells us to not set a timer to erase + // tell us. Setting mIsBlinking to false tells us to not set a timer to erase // ourselves, our consumer will take care of that. - mBlinkRate = 0; + mIsBlinking = false; nsCOMPtr node = do_QueryInterface(aNode); nsresult rv = DrawAtPositionWithHint(aNode, aOffset, @@ -547,7 +545,7 @@ void nsCaret::KillTimer() nsresult nsCaret::PrimeTimer() { // set up the blink timer - if (!mReadOnly && mBlinkRate > 0) + if (!mReadOnly && mIsBlinking) { if (!mBlinkTimer) { nsresult err; @@ -556,7 +554,10 @@ nsresult nsCaret::PrimeTimer() return err; } - mBlinkTimer->InitWithFuncCallback(CaretBlinkCallback, this, mBlinkRate, + uint32_t blinkRate = static_cast( + LookAndFeel::GetInt(LookAndFeel::eIntID_CaretBlinkTime, 500)); + + mBlinkTimer->InitWithFuncCallback(CaretBlinkCallback, this, blinkRate, nsITimer::TYPE_REPEATING_SLACK); } diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 759c9fc81dd4..0ec5e7eb893d 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -199,9 +199,7 @@ protected: nsCOMPtr mBlinkTimer; - // XXX these fields should go away and the values be acquired as needed, - // probably by ComputeMetrics. - uint32_t mBlinkRate; // time for one cyle (on then off), in milliseconds + bool mIsBlinking; bool mVisible; // is the caret blinking From bdbb11f64df3ebeb155f089e303d05528185c288 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:26 +1200 Subject: [PATCH 045/101] Bug 1048752. Part 13: Remove GetGeometry's aBidiIndicatorSize. r=tn Callers always pass null. --HG-- extra : rebase_source : 169f9fe4f4236cffe2c0f760305ebf8093300c69 --- layout/base/nsCaret.cpp | 5 ++--- layout/base/nsCaret.h | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 61bab9e8ccbe..abb433c9b7d0 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -339,8 +339,7 @@ nsCaret::GetGeometryForFrame(nsIFrame* aFrame, return NS_OK; } -nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect, - nscoord* aBidiIndicatorSize) +nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) { nsCOMPtr focusNode; nsresult rv = aSelection->GetFocusNode(getter_AddRefs(focusNode)); @@ -368,7 +367,7 @@ nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect, if (NS_FAILED(rv) || !frame) return nullptr; - GetGeometryForFrame(frame, frameOffset, aRect, aBidiIndicatorSize); + GetGeometryForFrame(frame, frameOffset, aRect, nullptr); return frame; } diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 0ec5e7eb893d..9a7e6b0599dc 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -94,11 +94,9 @@ class nsCaret : public nsISelectionListener * i.e., disregarding blink status). The geometry is stored in aRect, * and we return the frame aRect is relative to. * @param aRect must be non-null - * @param aBidiIndicatorSize if non-null, set to the bidi indicator size. */ nsIFrame* GetGeometry(nsISelection* aSelection, - nsRect* aRect, - nscoord* aBidiIndicatorSize = nullptr); + nsRect* aRect); /** GetCaretFrame * Get the current frame that the caret should be drawn in. If the caret is * not currently visible (i.e., it is between blinks), then this will From b4ed20d44151dc13bc0c6412d12b1ce54717650e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:26 +1200 Subject: [PATCH 046/101] Bug 1048752. Part 14: Split GetGeometry into a static and a non-static version. r=tn GetGeometry is used in two different ways. Sometimes it's used to get information about a particular caret. Sometimes it's used to get information about a particular selection that's not associated with a caret. Splitting GetGeometry into a non-static version for the former and a static version for the latter makes this more clear. Also it saves code since for the latter version we don't have to get an nsCaret first. --HG-- extra : rebase_source : b7730dac56b308a82b79b175749234c9a92b6f59 --- accessible/generic/HyperTextAccessible.cpp | 5 +--- dom/base/nsFocusManager.cpp | 3 +- dom/events/ContentEventHandler.cpp | 19 +++++------- layout/base/SelectionCarets.cpp | 3 +- layout/base/TouchCaret.cpp | 17 +++++------ layout/base/nsCaret.cpp | 10 +++---- layout/base/nsCaret.h | 35 +++++++++++++--------- layout/base/nsPresShell.cpp | 2 +- layout/generic/nsSelection.cpp | 6 ++-- 9 files changed, 46 insertions(+), 54 deletions(-) diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index cfc59d77a20b..738d3b00f0fa 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1322,16 +1322,13 @@ HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) nsRefPtr caret = mDoc->PresShell()->GetCaret(); NS_ENSURE_TRUE(caret, nsIntRect()); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); - NS_ENSURE_TRUE(caretSelection, nsIntRect()); - bool isVisible = false; caret->GetCaretVisible(&isVisible); if (!isVisible) return nsIntRect(); nsRect rect; - nsIFrame* frame = caret->GetGeometry(caretSelection, &rect); + nsIFrame* frame = caret->GetGeometry(&rect); if (!frame || rect.IsEmpty()) return nsIntRect(); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 7779ad7b6eb4..22ae0b0b4000 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -2295,9 +2295,8 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument, if (newCaretFrame && newCaretContent) { // If the caret is exactly at the same position of the new frame, // then we can use the newCaretFrame and newCaretContent for our position - nsRefPtr caret = aPresShell->GetCaret(); nsRect caretRect; - nsIFrame *frame = caret->GetGeometry(domSelection, &caretRect); + nsIFrame *frame = nsCaret::GetGeometry(domSelection, &caretRect); if (frame) { nsPoint caretWidgetOffset; nsIWidget *widget = frame->GetNearestWidget(caretWidgetOffset); diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 2c575918bcf2..5fcffd9d9d19 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -118,11 +118,8 @@ ContentEventHandler::Init(WidgetQueryContentEvent* aEvent) NS_ENSURE_SUCCESS(rv, NS_ERROR_NOT_AVAILABLE); aEvent->mReply.mHasSelection = !isCollapsed; - nsRefPtr caret = mPresShell->GetCaret(); - NS_ASSERTION(caret, "GetCaret returned null"); - nsRect r; - nsIFrame* frame = caret->GetGeometry(mSelection, &r); + nsIFrame* frame = nsCaret::GetGeometry(mSelection, &r); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); aEvent->mReply.mFocusedWidget = frame->GetNearestWidget(); @@ -843,30 +840,28 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent) LineBreakType lineBreakType = GetLineBreakType(aEvent); - nsRefPtr caret = mPresShell->GetCaret(); - NS_ASSERTION(caret, "GetCaret returned null"); - // When the selection is collapsed and the queried offset is current caret // position, we should return the "real" caret rect. bool selectionIsCollapsed; rv = mSelection->GetIsCollapsed(&selectionIsCollapsed); NS_ENSURE_SUCCESS(rv, rv); + nsRect caretRect; + nsIFrame* caretFrame = nsCaret::GetGeometry(mSelection, &caretRect); + if (selectionIsCollapsed) { uint32_t offset; rv = GetFlatTextOffsetOfRange(mRootContent, mFirstSelectedRange, &offset, lineBreakType); NS_ENSURE_SUCCESS(rv, rv); if (offset == aEvent->mInput.mOffset) { - nsRect rect; - nsIFrame* caretFrame = caret->GetGeometry(mSelection, &rect); if (!caretFrame) { return NS_ERROR_FAILURE; } - rv = ConvertToRootViewRelativeOffset(caretFrame, rect); + rv = ConvertToRootViewRelativeOffset(caretFrame, caretRect); NS_ENSURE_SUCCESS(rv, rv); aEvent->mReply.mRect = - rect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel()); + caretRect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel()); aEvent->mReply.mOffset = aEvent->mInput.mOffset; aEvent->mSucceeded = true; return NS_OK; @@ -892,7 +887,7 @@ ContentEventHandler::OnQueryCaretRect(WidgetQueryContentEvent* aEvent) nsRect rect; rect.x = posInFrame.x; rect.y = posInFrame.y; - rect.width = caret->GetCaretRect().width; + rect.width = caretRect.width; rect.height = frame->GetSize().height; rv = ConvertToRootViewRelativeOffset(frame, rect); diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index c7dcfb6ca674..cbf7ea9e6b38 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -794,9 +794,8 @@ SelectionCarets::GetCaretFocusFrame() nsRefPtr caret = mPresShell->GetCaret(); NS_ENSURE_TRUE(caret, nullptr); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); nsRect focusRect; - return caret->GetGeometry(caretSelection, &focusRect); + return caret->GetGeometry(&focusRect); } bool diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index 0a9ad432cf3b..cbe8f68253b2 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -168,9 +168,8 @@ TouchCaret::GetContentBoundary() } nsRefPtr caret = presShell->GetCaret(); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); nsRect focusRect; - nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect); + nsIFrame* focusFrame = caret->GetGeometry(&focusRect); nsIFrame* canvasFrame = GetCanvasFrame(); // Get the editing host to determine the touch caret dragable boundary. @@ -213,9 +212,8 @@ TouchCaret::GetCaretYCenterPosition() } nsRefPtr caret = presShell->GetCaret(); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); nsRect focusRect; - nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect); + nsIFrame* focusFrame = caret->GetGeometry(&focusRect); nsRect caretRect = focusFrame->GetRectRelativeToSelf(); nsIFrame *canvasFrame = GetCanvasFrame(); nsLayoutUtils::TransformRect(focusFrame, canvasFrame, caretRect); @@ -264,9 +262,8 @@ TouchCaret::MoveCaret(const nsPoint& movePoint) // Get scrollable frame. nsRefPtr caret = presShell->GetCaret(); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); nsRect focusRect; - nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect); + nsIFrame* focusFrame = caret->GetGeometry(&focusRect); nsIFrame* scrollable = nsLayoutUtils::GetClosestFrameOfType(focusFrame, nsGkAtoms::scrollFrame); @@ -455,9 +452,10 @@ TouchCaret::UpdatePosition() return; } nsRefPtr caret = presShell->GetCaret(); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); + + // Caret is visible and shown, update touch caret. nsRect focusRect; - nsIFrame* focusFrame = caret->GetGeometry(caretSelection, &focusRect); + nsIFrame* focusFrame = caret->GetGeometry(&focusRect); if (!focusFrame || focusRect.IsEmpty()) { return; } @@ -538,9 +536,8 @@ TouchCaret::SetSelectionDragState(bool aState) } nsRefPtr caret = presShell->GetCaret(); - nsISelection* caretSelection = caret->GetCaretDOMSelection(); nsRect focusRect; - nsIFrame* caretFocusFrame = caret->GetGeometry(caretSelection, &focusRect); + nsIFrame* caretFocusFrame = caret->GetGeometry(&focusRect); nsRefPtr fs = caretFocusFrame->GetFrameSelection(); fs->SetDragState(aState); } diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index abb433c9b7d0..31246ad05391 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -283,7 +283,7 @@ void nsCaret::SetCaretReadOnly(bool inMakeReadonly) mReadOnly = inMakeReadonly; } -nsresult +/* static */ nsresult nsCaret::GetGeometryForFrame(nsIFrame* aFrame, int32_t aFrameOffset, nsRect* aRect, @@ -339,7 +339,8 @@ nsCaret::GetGeometryForFrame(nsIFrame* aFrame, return NS_OK; } -nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) +/* static */ nsIFrame* +nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) { nsCOMPtr focusNode; nsresult rv = aSelection->GetFocusNode(getter_AddRefs(focusNode)); @@ -355,9 +356,8 @@ nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) if (!contentNode) return nullptr; - nsRefPtr frameSelection = GetFrameSelection(); - if (!frameSelection) - return nullptr; + nsFrameSelection* frameSelection = + static_cast(aSelection)->GetFrameSelection(); uint8_t bidiLevel = frameSelection->GetCaretBidiLevel(); nsIFrame* frame; int32_t frameOffset; diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 9a7e6b0599dc..97b566f1678c 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -88,15 +88,6 @@ class nsCaret : public nsISelectionListener **/ nsresult DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset); - /** - * Gets the position and size of the caret that would be drawn for - * the focus node/offset of aSelection (assuming it would be drawn, - * i.e., disregarding blink status). The geometry is stored in aRect, - * and we return the frame aRect is relative to. - * @param aRect must be non-null - */ - nsIFrame* GetGeometry(nsISelection* aSelection, - nsRect* aRect); /** GetCaretFrame * Get the current frame that the caret should be drawn in. If the caret is * not currently visible (i.e., it is between blinks), then this will @@ -115,6 +106,10 @@ class nsCaret : public nsISelectionListener r.UnionRect(mCaretRect, GetHookRect()); return r; } + nsIFrame* GetGeometry(nsRect* aRect) + { + return GetGeometry(GetCaretDOMSelection(), aRect); + } /** PaintCaret * Actually paint the caret onto the given rendering context. @@ -127,6 +122,17 @@ class nsCaret : public nsISelectionListener //nsISelectionListener interface NS_DECL_NSISELECTIONLISTENER + /** + * Gets the position and size of the caret that would be drawn for + * the focus node/offset of aSelection (assuming it would be drawn, + * i.e., disregarding blink status). The geometry is stored in aRect, + * and we return the frame aRect is relative to. + * Only looks at the focus node of aSelection, so you can call it even if + * aSelection is not collapsed. + * @param aRect must be non-null + */ + static nsIFrame* GetGeometry(nsISelection* aSelection, + nsRect* aRect); static nsresult GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection, nsIContent* aContentNode, int32_t aOffset, @@ -156,11 +162,12 @@ protected: nscoord mBidiIndicatorSize; // width and height of bidi indicator nscoord mCaretWidth; // full caret width including bidi indicator }; - Metrics ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight); - nsresult GetGeometryForFrame(nsIFrame* aFrame, - int32_t aFrameOffset, - nsRect* aRect, - nscoord* aBidiIndicatorSize); + static Metrics ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, + nscoord aCaretHeight); + static nsresult GetGeometryForFrame(nsIFrame* aFrame, + int32_t aFrameOffset, + nsRect* aRect, + nscoord* aBidiIndicatorSize); // Returns true if the caret should be drawn. When |mDrawn| is true, // this returns true, so that we erase the drawn caret. If |aIgnoreDrawnState| diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index d5eb5043edbc..8ec52777788f 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8135,7 +8135,7 @@ PresShell::PrepareToUseCaretPosition(nsIWidget* aEventWidget, nsIntPoint& aTarge // get caret position relative to the closest view nsRect caretCoords; - nsIFrame* caretFrame = caret->GetGeometry(domSelection, &caretCoords); + nsIFrame* caretFrame = caret->GetGeometry(&caretCoords); if (!caretFrame) return false; nsPoint viewOffset; diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 869ea94725e1..e91289e41956 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -434,7 +434,7 @@ nsFrameSelection::FetchDesiredX(nscoord &aDesiredX) //the x position requested b return result; nsRect coord; - nsIFrame* caretFrame = caret->GetGeometry(mDomSelections[index], &coord); + nsIFrame* caretFrame = caret->GetGeometry(&coord); if (!caretFrame) return NS_ERROR_FAILURE; nsPoint viewOffset(0, 0); @@ -1869,10 +1869,8 @@ nsFrameSelection::CommonPageMove(bool aForward, if (!domSel) return; - nsRefPtr caret = mShell->GetCaret(); - nsRect caretPos; - nsIFrame* caretFrame = caret->GetGeometry(domSel, &caretPos); + nsIFrame* caretFrame = nsCaret::GetGeometry(domSel, &caretPos); if (!caretFrame) return; From f500f71adb6e63b74f5b50e3cb8376d8e0268709 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:26 +1200 Subject: [PATCH 047/101] Bug 1048752. Part 15: Fix some comments. r=tn --HG-- extra : rebase_source : c21e494622615b306e796afedf6c0a424d6f1046 --- layout/base/nsCaret.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index 97b566f1678c..bde04fa2bde6 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -50,9 +50,9 @@ class nsCaret : public nsISelectionListener * @param inMakeVisible true to show the caret, false to hide it */ void SetCaretVisible(bool intMakeVisible); - /** GetCaretVisible will get the visibility of the caret - * This function is virtual so that it can be used by nsCaretAccessible - * without linking + /** GetCaretVisible will get the visibility of the caret. + * This returns false if the caret is hidden for any reason (other than + * blinking off). * @param outMakeVisible true if it is shown, false if it is hidden * @return NS_OK */ @@ -99,6 +99,7 @@ class nsCaret : public nsISelectionListener /** GetCaretRect * Get the current caret rect. Only call this when GetCaretFrame returns * non-null. + * This rect includes any extra decorations for bidi. */ nsRect GetCaretRect() { @@ -106,6 +107,10 @@ class nsCaret : public nsISelectionListener r.UnionRect(mCaretRect, GetHookRect()); return r; } + /** + * A simple wrapper around GetGeometry. Does not take any caret state into + * account other than the current selection. + */ nsIFrame* GetGeometry(nsRect* aRect) { return GetGeometry(GetCaretDOMSelection(), aRect); @@ -129,6 +134,7 @@ class nsCaret : public nsISelectionListener * and we return the frame aRect is relative to. * Only looks at the focus node of aSelection, so you can call it even if * aSelection is not collapsed. + * This rect does not include any extra decorations for bidi. * @param aRect must be non-null */ static nsIFrame* GetGeometry(nsISelection* aSelection, From 2489dc1f01b4c6308e657cf23be4248aff2fa1c4 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 6 Aug 2014 17:19:27 +1200 Subject: [PATCH 048/101] Bug 1048752. Part 16: Move nsFrameSelection::HINT to CaretAssociationHint.h. r=tn This patch started an attempt to remove nsFrameSelection.h from nsCaret.h and metastasized into a rather large refactoring patch that removed it from some other header files as well, and changed nsFrameSelection::HINT into a global-scope enum with better names. I also converted bools into CaretAssociationHint in a few places where that was appropriate, but there are still some more places (GetChildFrameContainingOffset) where bools need to be converted. I figured this patch was big enough already. --HG-- extra : rebase_source : cc618ef60e707e1360644340a2648de389383da0 --- accessible/base/SelectionManager.cpp | 1 + accessible/generic/HyperTextAccessible-inl.h | 3 +- accessible/generic/HyperTextAccessible.cpp | 2 +- accessible/generic/HyperTextAccessible.h | 13 +- accessible/windows/sdn/sdnAccessible.cpp | 1 + accessible/xpcom/xpcAccessibleTextRange.cpp | 4 +- .../html/content/src/nsTextEditorState.cpp | 5 +- dom/base/nsGlobalWindow.cpp | 1 + dom/events/ContentEventHandler.cpp | 4 +- dom/plugins/base/nsPluginInstanceOwner.cpp | 1 + .../html/tests/test_bug674770-1.html | 5 - layout/base/CaretAssociationHint.h | 22 +++ layout/base/SelectionCarets.cpp | 13 +- layout/base/TouchCaret.cpp | 2 +- layout/base/TouchCaret.h | 1 - layout/base/WordMovementType.h | 14 ++ layout/base/moz.build | 2 + layout/base/nsCaret.cpp | 30 ++-- layout/base/nsCaret.h | 20 ++- layout/base/nsDisplayList.cpp | 13 +- layout/base/nsLayoutUtils.cpp | 2 + layout/base/nsPresShell.cpp | 17 +- layout/base/nsPresShell.h | 13 +- layout/forms/nsImageControlFrame.cpp | 2 + layout/generic/TextOverflow.cpp | 1 + layout/generic/nsBRFrame.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 1 + layout/generic/nsFrame.cpp | 46 +++--- layout/generic/nsFrameSelection.h | 56 +++---- layout/generic/nsIFrame.h | 5 +- layout/generic/nsSelection.cpp | 153 ++++++++++-------- layout/generic/nsTextFrame.cpp | 3 +- layout/svg/SVGTextFrame.cpp | 3 +- layout/xul/nsImageBoxFrame.cpp | 1 + layout/xul/nsListItemFrame.cpp | 4 +- layout/xul/tree/nsTreeImageListener.cpp | 1 + 36 files changed, 273 insertions(+), 194 deletions(-) create mode 100644 layout/base/CaretAssociationHint.h create mode 100644 layout/base/WordMovementType.h diff --git a/accessible/base/SelectionManager.cpp b/accessible/base/SelectionManager.cpp index 1c3788036a08..d846e356bc87 100644 --- a/accessible/base/SelectionManager.cpp +++ b/accessible/base/SelectionManager.cpp @@ -12,6 +12,7 @@ #include "nsAccUtils.h" #include "nsCoreUtils.h" #include "nsEventShell.h" +#include "nsFrameSelection.h" #include "nsIAccessibleTypes.h" #include "nsIDOMDocument.h" diff --git a/accessible/generic/HyperTextAccessible-inl.h b/accessible/generic/HyperTextAccessible-inl.h index f47a0e200941..81e421536839 100644 --- a/accessible/generic/HyperTextAccessible-inl.h +++ b/accessible/generic/HyperTextAccessible-inl.h @@ -14,6 +14,7 @@ #include "nsIEditor.h" #include "nsIPersistentProperties2.h" #include "nsIPlaintextEditor.h" +#include "nsFrameSelection.h" namespace mozilla { namespace a11y { @@ -143,7 +144,7 @@ HyperTextAccessible::IsCaretAtEndOfLine() const { nsRefPtr frameSelection = FrameSelection(); return frameSelection && - frameSelection->GetHint() == nsFrameSelection::HINTLEFT; + frameSelection->GetHint() == CARET_ASSOCIATE_BEFORE; } inline already_AddRefed diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 738d3b00f0fa..cac3b749eb1f 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1269,7 +1269,7 @@ HyperTextAccessible::CaretLineNumber() int32_t returnOffsetUnused; uint32_t caretOffset = domSel->FocusOffset(); - nsFrameSelection::HINT hint = frameSelection->GetHint(); + CaretAssociationHint hint = frameSelection->GetHint(); nsIFrame *caretFrame = frameSelection->GetFrameForNodeOffset(caretContent, caretOffset, hint, &returnOffsetUnused); NS_ENSURE_TRUE(caretFrame, -1); diff --git a/accessible/generic/HyperTextAccessible.h b/accessible/generic/HyperTextAccessible.h index 7dfd652c6adf..99f4a8338320 100644 --- a/accessible/generic/HyperTextAccessible.h +++ b/accessible/generic/HyperTextAccessible.h @@ -9,11 +9,22 @@ #include "AccessibleWrap.h" #include "nsIAccessibleTypes.h" #include "xpcAccessibleHyperText.h" +#include "nsDirection.h" +#include "WordMovementType.h" +#include "nsIFrame.h" -#include "nsFrameSelection.h" #include "nsISelectionController.h" +class nsFrameSelection; +class nsRange; +class nsIWidget; + namespace mozilla { + +namespace dom { +class Selection; +} + namespace a11y { class TextRange; diff --git a/accessible/windows/sdn/sdnAccessible.cpp b/accessible/windows/sdn/sdnAccessible.cpp index ad3a5fe8dc65..046d734c3a8a 100644 --- a/accessible/windows/sdn/sdnAccessible.cpp +++ b/accessible/windows/sdn/sdnAccessible.cpp @@ -17,6 +17,7 @@ #include "nsNameSpaceManager.h" #include "nsServiceManagerUtils.h" #include "nsWinUtils.h" +#include "nsRange.h" #include "nsAutoPtr.h" diff --git a/accessible/xpcom/xpcAccessibleTextRange.cpp b/accessible/xpcom/xpcAccessibleTextRange.cpp index 51226e4f866a..8f278979c733 100644 --- a/accessible/xpcom/xpcAccessibleTextRange.cpp +++ b/accessible/xpcom/xpcAccessibleTextRange.cpp @@ -8,8 +8,8 @@ #include "HyperTextAccessible.h" #include "TextRange.h" - - #include "nsIMutableArray.h" +#include "nsIMutableArray.h" +#include "nsComponentManagerUtils.h" using namespace mozilla; using namespace mozilla::a11y; diff --git a/content/html/content/src/nsTextEditorState.cpp b/content/html/content/src/nsTextEditorState.cpp index 9bb4f03f98e8..7989c94e035f 100644 --- a/content/html/content/src/nsTextEditorState.cpp +++ b/content/html/content/src/nsTextEditorState.cpp @@ -45,6 +45,7 @@ #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/HTMLInputElement.h" #include "nsNumberControlFrame.h" +#include "nsFrameSelection.h" using namespace mozilla; using namespace mozilla::dom; @@ -546,7 +547,7 @@ nsTextInputSelectionImpl::CompleteMove(bool aForward, bool aExtend) // make the caret be either at the very beginning (0) or the very end int32_t offset = 0; - nsFrameSelection::HINT hint = nsFrameSelection::HINTLEFT; + CaretAssociationHint hint = CARET_ASSOCIATE_BEFORE; if (aForward) { offset = parentDIV->GetChildCount(); @@ -561,7 +562,7 @@ nsTextInputSelectionImpl::CompleteMove(bool aForward, bool aExtend) if (child->Tag() == nsGkAtoms::br) { --offset; - hint = nsFrameSelection::HINTRIGHT; // for Bug 106855 + hint = CARET_ASSOCIATE_AFTER; // for Bug 106855 } } } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index cea15c8e38b6..302deea54bb3 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -40,6 +40,7 @@ #include "nsWindowMemoryReporter.h" #include "WindowNamedPropertiesHandler.h" #include "nsFrameSelection.h" +#include "nsISelectionListener.h" // Helper Classes #include "nsJSUtils.h" diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 5fcffd9d9d19..65f48d9a3ffe 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -440,8 +440,8 @@ ContentEventHandler::ExpandToClusterBoundary(nsIContent* aContent, nsRefPtr fs = mPresShell->FrameSelection(); int32_t offsetInFrame; - nsFrameSelection::HINT hint = - aForward ? nsFrameSelection::HINTLEFT : nsFrameSelection::HINTRIGHT; + CaretAssociationHint hint = + aForward ? CARET_ASSOCIATE_BEFORE : CARET_ASSOCIATE_AFTER; nsIFrame* frame = fs->GetFrameForNodeOffset(aContent, int32_t(*aXPOffset), hint, &offsetInFrame); if (!frame) { diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 98d56d562e52..a1edf28dd587 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -55,6 +55,7 @@ using mozilla::DefaultXDisplay; #include "mozilla/MouseEvents.h" #include "mozilla/TextEvents.h" #include "mozilla/dom/HTMLObjectElementBinding.h" +#include "nsFrameSelection.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" diff --git a/editor/libeditor/html/tests/test_bug674770-1.html b/editor/libeditor/html/tests/test_bug674770-1.html index b422d2ee1769..f202a909897a 100644 --- a/editor/libeditor/html/tests/test_bug674770-1.html +++ b/editor/libeditor/html/tests/test_bug674770-1.html @@ -22,11 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=674770

 
diff --git a/layout/base/tests/bug646382-2-ref.html b/layout/base/tests/bug646382-2-ref.html
index 80e4f4162365..e21387a0bb36 100644
--- a/layout/base/tests/bug646382-2-ref.html
+++ b/layout/base/tests/bug646382-2-ref.html
@@ -7,7 +7,7 @@
         textarea.focus();
       }
       function done() {
-        textarea.selectionStart = textarea.selectionEnd = 0;
+        textarea.selectionStart = textarea.selectionEnd = 1;
         document.documentElement.removeAttribute("class");
       }
     

From 3fa85fd10e85e19fd031c012dedc2eaedbd4ce77 Mon Sep 17 00:00:00 2001
From: Robert O'Callahan 
Date: Fri, 15 Aug 2014 22:47:46 +1200
Subject: [PATCH 072/101] Bug 263049. Hack nsTypeAheadFind to search
 XMLPrettyPrinter's pretty-printed DOM when the root node has an XBL binding.
 r=mrbkap

--HG--
extra : rebase_source : 33bfe389b08dfb76964eb986f13ee7b93a2f0f54
---
 .../typeaheadfind/nsTypeAheadFind.cpp         | 38 +++++++++++++------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
index 359c5a3cc94d..459d4810dbd7 100644
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -51,6 +51,7 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Link.h"
 #include "nsRange.h"
+#include "nsXBLBinding.h"
 
 #include "nsTypeAheadFind.h"
 
@@ -746,19 +747,36 @@ nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
   if (!rootNode)
     return NS_ERROR_FAILURE;
 
-  uint32_t childCount = rootContent->GetChildCount();
-
   if (!mSearchRange) {
-    mSearchRange = new nsRange(rootContent);
+    mSearchRange = new nsRange(doc);
   }
+  nsCOMPtr searchRootNode = rootNode;
+
+  // Hack for XMLPrettyPrinter. nsFind can't handle complex anonymous content.
+  // If the root node has an XBL binding then there's not much we can do in
+  // in general, but we can try searching the binding's first child, which
+  // in the case of XMLPrettyPrinter contains the visible pretty-printed
+  // content.
+  nsXBLBinding* binding = rootContent->GetXBLBinding();
+  if (binding) {
+    nsIContent* child = binding->GetAnonymousContent()->GetFirstChild();
+    if (child) {
+      searchRootNode = do_QueryInterface(child);
+    }
+  }
+  mSearchRange->SelectNodeContents(searchRootNode);
+
+  if (!mStartPointRange) {
+    mStartPointRange = new nsRange(doc);
+  }
+  mStartPointRange->SetStart(searchRootNode, 0);
+  mStartPointRange->Collapse(true); // collapse to start
 
   if (!mEndPointRange) {
-    mEndPointRange = new nsRange(rootContent);
+    mEndPointRange = new nsRange(doc);
   }
-
-  mSearchRange->SelectNodeContents(rootNode);
-
-  mEndPointRange->SetEnd(rootNode, childCount);
+  nsCOMPtr searchRootTmp = do_QueryInterface(searchRootNode);
+  mEndPointRange->SetEnd(searchRootNode, searchRootTmp->Length());
   mEndPointRange->Collapse(false); // collapse to end
 
   // Consider current selection as null if
@@ -773,10 +791,6 @@ nsTypeAheadFind::GetSearchContainers(nsISupports *aContainer,
       selection->GetRangeAt(0, getter_AddRefs(currentSelectionRange));
   }
 
-  if (!mStartPointRange) {
-    mStartPointRange = new nsRange(doc);
-  }
-
   if (!currentSelectionRange) {
     // Ensure visible range, move forward if necessary
     // This uses ignores the return value, but usese the side effect of

From 6e7013bf5d94c97ddab0afde85c25f3c5a1ca0a9 Mon Sep 17 00:00:00 2001
From: Eitan Isaacson 
Date: Sat, 16 Aug 2014 01:06:16 -0400
Subject: [PATCH 073/101] Bug 1054409 - Add isFromUserInput to pivot change
 presentation. r=yzen

---
 accessible/jsat/ContentControl.jsm |  7 ++++---
 accessible/jsat/EventManager.jsm   |  3 ++-
 accessible/jsat/Presentation.jsm   | 27 +++++++++++++++------------
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/accessible/jsat/ContentControl.jsm b/accessible/jsat/ContentControl.jsm
index 96b0bb005c4a..3f7d0b034adf 100644
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -396,7 +396,7 @@ this.ContentControl.prototype = {
           this._contentScope.get().sendAsyncMessage(
             'AccessFu:Present', Presentation.pivotChanged(
               vc.position, null, Ci.nsIAccessiblePivot.REASON_NONE,
-              vc.startOffset, vc.endOffset));
+              vc.startOffset, vc.endOffset, false));
         }
       };
 
@@ -416,11 +416,12 @@ this.ContentControl.prototype = {
       let moveFirstOrLast = moveMethod in ['moveFirst', 'moveLast'];
       if (!moveFirstOrLast || acc) {
         // We either need next/previous or there is an anchor we need to use.
-        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true);
+        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true,
+                                                              false);
       }
       if (moveFirstOrLast && !moved) {
         // We move to first/last after no anchor move happened or succeeded.
-        moved = vc[moveMethod](rule);
+        moved = vc[moveMethod](rule, false);
       }
 
       let sentToChild = this.sendToChild(vc, {
diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm
index c4d6fe52469b..1e8c372bf1f5 100644
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -161,7 +161,8 @@ this.EventManager.prototype = {
         }
         this.present(
           Presentation.pivotChanged(position, oldAccessible, reason,
-                                    pivot.startOffset, pivot.endOffset));
+                                    pivot.startOffset, pivot.endOffset,
+                                    aEvent.isFromUserInput));
 
         break;
       }
diff --git a/accessible/jsat/Presentation.jsm b/accessible/jsat/Presentation.jsm
index 8f5682c6aad8..502fa32a8ef3 100644
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -46,8 +46,9 @@ Presenter.prototype = {
    *   position.
    * @param {int} aReason the reason for the pivot change.
    *   See nsIAccessiblePivot.
+   * @param {bool} aIsFromUserInput the pivot change was invoked by the user
    */
-  pivotChanged: function pivotChanged(aContext, aReason) {}, // jshint ignore:line
+  pivotChanged: function pivotChanged(aContext, aReason, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * An object's action has been invoked.
@@ -66,7 +67,7 @@ Presenter.prototype = {
    * Text selection has changed. TODO.
    */
   textSelectionChanged: function textSelectionChanged(
-    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {}, // jshint ignore:line
+    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * Selection has changed. TODO.
@@ -362,15 +363,15 @@ AndroidPresenter.prototype.textChanged = function AndroidPresenter_textChanged(
 
 AndroidPresenter.prototype.textSelectionChanged =
   function AndroidPresenter_textSelectionChanged(aText, aStart, aEnd, aOldStart,
-                                                 aOldEnd, aIsFromUser) {
+                                                 aOldEnd, aIsFromUserInput) {
     let androidEvents = [];
 
-    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
       if (!this._braillePresenter) {
         this._braillePresenter = new BraillePresenter();
       }
       let brailleOutput = this._braillePresenter.textSelectionChanged(
-        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser).details;
+        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput).details;
 
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
@@ -382,7 +383,7 @@ AndroidPresenter.prototype.textSelectionChanged =
       });
     }
 
-    if (Utils.AndroidSdkVersion >= 16 && aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
       let [from, to] = aOldStart < aStart ?
         [aOldStart, aStart] : [aStart, aOldStart];
       androidEvents.push({
@@ -469,7 +470,7 @@ B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
                                               'last', 'text', 'point'];
 
 B2GPresenter.prototype.pivotChanged =
-  function B2GPresenter_pivotChanged(aContext, aReason) {
+  function B2GPresenter_pivotChanged(aContext, aReason, aIsUserInput) {
     if (!aContext.accessible) {
       return null;
     }
@@ -482,7 +483,8 @@ B2GPresenter.prototype.pivotChanged =
         options: {
           pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
           isKey: aContext.accessible.role === Roles.KEY,
-          reason: this.pivotChangedReasons[aReason]
+          reason: this.pivotChangedReasons[aReason],
+          isUserInput: aIsUserInput
         }
       }
     };
@@ -584,10 +586,11 @@ this.Presentation = { // jshint ignore:line
   },
 
   pivotChanged: function Presentation_pivotChanged(
-    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset) {
+    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset, aIsUserInput) {
     let context = new PivotContext(
       aPosition, aOldPosition, aStartOffset, aEndOffset);
-    return [p.pivotChanged(context, aReason) for each (p in this.presenters)]; // jshint ignore:line
+    return [p.pivotChanged(context, aReason, aIsUserInput)
+      for each (p in this.presenters)]; // jshint ignore:line
   },
 
   actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
@@ -604,9 +607,9 @@ this.Presentation = { // jshint ignore:line
 
   textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
                                                       aOldStart, aOldEnd,
-                                                      aIsFromUser) {
+                                                      aIsFromUserInput) {
     return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
-      aIsFromUser) for each (p in this.presenters)]; // jshint ignore:line
+      aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   valueChanged: function valueChanged(aAccessible) {

From 9d5e0ae6c094445da1d811ba7f0b29757a0e0e8d Mon Sep 17 00:00:00 2001
From: Tooru Fujisawa 
Date: Fri, 15 Aug 2014 22:02:25 +0900
Subject: [PATCH 074/101] Bug 1053692 - Do not use optimized stub for spread
 call with many arguments. r=jandem

---
 .../tests/basic/spread-call-near-maxarg.js    | 73 +++++++++++++++++++
 js/src/jit/BaselineIC.cpp                     |  8 +-
 js/src/jit/BaselineIC.h                       |  5 ++
 3 files changed, 84 insertions(+), 2 deletions(-)
 create mode 100644 js/src/jit-test/tests/basic/spread-call-near-maxarg.js

diff --git a/js/src/jit-test/tests/basic/spread-call-near-maxarg.js b/js/src/jit-test/tests/basic/spread-call-near-maxarg.js
new file mode 100644
index 000000000000..2a91b53ac841
--- /dev/null
+++ b/js/src/jit-test/tests/basic/spread-call-near-maxarg.js
@@ -0,0 +1,73 @@
+var config = getBuildConfiguration();
+
+// FIXME: ASAN and debug builds run this too slowly for now.
+if (!config.debug && !config.asan) {
+    let longArray = [];
+    longArray.length = getMaxArgs() - 1;
+    let shortArray = [];
+    let a;
+
+    let f = function() {
+    };
+
+    // Call_Scripted
+    //   Optimized stub is used after some calls.
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            f(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Scripted (constructing)
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            new f(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Native
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            Math.max(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Native (constructing)
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            new Date(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // No optimized stub for eval.
+    a = longArray;
+    try {
+        eval(...a);
+    } catch (e) {
+        assertEq(e.message, "too much recursion");
+    }
+}
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 06182e324451..cb9d548c5cf4 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -8521,8 +8521,12 @@ ICCallStubCompiler::guardSpreadCall(MacroAssembler &masm, Register argcReg, Labe
     masm.loadPtr(Address(argcReg, JSObject::offsetOfElements()), argcReg);
     masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg);
 
-    // Ensure actual argc <= ARGS_LENGTH_MAX
-    masm.branch32(Assembler::Above, argcReg, Imm32(ARGS_LENGTH_MAX), failure);
+    // Limit actual argc to something reasonable (huge number of arguments can
+    // blow the stack limit).
+    static_assert(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH <= ARGS_LENGTH_MAX,
+                  "maximum arguments length for optimized stub should be <= ARGS_LENGTH_MAX");
+    masm.branch32(Assembler::Above, argcReg, Imm32(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH),
+                  failure);
 }
 
 void
diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h
index 52a2ad7c3e6c..e3a545e52187 100644
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -5606,6 +5606,11 @@ class ICCall_Fallback : public ICMonitoredFallbackStub
 class ICCall_Scripted : public ICMonitoredStub
 {
     friend class ICStubSpace;
+  public:
+    // The maximum number of inlineable spread call arguments. Keep this small
+    // to avoid controllable stack overflows by attackers passing large arrays
+    // to spread call. This value is shared with ICCall_Native.
+    static const uint32_t MAX_ARGS_SPREAD_LENGTH = 16;
 
   protected:
     HeapPtrScript calleeScript_;

From 0e20aca78da552ac9df3bf24053f637dabcdea8f Mon Sep 17 00:00:00 2001
From: Nigel Babu 
Date: Sat, 16 Aug 2014 16:57:02 +0530
Subject: [PATCH 075/101] Backed out changeset 62d9d374cd0f (bug 1054409) for
 windows nonunified bustage

---
 accessible/jsat/ContentControl.jsm |  7 +++----
 accessible/jsat/EventManager.jsm   |  3 +--
 accessible/jsat/Presentation.jsm   | 27 ++++++++++++---------------
 3 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/accessible/jsat/ContentControl.jsm b/accessible/jsat/ContentControl.jsm
index 3f7d0b034adf..96b0bb005c4a 100644
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -396,7 +396,7 @@ this.ContentControl.prototype = {
           this._contentScope.get().sendAsyncMessage(
             'AccessFu:Present', Presentation.pivotChanged(
               vc.position, null, Ci.nsIAccessiblePivot.REASON_NONE,
-              vc.startOffset, vc.endOffset, false));
+              vc.startOffset, vc.endOffset));
         }
       };
 
@@ -416,12 +416,11 @@ this.ContentControl.prototype = {
       let moveFirstOrLast = moveMethod in ['moveFirst', 'moveLast'];
       if (!moveFirstOrLast || acc) {
         // We either need next/previous or there is an anchor we need to use.
-        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true,
-                                                              false);
+        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true);
       }
       if (moveFirstOrLast && !moved) {
         // We move to first/last after no anchor move happened or succeeded.
-        moved = vc[moveMethod](rule, false);
+        moved = vc[moveMethod](rule);
       }
 
       let sentToChild = this.sendToChild(vc, {
diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm
index 1e8c372bf1f5..c4d6fe52469b 100644
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -161,8 +161,7 @@ this.EventManager.prototype = {
         }
         this.present(
           Presentation.pivotChanged(position, oldAccessible, reason,
-                                    pivot.startOffset, pivot.endOffset,
-                                    aEvent.isFromUserInput));
+                                    pivot.startOffset, pivot.endOffset));
 
         break;
       }
diff --git a/accessible/jsat/Presentation.jsm b/accessible/jsat/Presentation.jsm
index 502fa32a8ef3..8f5682c6aad8 100644
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -46,9 +46,8 @@ Presenter.prototype = {
    *   position.
    * @param {int} aReason the reason for the pivot change.
    *   See nsIAccessiblePivot.
-   * @param {bool} aIsFromUserInput the pivot change was invoked by the user
    */
-  pivotChanged: function pivotChanged(aContext, aReason, aIsFromUserInput) {}, // jshint ignore:line
+  pivotChanged: function pivotChanged(aContext, aReason) {}, // jshint ignore:line
 
   /**
    * An object's action has been invoked.
@@ -67,7 +66,7 @@ Presenter.prototype = {
    * Text selection has changed. TODO.
    */
   textSelectionChanged: function textSelectionChanged(
-    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput) {}, // jshint ignore:line
+    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {}, // jshint ignore:line
 
   /**
    * Selection has changed. TODO.
@@ -363,15 +362,15 @@ AndroidPresenter.prototype.textChanged = function AndroidPresenter_textChanged(
 
 AndroidPresenter.prototype.textSelectionChanged =
   function AndroidPresenter_textSelectionChanged(aText, aStart, aEnd, aOldStart,
-                                                 aOldEnd, aIsFromUserInput) {
+                                                 aOldEnd, aIsFromUser) {
     let androidEvents = [];
 
-    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
+    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUser) {
       if (!this._braillePresenter) {
         this._braillePresenter = new BraillePresenter();
       }
       let brailleOutput = this._braillePresenter.textSelectionChanged(
-        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput).details;
+        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser).details;
 
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
@@ -383,7 +382,7 @@ AndroidPresenter.prototype.textSelectionChanged =
       });
     }
 
-    if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
+    if (Utils.AndroidSdkVersion >= 16 && aIsFromUser) {
       let [from, to] = aOldStart < aStart ?
         [aOldStart, aStart] : [aStart, aOldStart];
       androidEvents.push({
@@ -470,7 +469,7 @@ B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
                                               'last', 'text', 'point'];
 
 B2GPresenter.prototype.pivotChanged =
-  function B2GPresenter_pivotChanged(aContext, aReason, aIsUserInput) {
+  function B2GPresenter_pivotChanged(aContext, aReason) {
     if (!aContext.accessible) {
       return null;
     }
@@ -483,8 +482,7 @@ B2GPresenter.prototype.pivotChanged =
         options: {
           pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
           isKey: aContext.accessible.role === Roles.KEY,
-          reason: this.pivotChangedReasons[aReason],
-          isUserInput: aIsUserInput
+          reason: this.pivotChangedReasons[aReason]
         }
       }
     };
@@ -586,11 +584,10 @@ this.Presentation = { // jshint ignore:line
   },
 
   pivotChanged: function Presentation_pivotChanged(
-    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset, aIsUserInput) {
+    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset) {
     let context = new PivotContext(
       aPosition, aOldPosition, aStartOffset, aEndOffset);
-    return [p.pivotChanged(context, aReason, aIsUserInput)
-      for each (p in this.presenters)]; // jshint ignore:line
+    return [p.pivotChanged(context, aReason) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
@@ -607,9 +604,9 @@ this.Presentation = { // jshint ignore:line
 
   textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
                                                       aOldStart, aOldEnd,
-                                                      aIsFromUserInput) {
+                                                      aIsFromUser) {
     return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
-      aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
+      aIsFromUser) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   valueChanged: function valueChanged(aAccessible) {

From 897ac778b311b5fd8abd75d27371e1b91b87a02d Mon Sep 17 00:00:00 2001
From: Tom Schuster 
Date: Sat, 16 Aug 2014 13:34:58 +0200
Subject: [PATCH 076/101] Bug 1054322 - Remove unused JSMSGs. r=till

---
 js/src/js.msg | 46 ----------------------------------------------
 1 file changed, 46 deletions(-)

diff --git a/js/src/js.msg b/js/src/js.msg
index 43e65ad94980..515041078ce6 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -51,15 +51,10 @@ MSG_DEF(JSMSG_ALLOC_OVERFLOW,          0, JSEXN_INTERNALERR, "allocation size ov
 MSG_DEF(JSMSG_MISSING_HEXDIGITS,       0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'")
 MSG_DEF(JSMSG_INCOMPATIBLE_PROTO,      3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
 MSG_DEF(JSMSG_NO_CONSTRUCTOR,          1, JSEXN_TYPEERR, "{0} has no constructor")
-MSG_DEF(JSMSG_CANT_ALIAS,              3, JSEXN_TYPEERR, "can't alias {0} to {1} in class {2}")
 MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION,   1, JSEXN_TYPEERR, "{0} is not a scripted function")
 MSG_DEF(JSMSG_BAD_SORT_ARG,            0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument")
-MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER,       1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
-MSG_DEF(JSMSG_TOO_MANY_LITERALS,       0, JSEXN_INTERNALERR, "too many literals")
 MSG_DEF(JSMSG_CANT_WATCH,              1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}")
-MSG_DEF(JSMSG_STACK_UNDERFLOW,         2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
 MSG_DEF(JSMSG_NEED_DIET,               1, JSEXN_INTERNALERR, "{0} too large")
-MSG_DEF(JSMSG_TOO_MANY_LOCAL_ROOTS,    0, JSEXN_ERR, "out of local root space")
 MSG_DEF(JSMSG_READ_ONLY,               1, JSEXN_TYPEERR, "{0} is read-only")
 MSG_DEF(JSMSG_BAD_FORMAL,              0, JSEXN_SYNTAXERR, "malformed formal parameter")
 MSG_DEF(JSMSG_CANT_DELETE,             1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted")
@@ -78,29 +73,21 @@ MSG_DEF(JSMSG_BAD_RADIX,               0, JSEXN_RANGEERR, "radix must be an inte
 MSG_DEF(JSMSG_PAREN_BEFORE_LET,        0, JSEXN_SYNTAXERR, "missing ( before let head")
 MSG_DEF(JSMSG_CANT_CONVERT,            1, JSEXN_ERR, "can't convert {0} to an integer")
 MSG_DEF(JSMSG_CYCLIC_VALUE,            1, JSEXN_TYPEERR, "cyclic {0} value")
-MSG_DEF(JSMSG_COMPILE_EXECED_SCRIPT,   0, JSEXN_TYPEERR, "can't compile over a script that is currently executing")
 MSG_DEF(JSMSG_CANT_CONVERT_TO,         2, JSEXN_TYPEERR, "can't convert {0} to {1}")
 MSG_DEF(JSMSG_NO_PROPERTIES,           1, JSEXN_TYPEERR, "{0} has no properties")
-MSG_DEF(JSMSG_CANT_FIND_CLASS,         1, JSEXN_TYPEERR, "can't find class id {0}")
 MSG_DEF(JSMSG_DEAD_OBJECT,             0, JSEXN_TYPEERR, "can't access dead object")
 MSG_DEF(JSMSG_BYTECODE_TOO_BIG,        2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
 MSG_DEF(JSMSG_UNKNOWN_FORMAT,          1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
 MSG_DEF(JSMSG_TOO_MANY_CON_ARGS,       0, JSEXN_SYNTAXERR, "too many constructor arguments")
 MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS,       0, JSEXN_SYNTAXERR, "too many function arguments")
-MSG_DEF(JSMSG_BAD_QUANTIFIER,          0, JSEXN_SYNTAXERR, "invalid quantifier")
-MSG_DEF(JSMSG_MIN_TOO_BIG,             1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
-MSG_DEF(JSMSG_MAX_TOO_BIG,             1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
-MSG_DEF(JSMSG_OUT_OF_ORDER,            1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
 MSG_DEF(JSMSG_BAD_DESTRUCT_DECL,       0, JSEXN_SYNTAXERR, "missing = in destructuring declaration")
 MSG_DEF(JSMSG_BAD_DESTRUCT_ASS,        0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator")
 MSG_DEF(JSMSG_PAREN_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing ) after let head")
 MSG_DEF(JSMSG_CURLY_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing } after let block")
 MSG_DEF(JSMSG_MISSING_PAREN,           0, JSEXN_SYNTAXERR, "unterminated parenthetical")
 MSG_DEF(JSMSG_UNTERM_CLASS,            0, JSEXN_SYNTAXERR, "unterminated character class")
-MSG_DEF(JSMSG_TRAILING_SLASH,          0, JSEXN_SYNTAXERR, "trailing \\ in regular expression")
 MSG_DEF(JSMSG_BAD_CLASS_RANGE,         0, JSEXN_SYNTAXERR, "invalid range in character class")
 MSG_DEF(JSMSG_BAD_REGEXP_FLAG,         1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
-MSG_DEF(JSMSG_NO_INPUT,                5, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}{3}{4}")
 MSG_DEF(JSMSG_CANT_OPEN,               2, JSEXN_ERR, "can't open {0}: {1}")
 MSG_DEF(JSMSG_TOO_MANY_FUN_APPLY_ARGS, 0, JSEXN_RANGEERR, "arguments array passed to Function.prototype.apply is too large")
 MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN,   0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
@@ -154,7 +141,6 @@ MSG_DEF(JSMSG_SEMI_BEFORE_STMNT,       0, JSEXN_SYNTAXERR, "missing ; before sta
 MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR,    0, JSEXN_SYNTAXERR, "missing } in template string")
 MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
 MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,         0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?")
-MSG_DEF(JSMSG_OPTIMIZED_CLOSURE_LEAK,  0, JSEXN_INTERNALERR, "can't access optimized closure")
 MSG_DEF(JSMSG_TOO_MANY_DEFAULTS,       0, JSEXN_SYNTAXERR, "more than one switch default")
 MSG_DEF(JSMSG_TOO_MANY_CASES,          0, JSEXN_INTERNALERR, "too many switch cases")
 MSG_DEF(JSMSG_BAD_SWITCH,              0, JSEXN_SYNTAXERR, "invalid switch statement")
@@ -166,10 +152,8 @@ MSG_DEF(JSMSG_LABEL_NOT_FOUND,         0, JSEXN_SYNTAXERR, "label not found")
 MSG_DEF(JSMSG_TOUGH_BREAK,             0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch")
 MSG_DEF(JSMSG_BAD_CONTINUE,            0, JSEXN_SYNTAXERR, "continue must be inside loop")
 MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD,     1, JSEXN_SYNTAXERR, "{0} not in function")
-MSG_DEF(JSMSG_BAD_LABEL,               0, JSEXN_SYNTAXERR, "invalid label")
 MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
 MSG_DEF(JSMSG_VAR_HIDES_ARG,           1, JSEXN_TYPEERR, "variable {0} redeclares argument")
-MSG_DEF(JSMSG_BAD_VAR_INIT,            0, JSEXN_SYNTAXERR, "invalid variable initialization")
 MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS,     0, JSEXN_REFERENCEERR, "invalid assignment left-hand side")
 MSG_DEF(JSMSG_BAD_OPERAND,             1, JSEXN_SYNTAXERR, "invalid {0} operand")
 MSG_DEF(JSMSG_BAD_PROP_ID,             0, JSEXN_SYNTAXERR, "invalid property id")
@@ -189,12 +173,9 @@ MSG_DEF(JSMSG_ILLEGAL_CHARACTER,       0, JSEXN_SYNTAXERR, "illegal character")
 MSG_DEF(JSMSG_BAD_OCTAL,               1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
 MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size")
 MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,      1, JSEXN_INTERNALERR, "uncaught exception: {0}")
-MSG_DEF(JSMSG_INVALID_BACKREF,         0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
-MSG_DEF(JSMSG_BAD_BACKREF,             0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
 MSG_DEF(JSMSG_PRECISION_RANGE,         1, JSEXN_RANGEERR, "precision {0} out of range")
 MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER,    1, JSEXN_TYPEERR, "invalid {0} usage")
 MSG_DEF(JSMSG_BAD_ARRAY_LENGTH,        0, JSEXN_RANGEERR, "invalid array length")
-MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS,     1, JSEXN_TYPEERR, "can't describe non-native properties of class {0}")
 MSG_DEF(JSMSG_BAD_APPLY_ARGS,          1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array")
 MSG_DEF(JSMSG_REDECLARED_VAR,          2, JSEXN_TYPEERR, "redeclaration of {0} {1}")
 MSG_DEF(JSMSG_UNDECLARED_VAR,          1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}")
@@ -207,9 +188,6 @@ MSG_DEF(JSMSG_UNDEFINED_PROP,          1, JSEXN_REFERENCEERR, "reference to unde
 MSG_DEF(JSMSG_USELESS_EXPR,            0, JSEXN_TYPEERR, "useless expression")
 MSG_DEF(JSMSG_REDECLARED_PARAM,        1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
 MSG_DEF(JSMSG_NEWREGEXP_FLAGGED,       0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
-MSG_DEF(JSMSG_RESERVED_SLOT_RANGE,     0, JSEXN_RANGEERR, "reserved slot index out of range")
-MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS,  0, JSEXN_INTERNALERR, "can't decode JSPrincipals")
-MSG_DEF(JSMSG_CANT_SEAL_OBJECT,        1, JSEXN_ERR, "can't seal {0} objects")
 MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS,     0, JSEXN_SYNTAXERR, "too many catch variables")
 MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative")
 MSG_DEF(JSMSG_INVALID_FOR_OF_INIT,     0, JSEXN_SYNTAXERR, "for-of loop variable declaration may not have an initializer")
@@ -223,7 +201,6 @@ MSG_DEF(JSMSG_NOTHING_TO_REPEAT,       0, JSEXN_SYNTAXERR, "nothing to repeat")
 MSG_DEF(JSMSG_INVALID_GROUP,           0, JSEXN_SYNTAXERR, "invalid regexp group")
 MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern")
 MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER,    0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.")
-MSG_DEF(JSMSG_BAD_GENERATOR_SEND,      1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator")
 MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE,     0, JSEXN_TYPEERR, "invalid transferable array for structured clone")
 MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE,     0, JSEXN_TYPEERR, "duplicate transferable for structured clone")
 MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible")
@@ -242,7 +219,6 @@ MSG_DEF(JSMSG_INTERNAL_INTL_ERROR,     0, JSEXN_ERR, "internal error while compu
 MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR,    0, JSEXN_ERR, "internal error getting the default locale")
 MSG_DEF(JSMSG_TOO_MANY_LOCALS,         0, JSEXN_SYNTAXERR, "too many local variables")
 MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,      0, JSEXN_INTERNALERR, "array initialiser too large")
-MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX,      0, JSEXN_INTERNALERR, "regular expression too complex")
 MSG_DEF(JSMSG_BUFFER_TOO_SMALL,        0, JSEXN_INTERNALERR, "buffer too small")
 MSG_DEF(JSMSG_BAD_SURROGATE_CHAR,      1, JSEXN_TYPEERR, "bad surrogate character {0}")
 MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE,     1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
@@ -261,16 +237,13 @@ MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE,     0, JSEXN_SYNTAXERR, "invalid array compre
 MSG_DEF(JSMSG_LET_COMP_BINDING,        0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
 MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE,      0, JSEXN_TYPEERR, "reduce of empty array with no initial value")
 MSG_DEF(JSMSG_BAD_SYMBOL,              1, JSEXN_TYPEERR, "{0} is not a well-known @@-symbol")
-MSG_DEF(JSMSG_BAD_DELETE_OPERAND,      0, JSEXN_REFERENCEERR, "invalid delete operand")
 MSG_DEF(JSMSG_BAD_INCOP_OPERAND,       0, JSEXN_REFERENCEERR, "invalid increment/decrement operand")
 MSG_DEF(JSMSG_UNEXPECTED_TYPE,         2, JSEXN_TYPEERR, "{0} is {1}")
 MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK,   0, JSEXN_SYNTAXERR, "let declaration not directly within block")
 MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE,   1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position")
 MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS,    0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties")
-MSG_DEF(JSMSG_EVAL_ARITY,              0, JSEXN_TYPEERR, "eval accepts only one parameter")
 MSG_DEF(JSMSG_MISSING_FUN_ARG,         2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}")
 MSG_DEF(JSMSG_JSON_BAD_PARSE,          3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data")
-MSG_DEF(JSMSG_JSON_BAD_STRINGIFY,      0, JSEXN_ERR, "JSON.stringify")
 MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined")
 MSG_DEF(JSMSG_NOT_NONNULL_OBJECT,      0, JSEXN_TYPEERR, "value is not a non-null object")
 MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
@@ -290,8 +263,6 @@ MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_ERR, "argument {0} must be >= 0"
 MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS,    0, JSEXN_ERR, "invalid arguments")
 MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION,    0, JSEXN_ERR, "call to Function() blocked by CSP")
 MSG_DEF(JSMSG_BAD_GET_SET_FIELD,       1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function")
-MSG_DEF(JSMSG_BAD_PROXY_FIX,           0, JSEXN_TYPEERR, "proxy was fixed while executing the handler")
-MSG_DEF(JSMSG_INVALID_EVAL_SCOPE_ARG,  0, JSEXN_EVALERR, "invalid eval scope argument")
 MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS,     3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}")
 MSG_DEF(JSMSG_THROW_TYPE_ERROR,        0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them")
 MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP,    0, JSEXN_TYPEERR, "toISOString property is not callable")
@@ -303,17 +274,14 @@ MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 0, JSEXN_ERR, "strict mode code may not
 MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility")
 MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA,  1, JSEXN_INTERNALERR, "bad serialized structured data ({0})")
 MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE,     0, JSEXN_TYPEERR, "unsupported type for structured data")
-MSG_DEF(JSMSG_SC_RECURSION,            0, JSEXN_INTERNALERR, "recursive object")
 MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee")
 MSG_DEF(JSMSG_BAD_CLONE_VERSION,       0, JSEXN_ERR, "unsupported structured clone version")
 MSG_DEF(JSMSG_CANT_CLONE_OBJECT,       0, JSEXN_TYPEERR, "can't clone object")
 MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
 MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
 MSG_DEF(JSMSG_INVALID_FOR_IN_INIT,     0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer")
-MSG_DEF(JSMSG_CLEARED_SCOPE,           0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope")
 MSG_DEF(JSMSG_MALFORMED_ESCAPE,        1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence")
 MSG_DEF(JSMSG_BAD_GENEXP_BODY,         1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression")
-MSG_DEF(JSMSG_YIELD_WITHOUT_OPERAND,   0, JSEXN_SYNTAXERR, "yield without a value is deprecated, and illegal in ES6 (use 'yield undefined' instead)")
 MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT,   0, JSEXN_SYNTAXERR, "function statement requires a name")
 MSG_DEF(JSMSG_CCW_REQUIRED,            1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment")
 MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION,    0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null")
@@ -327,8 +295,6 @@ MSG_DEF(JSMSG_DEBUG_BAD_OFFSET,        0, JSEXN_TYPEERR, "invalid script offset"
 MSG_DEF(JSMSG_DEBUG_BAD_LINE,          0, JSEXN_TYPEERR, "invalid line number")
 MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,     0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
 MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
-MSG_DEF(JSMSG_DEBUG_NOT_SCRIPT_FRAME,  0, JSEXN_ERR, "stack frame is not running JavaScript code")
-MSG_DEF(JSMSG_CANT_WATCH_PROP,         0, JSEXN_TYPEERR, "properties whose names are objects can't be watched")
 MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,        0, JSEXN_ERR, "call to eval() blocked by CSP")
 MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,   0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
 MSG_DEF(JSMSG_EMPTY_CONSEQUENT,        0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
@@ -343,10 +309,8 @@ MSG_DEF(JSMSG_FUNCTION_ARGUMENTS_AND_REST, 0, JSEXN_ERR, "the 'arguments' proper
 MSG_DEF(JSMSG_REST_WITH_DEFAULT,       0, JSEXN_SYNTAXERR, "rest parameter may not have a default")
 MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default")
 MSG_DEF(JSMSG_YIELD_IN_DEFAULT,        0, JSEXN_SYNTAXERR, "yield in default expression")
-MSG_DEF(JSMSG_INTRINSIC_NOT_DEFINED,   1, JSEXN_REFERENCEERR, "no intrinsic function {0}")
 MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA,      2, JSEXN_NONE,      "{0} is being assigned a {1}, but already has one")
 MSG_DEF(JSMSG_PAR_ARRAY_BAD_ARG,       0, JSEXN_RANGEERR, "invalid parallel method argument")
-MSG_DEF(JSMSG_REGEXP_RUNTIME_ERROR,    0, JSEXN_INTERNALERR, "an error occurred while executing regular expression")
 MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT,     0, JSEXN_ERR, "variable has been optimized out")
 MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_CONFLICT, 0, JSEXN_ERR, "no conflict resolution function provided")
@@ -393,21 +357,12 @@ MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN,     1, JSEXN_SYNTAXERR, "can't assign to {0}
 MSG_DEF(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS, 0, JSEXN_ERR, "Invalid arguments")
 MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
 MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor")
-MSG_DEF(JSMSG_TYPEDOBJECT_NOT_BINARYSTRUCT, 1, JSEXN_TYPEERR, "{0} is not a BinaryStruct")
-MSG_DEF(JSMSG_TYPEDOBJECT_SUBARRAY_INTEGER_ARG, 1, JSEXN_ERR, "argument {0} must be an integer")
-MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_EMPTY_DESCRIPTOR, 0, JSEXN_ERR, "field descriptor cannot be empty")
-MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_FIELD, 1, JSEXN_ERR, "field {0} is not a valid BinaryData Type descriptor")
-MSG_DEF(JSMSG_GENERATOR_FINISHED,      0, JSEXN_TYPEERR, "generator has already finished")
 MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG,     0, JSEXN_ERR, "Type is too large to allocate")
-MSG_DEF(JSMSG_TYPEDOBJECT_NOT_TYPE_OBJECT, 0, JSEXN_ERR, "Expected a type object")
 MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments")
 MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments")
 MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE,      2, JSEXN_ERR, "{0} is not a debuggee {1}")
-MSG_DEF(JSMSG_TYPEDOBJECT_NOT_TYPED_OBJECT, 0, JSEXN_ERR, "Expected a typed object")
-MSG_DEF(JSMSG_TYPEDOBJECT_NO_SUCH_PROP,1, JSEXN_TYPEERR, "No such property: {0}")
 MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS,    0, JSEXN_TYPEERR, "invalid arguments")
 MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached")
-MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE, 0, JSEXN_TYPEERR, "handle moved to destination of incorrect type")
 MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level")
 MSG_DEF(JSMSG_NO_IMPORT_NAME,          0, JSEXN_SYNTAXERR, "missing import name")
 MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD,  1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
@@ -422,7 +377,6 @@ MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after
 MSG_DEF(JSMSG_NO_EXPORT_NAME,          0, JSEXN_SYNTAXERR, "missing export name")
 MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
 MSG_DEF(JSMSG_INVALID_PROTOTYPE,       0, JSEXN_TYPEERR, "prototype field is not an object")
-MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_TO_UNSIZED, 0, JSEXN_TYPEERR, "cannot create a handle to an unsized type")
 MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL,     1, JSEXN_TYPEERR, "[[SetPrototypeOf]] failed on {0}")
 MSG_DEF(JSMSG_INVALID_ARG_TYPE,        3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}")
 MSG_DEF(JSMSG_TERMINATED,              1, JSEXN_ERR, "Script terminated by timeout at:\n{0}")

From d964b84eea669364e20af3232e1f9798e0025822 Mon Sep 17 00:00:00 2001
From: Jan de Mooij 
Date: Sat, 16 Aug 2014 14:04:17 +0200
Subject: [PATCH 077/101] Bug 1046585 part 6 - Move supportsFloatingPoint from
 JSC assembler to new assemblers. r=sunfish

---
 js/src/asmjs/AsmJSModule.cpp                  |  8 +--
 js/src/asmjs/AsmJSSignalHandlers.cpp          |  1 -
 js/src/assembler/assembler/MacroAssembler.h   | 67 -------------------
 .../assembler/assembler/MacroAssemblerMIPS.h  | 52 --------------
 .../assembler/assembler/MacroAssemblerSparc.h | 25 -------
 .../assembler/assembler/MacroAssemblerX86.h   | 44 ------------
 .../assembler/MacroAssemblerX86_64.h          | 44 ------------
 js/src/jit/Ion.cpp                            |  6 ++
 js/src/jit/Ion.h                              |  2 +
 js/src/jit/arm/Assembler-arm.h                |  4 ++
 js/src/jit/arm/Trampoline-arm.cpp             |  1 -
 js/src/jit/mips/Assembler-mips.h              |  8 +++
 js/src/jit/none/Architecture-none.h           |  4 +-
 js/src/jit/none/BaseMacroAssembler-none.h     | 26 -------
 js/src/jit/none/MacroAssembler-none.h         |  2 +
 js/src/jit/shared/Assembler-x86-shared.h      |  7 +-
 js/src/jit/x64/Architecture-x64.h             |  2 +-
 js/src/jit/x64/Assembler-x64.h                |  2 +
 js/src/jit/x86/Architecture-x86.h             |  2 +-
 js/src/jit/x86/Assembler-x86.h                |  4 ++
 js/src/jit/x86/Trampoline-x86.cpp             |  1 -
 js/src/shell/js.cpp                           |  6 +-
 js/src/vm/Runtime.cpp                         | 17 +----
 23 files changed, 45 insertions(+), 290 deletions(-)
 delete mode 100644 js/src/assembler/assembler/MacroAssembler.h
 delete mode 100644 js/src/assembler/assembler/MacroAssemblerMIPS.h
 delete mode 100644 js/src/assembler/assembler/MacroAssemblerSparc.h
 delete mode 100644 js/src/assembler/assembler/MacroAssemblerX86.h
 delete mode 100644 js/src/assembler/assembler/MacroAssemblerX86_64.h
 delete mode 100644 js/src/jit/none/BaseMacroAssembler-none.h

diff --git a/js/src/asmjs/AsmJSModule.cpp b/js/src/asmjs/AsmJSModule.cpp
index 8a8adf13407d..d7c377777c53 100644
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -1803,12 +1803,12 @@ GetCPUID(uint32_t *cpuId)
     };
 
 #if defined(JS_CODEGEN_X86)
-    JS_ASSERT(uint32_t(JSC::MacroAssembler::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
-    *cpuId = X86 | (JSC::MacroAssembler::getSSEState() << ARCH_BITS);
+    JS_ASSERT(uint32_t(JSC::MacroAssemblerX86Common::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
+    *cpuId = X86 | (JSC::MacroAssemblerX86Common::getSSEState() << ARCH_BITS);
     return true;
 #elif defined(JS_CODEGEN_X64)
-    JS_ASSERT(uint32_t(JSC::MacroAssembler::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
-    *cpuId = X64 | (JSC::MacroAssembler::getSSEState() << ARCH_BITS);
+    JS_ASSERT(uint32_t(JSC::MacroAssemblerX86Common::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
+    *cpuId = X64 | (JSC::MacroAssemblerX86Common::getSSEState() << ARCH_BITS);
     return true;
 #elif defined(JS_CODEGEN_ARM)
     JS_ASSERT(GetARMFlags() <= (UINT32_MAX >> ARCH_BITS));
diff --git a/js/src/asmjs/AsmJSSignalHandlers.cpp b/js/src/asmjs/AsmJSSignalHandlers.cpp
index 60a9364739c5..ca99d9214801 100644
--- a/js/src/asmjs/AsmJSSignalHandlers.cpp
+++ b/js/src/asmjs/AsmJSSignalHandlers.cpp
@@ -21,7 +21,6 @@
 #include "mozilla/DebugOnly.h"
 
 #include "asmjs/AsmJSModule.h"
-#include "assembler/assembler/MacroAssembler.h"
 #include "vm/Runtime.h"
 
 using namespace js;
diff --git a/js/src/assembler/assembler/MacroAssembler.h b/js/src/assembler/assembler/MacroAssembler.h
deleted file mode 100644
index d2e41e456184..000000000000
--- a/js/src/assembler/assembler/MacroAssembler.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssembler_h
-#define assembler_assembler_MacroAssembler_h
-
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
-#if JS_CODEGEN_NONE
-
-#include "jit/none/BaseMacroAssembler-none.h"
-namespace JSC { typedef MacroAssemblerNone MacroAssembler; }
-
-#elif JS_CODEGEN_ARM
-// Merged with the jit backend support.
-
-#elif JS_CODEGEN_MIPS
-#include "assembler/assembler/MacroAssemblerMIPS.h"
-namespace JSC { typedef MacroAssemblerMIPS MacroAssembler; }
-
-#elif JS_CODEGEN_X86
-#include "assembler/assembler/MacroAssemblerX86.h"
-namespace JSC { typedef MacroAssemblerX86 MacroAssembler; }
-
-#elif JS_CODEGEN_X64
-#include "assembler/assembler/MacroAssemblerX86_64.h"
-namespace JSC { typedef MacroAssemblerX86_64 MacroAssembler; }
-
-#elif WTF_CPU_SPARC
-#include "assembler/assembler/MacroAssemblerSparc.h"
-namespace JSC { typedef MacroAssemblerSparc MacroAssembler; }
-
-#else
-#error "The MacroAssembler is not supported on this platform."
-#endif
-
-#endif // ENABLE(ASSEMBLER)
-
-#endif /* assembler_assembler_MacroAssembler_h */
diff --git a/js/src/assembler/assembler/MacroAssemblerMIPS.h b/js/src/assembler/assembler/MacroAssemblerMIPS.h
deleted file mode 100644
index bac462580c32..000000000000
--- a/js/src/assembler/assembler/MacroAssemblerMIPS.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY MIPS TECHNOLOGIES, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef assembler_assembler_MacroAssemblerMIPS_h
-#define assembler_assembler_MacroAssemblerMIPS_h
-
-#if ENABLE(ASSEMBLER) && CPU(MIPS)
-
-#include "assembler/wtf/Platform.h"
-
-namespace JSC {
-
-class MacroAssemblerMIPS {
-public:
-    static bool supportsFloatingPoint()
-    {
-#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR)
-        return true;
-#else
-        return false;
-#endif
-    }
-};
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
-
-#endif /* assembler_assembler_MacroAssemblerMIPS_h */
diff --git a/js/src/assembler/assembler/MacroAssemblerSparc.h b/js/src/assembler/assembler/MacroAssemblerSparc.h
deleted file mode 100644
index 10929a71d4db..000000000000
--- a/js/src/assembler/assembler/MacroAssemblerSparc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99: */
-/* 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 assembler_assembler_MacroAssemblerSparc_h
-#define assembler_assembler_MacroAssemblerSparc_h
-
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER && WTF_CPU_SPARC
-
-namespace JSC {
-
-class MacroAssemblerSparc {
-public:
-    static bool supportsFloatingPoint() { return true; }
-};
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(SPARC)
-
-#endif /* assembler_assembler_MacroAssemblerSparc_h */
diff --git a/js/src/assembler/assembler/MacroAssemblerX86.h b/js/src/assembler/assembler/MacroAssemblerX86.h
deleted file mode 100644
index e51fc3e865a2..000000000000
--- a/js/src/assembler/assembler/MacroAssemblerX86.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssemblerX86_h
-#define assembler_assembler_MacroAssemblerX86_h
-
-#include "assembler/assembler/MacroAssemblerX86Common.h"
-
-namespace JSC {
-
-class MacroAssemblerX86 : public MacroAssemblerX86Common {
-public:
-    static bool supportsFloatingPoint() { return isSSE2Present(); }
-};
-
-} // namespace JSC
-
-#endif /* assembler_assembler_MacroAssemblerX86_h */
diff --git a/js/src/assembler/assembler/MacroAssemblerX86_64.h b/js/src/assembler/assembler/MacroAssemblerX86_64.h
deleted file mode 100644
index c9b8a8276374..000000000000
--- a/js/src/assembler/assembler/MacroAssemblerX86_64.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssemblerX86_64_h
-#define assembler_assembler_MacroAssemblerX86_64_h
-
-#include "assembler/assembler/MacroAssemblerX86Common.h"
-
-namespace JSC {
-
-class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
-public:
-    static bool supportsFloatingPoint() { return true; }
-};
-
-} // namespace JSC
-
-#endif /* assembler_assembler_MacroAssemblerX86_64_h */
diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp
index 8e6ebd60b19f..05d2610e2c29 100644
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -3214,3 +3214,9 @@ AutoDebugModeInvalidation::~AutoDebugModeInvalidation()
         }
     }
 }
+
+bool
+jit::JitSupportsFloatingPoint()
+{
+    return js::jit::MacroAssembler::SupportsFloatingPoint();
+}
diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h
index ba3d65ae5ca5..21116bd89da2 100644
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -203,6 +203,8 @@ bool RematerializeAllFrames(JSContext *cx, JSCompartment *comp);
 bool UpdateForDebugMode(JSContext *maybecx, JSCompartment *comp,
                         AutoDebugModeInvalidation &invalidate);
 
+bool JitSupportsFloatingPoint();
+
 } // namespace jit
 } // namespace js
 
diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h
index e20d4ebfeed9..9b74e44ff89d 100644
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1538,6 +1538,10 @@ class Assembler : public AssemblerShared
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
     static void TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() {
+        return HasVFP();
+    }
+
   protected:
     void addPendingJump(BufferOffset src, ImmPtr target, Relocation::Kind kind) {
         enoughMemory_ &= jumps_.append(RelativePatch(target.value, kind));
diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp
index 0f110770f3b4..a1846d1d41f3 100644
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -6,7 +6,6 @@
 
 #include "jscompartment.h"
 
-#include "assembler/assembler/MacroAssembler.h"
 #include "jit/arm/BaselineHelpers-arm.h"
 #include "jit/Bailouts.h"
 #include "jit/IonFrames.h"
diff --git a/js/src/jit/mips/Assembler-mips.h b/js/src/jit/mips/Assembler-mips.h
index 93df1585b892..5cc553373103 100644
--- a/js/src/jit/mips/Assembler-mips.h
+++ b/js/src/jit/mips/Assembler-mips.h
@@ -996,6 +996,14 @@ class Assembler : public AssemblerShared
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
     static void TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() {
+#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR)
+        return true;
+#else
+        return false;
+#endif
+    }
+
   protected:
     InstImm invertBranch(InstImm branch, BOffImm16 skipOffset);
     void bind(InstImm *inst, uint32_t branch, uint32_t target);
diff --git a/js/src/jit/none/Architecture-none.h b/js/src/jit/none/Architecture-none.h
index 7878b3ca5cc4..40bf91e11480 100644
--- a/js/src/jit/none/Architecture-none.h
+++ b/js/src/jit/none/Architecture-none.h
@@ -7,7 +7,9 @@
 #ifndef jit_none_Architecture_none_h
 #define jit_none_Architecture_none_h
 
-#include "assembler/assembler/MacroAssembler.h"
+// IonSpewer.h is included through MacroAssembler implementations for other
+// platforms, so include it here to avoid inadvertent build bustage.
+#include "jit/IonSpewer.h"
 
 namespace js {
 namespace jit {
diff --git a/js/src/jit/none/BaseMacroAssembler-none.h b/js/src/jit/none/BaseMacroAssembler-none.h
deleted file mode 100644
index b9126cacee56..000000000000
--- a/js/src/jit/none/BaseMacroAssembler-none.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 jit_none_BaseMacroAssembler_none_h
-#define jit_none_BaseMacroAssembler_none_h
-
-// Shim to act like a JSC MacroAssembler for platforms where no MacroAssembler exists.
-
-// IonSpewer.h is included through MacroAssembler implementations for other
-// platforms, so include it here to avoid inadvertent build bustage.
-#include "jit/IonSpewer.h"
-
-namespace JSC {
-
-class MacroAssemblerNone
-{
-  public:
-    static bool supportsFloatingPoint() { return false; }
-};
-
-} // namespace JSC
-
-#endif /* jit_none_BaseMacroAssembler_none_h */
diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h
index baba0d098e17..aa8ed95db880 100644
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -152,6 +152,8 @@ class MacroAssemblerNone : public Assembler
     static void TraceJumpRelocations(JSTracer *, JitCode *, CompactBufferReader &) { MOZ_CRASH(); }
     static void TraceDataRelocations(JSTracer *, JitCode *, CompactBufferReader &) { MOZ_CRASH(); }
 
+    static bool SupportsFloatingPoint() { return false; }
+
     void executableCopy(void *) { MOZ_CRASH(); }
     void copyJumpRelocationTable(uint8_t *) { MOZ_CRASH(); }
     void copyDataRelocationTable(uint8_t *) { MOZ_CRASH(); }
diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h
index ca92ad3e09a0..3c2c6b3725f5 100644
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -9,6 +9,7 @@
 
 #include 
 
+#include "assembler/assembler/MacroAssemblerX86Common.h"
 #include "assembler/assembler/X86Assembler.h"
 #include "jit/shared/Assembler-shared.h"
 
@@ -871,14 +872,14 @@ class AssemblerX86Shared : public AssemblerShared
 
 #ifdef DEBUG
     static bool HasSSE2() {
-        return JSC::MacroAssembler::isSSE2Present();
+        return JSC::MacroAssemblerX86Common::isSSE2Present();
     }
 #endif
     static bool HasSSE3() {
-        return JSC::MacroAssembler::isSSE3Present();
+        return JSC::MacroAssemblerX86Common::isSSE3Present();
     }
     static bool HasSSE41() {
-        return JSC::MacroAssembler::isSSE41Present();
+        return JSC::MacroAssemblerX86Common::isSSE41Present();
     }
 
     // The below cmpl methods switch the lhs and rhs when it invokes the
diff --git a/js/src/jit/x64/Architecture-x64.h b/js/src/jit/x64/Architecture-x64.h
index 84a75b4942dd..06cabdb1983d 100644
--- a/js/src/jit/x64/Architecture-x64.h
+++ b/js/src/jit/x64/Architecture-x64.h
@@ -7,7 +7,7 @@
 #ifndef jit_x64_Architecture_x64_h
 #define jit_x64_Architecture_x64_h
 
-#include "assembler/assembler/MacroAssembler.h"
+#include "assembler/assembler/X86Assembler.h"
 
 namespace js {
 namespace jit {
diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h
index dc38e38d8c03..8f28d9cfcad1 100644
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -265,6 +265,8 @@ class Assembler : public AssemblerX86Shared
 
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() { return true; }
+
     // The buffer is about to be linked, make sure any constant pools or excess
     // bookkeeping has been flushed to the instruction stream.
     void finish();
diff --git a/js/src/jit/x86/Architecture-x86.h b/js/src/jit/x86/Architecture-x86.h
index cb2a3023b6a5..337deb2facc9 100644
--- a/js/src/jit/x86/Architecture-x86.h
+++ b/js/src/jit/x86/Architecture-x86.h
@@ -7,7 +7,7 @@
 #ifndef jit_x86_Architecture_x86_h
 #define jit_x86_Architecture_x86_h
 
-#include "assembler/assembler/MacroAssembler.h"
+#include "assembler/assembler/X86Assembler.h"
 
 namespace js {
 namespace jit {
diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h
index ee55bb6fd3dc..bcc30cb547e1 100644
--- a/js/src/jit/x86/Assembler-x86.h
+++ b/js/src/jit/x86/Assembler-x86.h
@@ -190,6 +190,10 @@ class Assembler : public AssemblerX86Shared
 
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() {
+        return JSC::MacroAssemblerX86Common::isSSE2Present();
+    }
+
     // Copy the assembly code to the given buffer, and perform any pending
     // relocations relying on the target address.
     void executableCopy(uint8_t *buffer);
diff --git a/js/src/jit/x86/Trampoline-x86.cpp b/js/src/jit/x86/Trampoline-x86.cpp
index ecb9d79f338d..caca2352a1fa 100644
--- a/js/src/jit/x86/Trampoline-x86.cpp
+++ b/js/src/jit/x86/Trampoline-x86.cpp
@@ -6,7 +6,6 @@
 
 #include "jscompartment.h"
 
-#include "assembler/assembler/MacroAssembler.h"
 #include "jit/Bailouts.h"
 #include "jit/BaselineJIT.h"
 #include "jit/IonFrames.h"
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index f75008e52732..44374729d78f 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6176,16 +6176,16 @@ main(int argc, char **argv, char **envp)
 
 #ifdef JS_CODEGEN_X86
     if (op.getBoolOption("no-fpu"))
-        JSC::MacroAssembler::SetFloatingPointDisabled();
+        JSC::MacroAssemblerX86Common::SetFloatingPointDisabled();
 #endif
 
 #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
     if (op.getBoolOption("no-sse3")) {
-        JSC::MacroAssembler::SetSSE3Disabled();
+        JSC::MacroAssemblerX86Common::SetSSE3Disabled();
         PropagateFlagToNestedShells("--no-sse3");
     }
     if (op.getBoolOption("no-sse4")) {
-        JSC::MacroAssembler::SetSSE4Disabled();
+        JSC::MacroAssemblerX86Common::SetSSE4Disabled();
         PropagateFlagToNestedShells("--no-sse4");
     }
 #endif
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
index 994cdfd3f9d1..071b32ceb0be 100644
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -30,7 +30,6 @@
 #include "jswrapper.h"
 
 #include "asmjs/AsmJSSignalHandlers.h"
-#include "assembler/assembler/MacroAssembler.h"
 #include "jit/arm/Simulator-arm.h"
 #include "jit/JitCompartment.h"
 #include "jit/mips/Simulator-mips.h"
@@ -233,20 +232,6 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
     PodZero(&asmJSCacheOps);
 }
 
-static bool
-JitSupportsFloatingPoint()
-{
-#if defined(JS_CODEGEN_ARM)
-    if (!js::jit::HasVFP())
-        return false;
-#else
-    if (!JSC::MacroAssembler::supportsFloatingPoint())
-        return false;
-#endif
-
-    return true;
-}
-
 static bool
 SignalBasedTriggersDisabled()
 {
@@ -328,7 +313,7 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
 
     nativeStackBase = GetNativeStackBase();
 
-    jitSupportsFloatingPoint = JitSupportsFloatingPoint();
+    jitSupportsFloatingPoint = js::jit::JitSupportsFloatingPoint();
 
     signalHandlersInstalled_ = EnsureAsmJSSignalHandlersInstalled(this);
     canUseSignalHandlers_ = signalHandlersInstalled_ && !SignalBasedTriggersDisabled();

From 815dfdccd952e2df64ff9dd818c4a12e10f3ddf1 Mon Sep 17 00:00:00 2001
From: Jan de Mooij 
Date: Sat, 16 Aug 2014 14:04:25 +0200
Subject: [PATCH 078/101] Bug 1046585 part 7 - rm
 js/src/assembler/wtf/Platform.h and some other cruft. r=sunfish

---
 js/src/assembler/assembler/AssemblerBuffer.h  |    6 -
 .../assembler/MacroAssemblerX86Common.cpp     |    2 -
 .../assembler/MacroAssemblerX86Common.h       |    6 -
 js/src/assembler/assembler/X86Assembler.h     |    2 -
 js/src/assembler/wtf/Platform.h               | 1272 -----------------
 js/src/jit/ExecutableAllocator.h              |    9 +-
 js/src/moz.build                              |    6 -
 7 files changed, 6 insertions(+), 1297 deletions(-)
 delete mode 100644 js/src/assembler/wtf/Platform.h

diff --git a/js/src/assembler/assembler/AssemblerBuffer.h b/js/src/assembler/assembler/AssemblerBuffer.h
index 88970e1a6f54..04727ba79d59 100644
--- a/js/src/assembler/assembler/AssemblerBuffer.h
+++ b/js/src/assembler/assembler/AssemblerBuffer.h
@@ -30,10 +30,6 @@
 #ifndef assembler_assembler_AssemblerBuffer_h
 #define assembler_assembler_AssemblerBuffer_h
 
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
 #include 
 #include 
 #include 
@@ -329,6 +325,4 @@ namespace JSC {
 
 } // namespace JSC
 
-#endif // ENABLE(ASSEMBLER)
-
 #endif /* assembler_assembler_AssemblerBuffer_h */
diff --git a/js/src/assembler/assembler/MacroAssemblerX86Common.cpp b/js/src/assembler/assembler/MacroAssemblerX86Common.cpp
index 58d9e4298c74..0ded5a951e02 100644
--- a/js/src/assembler/assembler/MacroAssemblerX86Common.cpp
+++ b/js/src/assembler/assembler/MacroAssemblerX86Common.cpp
@@ -6,8 +6,6 @@
 
 #include "assembler/assembler/MacroAssemblerX86Common.h"
 
-#include "assembler/wtf/Platform.h"
-
 #ifdef _MSC_VER
 #ifdef JS_CODEGEN_X64
 /* for __cpuid */
diff --git a/js/src/assembler/assembler/MacroAssemblerX86Common.h b/js/src/assembler/assembler/MacroAssemblerX86Common.h
index 736eadf085da..945a23b9fe74 100644
--- a/js/src/assembler/assembler/MacroAssemblerX86Common.h
+++ b/js/src/assembler/assembler/MacroAssemblerX86Common.h
@@ -30,10 +30,6 @@
 #ifndef assembler_assembler_MacroAssemblerX86Common_h
 #define assembler_assembler_MacroAssemblerX86Common_h
 
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
 #include "assembler/assembler/X86Assembler.h"
 
 namespace JSC {
@@ -192,6 +188,4 @@ private:
 
 } // namespace JSC
 
-#endif // ENABLE(ASSEMBLER)
-
 #endif /* assembler_assembler_MacroAssemblerX86Common_h */
diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h
index b5ce80e31f65..368bee1ae9f0 100644
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -32,8 +32,6 @@
 
 #include 
 
-#include "assembler/wtf/Platform.h"
-
 #include "assembler/assembler/AssemblerBuffer.h"
 #include "js/Vector.h"
 
diff --git a/js/src/assembler/wtf/Platform.h b/js/src/assembler/wtf/Platform.h
deleted file mode 100644
index 06bc5b3fe5f1..000000000000
--- a/js/src/assembler/wtf/Platform.h
+++ /dev/null
@@ -1,1272 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc.  All rights reserved.
- * Copyright (C) 2007-2009 Torch Mobile, Inc.
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef assembler_wtf_Platform_h
-#define assembler_wtf_Platform_h
-
-/* ==== PLATFORM handles OS, operating environment, graphics API, and
-   CPU. This macro will be phased out in favor of platform adaptation
-   macros, policy decision macros, and top-level port definitions. ==== */
-#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE  && WTF_PLATFORM_##WTF_FEATURE)
-
-
-/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */
-
-/* COMPILER() - the compiler being used to build the project */
-#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE  && WTF_COMPILER_##WTF_FEATURE)
-/* CPU() - the target CPU architecture */
-#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE  && WTF_CPU_##WTF_FEATURE)
-/* HAVE() - specific system features (headers, functions or similar) that are present or not */
-#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE  && HAVE_##WTF_FEATURE)
-/* OS() - underlying operating system; only to be used for mandated low-level services like
-   virtual memory, not to choose a GUI toolkit */
-#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE  && WTF_OS_##WTF_FEATURE)
-
-
-/* ==== Policy decision macros: these define policy choices for a particular port. ==== */
-
-/* USE() - use a particular third-party library or optional OS service */
-#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE  && WTF_USE_##WTF_FEATURE)
-/* ENABLE() - turn on a specific feature of WebKit */
-#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE  && ENABLE_##WTF_FEATURE)
-
-
-
-/* ==== COMPILER() - the compiler being used to build the project ==== */
-
-/* WTF_COMPILER_MSVC Microsoft Visual C++ */
-/* WTF_COMPILER_MSVC7_OR_LOWER Microsoft Visual C++ 2003 or lower*/
-/* WTF_COMPILER_MSVC9_OR_LOWER Microsoft Visual C++ 2008 or lower*/
-#if defined(_MSC_VER)
-#define WTF_COMPILER_MSVC 1
-#if _MSC_VER < 1400
-#define WTF_COMPILER_MSVC7_OR_LOWER 1
-#elif _MSC_VER < 1600
-#define WTF_COMPILER_MSVC9_OR_LOWER 1
-#endif
-#endif
-
-/* WTF_COMPILER_RVCT  - ARM RealView Compilation Tools */
-/* WTF_COMPILER_RVCT4_OR_GREATER - ARM RealView Compilation Tools 4.0 or greater */
-#if defined(__CC_ARM) || defined(__ARMCC__)
-#define WTF_COMPILER_RVCT 1
-#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) (__ARMCC_VERSION >= (major * 100000 + minor * 10000 + patch * 1000 + build))
-#else
-/* Define this for !RVCT compilers, just so we can write things like RVCT_VERSION_AT_LEAST(3, 0, 0, 0). */
-#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) 0
-#endif
-
-/* WTF_COMPILER_GCC - GNU Compiler Collection */
-/* --gnu option of the RVCT compiler also defines __GNUC__ */
-#if defined(__GNUC__) && !WTF_COMPILER_RVCT
-#define WTF_COMPILER_GCC 1
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch))
-#else
-/* Define this for !GCC compilers, just so we can write things like GCC_VERSION_AT_LEAST(4, 1, 0). */
-#define GCC_VERSION_AT_LEAST(major, minor, patch) 0
-#endif
-
-/* WTF_COMPILER_MINGW - MinGW GCC */
-/* WTF_COMPILER_MINGW64 - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */
-#if defined(__MINGW32__)
-#define WTF_COMPILER_MINGW 1
-#include <_mingw.h> /* private MinGW header */
-    #if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */
-        #define WTF_COMPILER_MINGW64 1
-    #endif /* __MINGW64_VERSION_MAJOR */
-#endif /* __MINGW32__ */
-
-/* WTF_COMPILER_WINSCW - CodeWarrior for Symbian emulator */
-#if defined(__WINSCW__)
-#define WTF_COMPILER_WINSCW 1
-/* cross-compiling, it is not really windows */
-#undef WIN32
-#undef _WIN32
-#endif
-
-/* WTF_COMPILER_INTEL - Intel C++ Compiler */
-#if defined(__INTEL_COMPILER)
-#define WTF_COMPILER_INTEL 1
-#endif
-
-/* WTF_COMPILER_SUNCC */
-#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
-#define WTF_COMPILER_SUNCC 1
-#endif
-
-/* ==== CPU() - the target CPU architecture ==== */
-
-/* This also defines WTF_CPU_BIG_ENDIAN or WTF_CPU_MIDDLE_ENDIAN or neither, as appropriate. */
-
-/* WTF_CPU_ALPHA - DEC Alpha */
-#if defined(__alpha__)
-#define WTF_CPU_ALPHA 1
-#endif
-
-/* WTF_CPU_IA64 - Itanium / IA-64 */
-#if defined(__ia64__)
-#define WTF_CPU_IA64 1
-/* 32-bit mode on Itanium */
-#if !defined(__LP64__)
-#define WTF_CPU_IA64_32 1
-#endif
-#endif
-
-/* WTF_CPU_MIPS - MIPS 32-bit */
-/* Note: Only O32 ABI is tested, so we enable it for O32 ABI for now.  */
-#if (defined(mips) || defined(__mips__) || defined(MIPS) || defined(_MIPS_)) \
-    && defined(_ABIO32)
-#define WTF_CPU_MIPS 1
-#if defined(__MIPSEB__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#define WTF_MIPS_PIC (defined __PIC__)
-#define WTF_MIPS_ARCH __mips
-#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
-#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
-#define WTF_MIPS_ARCH_REV __mips_isa_rev
-#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
-#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float)
-#define WTF_MIPS_FP64 (defined __mips_fpr && __mips_fpr == 64)
-/* MIPS requires allocators to use aligned memory */
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-#endif /* MIPS */
-
-#if defined(JS_MIPS_SIMULATOR)
-#define WTF_MIPS_ARCH 32
-#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
-#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
-#define WTF_MIPS_ARCH_REV 2
-#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
-#define WTF_MIPS_DOUBLE_FLOAT 1
-#undef WTF_MIPS_FP64
-#endif
-
-/* WTF_CPU_PPC - PowerPC 32-bit */
-#if   defined(__ppc__)     \
-    || defined(__PPC__)     \
-    || defined(__powerpc__) \
-    || defined(__powerpc)   \
-    || defined(__POWERPC__) \
-    || defined(_M_PPC)      \
-    || defined(__PPC)
-#if !defined(__ppc64__) && !defined(__PPC64__)
-#define WTF_CPU_PPC 1
-#endif
-#if !defined(__LITTLE_ENDIAN__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_PPC64 - PowerPC 64-bit */
-#if   defined(__ppc64__) \
-    || defined(__PPC64__)
-#define WTF_CPU_PPC64 1
-#if !defined(__LITTLE_ENDIAN__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_SH4 - SuperH SH-4 */
-#if defined(__SH4__)
-#define WTF_CPU_SH4 1
-#endif
-
-/* WTF_CPU_SPARC32 - SPARC 32-bit */
-#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
-#define WTF_CPU_SPARC32 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_SPARC64 - SPARC 64-bit */
-#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)
-#define WTF_CPU_SPARC64 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_SPARC - any SPARC, true for WTF_CPU_SPARC32 and WTF_CPU_SPARC64 */
-#if WTF_CPU_SPARC32 || WTF_CPU_SPARC64
-#define WTF_CPU_SPARC 1
-#endif
-
-/* WTF_CPU_S390X - S390 64-bit */
-#if defined(__s390x__)
-#define WTF_CPU_S390X 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_S390 - S390 32-bit */
-#if defined(__s390__)
-#define WTF_CPU_S390 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-#if defined(__aarch64__)
-#define WTF_CPU_AARCH64 1
-#if defined(__AARCH64EB__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_X86 - i386 / x86 32-bit */
-#if   defined(__i386__) \
-    || defined(i386)     \
-    || defined(_M_IX86)  \
-    || defined(_X86_)    \
-    || defined(__THW_INTEL)
-#define WTF_CPU_X86 1
-#endif
-
-/* WTF_CPU_X86_64 - AMD64 / Intel64 / x86_64 64-bit */
-#if   defined(__x86_64__) \
-    || defined(_M_X64)
-#define WTF_CPU_X86_64 1
-#endif
-
-/* WTF_CPU_ARM - ARM, any version*/
-#if   defined(arm) \
-    || defined(__arm__) \
-    || defined(ARM) \
-    || defined(_ARM_)
-#define WTF_CPU_ARM 1
-
-#if defined(__ARMEB__) || (WTF_COMPILER_RVCT && defined(__BIG_ENDIAN))
-#define WTF_CPU_BIG_ENDIAN 1
-
-#elif !defined(__ARM_EABI__) \
-    && !defined(__EABI__) \
-    && !defined(__VFP_FP__) \
-    && !defined(_WIN32_WCE) \
-    && !defined(ANDROID)
-#define WTF_CPU_MIDDLE_ENDIAN 1
-
-#endif
-
-#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
-#define WTF_ARM_ARCH_AT_LEAST_5 (WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 5)
-
-/* Set WTF_ARM_ARCH_VERSION */
-#if   defined(__ARM_ARCH_4__) \
-    || defined(__ARM_ARCH_4T__) \
-    || defined(__MARM_ARMV4__) \
-    || defined(_ARMV4I_)
-#define WTF_ARM_ARCH_VERSION 4
-
-#elif defined(__ARM_ARCH_5__) \
-    || defined(__ARM_ARCH_5T__) \
-    || defined(__MARM_ARMV5__)
-#define WTF_ARM_ARCH_VERSION 5
-
-#elif defined(__ARM_ARCH_5E__) \
-    || defined(__ARM_ARCH_5TE__) \
-    || defined(__ARM_ARCH_5TEJ__)
-#define WTF_ARM_ARCH_VERSION 5
-/*ARMv5TE requires allocators to use aligned memory*/
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-
-#elif defined(__ARM_ARCH_6__) \
-    || defined(__ARM_ARCH_6J__) \
-    || defined(__ARM_ARCH_6K__) \
-    || defined(__ARM_ARCH_6Z__) \
-    || defined(__ARM_ARCH_6ZK__) \
-    || defined(__ARM_ARCH_6T2__) \
-    || defined(__ARMV6__)
-#define WTF_ARM_ARCH_VERSION 6
-
-#elif defined(__ARM_ARCH_7A__) \
-    || defined(__ARM_ARCH_7R__)
-#define WTF_ARM_ARCH_VERSION 7
-
-/* RVCT sets _TARGET_ARCH_ARM */
-#elif defined(__TARGET_ARCH_ARM)
-#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM
-
-#if defined(__TARGET_ARCH_5E) \
-    || defined(__TARGET_ARCH_5TE) \
-    || defined(__TARGET_ARCH_5TEJ)
-/*ARMv5TE requires allocators to use aligned memory*/
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-#endif
-
-#else
-#define WTF_ARM_ARCH_VERSION 0
-
-#endif
-
-/* Set WTF_THUMB_ARCH_VERSION */
-#if   defined(__ARM_ARCH_4T__)
-#define WTF_THUMB_ARCH_VERSION 1
-
-#elif defined(__ARM_ARCH_5T__) \
-    || defined(__ARM_ARCH_5TE__) \
-    || defined(__ARM_ARCH_5TEJ__)
-#define WTF_THUMB_ARCH_VERSION 2
-
-#elif defined(__ARM_ARCH_6J__) \
-    || defined(__ARM_ARCH_6K__) \
-    || defined(__ARM_ARCH_6Z__) \
-    || defined(__ARM_ARCH_6ZK__) \
-    || defined(__ARM_ARCH_6M__)
-#define WTF_THUMB_ARCH_VERSION 3
-
-#elif defined(__ARM_ARCH_6T2__) \
-    || defined(__ARM_ARCH_7__) \
-    || defined(__ARM_ARCH_7A__) \
-    || defined(__ARM_ARCH_7R__) \
-    || defined(__ARM_ARCH_7M__)
-#define WTF_THUMB_ARCH_VERSION 4
-
-/* RVCT sets __TARGET_ARCH_THUMB */
-#elif defined(__TARGET_ARCH_THUMB)
-#define WTF_THUMB_ARCH_VERSION __TARGET_ARCH_THUMB
-
-#else
-#define WTF_THUMB_ARCH_VERSION 0
-#endif
-
-
-/* WTF_CPU_ARMV5_OR_LOWER - ARM instruction set v5 or earlier */
-/* On ARMv5 and below the natural alignment is required.
-   And there are some other differences for v5 or earlier. */
-#if !defined(ARMV5_OR_LOWER) && WTF_CPU_ARM && !(WTF_ARM_ARCH_VERSION >= 6)
-#define WTF_CPU_ARMV5_OR_LOWER 1
-#endif
-
-
-/* WTF_CPU_ARM_TRADITIONAL - Thumb2 is not available, only traditional ARM (v4 or greater) */
-/* WTF_CPU_ARM_THUMB2 - Thumb2 instruction set is available */
-/* Only one of these will be defined. */
-#if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2)
-#  if defined(thumb2) || defined(__thumb2__) \
-    || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4)
-#    define WTF_CPU_ARM_TRADITIONAL 1
-#    define WTF_CPU_ARM_THUMB2 0
-#  elif WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 4
-#    define WTF_CPU_ARM_TRADITIONAL 1
-#    define WTF_CPU_ARM_THUMB2 0
-#  else
-#    error "Not supported ARM architecture"
-#  endif
-#elif WTF_CPU_ARM_TRADITIONAL && WTF_CPU_ARM_THUMB2 /* Sanity Check */
-#  error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms"
-#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */
-
-#if defined(__ARM_NEON__) && !defined(WTF_CPU_ARM_NEON)
-#define WTF_CPU_ARM_NEON 1
-#endif
-
-#endif /* ARM */
-
-#if defined(JS_ARM_SIMULATOR)
-#  undef WTF_CPU_X86
-#  undef WTF_CPU_X64
-#  define WTF_CPU_ARM_TRADITIONAL 1
-#  define WTF_CPU_ARM 1
-#endif
-
-#if defined(JS_MIPS_SIMULATOR)
-#  undef WTF_CPU_X86
-#  undef WTF_CPU_X64
-#  define WTF_CPU_MIPS 1
-#endif
-
-#if WTF_CPU_ARM || WTF_CPU_MIPS
-#define WTF_CPU_NEEDS_ALIGNED_ACCESS 1
-#endif
-
-/* ==== OS() - underlying operating system; only to be used for mandated low-level services like
-   virtual memory, not to choose a GUI toolkit ==== */
-
-/* WTF_OS_ANDROID - Android */
-#ifdef ANDROID
-#define WTF_OS_ANDROID 1
-#endif
-
-/* WTF_OS_AIX - AIX */
-#ifdef _AIX
-#define WTF_OS_AIX 1
-#endif
-
-/* WTF_OS_DARWIN - Any Darwin-based OS, including Mac OS X and iPhone OS */
-#ifdef __APPLE__
-#define WTF_OS_DARWIN 1
-
-/* FIXME: BUILDING_ON_.., and TARGETING... macros should be folded into the OS() system */
-#include 
-#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_TIGER 1
-#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
-#define BUILDING_ON_LEOPARD 1
-#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-#define BUILDING_ON_SNOW_LEOPARD 1
-#endif
-#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
-#define TARGETING_TIGER 1
-#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-#define TARGETING_LEOPARD 1
-#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
-#define TARGETING_SNOW_LEOPARD 1
-#endif
-#include 
-
-#endif
-
-/* WTF_OS_IOS - iOS */
-/* WTF_OS_MAC_OS_X - Mac OS X (not including iOS) */
-#if WTF_OS_DARWIN && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED)  \
-    || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)                   \
-    || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR))
-#define WTF_OS_IOS 1
-#elif WTF_OS_DARWIN && defined(TARGET_OS_MAC) && TARGET_OS_MAC
-#define WTF_OS_MAC_OS_X 1
-#endif
-
-
-/* WTF_OS_FREEBSD - FreeBSD */
-#if defined(__FreeBSD__) || defined(__DragonFly__)
-#define WTF_OS_FREEBSD 1
-#endif
-
-/* WTF_OS_HAIKU - Haiku */
-#ifdef __HAIKU__
-#define WTF_OS_HAIKU 1
-#endif
-
-/* WTF_OS_LINUX - Linux */
-#if defined(__linux__) && !defined(ANDROID)
-#define WTF_OS_LINUX 1
-#endif
-
-/* WTF_OS_NETBSD - NetBSD */
-#if defined(__NetBSD__)
-#define WTF_OS_NETBSD 1
-#endif
-
-/* WTF_OS_OPENBSD - OpenBSD */
-#ifdef __OpenBSD__
-#define WTF_OS_OPENBSD 1
-#endif
-
-/* WTF_OS_QNX - QNX */
-#if defined(__QNXNTO__)
-#define WTF_OS_QNX 1
-#endif
-
-/* WTF_OS_SOLARIS - Solaris */
-#if defined(sun) || defined(__sun)
-#define WTF_OS_SOLARIS 1
-#endif
-
-/* WTF_OS_WINCE - Windows CE; note that for this platform WTF_OS_WINDOWS is also defined */
-#if defined(_WIN32_WCE)
-#define WTF_OS_WINCE 1
-#endif
-
-/* WTF_OS_WINDOWS - Any version of Windows */
-#if defined(WIN32) || defined(_WIN32)
-#define WTF_OS_WINDOWS 1
-#endif
-
-/* WTF_OS_SYMBIAN - Symbian */
-#if defined (__SYMBIAN32__)
-#define WTF_OS_SYMBIAN 1
-#endif
-
-/* WTF_OS_UNIX - Any Unix-like system */
-#if   WTF_OS_AIX              \
-    || WTF_OS_ANDROID          \
-    || WTF_OS_DARWIN           \
-    || WTF_OS_FREEBSD          \
-    || WTF_OS_HAIKU            \
-    || WTF_OS_LINUX            \
-    || WTF_OS_NETBSD           \
-    || WTF_OS_OPENBSD          \
-    || WTF_OS_QNX              \
-    || WTF_OS_SOLARIS          \
-    || WTF_OS_SYMBIAN          \
-    || defined(unix)        \
-    || defined(__unix)      \
-    || defined(__unix__)
-#define WTF_OS_UNIX 1
-#endif
-
-/* WTF_OS_OS2 - OS/2 */
-#if defined (__OS2__)
-#define WTF_OS_OS2 1
-#endif
-
-/* Operating environments */
-
-/* FIXME: these are all mixes of OS, operating environment and policy choices. */
-/* WTF_PLATFORM_CHROMIUM */
-/* WTF_PLATFORM_QT */
-/* WTF_PLATFORM_WX */
-/* WTF_PLATFORM_GTK */
-/* WTF_PLATFORM_HAIKU */
-/* WTF_PLATFORM_MAC */
-/* WTF_PLATFORM_WIN */
-#if defined(BUILDING_CHROMIUM__)
-#define WTF_PLATFORM_CHROMIUM 1
-#elif defined(BUILDING_QT__)
-#define WTF_PLATFORM_QT 1
-#elif defined(BUILDING_WX__)
-#define WTF_PLATFORM_WX 1
-#elif defined(BUILDING_GTK__)
-#define WTF_PLATFORM_GTK 1
-#elif defined(BUILDING_HAIKU__)
-#define WTF_PLATFORM_HAIKU 1
-#elif defined(BUILDING_BREWMP__)
-#define WTF_PLATFORM_BREWMP 1
-#if defined(AEE_SIMULATOR)
-#define WTF_PLATFORM_BREWMP_SIMULATOR 1
-#else
-#define WTF_PLATFORM_BREWMP_SIMULATOR 0
-#endif
-#undef WTF_OS_WINDOWS
-#undef WTF_PLATFORM_WIN
-#elif WTF_OS_DARWIN
-#define WTF_PLATFORM_MAC 1
-#elif WTF_OS_WINDOWS
-#define WTF_PLATFORM_WIN 1
-#endif
-
-/* WTF_PLATFORM_IOS */
-/* FIXME: this is sometimes used as an OS switch and sometimes for higher-level things */
-#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
-#define WTF_PLATFORM_IOS 1
-#endif
-
-/* WTF_PLATFORM_IOS_SIMULATOR */
-#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
-#define WTF_PLATFORM_IOS 1
-#define WTF_PLATFORM_IOS_SIMULATOR 1
-#else
-#define WTF_PLATFORM_IOS_SIMULATOR 0
-#endif
-
-#if !defined(WTF_PLATFORM_IOS)
-#define WTF_PLATFORM_IOS 0
-#endif
-
-/* WTF_PLATFORM_ANDROID */
-/* FIXME: this is sometimes used as an OS() switch, and other times to drive
-   policy choices */
-#if defined(ANDROID)
-#define WTF_PLATFORM_ANDROID 1
-#endif
-
-/* Graphics engines */
-
-/* WTF_USE_CG and WTF_PLATFORM_CI */
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_IOS
-#define WTF_USE_CG 1
-#endif
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_IOS || (WTF_PLATFORM_WIN && WTF_USE_CG)
-#define WTF_USE_CA 1
-#endif
-
-/* WTF_USE_SKIA for Win/Linux, CG for Mac */
-#if WTF_PLATFORM_CHROMIUM
-#if WTF_OS_DARWIN
-#define WTF_USE_CG 1
-#define WTF_USE_ATSUI 1
-#define WTF_USE_CORE_TEXT 1
-#define WTF_USE_ICCJPEG 1
-#else
-#define WTF_USE_SKIA 1
-#define WTF_USE_CHROMIUM_NET 1
-#endif
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define WTF_USE_SKIA 1
-#endif
-
-#if WTF_PLATFORM_GTK
-#define WTF_USE_CAIRO 1
-#endif
-
-
-#if WTF_OS_WINCE
-#include 
-#define WTF_USE_MERSENNE_TWISTER_19937 1
-#endif
-
-#if WTF_PLATFORM_QT && WTF_OS_UNIX && !WTF_OS_SYMBIAN && !WTF_OS_DARWIN
-#define WTF_USE_PTHREAD_BASED_QT 1
-#endif
-
-#if (WTF_PLATFORM_GTK || WTF_PLATFORM_IOS || WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || (WTF_PLATFORM_QT && (WTF_OS_DARWIN || WTF_USE_PTHREAD_BASED_QT) && !ENABLE_SINGLE_THREADED)) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
-#define ENABLE_JSC_MULTIPLE_THREADS 1
-#endif
-
-#if ENABLE_JSC_MULTIPLE_THREADS
-#define ENABLE_WTF_MULTIPLE_THREADS 1
-#endif
-
-/* On Windows, use QueryPerformanceCounter by default */
-#if WTF_OS_WINDOWS
-#define WTF_USE_QUERY_PERFORMANCE_COUNTER  1
-#endif
-
-#if WTF_OS_WINCE && !WTF_PLATFORM_QT
-#define NOMINMAX       /* Windows min and max conflict with standard macros */
-#define NOSHLWAPI      /* shlwapi.h not available on WinCe */
-
-/* MSDN documentation says these functions are provided with uspce.lib.  But we cannot find this file. */
-#define __usp10__      /* disable "usp10.h" */
-
-#define _INC_ASSERT    /* disable "assert.h" */
-#define assert(x)
-
-#endif  /* WTF_OS_WINCE && !WTF_PLATFORM_QT */
-
-#if WTF_PLATFORM_QT
-#define WTF_USE_QT4_UNICODE 1
-#elif WTF_OS_WINCE
-#define WTF_USE_WINCE_UNICODE 1
-#elif WTF_PLATFORM_BREWMP
-#define WTF_USE_BREWMP_UNICODE 1
-#elif WTF_PLATFORM_GTK
-/* The GTK+ Unicode backend is configurable */
-#else
-#define WTF_USE_ICU_UNICODE 1
-#endif
-
-#if WTF_PLATFORM_MAC && !WTF_PLATFORM_IOS
-#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && WTF_CPU_X86_64
-#define WTF_USE_PLUGIN_HOST_PROCESS 1
-#endif
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
-#define ENABLE_GESTURE_EVENTS 1
-#define ENABLE_RUBBER_BANDING 1
-#define WTF_USE_WK_SCROLLBAR_PAINTER 1
-#endif
-#if !defined(ENABLE_JAVA_BRIDGE)
-#define ENABLE_JAVA_BRIDGE 1
-#endif
-#if !defined(ENABLE_DASHBOARD_SUPPORT)
-#define ENABLE_DASHBOARD_SUPPORT 1
-#endif
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define HAVE_READLINE 1
-#define HAVE_RUNLOOP_TIMER 1
-#define ENABLE_FULLSCREEN_API 1
-#define ENABLE_SMOOTH_SCROLLING 1
-#define ENABLE_WEB_ARCHIVE 1
-#endif /* WTF_PLATFORM_MAC && !WTF_PLATFORM_IOS */
-
-#if WTF_PLATFORM_CHROMIUM && WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define ENABLE_SINGLE_THREADED 1
-#endif
-
-#if WTF_PLATFORM_QT && WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#endif
-
-#if WTF_OS_DARWIN && !defined(BUILDING_ON_TIGER) && !WTF_PLATFORM_GTK && !WTF_PLATFORM_QT
-#define ENABLE_PURGEABLE_MEMORY 1
-#endif
-
-#if WTF_PLATFORM_IOS
-#define ENABLE_CONTEXT_MENUS 0
-#define ENABLE_DRAG_SUPPORT 0
-#define ENABLE_DATA_TRANSFER_ITEMS 0
-#define ENABLE_FTPDIR 1
-#define ENABLE_GEOLOCATION 1
-#define ENABLE_ICONDATABASE 0
-#define ENABLE_INSPECTOR 0
-#define ENABLE_JAVA_BRIDGE 0
-#define ENABLE_NETSCAPE_PLUGIN_API 0
-#define ENABLE_ORIENTATION_EVENTS 1
-#define ENABLE_REPAINT_THROTTLING 1
-#define HAVE_READLINE 1
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-
-#if WTF_PLATFORM_ANDROID
-#define WTF_USE_PTHREADS 1
-#define USE_SYSTEM_MALLOC 1
-#define ENABLE_JAVA_BRIDGE 1
-#define LOG_DISABLED 1
-/* Prevents Webkit from drawing the caret in textfields and textareas
-   This prevents unnecessary invals. */
-#define ENABLE_TEXT_CARET 1
-#define ENABLE_JAVASCRIPT_DEBUGGER 0
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 0
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE && !WTF_PLATFORM_CHROMIUM && !defined(WIN_CAIRO)
-#define WTF_USE_CFNETWORK 1
-#endif
-
-#if WTF_USE_CFNETWORK || WTF_PLATFORM_MAC
-#define WTF_USE_CFURLCACHE 1
-#define WTF_USE_CFURLSTORAGESESSIONS 1
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE && !WTF_PLATFORM_CHROMIUM && !WTF_PLATFORM_QT
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-
-#if WTF_PLATFORM_WX
-#define ENABLE_ASSEMBLER 1
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#if WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#ifndef BUILDING_ON_TIGER
-#define WTF_USE_CORE_TEXT 1
-#define ENABLE_WEB_ARCHIVE 1
-#else
-#define WTF_USE_ATSUI 1
-#endif
-#endif
-#endif
-
-#if WTF_PLATFORM_GTK
-#if HAVE_PTHREAD_H
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#endif
-#endif
-
-#if WTF_PLATFORM_HAIKU
-#define HAVE_POSIX_MEMALIGN 1
-#define WTF_USE_CURL 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define USE_SYSTEM_MALLOC 1
-#define ENABLE_NETSCAPE_PLUGIN_API 0
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define USE_SYSTEM_MALLOC 1
-#endif
-
-#if WTF_PLATFORM_BREWMP_SIMULATOR
-#define ENABLE_JIT 0
-#endif
-
-#if !defined(HAVE_ACCESSIBILITY)
-#if WTF_PLATFORM_IOS || WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || WTF_PLATFORM_GTK || WTF_PLATFORM_CHROMIUM
-#define HAVE_ACCESSIBILITY 1
-#endif
-#endif /* !defined(HAVE_ACCESSIBILITY) */
-
-#if WTF_OS_UNIX && !WTF_OS_SYMBIAN
-#define HAVE_SIGNAL_H 1
-#endif
-
-#if !defined(HAVE_STRNSTR)
-#if WTF_OS_DARWIN || WTF_OS_FREEBSD
-#define HAVE_STRNSTR 1
-#endif
-#endif
-
-#if !WTF_OS_WINDOWS && !WTF_OS_SOLARIS && !WTF_OS_QNX \
-    && !WTF_OS_SYMBIAN && !WTF_OS_HAIKU && !WTF_OS_RVCT \
-    && !WTF_OS_ANDROID && !WTF_PLATFORM_BREWMP
-#define HAVE_TM_GMTOFF 1
-#define HAVE_TM_ZONE 1
-#define HAVE_TIMEGM 1
-#endif
-
-#if WTF_OS_DARWIN
-
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 1
-#define HAVE_MERGESORT 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_SYS_TIMEB_H 1
-#define WTF_USE_ACCELERATE 1
-
-#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD)
-
-#define HAVE_DISPATCH_H 1
-#define HAVE_HOSTED_CORE_ANIMATION 1
-
-#if !WTF_PLATFORM_IOS
-#define HAVE_MADV_FREE_REUSE 1
-#define HAVE_MADV_FREE 1
-#define HAVE_PTHREAD_SETNAME_NP 1
-#endif
-
-#endif
-
-#if WTF_PLATFORM_IOS
-#define HAVE_MADV_FREE 1
-#endif
-
-#elif WTF_OS_WINDOWS
-
-#if WTF_OS_WINCE
-#define HAVE_ERRNO_H 0
-#else
-#define HAVE_SYS_TIMEB_H 1
-#define HAVE_ALIGNED_MALLOC 1
-#define HAVE_ISDEBUGGERPRESENT 1
-#endif
-#define HAVE_VIRTUALALLOC 1
-
-#elif WTF_OS_SYMBIAN
-
-#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 0
-#define HAVE_SBRK 1
-
-#define HAVE_SYS_TIME_H 1
-#define HAVE_STRINGS_H 1
-
-#if !WTF_COMPILER_RVCT
-#define HAVE_SYS_PARAM_H 1
-#endif
-
-#elif WTF_PLATFORM_BREWMP
-
-#define HAVE_ERRNO_H 1
-
-#elif WTF_OS_QNX
-
-#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#elif WTF_OS_ANDROID
-
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 0
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#elif WTF_OS_OS2
-
-#define USE_SYSTEM_MALLOC 1
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 0
-#define HAVE_POSIX_MEMALIGN 1
-#define HAVE_SBRK 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_STRINGS_H 1
-
-#else
-
-/* FIXME: is this actually used or do other platforms generate their own config.h? */
-
-#define HAVE_ERRNO_H 1
-/* As long as Haiku doesn't have a complete support of locale this will be disabled. */
-#if !WTF_OS_HAIKU
-#define HAVE_LANGINFO_H 1
-#endif
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#endif
-
-/* ENABLE macro defaults */
-
-#if WTF_PLATFORM_QT
-/* We must not customize the global operator new and delete for the Qt port. */
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#if !WTF_OS_UNIX || WTF_OS_SYMBIAN
-#define USE_SYSTEM_MALLOC 1
-#endif
-#endif
-
-/* fastMalloc match validation allows for runtime verification that
-   new is matched by delete, fastMalloc is matched by fastFree, etc. */
-#if !defined(ENABLE_FAST_MALLOC_MATCH_VALIDATION)
-#define ENABLE_FAST_MALLOC_MATCH_VALIDATION 0
-#endif
-
-#if !defined(ENABLE_ICONDATABASE)
-#define ENABLE_ICONDATABASE 1
-#endif
-
-#if !defined(ENABLE_DATABASE)
-#define ENABLE_DATABASE 1
-#endif
-
-#if !defined(ENABLE_JAVASCRIPT_DEBUGGER)
-#define ENABLE_JAVASCRIPT_DEBUGGER 1
-#endif
-
-#if !defined(ENABLE_FTPDIR)
-#define ENABLE_FTPDIR 1
-#endif
-
-#if !defined(ENABLE_CONTEXT_MENUS)
-#define ENABLE_CONTEXT_MENUS 1
-#endif
-
-#if !defined(ENABLE_DRAG_SUPPORT)
-#define ENABLE_DRAG_SUPPORT 1
-#endif
-
-#if !defined(ENABLE_DATA_TRANSFER_ITEMS)
-#define ENABLE_DATA_TRANSFER_ITEMS 0
-#endif
-
-#if !defined(ENABLE_DASHBOARD_SUPPORT)
-#define ENABLE_DASHBOARD_SUPPORT 0
-#endif
-
-#if !defined(ENABLE_INSPECTOR)
-#define ENABLE_INSPECTOR 1
-#endif
-
-#if !defined(ENABLE_JAVA_BRIDGE)
-#define ENABLE_JAVA_BRIDGE 0
-#endif
-
-#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
-#define ENABLE_NETSCAPE_PLUGIN_API 1
-#endif
-
-#if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE)
-#define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0
-#endif
-
-#if !defined(ENABLE_PURGEABLE_MEMORY)
-#define ENABLE_PURGEABLE_MEMORY 0
-#endif
-
-#if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
-#define WTF_USE_PLUGIN_HOST_PROCESS 0
-#endif
-
-#if !defined(ENABLE_ORIENTATION_EVENTS)
-#define ENABLE_ORIENTATION_EVENTS 0
-#endif
-
-#if !defined(ENABLE_OPCODE_STATS)
-#define ENABLE_OPCODE_STATS 0
-#endif
-
-#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW)
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 1
-#endif
-
-#define ENABLE_DEBUG_WITH_BREAKPOINT 0
-#define ENABLE_SAMPLING_COUNTERS 0
-#define ENABLE_SAMPLING_FLAGS 0
-#define ENABLE_OPCODE_SAMPLING 0
-#define ENABLE_CODEBLOCK_SAMPLING 0
-#if ENABLE_CODEBLOCK_SAMPLING && !ENABLE_OPCODE_SAMPLING
-#error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING"
-#endif
-#if ENABLE_OPCODE_SAMPLING || ENABLE_SAMPLING_FLAGS
-#define ENABLE_SAMPLING_THREAD 1
-#endif
-
-#if !defined(ENABLE_GEOLOCATION)
-#define ENABLE_GEOLOCATION 0
-#endif
-
-#if !defined(ENABLE_GESTURE_RECOGNIZER)
-#define ENABLE_GESTURE_RECOGNIZER 0
-#endif
-
-#if !defined(ENABLE_NOTIFICATIONS)
-#define ENABLE_NOTIFICATIONS 0
-#endif
-
-#if WTF_PLATFORM_IOS
-#define ENABLE_TEXT_CARET 0
-#endif
-
-#if !defined(ENABLE_TEXT_CARET)
-#define ENABLE_TEXT_CARET 1
-#endif
-
-#if !defined(ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
-#define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
-#endif
-
-#if !defined(ENABLE_FULLSCREEN_API)
-#define ENABLE_FULLSCREEN_API 0
-#endif
-
-#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64)
-#if (WTF_CPU_X86_64 && (WTF_OS_UNIX || WTF_OS_WINDOWS)) \
-    || (WTF_CPU_IA64 && !WTF_CPU_IA64_32) \
-    || WTF_CPU_ALPHA \
-    || WTF_CPU_SPARC64 \
-    || WTF_CPU_S390X \
-    || WTF_CPU_PPC64
-#define WTF_USE_JSVALUE64 1
-#else
-#define WTF_USE_JSVALUE32_64 1
-#endif
-#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) */
-
-#if !defined(ENABLE_REPAINT_THROTTLING)
-#define ENABLE_REPAINT_THROTTLING 0
-#endif
-
-/* Disable the JIT on versions of GCC prior to 4.1 */
-#if !defined(ENABLE_JIT) && WTF_COMPILER_GCC && !GCC_VERSION_AT_LEAST(4, 1, 0)
-#define ENABLE_JIT 0
-#endif
-
-/* The JIT is enabled by default on all x86, x64-64, ARM platforms. */
-#if !defined(ENABLE_JIT) \
-    && (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_SPARC32 || WTF_CPU_MIPS) \
-    && (WTF_OS_DARWIN || !WTF_COMPILER_GCC || GCC_VERSION_AT_LEAST(4, 1, 0)) \
-    && !WTF_OS_WINCE
-#define ENABLE_JIT 1
-#endif
-
-/* Currently only implemented for JSVALUE64, only tested on WTF_PLATFORM_MAC */
-#if ENABLE_JIT && WTF_USE_JSVALUE64 && WTF_PLATFORM_MAC
-#define ENABLE_DFG_JIT 1
-/* Enabled with restrictions to circumvent known performance regressions. */
-#define ENABLE_DFG_JIT_RESTRICTIONS 1
-#endif
-
-/* Ensure that either the JIT or the interpreter has been enabled. */
-#if !defined(ENABLE_INTERPRETER) && !ENABLE_JIT
-#define ENABLE_INTERPRETER 1
-#endif
-#if !(ENABLE_JIT || ENABLE_INTERPRETER)
-#error You have to have at least one execution model enabled to build JSC
-#endif
-
-#if WTF_CPU_SH4 && WTF_PLATFORM_QT
-#define ENABLE_JIT 1
-#define ENABLE_YARR 1
-#define ENABLE_YARR_JIT 1
-#define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
-#define ENABLE_ASSEMBLER 1
-#endif
-
-/* Configure the JIT */
-#if ENABLE_JIT
-    #if WTF_CPU_ARM
-    #if !defined(ENABLE_JIT_USE_SOFT_MODULO) && WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 5
-    #define ENABLE_JIT_USE_SOFT_MODULO 1
-    #endif
-    #endif
-
-    #ifndef ENABLE_JIT_OPTIMIZE_CALL
-    #define ENABLE_JIT_OPTIMIZE_CALL 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL
-    #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
-    #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
-    #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
-    #endif
-#endif
-
-#if WTF_CPU_X86 && WTF_COMPILER_MSVC
-#define JSC_HOST_CALL __fastcall
-#elif WTF_CPU_X86 && WTF_COMPILER_GCC
-#define JSC_HOST_CALL __attribute__ ((fastcall))
-#else
-#define JSC_HOST_CALL
-#endif
-
-/* Configure the interpreter */
-#if WTF_COMPILER_GCC || (RVCT_VERSION_AT_LEAST(4, 0, 0, 0) && defined(__GNUC__))
-#define HAVE_COMPUTED_GOTO 1
-#endif
-#if HAVE_COMPUTED_GOTO && ENABLE_INTERPRETER
-#define ENABLE_COMPUTED_GOTO_INTERPRETER 1
-#endif
-
-/* Regular Expression Tracing - Set to 1 to trace RegExp's in jsc.  Results dumped at exit */
-#define ENABLE_REGEXP_TRACING 0
-
-/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
-#if WTF_PLATFORM_CHROMIUM
-#define ENABLE_YARR_JIT 0
-
-#elif ENABLE_YARR_JIT
-/* Setting this flag compares JIT results with interpreter results. */
-#define ENABLE_YARR_JIT_DEBUG 0
-#endif
-
-#if ENABLE_JIT || ENABLE_YARR_JIT
-#define ENABLE_ASSEMBLER 1
-#endif
-/* Setting this flag prevents the assembler from using RWX memory; this may improve
-   security but currectly comes at a significant performance cost. */
-#if WTF_PLATFORM_IOS
-//XXX: this doesn't currently compile in the spidermonkey build
-#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0
-#endif
-
-/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in.
-   On x86-64 we use a single fixed mmap, on other platforms we mmap on demand. */
-#if ENABLE_ASSEMBLER
-#if WTF_CPU_X86_64
-#define ENABLE_EXECUTABLE_ALLOCATOR_FIXED 1
-#else
-#define ENABLE_EXECUTABLE_ALLOCATOR_DEMAND 1
-#endif
-#endif
-
-#if !defined(ENABLE_PAN_SCROLLING) && WTF_OS_WINDOWS
-#define ENABLE_PAN_SCROLLING 1
-#endif
-
-#if !defined(ENABLE_SMOOTH_SCROLLING)
-#define ENABLE_SMOOTH_SCROLLING 0
-#endif
-
-#if !defined(ENABLE_WEB_ARCHIVE)
-#define ENABLE_WEB_ARCHIVE 0
-#endif
-
-/* Use the QXmlStreamReader implementation for XMLDocumentParser */
-/* Use the QXmlQuery implementation for XSLTProcessor */
-#if WTF_PLATFORM_QT
-#define WTF_USE_QXMLSTREAM 1
-#define WTF_USE_QXMLQUERY 1
-#endif
-
-#if WTF_PLATFORM_MAC
-/* Complex text framework */
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
-#define WTF_USE_ATSUI 0
-#define WTF_USE_CORE_TEXT 1
-#else
-#define WTF_USE_ATSUI 1
-#define WTF_USE_CORE_TEXT 0
-#endif
-#endif
-
-/* Accelerated compositing */
-#if (WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER)) || WTF_PLATFORM_IOS || WTF_PLATFORM_QT || (WTF_PLATFORM_WIN && !WTF_OS_WINCE &&!defined(WIN_CAIRO))
-#define WTF_USE_ACCELERATED_COMPOSITING 1
-#endif
-
-#if (WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)) || WTF_PLATFORM_IOS
-#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
-#endif
-
-#if WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
-#define WTF_USE_AVFOUNDATION 1
-#endif
-
-#if WTF_COMPILER_GCC
-#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
-#else
-#define WARN_UNUSED_RETURN
-#endif
-
-/* COMPILER(CLANG) - Clang  */
-#if defined(__clang__)
-#define WTF_COMPILER_CLANG 1
-#endif
-
-#if !ENABLE_NETSCAPE_PLUGIN_API || (ENABLE_NETSCAPE_PLUGIN_API && ((WTF_OS_UNIX && (WTF_PLATFORM_QT || WTF_PLATFORM_WX)) || WTF_PLATFORM_GTK))
-#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
-#endif
-
-/* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */
-#define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK
-
-#define ENABLE_JSC_ZOMBIES 0
-
-/* FIXME: Eventually we should enable this for all platforms and get rid of the define. */
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || WTF_PLATFORM_QT
-#define WTF_USE_PLATFORM_STRATEGIES 1
-#endif
-
-#if WTF_PLATFORM_WIN
-#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1
-#endif
-
-/* Geolocation request policy. pre-emptive policy is to acquire user permission before acquiring location.
-   Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy.
-   pre-emptive permission policy is enabled by default for all client-based implementations. */
-#if ENABLE_CLIENT_BASED_GEOLOCATION
-#define WTF_USE_PREEMPT_GEOLOCATION_PERMISSION 1
-#endif
-
-#if WTF_CPU_ARM_THUMB2
-#define ENABLE_BRANCH_COMPACTION 1
-#endif
-
-#if !defined(ENABLE_THREADING_OPENMP) && defined(_OPENMP)
-#define ENABLE_THREADING_OPENMP 1
-#endif
-
-#if !defined(ENABLE_PARALLEL_JOBS) && !ENABLE_SINGLE_THREADED && (ENABLE_THREADING_GENERIC || ENABLE_THREADING_LIBDISPATCH || ENABLE_THREADING_OPENMP)
-#define ENABLE_PARALLEL_JOBS 1
-#endif
-
-#if ENABLE_GLIB_SUPPORT
-//#include "GTypedefs.h"
-#endif
-
-/* FIXME: This define won't be needed once #27551 is fully landed. However,
-   since most ports try to support sub-project independence, adding new headers
-   to WTF causes many ports to break, and so this way we can address the build
-   breakages one port at a time. */
-#define WTF_USE_EXPORT_MACROS 0
-
-#if WTF_PLATFORM_QT || WTF_PLATFORM_GTK
-#define WTF_USE_UNIX_DOMAIN_SOCKETS 1
-#endif
-
-#endif /* assembler_wtf_Platform_h */
diff --git a/js/src/jit/ExecutableAllocator.h b/js/src/jit/ExecutableAllocator.h
index a8aabf9abd8d..412d72daa42d 100644
--- a/js/src/jit/ExecutableAllocator.h
+++ b/js/src/jit/ExecutableAllocator.h
@@ -31,7 +31,6 @@
 
 #include "jsalloc.h"
 
-#include "assembler/wtf/Platform.h"
 #include "jit/arm/Simulator-arm.h"
 #include "jit/mips/Simulator-mips.h"
 #include "js/HashTable.h"
@@ -402,8 +401,10 @@ public:
 #elif defined(JS_CODEGEN_MIPS)
     static void cacheFlush(void* code, size_t size)
     {
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+
 #if defined(__GNUC__) && (GCC_VERSION >= 40300)
-#if WTF_MIPS_ISA_REV(2) && (GCC_VERSION < 40403)
+#if (__mips_isa_rev == 2) && (GCC_VERSION < 40403)
         int lineSize;
         asm("rdhwr %0, $1" : "=r" (lineSize));
         //
@@ -424,8 +425,10 @@ public:
 #else
         _flush_cache(reinterpret_cast(code), size, BCACHE);
 #endif
+
+#undef GCC_VERSION
     }
-#elif WTF_CPU_ARM_TRADITIONAL && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
+#elif defined(JS_CODEGEN_ARM) && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
     static void cacheFlush(void* code, size_t size)
     {
         asm volatile (
diff --git a/js/src/moz.build b/js/src/moz.build
index 5284f043650f..2b8af8b07107 100644
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -485,12 +485,6 @@ if CONFIG['_MSC_VER']:
     # XXX We should add this to CXXFLAGS, too?
     CFLAGS += ['-fp:precise']
 
-# Needed to "configure" it correctly.  Unfortunately these
-# flags wind up being applied to all code in js/src, not just
-# the code in js/src/assembler.
-DEFINES['USE_SYSTEM_MALLOC'] = 1
-DEFINES['ENABLE_ASSEMBLER'] = 1
-
 if CONFIG['OS_ARCH'] not in ('WINNT', 'HP-UX'):
     OS_LIBS += [
         'm',

From 1fa187f695c0af3ee8aff7d112362b48e2d25b36 Mon Sep 17 00:00:00 2001
From: Eitan Isaacson 
Date: Sat, 16 Aug 2014 01:06:16 -0400
Subject: [PATCH 079/101] Bug 1054409 - Add isFromUserInput to pivot change
 presentation. r=yzen

---
 accessible/jsat/ContentControl.jsm |  7 ++++---
 accessible/jsat/EventManager.jsm   |  3 ++-
 accessible/jsat/Presentation.jsm   | 27 +++++++++++++++------------
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/accessible/jsat/ContentControl.jsm b/accessible/jsat/ContentControl.jsm
index 96b0bb005c4a..3f7d0b034adf 100644
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -396,7 +396,7 @@ this.ContentControl.prototype = {
           this._contentScope.get().sendAsyncMessage(
             'AccessFu:Present', Presentation.pivotChanged(
               vc.position, null, Ci.nsIAccessiblePivot.REASON_NONE,
-              vc.startOffset, vc.endOffset));
+              vc.startOffset, vc.endOffset, false));
         }
       };
 
@@ -416,11 +416,12 @@ this.ContentControl.prototype = {
       let moveFirstOrLast = moveMethod in ['moveFirst', 'moveLast'];
       if (!moveFirstOrLast || acc) {
         // We either need next/previous or there is an anchor we need to use.
-        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true);
+        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true,
+                                                              false);
       }
       if (moveFirstOrLast && !moved) {
         // We move to first/last after no anchor move happened or succeeded.
-        moved = vc[moveMethod](rule);
+        moved = vc[moveMethod](rule, false);
       }
 
       let sentToChild = this.sendToChild(vc, {
diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm
index c4d6fe52469b..1e8c372bf1f5 100644
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -161,7 +161,8 @@ this.EventManager.prototype = {
         }
         this.present(
           Presentation.pivotChanged(position, oldAccessible, reason,
-                                    pivot.startOffset, pivot.endOffset));
+                                    pivot.startOffset, pivot.endOffset,
+                                    aEvent.isFromUserInput));
 
         break;
       }
diff --git a/accessible/jsat/Presentation.jsm b/accessible/jsat/Presentation.jsm
index 8f5682c6aad8..502fa32a8ef3 100644
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -46,8 +46,9 @@ Presenter.prototype = {
    *   position.
    * @param {int} aReason the reason for the pivot change.
    *   See nsIAccessiblePivot.
+   * @param {bool} aIsFromUserInput the pivot change was invoked by the user
    */
-  pivotChanged: function pivotChanged(aContext, aReason) {}, // jshint ignore:line
+  pivotChanged: function pivotChanged(aContext, aReason, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * An object's action has been invoked.
@@ -66,7 +67,7 @@ Presenter.prototype = {
    * Text selection has changed. TODO.
    */
   textSelectionChanged: function textSelectionChanged(
-    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {}, // jshint ignore:line
+    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * Selection has changed. TODO.
@@ -362,15 +363,15 @@ AndroidPresenter.prototype.textChanged = function AndroidPresenter_textChanged(
 
 AndroidPresenter.prototype.textSelectionChanged =
   function AndroidPresenter_textSelectionChanged(aText, aStart, aEnd, aOldStart,
-                                                 aOldEnd, aIsFromUser) {
+                                                 aOldEnd, aIsFromUserInput) {
     let androidEvents = [];
 
-    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
       if (!this._braillePresenter) {
         this._braillePresenter = new BraillePresenter();
       }
       let brailleOutput = this._braillePresenter.textSelectionChanged(
-        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser).details;
+        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput).details;
 
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
@@ -382,7 +383,7 @@ AndroidPresenter.prototype.textSelectionChanged =
       });
     }
 
-    if (Utils.AndroidSdkVersion >= 16 && aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
       let [from, to] = aOldStart < aStart ?
         [aOldStart, aStart] : [aStart, aOldStart];
       androidEvents.push({
@@ -469,7 +470,7 @@ B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
                                               'last', 'text', 'point'];
 
 B2GPresenter.prototype.pivotChanged =
-  function B2GPresenter_pivotChanged(aContext, aReason) {
+  function B2GPresenter_pivotChanged(aContext, aReason, aIsUserInput) {
     if (!aContext.accessible) {
       return null;
     }
@@ -482,7 +483,8 @@ B2GPresenter.prototype.pivotChanged =
         options: {
           pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
           isKey: aContext.accessible.role === Roles.KEY,
-          reason: this.pivotChangedReasons[aReason]
+          reason: this.pivotChangedReasons[aReason],
+          isUserInput: aIsUserInput
         }
       }
     };
@@ -584,10 +586,11 @@ this.Presentation = { // jshint ignore:line
   },
 
   pivotChanged: function Presentation_pivotChanged(
-    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset) {
+    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset, aIsUserInput) {
     let context = new PivotContext(
       aPosition, aOldPosition, aStartOffset, aEndOffset);
-    return [p.pivotChanged(context, aReason) for each (p in this.presenters)]; // jshint ignore:line
+    return [p.pivotChanged(context, aReason, aIsUserInput)
+      for each (p in this.presenters)]; // jshint ignore:line
   },
 
   actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
@@ -604,9 +607,9 @@ this.Presentation = { // jshint ignore:line
 
   textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
                                                       aOldStart, aOldEnd,
-                                                      aIsFromUser) {
+                                                      aIsFromUserInput) {
     return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
-      aIsFromUser) for each (p in this.presenters)]; // jshint ignore:line
+      aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   valueChanged: function valueChanged(aAccessible) {

From 7aa484acd144fb14ca14a66df5a2d19247381ee5 Mon Sep 17 00:00:00 2001
From: Jan de Mooij 
Date: Sat, 16 Aug 2014 16:00:40 +0200
Subject: [PATCH 080/101] Bug 1030460 - Always initialize shadowsResult in
 EffectlesslyLookupProperty to work around a Clang/Valgrind issue. r=djvj

---
 js/src/jit/BaselineIC.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index cb9d548c5cf4..5e6c6871aabe 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -3316,8 +3316,10 @@ EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName n
     shape.set(nullptr);
     holder.set(nullptr);
 
-    if (checkDOMProxy)
+    if (checkDOMProxy) {
         *checkDOMProxy = false;
+        *shadowsResult = ShadowCheckFailed;
+    }
 
     // Check for list base if asked to.
     RootedObject checkObj(cx, obj);

From 1230a33c4e158341f38e253b3041fe0a70922c56 Mon Sep 17 00:00:00 2001
From: Jan de Mooij 
Date: Sat, 16 Aug 2014 16:13:30 +0200
Subject: [PATCH 081/101] Bug 1053431 - Fix a shell-only race with
 enableOsiPointRegisterChecks(). r=nbp

---
 js/src/jit/shared/CodeGenerator-shared.cpp | 5 ++++-
 js/src/jit/shared/CodeGenerator-shared.h   | 7 +++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp
index 3adea610ccb6..c8523853dc45 100644
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -60,6 +60,9 @@ CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph, Mac
     sps_(&GetIonContext()->runtime->spsProfiler(), &lastNotInlinedPC_),
     osrEntryOffset_(0),
     skipArgCheckEntryOffset_(0),
+#ifdef CHECK_OSIPOINT_REGISTERS
+    checkOsiPointRegisters(js_JitOptions.checkOsiPointRegisters),
+#endif
     frameDepth_(graph->paddedLocalSlotsSize() + graph->argumentsSize()),
     frameInitialAdjustment_(0)
 {
@@ -965,7 +968,7 @@ CodeGeneratorShared::verifyOsiPointRegs(LSafepoint *safepoint)
 bool
 CodeGeneratorShared::shouldVerifyOsiPointRegs(LSafepoint *safepoint)
 {
-    if (!js_JitOptions.checkOsiPointRegisters)
+    if (!checkOsiPointRegisters)
         return false;
 
     if (gen->info().executionMode() != SequentialExecution)
diff --git a/js/src/jit/shared/CodeGenerator-shared.h b/js/src/jit/shared/CodeGenerator-shared.h
index 530c4e8974db..e810da03ecb4 100644
--- a/js/src/jit/shared/CodeGenerator-shared.h
+++ b/js/src/jit/shared/CodeGenerator-shared.h
@@ -158,6 +158,13 @@ class CodeGeneratorShared : public LInstructionVisitor
     void dropArguments(unsigned argc);
 
   protected:
+#ifdef CHECK_OSIPOINT_REGISTERS
+    // See js_JitOptions.checkOsiPointRegisters. We set this here to avoid
+    // races when enableOsiPointRegisterChecks is called while we're generating
+    // code off-thread.
+    bool checkOsiPointRegisters;
+#endif
+
     // The initial size of the frame in bytes. These are bytes beyond the
     // constant header present for every Ion frame, used for pre-determined
     // spills.

From 1c46913c479b5e016cbbb2c58a501be8fdd7a46a Mon Sep 17 00:00:00 2001
From: Jonathan Kew 
Date: Sat, 16 Aug 2014 16:13:53 +0100
Subject: [PATCH 082/101] bug 1048752 followup - fix for Windows non-unified
 build. no_r=me, bustage fix

---
 accessible/windows/sdn/sdnTextAccessible.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/accessible/windows/sdn/sdnTextAccessible.cpp b/accessible/windows/sdn/sdnTextAccessible.cpp
index 156d0fed1a3c..028a0f28c7f0 100644
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -15,6 +15,7 @@
 #include "nsFontMetrics.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
+#include "nsRange.h"
 #include "gfxFont.h"
 #include "nsIAccessibleTypes.h"
 #include "mozilla/gfx/2D.h"

From 2edcef48ed977f5ae1f759bc4c2ec3846c10dc24 Mon Sep 17 00:00:00 2001
From: Guptha Rajagopal 
Date: Fri, 15 Aug 2014 15:55:00 -0400
Subject: [PATCH 083/101] Bug 924672 - Implement ES6 method definitions.
 r=jorendorff

---
 js/src/frontend/FullParseHandler.h            |   2 +-
 js/src/frontend/ParseNode.h                   |   2 +-
 js/src/frontend/Parser.cpp                    |  63 +++++++-
 js/src/frontend/Parser.h                      |   3 +
 js/src/frontend/SyntaxParseHandler.h          |   2 +-
 js/src/jit-test/tests/class/methDefn.js       |  15 ++
 js/src/jsreflect.cpp                          |   9 +-
 js/src/tests/ecma_6/Class/methDefn.js         | 151 ++++++++++++++++++
 js/src/tests/ecma_6/Class/methDefnGen.js      |  70 ++++++++
 .../tests/js1_8_5/extensions/reflect-parse.js |  10 ++
 10 files changed, 313 insertions(+), 14 deletions(-)
 create mode 100644 js/src/jit-test/tests/class/methDefn.js
 create mode 100644 js/src/tests/ecma_6/Class/methDefn.js
 create mode 100644 js/src/tests/ecma_6/Class/methDefnGen.js

diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h
index eef3dbfee5e9..a1e3d6169cc9 100644
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -299,7 +299,7 @@ class FullParseHandler
         return true;
     }
 
-    bool addAccessorPropertyDefinition(ParseNode *literal, ParseNode *name, ParseNode *fn, JSOp op)
+    bool addMethodDefinition(ParseNode *literal, ParseNode *name, ParseNode *fn, JSOp op)
     {
         JS_ASSERT(literal->isArity(PN_LIST));
         literal->pn_xflags |= PNX_NONCONST;
diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h
index b9400434c51b..3ea403d4aa74 100644
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -1514,7 +1514,7 @@ enum ParseReportKind
     ParseStrictError
 };
 
-enum FunctionSyntaxKind { Expression, Statement, Arrow };
+enum FunctionSyntaxKind { Expression, Statement, Arrow, Method };
 
 static inline ParseNode *
 FunctionArgsList(ParseNode *fn, unsigned *numFormals)
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 83d5d57b32bc..ac25cd285c43 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7095,9 +7095,17 @@ Parser::objectLiteral()
         if (ltok == TOK_RC)
             break;
 
+        bool isGenerator = false;
+        if (ltok == TOK_MUL) {
+            isGenerator = true;
+            ltok = tokenStream.getToken(TokenStream::KeywordIsName);
+        }
+
         JSOp op = JSOP_INITPROP;
         Node propname;
         switch (ltok) {
+          case TOK_ERROR:
+            return null();
           case TOK_NUMBER:
             atom = DoubleToAtom(context, tokenStream.currentToken().number());
             if (!atom)
@@ -7122,8 +7130,16 @@ Parser::objectLiteral()
           case TOK_NAME: {
             atom = tokenStream.currentName();
             if (atom == context->names().get) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 op = JSOP_INITPROP_GETTER;
             } else if (atom == context->names().set) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 op = JSOP_INITPROP_SETTER;
             } else {
                 propname = handler.newIdentifier(atom, pos());
@@ -7201,6 +7217,10 @@ Parser::objectLiteral()
             TokenKind tt = tokenStream.getToken();
             Node propexpr;
             if (tt == TOK_COLON) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 propexpr = assignExpr();
                 if (!propexpr)
                     return null();
@@ -7223,6 +7243,10 @@ Parser::objectLiteral()
                  * Support, e.g., |var {x, y} = o| as destructuring shorthand
                  * for |var {x: x, y: y} = o|, per proposed JS2/ES4 for JS1.8.
                  */
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 if (!abortIfSyntaxParser())
                     return null();
                 tokenStream.ungetToken();
@@ -7236,21 +7260,22 @@ Parser::objectLiteral()
                 Node ident = identifierName();
                 if (!handler.addPropertyDefinition(literal, propname, ident, true))
                     return null();
+            } else if (tt == TOK_LP) {
+                tokenStream.ungetToken();
+                if (!methodDefinition(literal, propname, Normal, Method,
+                                      isGenerator ? StarGenerator : NotGenerator, op)) {
+                    return null();
+                }
             } else {
                 report(ParseError, false, null(), JSMSG_COLON_AFTER_ID);
                 return null();
             }
         } else {
             /* NB: Getter function in { get x(){} } is unnamed. */
-            Rooted funName(context, nullptr);
-            TokenStream::Position start(keepAtoms);
-            tokenStream.tell(&start);
-            Node accessor = functionDef(funName, start, op == JSOP_INITPROP_GETTER ? Getter : Setter,
-                                        Expression, NotGenerator);
-            if (!accessor)
-                return null();
-            if (!handler.addAccessorPropertyDefinition(literal, propname, accessor, op))
+            if (!methodDefinition(literal, propname, op == JSOP_INITPROP_GETTER ? Getter : Setter,
+                                  Expression, NotGenerator, op)) {
                 return null();
+            }
         }
 
         /*
@@ -7309,6 +7334,28 @@ Parser::objectLiteral()
     return literal;
 }
 
+template 
+bool
+Parser::methodDefinition(Node literal, Node propname, FunctionType type,
+                                       FunctionSyntaxKind kind, GeneratorKind generatorKind,
+                                       JSOp op)
+{
+    RootedPropertyName funName(context);
+    if (kind == Method && tokenStream.isCurrentTokenType(TOK_NAME))
+        funName = tokenStream.currentName();
+    else
+        funName = nullptr;
+
+    TokenStream::Position start(keepAtoms);
+    tokenStream.tell(&start);
+    Node fn = functionDef(funName, start, type, kind, generatorKind);
+    if (!fn)
+        return false;
+    if (!handler.addMethodDefinition(literal, propname, fn, op))
+        return false;
+    return true;
+}
+
 template 
 typename ParseHandler::Node
 Parser::primaryExpr(TokenKind tt)
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index e82b1c080963..cb04aa28c9bf 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -538,6 +538,9 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
     Node parenExprOrGeneratorComprehension();
     Node exprInParens();
 
+    bool methodDefinition(Node literal, Node propname, FunctionType type, FunctionSyntaxKind kind,
+                          GeneratorKind generatorKind, JSOp Op);
+
     /*
      * Additional JS parsers.
      */
diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h
index c09ee1c050de..83161a5b879c 100644
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -134,7 +134,7 @@ class SyntaxParseHandler
     Node newObjectLiteral(uint32_t begin) { return NodeGeneric; }
     bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
     bool addPropertyDefinition(Node literal, Node name, Node expr, bool isShorthand = false) { return true; }
-    bool addAccessorPropertyDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
+    bool addMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
 
     // Statements
 
diff --git a/js/src/jit-test/tests/class/methDefn.js b/js/src/jit-test/tests/class/methDefn.js
new file mode 100644
index 000000000000..f8a6d883a470
--- /dev/null
+++ b/js/src/jit-test/tests/class/methDefn.js
@@ -0,0 +1,15 @@
+load(libdir + "asserts.js");
+
+function f(tag) { return {[tag](){return 1;}}; }
+a = [];
+for (var i = 0; i < 2000; i++)
+    a[i] = f("first");
+
+for (var i = 0; i < 2000; i++)
+    assertEq(a[i].first(), 1);
+
+for (var i = 0; i < 2000; i++)
+    a[i] = f("second");
+
+for (var i = 0; i < 2000; i++)
+    assertEq(a[i].second(), 1);
diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp
index 10233faf01da..c884ac68b839 100644
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -552,7 +552,7 @@ class NodeBuilder
                      MutableHandleValue dst);
 
     bool propertyInitializer(HandleValue key, HandleValue val, PropKind kind, bool isShorthand,
-                             TokenPos *pos, MutableHandleValue dst);
+                             bool isMethod, TokenPos *pos, MutableHandleValue dst);
 
 
     /*
@@ -1314,7 +1314,7 @@ NodeBuilder::propertyPattern(HandleValue key, HandleValue patt, bool isShorthand
 
 bool
 NodeBuilder::propertyInitializer(HandleValue key, HandleValue val, PropKind kind, bool isShorthand,
-                                 TokenPos *pos, MutableHandleValue dst)
+                                 bool isMethod, TokenPos *pos, MutableHandleValue dst)
 {
     RootedValue kindName(cx);
     if (!atomValue(kind == PROP_INIT
@@ -1326,6 +1326,7 @@ NodeBuilder::propertyInitializer(HandleValue key, HandleValue val, PropKind kind
     }
 
     RootedValue isShorthandVal(cx, BooleanValue(isShorthand));
+    RootedValue isMethodVal(cx, BooleanValue(isMethod));
 
     RootedValue cb(cx, callbacks[AST_PROPERTY]);
     if (!cb.isNull())
@@ -1335,6 +1336,7 @@ NodeBuilder::propertyInitializer(HandleValue key, HandleValue val, PropKind kind
                    "key", key,
                    "value", val,
                    "kind", kindName,
+                   "method", isMethodVal,
                    "shorthand", isShorthandVal,
                    dst);
 }
@@ -3030,10 +3032,11 @@ ASTSerializer::property(ParseNode *pn, MutableHandleValue dst)
     }
 
     bool isShorthand = pn->isKind(PNK_SHORTHAND);
+    bool isMethod = pn->pn_right->isKind(PNK_FUNCTION) && kind == PROP_INIT;
     RootedValue key(cx), val(cx);
     return propertyName(pn->pn_left, &key) &&
            expression(pn->pn_right, &val) &&
-           builder.propertyInitializer(key, val, kind, isShorthand, &pn->pn_pos, dst);
+           builder.propertyInitializer(key, val, kind, isShorthand, isMethod, &pn->pn_pos, dst);
 }
 
 bool
diff --git a/js/src/tests/ecma_6/Class/methDefn.js b/js/src/tests/ecma_6/Class/methDefn.js
new file mode 100644
index 000000000000..64338f93c066
--- /dev/null
+++ b/js/src/tests/ecma_6/Class/methDefn.js
@@ -0,0 +1,151 @@
+var BUGNUMBER = 924672;
+var summary = 'Method Definitions'
+
+print(BUGNUMBER + ": " + summary);
+
+// Function definitions.
+function syntaxError (script) {
+    try {
+        Function(script);
+    } catch (e) {
+        if (e instanceof SyntaxError) {
+            return;
+        }
+    }
+    throw new Error('Expected syntax error: ' + script);
+}
+
+
+// Tests begin.
+
+syntaxError("{a(){}}");
+syntaxError("b = {a(");
+syntaxError("b = {a)");
+syntaxError("b = {a(}");
+syntaxError("b = {a)}");
+syntaxError("b = {a()");
+syntaxError("b = {a()}");
+syntaxError("b = {a(){}");
+syntaxError("b = {a){}");
+syntaxError("b = {a}}");
+syntaxError("b = {a{}}");
+syntaxError("b = {a({}}");
+syntaxError("b = {a@(){}}");
+syntaxError("b = {a() => 0}");
+
+b = {a(){return 5;}};
+assertEq(b.a(), 5);
+
+b = {a(){return "hey";}};
+assertEq(b.a(), "hey");
+
+b = {a(){return arguments;}};
+assertEq(b.a().length, 0);
+
+b = {a(c){return arguments;}};
+assertEq(b.a().length, 0);
+
+b = {a(c){return arguments;}};
+assertEq(b.a(1).length, 1);
+
+b = {a(c){return arguments;}};
+assertEq(b.a(1)[0], 1);
+
+b = {a(c,d){return arguments;}};
+assertEq(b.a(1,2).length, 2);
+
+b = {a(c,d){return arguments;}};
+assertEq(b.a(1,2)[0], 1);
+
+b = {a(c,d){return arguments;}};
+assertEq(b.a(1,2)[1], 2);
+
+// Methods along with other properties.
+syntaxError("b = {,a(){}}");
+syntaxError("b = {@,a(){}}");
+syntaxError("b = {a(){},@}");
+syntaxError("b = {a : 5 , (){}}");
+syntaxError("b = {a : 5@ , a(){}}");
+syntaxError("b = {a : , a(){}}");
+syntaxError("b = {a : 5, a()}}");
+syntaxError("b = {a : 5, a({}}");
+syntaxError("b = {a : 5, a){}}");
+syntaxError("b = {a : 5, a(){}");
+var c = "d";
+b = { a   : 5,
+      [c] : "hey",
+      e() {return 6;},
+      get f() {return 7;},
+      set f(g) {this.h = 9;}
+}
+assertEq(b.a, 5);
+assertEq(b.d, "hey");
+assertEq(b.e(), 6);
+assertEq(b.f, 7);
+assertEq(b.h !== 9, true);
+b.f = 15;
+assertEq(b.h, 9);
+
+
+var i = 0;
+var a = {
+    foo0 : function (){return 0;},
+    ["foo" + ++i](){return 1;},
+    ["foo" + ++i](){return 2;},
+    ["foo" + ++i](){return 3;},
+    foo4(){return 4;}
+};
+assertEq(a.foo0(), 0);
+assertEq(a.foo1(), 1);
+assertEq(a.foo2(), 2);
+assertEq(a.foo3(), 3);
+assertEq(a.foo4(), 4);
+
+// Symbols.
+var unique_sym = Symbol("1"), registered_sym = Symbol.for("2");
+a = { [unique_sym](){return 2;}, [registered_sym](){return 3;} };
+assertEq(a[unique_sym](), 2);
+assertEq(a[registered_sym](), 3);
+
+// Method characteristics.
+a = { b(){ return 4;} };
+b = Object.getOwnPropertyDescriptor(a, "b");
+assertEq(b.configurable, true);
+assertEq(b.enumerable, true);
+assertEq(b.writable, true);
+assertEq(b.value(), 4);
+
+// Defining several methods using eval.
+var code = "({";
+for (i = 0; i < 1000; i++)
+    code += "['foo' + " + i + "]() {return 'ok';}, "
+code += "['bar']() {return 'all ok'}});";
+var obj = eval(code);
+for (i = 0; i < 1000; i++)
+    assertEq(obj["foo" + i](), "ok");
+assertEq(obj["bar"](), "all ok");
+
+// this
+var obj = {
+    a : "hey",
+    meth(){return this.a;}
+}
+assertEq(obj.meth(), "hey");
+
+// Inheritance
+var obj2 = Object.create(obj);
+assertEq(obj2.meth(), "hey");
+
+var obj = {
+    a() {
+        return "hey";
+    }
+}
+assertEq(obj.a.call(), "hey");
+
+// Tests provided by benvie in the bug to distinguish from ES5 desugar.
+assertEq(({ method() {} }).method.name, "method");
+assertThrowsInstanceOf(function() {({ method() { method() } }).method() }, ReferenceError);
+
+
+reportCompare(0, 0, "ok");
diff --git a/js/src/tests/ecma_6/Class/methDefnGen.js b/js/src/tests/ecma_6/Class/methDefnGen.js
new file mode 100644
index 000000000000..05abcc19b953
--- /dev/null
+++ b/js/src/tests/ecma_6/Class/methDefnGen.js
@@ -0,0 +1,70 @@
+var BUGNUMBER = 924672;
+var summary = 'Method Definitions - Generators'
+
+print(BUGNUMBER + ": " + summary);
+
+// Function definitions.
+function syntaxError (script) {
+    try {
+        Function(script);
+    } catch (e) {
+        if (e instanceof SyntaxError) {
+            return;
+        }
+    }
+    throw new Error('Expected syntax error: ' + script);
+}
+
+
+// Tests begin.
+
+syntaxError("{*a(){}}");
+syntaxError("b = {*(){}");
+syntaxError("b = {*{}");
+syntaxError("b = {*){}");
+syntaxError("b = {*({}");
+syntaxError("b = {*(){");
+syntaxError("b = {*()}");
+syntaxError("b = {*a(");
+syntaxError("b = {*a)");
+syntaxError("b = {*a(}");
+syntaxError("b = {*a)}");
+syntaxError("b = {*a()");
+syntaxError("b = {*a()}");
+syntaxError("b = {*a(){}");
+syntaxError("b = {*a){}");
+syntaxError("b = {*a}}");
+syntaxError("b = {*a{}}");
+syntaxError("b = {*a({}}");
+syntaxError("b = {*a@(){}}");
+syntaxError("b = {*@(){}}");
+syntaxError("b = {*get a(){}}");
+syntaxError("b = {get *a(){}}");
+syntaxError("b = {get a*(){}}");
+syntaxError("b = {*set a(c){}}");
+syntaxError("b = {set *a(c){}}");
+syntaxError("b = {set a*(c){}}");
+syntaxError("b = {*a : 1}");
+syntaxError("b = {a* : 1}");
+syntaxError("b = {a :* 1}");
+syntaxError("b = {a*(){}}");
+
+// Generator methods.
+b = { * g() {
+    var a = { [yield 1]: 2, [yield 2]: 3};
+    return a;
+} }
+var it = b.g();
+var next = it.next();
+assertEq(next.done, false);
+assertEq(next.value, 1);
+next = it.next("hello");
+assertEq(next.done, false);
+assertEq(next.value, 2);
+next = it.next("world");
+assertEq(next.done, true);
+assertEq(next.value.hello, 2);
+assertEq(next.value.world, 3);
+
+
+reportCompare(0, 0, "ok");
diff --git a/js/src/tests/js1_8_5/extensions/reflect-parse.js b/js/src/tests/js1_8_5/extensions/reflect-parse.js
index 5269aaa10abe..b58350e7af6c 100644
--- a/js/src/tests/js1_8_5/extensions/reflect-parse.js
+++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js
@@ -502,6 +502,16 @@ assertStmt("try { } catch (e if foo) { } catch (e if bar) { } catch (e) { } fina
                    catchClause(ident("e"), null, blockStmt([])),
                    blockStmt([])));
 
+
+// Bug 924672: Method definitions
+assertExpr("b = { a() { } }", aExpr("=", ident("b"),
+              objExpr([{ key: ident("a"), value: funExpr(ident("a"), [], blockStmt([])), method:
+              true}])));
+
+assertExpr("b = { *a() { } }", aExpr("=", ident("b"),
+              objExpr([{ key: ident("a"), value: genFunExpr(ident("a"), [], blockStmt([])), method:
+              true}])));
+
 // Bug 632028: yield outside of a function should throw
 (function() {
     var threw = false;

From 84ba2c2da153125e3862545d4e95351fa9d5e07f Mon Sep 17 00:00:00 2001
From: Guptha Rajagopal 
Date: Wed, 13 Aug 2014 11:01:00 -0400
Subject: [PATCH 084/101] Bug 1045848 - MUST_MATCH_TOKEN should not report
 error when token is TOK_ERROR. r=jorendorff

---
 js/src/frontend/Parser.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index ac25cd285c43..d6a8331a9cf8 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -56,14 +56,13 @@ typedef Rooted RootedNestedScopeObject;
 typedef Handle HandleNestedScopeObject;
 
 
-/*
- * Insist that the next token be of type tt, or report errno and return null.
- * NB: this macro uses cx and ts from its lexical environment.
- */
+/* Read a token. Report an error and return null() if that token isn't of type tt. */
 #define MUST_MATCH_TOKEN(tt, errno)                                                         \
     JS_BEGIN_MACRO                                                                          \
-        if (tokenStream.getToken() != tt) {                                                 \
-            report(ParseError, false, null(), errno);                                       \
+        TokenKind token = tokenStream.getToken();                                           \
+        if (token != tt) {                                                                  \
+            if (token != TOK_ERROR)                                                         \
+                report(ParseError, false, null(), errno);                                   \
             return null();                                                                  \
         }                                                                                   \
     JS_END_MACRO

From a95040d7a7cb332f9b02a0b2fceec69a40c7a83b Mon Sep 17 00:00:00 2001
From: Jan-Ivar Bruaroey 
Date: Wed, 13 Aug 2014 21:40:41 -0400
Subject: [PATCH 085/101] Bug 1032835 - RTCRtpSender webidl. r=smaug

---
 dom/media/PeerConnection.js             | 36 +++++++++++++++++++++++++
 dom/media/PeerConnection.manifest       |  4 +++
 dom/webidl/MediaStreamTrackEvent.webidl | 22 +++++++++++++++
 dom/webidl/RTCPeerConnection.webidl     | 12 +++++++++
 dom/webidl/RTCRtpReceiver.webidl        | 15 +++++++++++
 dom/webidl/RTCRtpSender.webidl          | 15 +++++++++++
 dom/webidl/moz.build                    |  3 +++
 7 files changed, 107 insertions(+)
 create mode 100644 dom/webidl/MediaStreamTrackEvent.webidl
 create mode 100644 dom/webidl/RTCRtpReceiver.webidl
 create mode 100644 dom/webidl/RTCRtpSender.webidl

diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js
index 215e3da71215..fcb56e888a2c 100644
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -22,6 +22,8 @@ const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
 const PC_IDENTITY_CONTRACT = "@mozilla.org/dom/rtcidentityassertion;1";
 const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
+const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
+const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
 
 const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
 const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
@@ -31,6 +33,8 @@ const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 const PC_IDENTITY_CID = Components.ID("{1abc7499-3c54-43e0-bd60-686e2703f072}");
 const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
+const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
+const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
 
 // Global list of PeerConnection objects, so they can be cleaned up when
 // a page is torn down. (Maps inner window ID to an array of PC objects).
@@ -1275,12 +1279,44 @@ RTCPeerConnectionStatic.prototype = {
   },
 };
 
+function RTCRtpSender() {}
+RTCRtpSender.prototype = {
+  classDescription: "RTCRtpSender",
+  classID: PC_SENDER_CID,
+  contractID: PC_SENDER_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
+                                         Ci.nsIDOMGlobalPropertyInitializer]),
+
+  init: function(win) { this._win = win; },
+
+  __init: function(track) {
+    this.track = track;
+  }
+};
+
+function RTCRtpReceiver() {}
+RTCRtpReceiver.prototype = {
+  classDescription: "RTCRtpReceiver",
+  classID: PC_RECEIVER_CID,
+  contractID: PC_RECEIVER_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
+                                         Ci.nsIDOMGlobalPropertyInitializer]),
+
+  init: function(win) { this._win = win; },
+
+  __init: function(track) {
+    this.track = track;
+  }
+};
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [GlobalPCList,
    RTCIceCandidate,
    RTCSessionDescription,
    RTCPeerConnection,
    RTCPeerConnectionStatic,
+   RTCRtpReceiver,
+   RTCRtpSender,
    RTCStatsReport,
    RTCIdentityAssertion,
    PeerConnectionObserver]
diff --git a/dom/media/PeerConnection.manifest b/dom/media/PeerConnection.manifest
index 7973ab596126..d0315f160e66 100644
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -6,6 +6,8 @@ component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
 component {1abc7499-3c54-43e0-bd60-686e2703f072} PeerConnection.js
 component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
+component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
+component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
 
 contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
 contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
@@ -15,3 +17,5 @@ contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6
 contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
 contract @mozilla.org/dom/rtcidentityassertion;1 {1abc7499-3c54-43e0-bd60-686e2703f072}
 contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
+contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
+contract @mozilla.org/dom/rtpreceiver;1 {d974b814-8fde-411c-8c45-b86791b81030}
diff --git a/dom/webidl/MediaStreamTrackEvent.webidl b/dom/webidl/MediaStreamTrackEvent.webidl
new file mode 100644
index 000000000000..a2ad8efced99
--- /dev/null
+++ b/dom/webidl/MediaStreamTrackEvent.webidl
@@ -0,0 +1,22 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * http://dev.w3.org/2011/webrtc/editor/webrtc.html#mediastreamevent
+ */
+
+dictionary MediaStreamTrackEventInit : EventInit {
+  MediaStreamTrack? track = null;
+  RTCRtpReceiver? receiver = null;
+  MediaStream? stream = null;
+};
+
+[Pref="media.peerconnection.enabled",
+ Constructor(DOMString type, optional MediaStreamTrackEventInit eventInitDict)]
+interface MediaStreamTrackEvent : Event {
+  readonly attribute RTCRtpReceiver? receiver;
+  readonly attribute MediaStreamTrack? track;
+  readonly attribute MediaStream? stream;
+};
diff --git a/dom/webidl/RTCPeerConnection.webidl b/dom/webidl/RTCPeerConnection.webidl
index c6345c0a8508..1f09106c0bdd 100644
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -105,11 +105,23 @@ interface mozRTCPeerConnection : EventTarget  {
   MediaStream? getStreamById (DOMString streamId);
   void addStream (MediaStream stream);
   void removeStream (MediaStream stream);
+
+  // replaces addStream; fails if already added
+  // because a track can be part of multiple streams, the id parameter
+  // indicates which particular stream should be referenced in signaling
+
+  RTCRtpSender addTrack(MediaStreamTrack track, DOMString streamId);
+  void removeTrack(RTCRtpSender sender);
+
+  sequence getSenders();
+  sequence getReceivers();
+
   void close ();
   attribute EventHandler onnegotiationneeded;
   attribute EventHandler onicecandidate;
   attribute EventHandler onsignalingstatechange;
   attribute EventHandler onaddstream;
+  attribute EventHandler onaddtrack;  // replaces onaddstream; see AddTrackEvent
   attribute EventHandler onremovestream;
   attribute EventHandler oniceconnectionstatechange;
 
diff --git a/dom/webidl/RTCRtpReceiver.webidl b/dom/webidl/RTCRtpReceiver.webidl
new file mode 100644
index 000000000000..6c526ca5eebe
--- /dev/null
+++ b/dom/webidl/RTCRtpReceiver.webidl
@@ -0,0 +1,15 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * http://lists.w3.org/Archives/Public/public-webrtc/2014May/0067.html
+ */
+
+[Pref="media.peerconnection.enabled",
+ JSImplementation="@mozilla.org/dom/rtpreceiver;1",
+ Constructor (MediaStreamTrack track)]
+interface RTCRtpReceiver {
+  readonly attribute MediaStreamTrack track;
+};
diff --git a/dom/webidl/RTCRtpSender.webidl b/dom/webidl/RTCRtpSender.webidl
new file mode 100644
index 000000000000..f028f3010caa
--- /dev/null
+++ b/dom/webidl/RTCRtpSender.webidl
@@ -0,0 +1,15 @@
+/* -*- Mode: IDL; 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/.
+ *
+ * The origin of this IDL file is
+ * http://lists.w3.org/Archives/Public/public-webrtc/2014May/0067.html
+ */
+
+[Pref="media.peerconnection.enabled",
+ JSImplementation="@mozilla.org/dom/rtpsender;1",
+ Constructor (MediaStreamTrack track)]
+interface RTCRtpSender {
+  readonly attribute MediaStreamTrack track;
+};
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index 5c9de3dcbd47..defe8d42f831 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -314,6 +314,8 @@ WEBIDL_FILES = [
     'RTCIdentityAssertion.webidl',
     'RTCPeerConnection.webidl',
     'RTCPeerConnectionStatic.webidl',
+    'RTCRtpReceiver.webidl',
+    'RTCRtpSender.webidl',
     'RTCSessionDescription.webidl',
     'RTCStatsReport.webidl',
     'Screen.webidl',
@@ -645,6 +647,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'HashChangeEvent.webidl',
     'IccChangeEvent.webidl',
     'MediaStreamEvent.webidl',
+    'MediaStreamTrackEvent.webidl',
     'MozApplicationEvent.webidl',
     'MozClirModeEvent.webidl',
     'MozContactChangeEvent.webidl',

From 2114490617314d7df51b7900a4b426f306b299a5 Mon Sep 17 00:00:00 2001
From: Jan-Ivar Bruaroey 
Date: Wed, 13 Aug 2014 21:40:54 -0400
Subject: [PATCH 086/101] Bug 1032835 - addTrack/removeTrack on-top of existing
 implementation. r=smaug, r=jesup

---
 content/media/DOMMediaStream.cpp              |  12 ++
 content/media/DOMMediaStream.h                |   2 +
 dom/media/PeerConnection.js                   |  98 +++++++++---
 dom/media/tests/mochitest/pc.js               |   4 +-
 dom/webidl/MediaStream.webidl                 |   5 +-
 dom/webidl/PeerConnectionImpl.webidl          |   6 +-
 dom/webidl/PeerConnectionObserver.webidl      |   4 +-
 dom/webidl/RTCPeerConnection.webidl           |   8 +-
 dom/webidl/RTCRtpReceiver.webidl              |   3 +-
 dom/webidl/RTCRtpSender.webidl                |   3 +-
 .../signaling/src/media/VcmSIPCCBinding.cpp   |   4 +
 .../src/peerconnection/PeerConnectionImpl.cpp | 141 +++++++++++++++++-
 .../src/peerconnection/PeerConnectionImpl.h   |  12 ++
 .../peerconnection/PeerConnectionMedia.cpp    |  65 +++++---
 .../src/peerconnection/PeerConnectionMedia.h  |   9 +-
 15 files changed, 317 insertions(+), 59 deletions(-)

diff --git a/content/media/DOMMediaStream.cpp b/content/media/DOMMediaStream.cpp
index 7aa4f47bc932..8f86edcec65b 100644
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -196,6 +196,18 @@ DOMMediaStream::GetVideoTracks(nsTArray >& aTracks)
   }
 }
 
+void
+DOMMediaStream::GetTracks(nsTArray >& aTracks)
+{
+  aTracks.AppendElements(mTracks);
+}
+
+bool
+DOMMediaStream::HasTrack(const MediaStreamTrack& aTrack) const
+{
+  return mTracks.Contains(&aTrack);
+}
+
 bool
 DOMMediaStream::IsFinished()
 {
diff --git a/content/media/DOMMediaStream.h b/content/media/DOMMediaStream.h
index c58bff7cac12..18b85b9c8bb1 100644
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -81,6 +81,8 @@ public:
 
   void GetAudioTracks(nsTArray >& aTracks);
   void GetVideoTracks(nsTArray >& aTracks);
+  void GetTracks(nsTArray >& aTracks);
+  bool HasTrack(const MediaStreamTrack& aTrack) const;
 
   MediaStream* GetStream() const { return mStream; }
 
diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js
index fcb56e888a2c..a35ed4ccdbb4 100644
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -210,12 +210,6 @@ RTCSessionDescription.prototype = {
 };
 
 function RTCStatsReport(win, dict) {
-  function appendStats(stats, report) {
-    stats.forEach(function(stat) {
-        report[stat.id] = stat;
-      });
-  }
-
   this._win = win;
   this._pcid = dict.pcid;
   this._report = convertToRTCStatsReport(dict);
@@ -287,6 +281,8 @@ RTCIdentityAssertion.prototype = {
 
 function RTCPeerConnection() {
   this._queue = [];
+  this._senders = [];
+  this._receivers = [];
 
   this._pc = null;
   this._observer = null;
@@ -341,6 +337,7 @@ RTCPeerConnection.prototype = {
     }
 
     this.makeGetterSetterEH("onaddstream");
+    this.makeGetterSetterEH("onaddtrack");
     this.makeGetterSetterEH("onicecandidate");
     this.makeGetterSetterEH("onnegotiationneeded");
     this.makeGetterSetterEH("onsignalingstatechange");
@@ -805,6 +802,26 @@ RTCPeerConnection.prototype = {
     throw new this._win.DOMError("", "getStreamById not yet implemented");
   },
 
+  addTrack: function(track, stream) {
+    if (stream.currentTime === undefined) {
+      throw new this._win.DOMError("", "invalid stream.");
+    }
+    if (stream.getTracks().indexOf(track) == -1) {
+      throw new this._win.DOMError("", "track is not in stream.");
+    }
+    this._checkClosed();
+    this._impl.addTrack(track, stream);
+    let sender = this._win.RTCRtpSender._create(this._win,
+                                                new RTCRtpSender(this, track));
+    this._senders.push({ sender: sender, stream: stream });
+    return sender;
+  },
+
+  removeTrack: function(sender) {
+     // Bug 844295: Not implementing this functionality.
+     throw new this._win.DOMError("", "removeTrack not yet implemented");
+  },
+
   close: function() {
     if (this._closed) {
       return;
@@ -830,6 +847,36 @@ RTCPeerConnection.prototype = {
     return this._impl.getRemoteStreams();
   },
 
+  getSenders: function() {
+    this._checkClosed();
+    let streams = this._impl.getLocalStreams();
+    let senders = [];
+    // prune senders in case any streams have disappeared down below
+    for (let i = this._senders.length - 1; i >= 0; i--) {
+      if (streams.indexOf(this._senders[i].stream) != -1) {
+        senders.push(this._senders[i].sender);
+      } else {
+        this._senders.splice(i,1);
+      }
+    }
+    return senders;
+  },
+
+  getReceivers: function() {
+    this._checkClosed();
+    let streams = this._impl.getRemoteStreams();
+    let receivers = [];
+    // prune receivers in case any streams have disappeared down below
+    for (let i = this._receivers.length - 1; i >= 0; i--) {
+      if (streams.indexOf(this._receivers[i].stream) != -1) {
+        receivers.push(this._receivers[i].receiver);
+      } else {
+        this._receivers.splice(i,1);
+      }
+    }
+    return receivers;
+  },
+
   get localDescription() {
     this._checkClosed();
     let sdp = this._impl.localDescription;
@@ -1248,6 +1295,17 @@ PeerConnectionObserver.prototype = {
                                                              { stream: stream }));
   },
 
+  onAddTrack: function(track) {
+    let ev = new this._dompc._win.MediaStreamTrackEvent("addtrack",
+                                                        { track: track });
+    this._dompc.dispatchEvent(ev);
+  },
+
+  onRemoveTrack: function(track, type) {
+    this.dispatchEvent(new this._dompc._win.MediaStreamTrackEvent("removetrack",
+                                                                  { track: track }));
+  },
+
   foundIceCandidate: function(cand) {
     this.dispatchEvent(new this._dompc._win.RTCPeerConnectionIceEvent("icecandidate",
                                                                       { candidate: cand } ));
@@ -1279,34 +1337,26 @@ RTCPeerConnectionStatic.prototype = {
   },
 };
 
-function RTCRtpSender() {}
+function RTCRtpSender(pc, track) {
+  this.pc = pc;
+  this.track = track;
+}
 RTCRtpSender.prototype = {
   classDescription: "RTCRtpSender",
   classID: PC_SENDER_CID,
   contractID: PC_SENDER_CONTRACT,
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
-                                         Ci.nsIDOMGlobalPropertyInitializer]),
-
-  init: function(win) { this._win = win; },
-
-  __init: function(track) {
-    this.track = track;
-  }
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
 };
 
-function RTCRtpReceiver() {}
+function RTCRtpReceiver(pc, track) {
+  this.pc = pc;
+  this.track = track;
+}
 RTCRtpReceiver.prototype = {
   classDescription: "RTCRtpReceiver",
   classID: PC_RECEIVER_CID,
   contractID: PC_RECEIVER_CONTRACT,
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
-                                         Ci.nsIDOMGlobalPropertyInitializer]),
-
-  init: function(win) { this._win = win; },
-
-  __init: function(track) {
-    this.track = track;
-  }
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js
index 7cd0d025cf36..7f48d679bef4 100644
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1543,7 +1543,9 @@ PeerConnectionWrapper.prototype = {
     this.streams.push(stream);
 
     if (side === 'local') {
-      this._pc.addStream(stream);
+      stream.getTracks().forEach(function(track) {
+        this._pc.addTrack(track, stream);
+      }.bind(this));
     }
 
     var element = createMediaElement(type, this.label + '_' + side);
diff --git a/dom/webidl/MediaStream.webidl b/dom/webidl/MediaStream.webidl
index 988545cf1cdb..1db6b176602e 100644
--- a/dom/webidl/MediaStream.webidl
+++ b/dom/webidl/MediaStream.webidl
@@ -23,8 +23,9 @@ dictionary MediaStreamConstraints {
 
 interface MediaStream {
     // readonly attribute DOMString    id;
-    sequence getAudioTracks ();
-    sequence getVideoTracks ();
+    sequence getAudioTracks();
+    sequence getVideoTracks();
+    sequence getTracks();
     // MediaStreamTrack           getTrackById (DOMString trackId);
     // void                       addTrack (MediaStreamTrack track);
     // void                       removeTrack (MediaStreamTrack track);
diff --git a/dom/webidl/PeerConnectionImpl.webidl b/dom/webidl/PeerConnectionImpl.webidl
index 659ac21de64a..46ffe022b36b 100644
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -38,7 +38,11 @@ interface PeerConnectionImpl  {
   [Throws]
   void getStats(MediaStreamTrack? selector);
 
-  /* Adds the stream created by GetUserMedia */
+  /* Adds the tracks created by GetUserMedia */
+  [Throws]
+  void addTrack(MediaStreamTrack track, MediaStream... streams);
+  [Throws]
+  void removeTrack(MediaStreamTrack track);
   [Throws]
   void addStream(MediaStream stream);
   [Throws]
diff --git a/dom/webidl/PeerConnectionObserver.webidl b/dom/webidl/PeerConnectionObserver.webidl
index a68ba9d9c581..45b24ae92b7d 100644
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -34,9 +34,9 @@ interface PeerConnectionObserver
   /* Notification of one of several types of state changed */
   void onStateChange(PCObserverStateType state);
 
-  /* Changes to MediaStreams */
+  /* Changes to MediaStreamTracks */
   void onAddStream(MediaStream stream);
   void onRemoveStream();
-  void onAddTrack();
+  void onAddTrack(MediaStreamTrack track);
   void onRemoveTrack();
 };
diff --git a/dom/webidl/RTCPeerConnection.webidl b/dom/webidl/RTCPeerConnection.webidl
index 1f09106c0bdd..3b56e6de8afb 100644
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -107,10 +107,12 @@ interface mozRTCPeerConnection : EventTarget  {
   void removeStream (MediaStream stream);
 
   // replaces addStream; fails if already added
-  // because a track can be part of multiple streams, the id parameter
-  // indicates which particular stream should be referenced in signaling
+  // because a track can be part of multiple streams, stream parameters
+  // indicate which particular streams should be referenced in signaling
 
-  RTCRtpSender addTrack(MediaStreamTrack track, DOMString streamId);
+  RTCRtpSender addTrack(MediaStreamTrack track,
+                        MediaStream stream,
+                        MediaStream... moreStreams);
   void removeTrack(RTCRtpSender sender);
 
   sequence getSenders();
diff --git a/dom/webidl/RTCRtpReceiver.webidl b/dom/webidl/RTCRtpReceiver.webidl
index 6c526ca5eebe..94343ea03c3c 100644
--- a/dom/webidl/RTCRtpReceiver.webidl
+++ b/dom/webidl/RTCRtpReceiver.webidl
@@ -8,8 +8,7 @@
  */
 
 [Pref="media.peerconnection.enabled",
- JSImplementation="@mozilla.org/dom/rtpreceiver;1",
- Constructor (MediaStreamTrack track)]
+ JSImplementation="@mozilla.org/dom/rtpreceiver;1"]
 interface RTCRtpReceiver {
   readonly attribute MediaStreamTrack track;
 };
diff --git a/dom/webidl/RTCRtpSender.webidl b/dom/webidl/RTCRtpSender.webidl
index f028f3010caa..f7ffb292ff17 100644
--- a/dom/webidl/RTCRtpSender.webidl
+++ b/dom/webidl/RTCRtpSender.webidl
@@ -8,8 +8,7 @@
  */
 
 [Pref="media.peerconnection.enabled",
- JSImplementation="@mozilla.org/dom/rtpsender;1",
- Constructor (MediaStreamTrack track)]
+ JSImplementation="@mozilla.org/dom/rtpsender;1"]
 interface RTCRtpSender {
   readonly attribute MediaStreamTrack track;
 };
diff --git a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
index 42daafede6a6..d063ed9a6055 100644
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
@@ -2535,6 +2535,10 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
   ENSURE_PC(pc, VCM_ERROR);
   nsRefPtr stream =
     pc.impl()->media()->GetLocalStream(pc_stream_id);
+  if (!stream) {
+    CSFLogError(logTag, "Stream not found");
+    return VCM_ERROR;
+  }
 
   // Create the transport flows
   mozilla::RefPtr rtp_flow =
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index c025c412a298..8c6014342890 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -285,6 +285,17 @@ public:
       CSFLogInfo(logTag, "Returning success for OnAddStream()");
       // We are running on main thread here so we shouldn't have a race
       // on this callback
+
+      nsTArray> tracks;
+      aStream->GetTracks(tracks);
+      for (uint32_t i = 0; i < tracks.Length(); i++) {
+        JSErrorResult rv;
+        mObserver->OnAddTrack(*tracks[i], rv);
+        if (rv.Failed()) {
+          CSFLogError(logTag, ": OnAddTrack(%d) failed! Error: %d", i,
+                      rv.ErrorCode());
+        }
+      }
       JSErrorResult rv;
       mObserver->OnAddStream(*aStream, rv);
       if (rv.Failed()) {
@@ -1465,7 +1476,7 @@ PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream)
   }
 
   uint32_t stream_id;
-  nsresult res = mMedia->AddStream(&aMediaStream, &stream_id);
+  nsresult res = mMedia->AddStream(&aMediaStream, hints, &stream_id);
   if (NS_FAILED(res)) {
     return res;
   }
@@ -1490,15 +1501,141 @@ NS_IMETHODIMP
 PeerConnectionImpl::RemoveStream(DOMMediaStream& aMediaStream) {
   PC_AUTO_ENTER_API_CALL(true);
 
+  uint32_t hints = aMediaStream.GetHintContents();
+
   uint32_t stream_id;
-  nsresult res = mMedia->RemoveStream(&aMediaStream, &stream_id);
+  nsresult res = mMedia->RemoveStream(&aMediaStream, hints, &stream_id);
 
   if (NS_FAILED(res))
     return res;
 
   aMediaStream.RemovePrincipalChangeObserver(this);
 
+  if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
+    mInternal->mCall->removeStream(stream_id, 0, AUDIO);
+    MOZ_ASSERT(mNumAudioStreams > 0);
+    mNumAudioStreams--;
+  }
+
+  if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
+    mInternal->mCall->removeStream(stream_id, 1, VIDEO);
+    MOZ_ASSERT(mNumVideoStreams > 0);
+    mNumVideoStreams--;
+  }
+
+  return NS_OK;
+}
+
+nsresult
+PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
+                             const Sequence>& aStreams)
+{
+  PC_AUTO_ENTER_API_CALL(true);
+
+  if (!aStreams.Length()) {
+    CSFLogError(logTag, "%s: At least one stream arg required", __FUNCTION__);
+    return NS_ERROR_FAILURE;
+  }
+  DOMMediaStream& aMediaStream = aStreams[0];
+#ifdef MOZILLA_INTERNAL_API
+  if (!aMediaStream.HasTrack(aTrack)) {
+    CSFLogError(logTag, "%s: Track is not in stream", __FUNCTION__);
+    return NS_ERROR_FAILURE;
+  }
+  uint32_t hints = aMediaStream.GetHintContents() &
+      ((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
+       (aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
+#else
   uint32_t hints = aMediaStream.GetHintContents();
+#endif
+
+  // XXX Remove this check once addStream has an error callback
+  // available and/or we have plumbing to handle multiple
+  // local audio streams.
+  if ((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) &&
+      mNumAudioStreams > 0) {
+    CSFLogError(logTag, "%s: Only one local audio stream is supported for now",
+                __FUNCTION__);
+    return NS_ERROR_FAILURE;
+  }
+
+  // XXX Remove this check once addStream has an error callback
+  // available and/or we have plumbing to handle multiple
+  // local video streams.
+  if ((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) &&
+      mNumVideoStreams > 0) {
+    CSFLogError(logTag, "%s: Only one local video stream is supported for now",
+                __FUNCTION__);
+    return NS_ERROR_FAILURE;
+  }
+
+  uint32_t num = mMedia->LocalStreamsLength();
+
+  uint32_t stream_id;
+  nsresult res = mMedia->AddStream(&aMediaStream, hints, &stream_id);
+  if (NS_FAILED(res)) {
+    return res;
+  }
+
+  if (num != mMedia->LocalStreamsLength()) {
+    aMediaStream.AddPrincipalChangeObserver(this);
+  }
+
+  // TODO(ekr@rtfm.com): these integers should be the track IDs
+  if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
+    mInternal->mCall->addStream(stream_id, 0, AUDIO);
+    mNumAudioStreams++;
+  }
+
+  if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
+    mInternal->mCall->addStream(stream_id, 1, VIDEO);
+    mNumVideoStreams++;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
+  PC_AUTO_ENTER_API_CALL(true);
+
+  DOMMediaStream *stream = nullptr;
+#ifdef MOZILLA_INTERNAL_API
+  for (uint32_t i = 0; i < mMedia->LocalStreamsLength(); ++i) {
+    auto* candidate = mMedia->GetLocalStream(i)->GetMediaStream();
+    if (candidate->HasTrack(aTrack)) {
+      stream = candidate;
+      break;
+    }
+  }
+#endif
+  if (!stream) {
+    CSFLogError(logTag, "%s: Track not found", __FUNCTION__);
+    return NS_OK;
+  }
+
+  DOMMediaStream& aMediaStream = *stream;
+
+#ifdef MOZILLA_INTERNAL_API
+  uint32_t hints = aMediaStream.GetHintContents() &
+      ((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
+       (aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
+#else
+  uint32_t hints = aMediaStream.GetHintContents();
+#endif
+
+  uint32_t num = mMedia->LocalStreamsLength();
+
+  uint32_t stream_id;
+  nsresult res = mMedia->RemoveStream(&aMediaStream, hints, &stream_id);
+
+  if (NS_FAILED(res)) {
+    return res;
+  }
+
+  if (num != mMedia->LocalStreamsLength()) {
+    aMediaStream.RemovePrincipalChangeObserver(this);
+  }
 
   if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
     mInternal->mCall->removeStream(stream_id, 0, AUDIO);
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 05e1f0384e35..67299d00705f 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -375,6 +375,18 @@ public:
     rv = RemoveStream(aMediaStream);
   }
 
+  NS_IMETHODIMP_TO_ERRORRESULT(AddTrack, ErrorResult &rv,
+      mozilla::dom::MediaStreamTrack& aTrack,
+      const mozilla::dom::Sequence>& aStreams)
+  {
+    rv = AddTrack(aTrack, aStreams);
+  }
+
+  NS_IMETHODIMP_TO_ERRORRESULT(RemoveTrack, ErrorResult &rv,
+                               mozilla::dom::MediaStreamTrack& aTrack)
+  {
+    rv = RemoveTrack(aTrack);
+  }
 
   nsresult GetPeerIdentity(nsAString& peerIdentity)
   {
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
index 347ff6c35d82..46e9ea928b71 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -43,6 +43,12 @@ LocalSourceStreamInfo::ExpectAudio(const mozilla::TrackID aID)
   mAudioTracks.AppendElement(aID);
 }
 
+void
+LocalSourceStreamInfo::RemoveAudio(const mozilla::TrackID aID)
+{
+  mAudioTracks.RemoveElement(aID);
+}
+
 // If the ExpectVideo hint is on we will add a track at the default first
 // video track ID (1).
 void
@@ -51,6 +57,12 @@ LocalSourceStreamInfo::ExpectVideo(const mozilla::TrackID aID)
   mVideoTracks.AppendElement(aID);
 }
 
+void
+LocalSourceStreamInfo::RemoveVideo(const mozilla::TrackID aID)
+{
+  mVideoTracks.RemoveElement(aID);
+}
+
 unsigned
 LocalSourceStreamInfo::AudioTrackCount()
 {
@@ -234,7 +246,9 @@ nsresult PeerConnectionMedia::Init(const std::vector& stun_serv
 }
 
 nsresult
-PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id)
+PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
+                               uint32_t hints,
+                               uint32_t *stream_id)
 {
   ASSERT_ON_THREAD(mMainThread);
 
@@ -245,11 +259,9 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
 
   DOMMediaStream* stream = static_cast(aMediaStream);
 
-  CSFLogDebug(logTag, "%s: MediaStream: %p",
-    __FUNCTION__, aMediaStream);
+  CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream);
 
   // Adding tracks here based on nsDOMMediaStream expectation settings
-  uint32_t hints = stream->GetHintContents();
 #ifdef MOZILLA_INTERNAL_API
   if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
     hints &= ~(DOMMediaStream::HINT_CONTENTS_VIDEO);
@@ -262,23 +274,30 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
     return NS_OK;
   }
 
-  // Now see if we already have a stream of this type, since we only
-  // allow one of each.
+  // Now see if we already have this stream or another stream with
+  // tracks of the same type, since we only allow one track of each type.
   // TODO(ekr@rtfm.com): remove this when multiple of each stream
   // is allowed
-  for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
-    nsRefPtr localSourceStream = mLocalSourceStreams[u];
+  nsRefPtr localSourceStream = nullptr;
 
-    if (localSourceStream->GetMediaStream()->GetHintContents() & hints) {
+  for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
+    auto& lss = mLocalSourceStreams[u];
+    if (((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) && lss->AudioTrackCount()) ||
+        ((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) && lss->VideoTrackCount())) {
       CSFLogError(logTag, "Only one stream of any given type allowed");
       return NS_ERROR_FAILURE;
     }
+    if (stream == lss->GetMediaStream()) {
+      localSourceStream = lss;
+      *stream_id = u;
+      break;
+    }
+  }
+  if (!localSourceStream) {
+    localSourceStream = new LocalSourceStreamInfo(stream, this);
+    mLocalSourceStreams.AppendElement(localSourceStream);
+    *stream_id = mLocalSourceStreams.Length() - 1;
   }
-
-  // OK, we're good to add
-  nsRefPtr localSourceStream =
-      new LocalSourceStreamInfo(stream, this);
-  *stream_id = mLocalSourceStreams.Length();
 
   if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
     localSourceStream->ExpectAudio(TRACK_AUDIO);
@@ -287,14 +306,13 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream
   if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
     localSourceStream->ExpectVideo(TRACK_VIDEO);
   }
-
-  mLocalSourceStreams.AppendElement(localSourceStream);
-
   return NS_OK;
 }
 
 nsresult
-PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id)
+PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream,
+                                  uint32_t hints,
+                                  uint32_t *stream_id)
 {
   MOZ_ASSERT(aMediaStream);
   ASSERT_ON_THREAD(mMainThread);
@@ -308,6 +326,17 @@ PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *str
     nsRefPtr localSourceStream = mLocalSourceStreams[u];
     if (localSourceStream->GetMediaStream() == stream) {
       *stream_id = u;
+
+      if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
+        localSourceStream->RemoveAudio(TRACK_AUDIO);
+      }
+      if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
+        localSourceStream->RemoveAudio(TRACK_VIDEO);
+      }
+      if (!(localSourceStream->AudioTrackCount() +
+            localSourceStream->VideoTrackCount())) {
+        mLocalSourceStreams.RemoveElementAt(u);
+      }
       return NS_OK;
     }
   }
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
index 0ab20580036e..4d34dafb7355 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -226,6 +226,8 @@ public:
 
   void ExpectAudio(const mozilla::TrackID);
   void ExpectVideo(const mozilla::TrackID);
+  void RemoveAudio(const mozilla::TrackID);
+  void RemoveVideo(const mozilla::TrackID);
   unsigned AudioTrackCount();
   unsigned VideoTrackCount();
   void DetachTransport_s();
@@ -301,10 +303,13 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
   }
 
   // Add a stream (main thread only)
-  nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id);
+  nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t hints,
+                     uint32_t *stream_id);
 
   // Remove a stream (main thread only)
-  nsresult RemoveStream(nsIDOMMediaStream* aMediaStream, uint32_t *stream_id);
+  nsresult RemoveStream(nsIDOMMediaStream* aMediaStream,
+                        uint32_t hints,
+                        uint32_t *stream_id);
 
   // Get a specific local stream
   uint32_t LocalStreamsLength()

From 107644c4796598aa6590911b9a8c7cb7df379a88 Mon Sep 17 00:00:00 2001
From: Jan-Ivar Bruaroey 
Date: Wed, 13 Aug 2014 21:41:08 -0400
Subject: [PATCH 087/101] Bug 1032835 - Rubberstamp RTCRtpSender,
 RTCRtpReceiver + MediaStreamTrackEvent. r=smaug

---
 dom/events/test/test_all_synthetic_events.html   | 4 ++++
 dom/tests/mochitest/general/test_interfaces.html | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/dom/events/test/test_all_synthetic_events.html b/dom/events/test/test_all_synthetic_events.html
index 06dbf851e557..92bbbda8ea6c 100644
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -211,6 +211,10 @@ const kEventConstructors = {
                                                          return new MediaStreamEvent(aName, aProps);
                                                        },
                                              },
+  MediaStreamTrackEvent:                     { create: function (aName, aProps) {
+                                                         return new MediaStreamTrackEvent(aName, aProps);
+                                                       },
+                                             },
   MessageEvent:                              { create: function (aName, aProps) {
                                                          var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles,
                                                              cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html
index de11419e4cae..2d5b19ecb6d1 100644
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -619,6 +619,8 @@ var interfaceNamesInGlobalScope =
     "MediaStreamAudioSourceNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MediaStreamEvent", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "MediaStreamTrackEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaStreamTrack",
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -833,6 +835,10 @@ var interfaceNamesInGlobalScope =
     {name: "RTCDataChannelEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "RTCPeerConnectionIceEvent", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "RTCRtpReceiver", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "RTCRtpSender", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "RTCStatsReport", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!

From 20328fdf5c2b8a5428cfb87eac6cd7efe1ecafdc Mon Sep 17 00:00:00 2001
From: Jan-Ivar Bruaroey 
Date: Fri, 15 Aug 2014 14:53:14 -0400
Subject: [PATCH 088/101] Bug 1032835 - add/removeStream now implemented with
 addTrack/removeTrack. r=jesup, r=smaug

---
 dom/media/PeerConnection.js                   |  11 +-
 dom/media/tests/mochitest/pc.js               |  12 ++-
 dom/webidl/PeerConnectionImpl.webidl          |   4 -
 .../src/peerconnection/PeerConnectionImpl.cpp | 100 ++----------------
 .../src/peerconnection/PeerConnectionImpl.h   |  20 ++--
 .../webrtc/signaling/test/FakeMediaStreams.h  |  54 +++++++++-
 .../signaling/test/signaling_unittests.cpp    |  40 +++----
 7 files changed, 99 insertions(+), 142 deletions(-)

diff --git a/dom/media/PeerConnection.js b/dom/media/PeerConnection.js
index a35ed4ccdbb4..9dc6f3105b4d 100644
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -781,16 +781,7 @@ RTCPeerConnection.prototype = {
   },
 
   addStream: function(stream) {
-    if (stream.currentTime === undefined) {
-      throw new this._win.DOMError("", "Invalid stream passed to addStream!");
-    }
-    this._queueOrRun({ func: this._addStream,
-                       args: [stream],
-                       wait: false });
-  },
-
-  _addStream: function(stream) {
-    this._impl.addStream(stream);
+    stream.getTracks().forEach(track => this.addTrack(track, stream));
   },
 
   removeStream: function(stream) {
diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js
index 7f48d679bef4..98a5fa708122 100644
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1543,9 +1543,15 @@ PeerConnectionWrapper.prototype = {
     this.streams.push(stream);
 
     if (side === 'local') {
-      stream.getTracks().forEach(function(track) {
-        this._pc.addTrack(track, stream);
-      }.bind(this));
+      // In order to test both the addStream and addTrack APIs, we do video one
+      // way and audio + audiovideo the other.
+      if (type == "video") {
+        this._pc.addStream(stream);
+      } else {
+        stream.getTracks().forEach(function(track) {
+          this._pc.addTrack(track, stream);
+        }.bind(this));
+      }
     }
 
     var element = createMediaElement(type, this.label + '_' + side);
diff --git a/dom/webidl/PeerConnectionImpl.webidl b/dom/webidl/PeerConnectionImpl.webidl
index 46ffe022b36b..1fbcb8b1c965 100644
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -44,10 +44,6 @@ interface PeerConnectionImpl  {
   [Throws]
   void removeTrack(MediaStreamTrack track);
   [Throws]
-  void addStream(MediaStream stream);
-  [Throws]
-  void removeStream(MediaStream stream);
-  [Throws]
   void closeStreams();
 
   sequence getLocalStreams();
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index 8c6014342890..7d88d9d57c9b 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -1448,84 +1448,6 @@ PeerConnectionImpl::PrincipalChanged(DOMMediaStream* aMediaStream) {
 }
 #endif
 
-nsresult
-PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream)
-{
-  PC_AUTO_ENTER_API_CALL(true);
-
-  uint32_t hints = aMediaStream.GetHintContents();
-
-  // XXX Remove this check once addStream has an error callback
-  // available and/or we have plumbing to handle multiple
-  // local audio streams.
-  if ((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) &&
-      mNumAudioStreams > 0) {
-    CSFLogError(logTag, "%s: Only one local audio stream is supported for now",
-                __FUNCTION__);
-    return NS_ERROR_FAILURE;
-  }
-
-  // XXX Remove this check once addStream has an error callback
-  // available and/or we have plumbing to handle multiple
-  // local video streams.
-  if ((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) &&
-      mNumVideoStreams > 0) {
-    CSFLogError(logTag, "%s: Only one local video stream is supported for now",
-                __FUNCTION__);
-    return NS_ERROR_FAILURE;
-  }
-
-  uint32_t stream_id;
-  nsresult res = mMedia->AddStream(&aMediaStream, hints, &stream_id);
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  aMediaStream.AddPrincipalChangeObserver(this);
-
-  // TODO(ekr@rtfm.com): these integers should be the track IDs
-  if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
-    mInternal->mCall->addStream(stream_id, 0, AUDIO);
-    mNumAudioStreams++;
-  }
-
-  if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
-    mInternal->mCall->addStream(stream_id, 1, VIDEO);
-    mNumVideoStreams++;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PeerConnectionImpl::RemoveStream(DOMMediaStream& aMediaStream) {
-  PC_AUTO_ENTER_API_CALL(true);
-
-  uint32_t hints = aMediaStream.GetHintContents();
-
-  uint32_t stream_id;
-  nsresult res = mMedia->RemoveStream(&aMediaStream, hints, &stream_id);
-
-  if (NS_FAILED(res))
-    return res;
-
-  aMediaStream.RemovePrincipalChangeObserver(this);
-
-  if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
-    mInternal->mCall->removeStream(stream_id, 0, AUDIO);
-    MOZ_ASSERT(mNumAudioStreams > 0);
-    mNumAudioStreams--;
-  }
-
-  if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
-    mInternal->mCall->removeStream(stream_id, 1, VIDEO);
-    MOZ_ASSERT(mNumVideoStreams > 0);
-    mNumVideoStreams--;
-  }
-
-  return NS_OK;
-}
-
 nsresult
 PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
                              const Sequence>& aStreams)
@@ -1536,8 +1458,13 @@ PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
     CSFLogError(logTag, "%s: At least one stream arg required", __FUNCTION__);
     return NS_ERROR_FAILURE;
   }
-  DOMMediaStream& aMediaStream = aStreams[0];
-#ifdef MOZILLA_INTERNAL_API
+  return AddTrack(aTrack, aStreams[0]);
+}
+
+nsresult
+PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
+                             DOMMediaStream& aMediaStream)
+{
   if (!aMediaStream.HasTrack(aTrack)) {
     CSFLogError(logTag, "%s: Track is not in stream", __FUNCTION__);
     return NS_ERROR_FAILURE;
@@ -1545,9 +1472,6 @@ PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
   uint32_t hints = aMediaStream.GetHintContents() &
       ((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
        (aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
-#else
-  uint32_t hints = aMediaStream.GetHintContents();
-#endif
 
   // XXX Remove this check once addStream has an error callback
   // available and/or we have plumbing to handle multiple
@@ -1600,7 +1524,6 @@ PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
   PC_AUTO_ENTER_API_CALL(true);
 
   DOMMediaStream *stream = nullptr;
-#ifdef MOZILLA_INTERNAL_API
   for (uint32_t i = 0; i < mMedia->LocalStreamsLength(); ++i) {
     auto* candidate = mMedia->GetLocalStream(i)->GetMediaStream();
     if (candidate->HasTrack(aTrack)) {
@@ -1608,22 +1531,15 @@ PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
       break;
     }
   }
-#endif
   if (!stream) {
     CSFLogError(logTag, "%s: Track not found", __FUNCTION__);
     return NS_OK;
   }
+  auto& aMediaStream = *stream;
 
-  DOMMediaStream& aMediaStream = *stream;
-
-#ifdef MOZILLA_INTERNAL_API
   uint32_t hints = aMediaStream.GetHintContents() &
       ((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
        (aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
-#else
-  uint32_t hints = aMediaStream.GetHintContents();
-#endif
-
   uint32_t num = mMedia->LocalStreamsLength();
 
   uint32_t stream_id;
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 67299d00705f..26edb09b5726 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -50,6 +50,7 @@ class AFakePCObserver;
 
 #ifdef USE_FAKE_MEDIA_STREAMS
 class Fake_DOMMediaStream;
+class Fake_MediaStreamTrack;
 #endif
 
 class nsGlobalWindow;
@@ -74,7 +75,11 @@ class DOMMediaStream;
 namespace dom {
 struct RTCConfiguration;
 struct RTCOfferOptions;
+#ifdef USE_FAKE_MEDIA_STREAMS
+typedef Fake_MediaStreamTrack MediaStreamTrack;
+#else
 class MediaStreamTrack;
+#endif
 
 #ifdef USE_FAKE_PCOBSERVER
 typedef test::AFakePCObserver PeerConnectionObserver;
@@ -363,18 +368,6 @@ public:
     rv = CloseStreams();
   }
 
-  NS_IMETHODIMP_TO_ERRORRESULT(AddStream, ErrorResult &rv,
-                               DOMMediaStream& aMediaStream)
-  {
-    rv = AddStream(aMediaStream);
-  }
-
-  NS_IMETHODIMP_TO_ERRORRESULT(RemoveStream, ErrorResult &rv,
-                               DOMMediaStream& aMediaStream)
-  {
-    rv = RemoveStream(aMediaStream);
-  }
-
   NS_IMETHODIMP_TO_ERRORRESULT(AddTrack, ErrorResult &rv,
       mozilla::dom::MediaStreamTrack& aTrack,
       const mozilla::dom::Sequence>& aStreams)
@@ -388,6 +381,9 @@ public:
     rv = RemoveTrack(aTrack);
   }
 
+  nsresult
+  AddTrack(mozilla::dom::MediaStreamTrack& aTrack, DOMMediaStream& aStream);
+
   nsresult GetPeerIdentity(nsAString& peerIdentity)
   {
 #ifdef MOZILLA_INTERNAL_API
diff --git a/media/webrtc/signaling/test/FakeMediaStreams.h b/media/webrtc/signaling/test/FakeMediaStreams.h
index 59ba9a83cc01..72c6b9a9ce58 100644
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -15,6 +15,7 @@
 
 // #includes from MediaStream.h
 #include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
 #include "AudioSegment.h"
 #include "MediaSegment.h"
 #include "StreamBuffer.h"
@@ -209,6 +210,21 @@ class Fake_SourceMediaStream : public Fake_MediaStream {
   nsCOMPtr mTimer;
 };
 
+class Fake_MediaStreamTrack : public mozilla::RefCounted
+{
+public:
+  Fake_MediaStreamTrack(bool aIsVideo) : mIsVideo (aIsVideo) {}
+  const Fake_MediaStreamTrack* AsVideoStreamTrack() const
+  {
+    return mIsVideo? this : nullptr;
+  }
+  const Fake_MediaStreamTrack* AsAudioStreamTrack() const
+  {
+    return mIsVideo? nullptr : this;
+  }
+private:
+  const bool mIsVideo;
+};
 
 class Fake_DOMMediaStream : public nsIDOMMediaStream
 {
@@ -219,9 +235,10 @@ protected:
   }
 
 public:
-  Fake_DOMMediaStream() : mMediaStream(new Fake_MediaStream()) {}
-  Fake_DOMMediaStream(Fake_MediaStream *stream) :
-      mMediaStream(stream) {}
+  Fake_DOMMediaStream(Fake_MediaStream *stream = nullptr)
+    : mMediaStream(stream? stream : new Fake_MediaStream())
+    , mVideoTrack(new Fake_MediaStreamTrack(true))
+    , mAudioTrack(new Fake_MediaStreamTrack(false)) {}
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
@@ -252,6 +269,35 @@ public:
   uint32_t GetHintContents() const { return mHintContents; }
   void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; }
 
+  void
+  GetTracks(nsTArray >& aTracks)
+  {
+    GetAudioTracks(aTracks);
+    GetVideoTracks(aTracks);
+  }
+
+  void GetAudioTracks(nsTArray >& aTracks)
+  {
+    if (mHintContents & HINT_CONTENTS_AUDIO) {
+      aTracks.AppendElement(mAudioTrack);
+    }
+  }
+
+  void
+  GetVideoTracks(nsTArray >& aTracks)
+  {
+    if (mHintContents & HINT_CONTENTS_VIDEO) {
+      aTracks.AppendElement(mVideoTrack);
+    }
+  }
+
+  bool
+  HasTrack(const Fake_MediaStreamTrack& aTrack) const
+  {
+    return ((mHintContents & HINT_CONTENTS_AUDIO) && aTrack.AsAudioStreamTrack()) ||
+           ((mHintContents & HINT_CONTENTS_VIDEO) && aTrack.AsVideoStreamTrack());
+  }
+
   void SetTrackEnabled(mozilla::TrackID aTrackID, bool aEnabled) {}
 
   class PrincipalChangeObserver
@@ -268,6 +314,8 @@ private:
   // tells the SDP generator about whether this
   // MediaStream probably has audio and/or video
   uint32_t mHintContents;
+  nsRefPtr mVideoTrack;
+  nsRefPtr mAudioTrack;
 };
 
 class Fake_MediaStreamGraph
diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp
index 4b9c52243eaf..8118dcdaf0a5 100644
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -806,29 +806,31 @@ class PCDispatchWrapper : public nsSupportsWeakReference
     return rv;
   }
 
-  NS_IMETHODIMP AddStream(DOMMediaStream *aMediaStream) {
+  NS_IMETHODIMP AddTrack(MediaStreamTrack *aTrack,
+                         DOMMediaStream *aMediaStream)
+  {
     nsresult rv;
 
     if (NS_IsMainThread()) {
-      rv = pc_->AddStream(*aMediaStream);
+      rv = pc_->AddTrack(*aTrack, *aMediaStream);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::AddStream, aMediaStream, &rv),
+        WrapRunnableRet(this, &PCDispatchWrapper::AddTrack, aTrack,
+                        aMediaStream, &rv),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
-  NS_IMETHODIMP RemoveStream(DOMMediaStream *aMediaStream) {
+  NS_IMETHODIMP RemoveTrack(MediaStreamTrack *aTrack) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
-      rv = pc_->RemoveStream(*aMediaStream);
+      rv = pc_->RemoveTrack(*aTrack);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::RemoveStream,
-          aMediaStream, &rv),
+        WrapRunnableRet(this, &PCDispatchWrapper::RemoveTrack, aTrack, &rv),
         NS_DISPATCH_SYNC);
     }
 
@@ -1082,24 +1084,26 @@ class SignalingAgent {
          DOMMediaStream::HINT_CONTENTS_VIDEO,
        MediaStream *stream = nullptr) {
 
-    nsRefPtr domMediaStream;
-    if (stream) {
-      domMediaStream = new DOMMediaStream(stream);
-    } else {
-      domMediaStream = new DOMMediaStream();
-    }
-
+    nsRefPtr domMediaStream = new DOMMediaStream(stream);
     domMediaStream->SetHintContents(hint);
-    ASSERT_EQ(pc->AddStream(domMediaStream), NS_OK);
+
+    nsTArray> tracks;
+    domMediaStream->GetTracks(tracks);
+    for (uint32_t i = 0; i < tracks.Length(); i++) {
+      ASSERT_EQ(pc->AddTrack(tracks[i], domMediaStream), NS_OK);
+    }
     domMediaStream_ = domMediaStream;
   }
 
-
   // Removes a stream from the PeerConnection. If the stream
   // parameter is absent, removes the stream that was most
   // recently added to the PeerConnection.
   void RemoveLastStreamAdded() {
-    ASSERT_EQ(pc->RemoveStream(domMediaStream_), NS_OK);
+    nsTArray> tracks;
+    domMediaStream_->GetTracks(tracks);
+    for (uint32_t i = 0; i < tracks.Length(); i++) {
+      ASSERT_EQ(pc->RemoveTrack(tracks[i]), NS_OK);
+    }
   }
 
   void CreateOffer(sipcc::OfferOptions& options,
@@ -1182,7 +1186,7 @@ void CreateAnswer(std::string offer,
     // hints as were passed in.
     // When complete RemoveStream will remove and entire stream and its tracks
     // not just disable a track as this is currently doing
-    ASSERT_EQ(pc->RemoveStream(domMediaStream_), NS_OK);
+    RemoveLastStreamAdded();
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;

From b47d5e54c31636e772395aeba993d6bffb727f75 Mon Sep 17 00:00:00 2001
From: Ahmed Kachkach 
Date: Fri, 15 Aug 2014 14:42:00 -0400
Subject: [PATCH 089/101] Bug 1050251 - Use the correct message/name for chrome
 mochitest asserts. r=chmanchester

---
 testing/mochitest/browser-harness.xul            | 2 +-
 testing/mochitest/browser-test.js                | 9 +++++----
 testing/mochitest/runtests.py                    | 5 ++---
 testing/mochitest/tests/SimpleTest/TestRunner.js | 2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/testing/mochitest/browser-harness.xul b/testing/mochitest/browser-harness.xul
index caed4380cfd1..1f3369df136d 100644
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -150,7 +150,7 @@
         }
 
         this.dumper.structuredLogger.testStatus(this.path,
-                                                result.msg,
+                                                result.name,
                                                 result.status,
                                                 result.expected,
                                                 result.msg);
diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js
index 2338e81790b3..12cd7ea7c1fd 100644
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -684,7 +684,7 @@ Tester.prototype = {
           return;
         }
 
-        self.currentTest.addResult(new testResult(false, "Test timed out", "", false));
+        self.currentTest.addResult(new testResult(false, "Test timed out", null, false));
         self.currentTest.timedOut = true;
         self.currentTest.scope.__waitTimer = null;
         self.nextTest();
@@ -702,7 +702,8 @@ Tester.prototype = {
 };
 
 function testResult(aCondition, aName, aDiag, aIsTodo, aStack) {
-  this.msg = aName || "";
+  this.name = aName;
+  this.msg = "";
 
   this.info = false;
   this.pass = !!aCondition;
@@ -721,9 +722,9 @@ function testResult(aCondition, aName, aDiag, aIsTodo, aStack) {
     if (aDiag) {
       if (typeof aDiag == "object" && "fileName" in aDiag) {
         // we have an exception - print filename and linenumber information
-        this.msg += " at " + aDiag.fileName + ":" + aDiag.lineNumber;
+        this.msg += "at " + aDiag.fileName + ":" + aDiag.lineNumber + " - ";
       }
-      this.msg += " - " + aDiag;
+      this.msg += String(aDiag);
     }
     if (aStack) {
       this.msg += "\nStack trace:\n";
diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py
index 5354970d5df5..21433736e74f 100644
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -1980,9 +1980,8 @@ class Mochitest(MochitestUtilsMixin):
     def dumpScreenOnTimeout(self, message):
       if (not self.dump_screen_on_fail
           and self.dump_screen_on_timeout
-          and 'expected' in message and message['status'] == 'FAIL'
-          and 'message' in message
-          and "Test timed out" in message['message']):
+          and message['action'] == 'test_status' and 'expected' in message
+          and "Test timed out" in message['subtest']):
         self.harness.dumpScreen(self.utilityPath)
       return message
 
diff --git a/testing/mochitest/tests/SimpleTest/TestRunner.js b/testing/mochitest/tests/SimpleTest/TestRunner.js
index 2aeb7eb8bc52..362c91863f5a 100644
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -141,7 +141,7 @@ function StructuredLogger(name) {
     this.testStatus = function(test, subtest, status, expected="PASS", message=null) {
         var data = {test: test, subtest: subtest, status: status};
 
-        if (message !== null) {
+        if (message) {
             data.message = String(message);
         }
         if (expected != status && status != 'SKIP') {

From c9a73bec1b8c48fe180e348df53b65efce5eb219 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kan-Ru=20Chen=20=28=E9=99=B3=E4=BE=83=E5=A6=82=29?=
 
Date: Fri, 15 Aug 2014 04:24:00 -0400
Subject: [PATCH 090/101] Bug 1050899 - Check mAGpsRilInterface before use.
 r=dougt

---
 dom/system/gonk/GonkGPSGeolocationProvider.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/dom/system/gonk/GonkGPSGeolocationProvider.cpp b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
index 2f34c8f75299..fb6c33bf4d89 100644
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -338,7 +338,8 @@ GonkGPSGeolocationProvider::SetAGpsDataConn(nsAString& aApn)
   MOZ_ASSERT(mAGpsInterface);
 
   bool hasUpdateNetworkAvailability = false;
-  if (mAGpsRilInterface->size >= sizeof(AGpsRilInterface) &&
+  if (mAGpsRilInterface &&
+      mAGpsRilInterface->size >= sizeof(AGpsRilInterface) &&
       mAGpsRilInterface->update_network_availability) {
     hasUpdateNetworkAvailability = true;
   }
@@ -426,7 +427,8 @@ GonkGPSGeolocationProvider::RequestSetID(uint32_t flags)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (!mRadioInterface) {
+  if (!mRadioInterface ||
+      !mAGpsInterface) {
     return;
   }
 
@@ -464,7 +466,8 @@ GonkGPSGeolocationProvider::SetReferenceLocation()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (!mRadioInterface) {
+  if (!mRadioInterface ||
+      !mAGpsRilInterface) {
     return;
   }
 
@@ -522,9 +525,7 @@ GonkGPSGeolocationProvider::SetReferenceLocation()
         }
       }
     }
-    if (mAGpsRilInterface) {
-      mAGpsRilInterface->set_ref_location(&location, sizeof(location));
-    }
+    mAGpsRilInterface->set_ref_location(&location, sizeof(location));
   }
 }
 

From 1299cec0fff09384574e52b5d9798ba7d420982b Mon Sep 17 00:00:00 2001
From: Gabriele Svelto 
Date: Fri, 15 Aug 2014 11:36:49 +0200
Subject: [PATCH 091/101] Bug 1052923 - Fix the volume conversion in millibels.
 r=padenot

---
 media/libcubeb/src/cubeb_opensl.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/media/libcubeb/src/cubeb_opensl.c b/media/libcubeb/src/cubeb_opensl.c
index d35d21568471..8ab149159833 100644
--- a/media/libcubeb/src/cubeb_opensl.c
+++ b/media/libcubeb/src/cubeb_opensl.c
@@ -745,6 +745,7 @@ opensl_stream_set_volume(cubeb_stream * stm, float volume)
 {
   SLresult res;
   SLmillibel max_level, millibels;
+  float unclamped_millibels;
 
   res = (*stm->volume)->GetMaxVolumeLevel(stm->volume, &max_level);
 
@@ -752,12 +753,15 @@ opensl_stream_set_volume(cubeb_stream * stm, float volume)
     return CUBEB_ERROR;
   }
 
-  millibels = SL_MILLIBEL_MIN + (float)(max_level - SL_MILLIBEL_MIN) * volume;
+  /* millibels are 100*dB, so the conversion from the volume's linear amplitude
+   * is 100 * 20 * log(volume). However we clamp the resulting value before
+   * passing it to lroundf() in order to prevent it from silently returning an
+   * erroneous value when the unclamped value exceeds the size of a long. */
+  unclamped_millibels = 100.0f * 20.0f * log10f(fmaxf(volume, 0.0f));
+  unclamped_millibels = fmaxf(unclamped_millibels, SL_MILLIBEL_MIN);
+  unclamped_millibels = fminf(unclamped_millibels, max_level);
 
-  /* clamp to supported range */
-  if (millibels > max_level) {
-   millibels = max_level;
-  }
+  millibels = lroundf(unclamped_millibels);
 
   res = (*stm->volume)->SetVolumeLevel(stm->volume, millibels);
 

From dbbcf5b458a797b1899e6339bc9df3f6c2b1af9b Mon Sep 17 00:00:00 2001
From: Chris Manchester 
Date: Fri, 15 Aug 2014 12:00:55 -0400
Subject: [PATCH 092/101] Bug 1054324 - Bump mozlog version to pick up
 exception stack logging. r=ahal

---
 testing/mozbase/mozlog/setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/testing/mozbase/mozlog/setup.py b/testing/mozbase/mozlog/setup.py
index d4eb24364f70..cabe4cd291d6 100644
--- a/testing/mozbase/mozlog/setup.py
+++ b/testing/mozbase/mozlog/setup.py
@@ -5,7 +5,7 @@
 from setuptools import setup, find_packages
 
 PACKAGE_NAME = 'mozlog'
-PACKAGE_VERSION = '2.4'
+PACKAGE_VERSION = '2.5'
 
 setup(name=PACKAGE_NAME,
       version=PACKAGE_VERSION,

From d9f51c6e279c997af83183dccc5b100f9ec0cf99 Mon Sep 17 00:00:00 2001
From: Chris Manchester 
Date: Fri, 15 Aug 2014 14:30:38 -0400
Subject: [PATCH 093/101] Bug 1054375 - Fix reference to tbplformatter in
 mozlog docs. r=wlach

---
 testing/mozbase/docs/mozlog_structured.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/testing/mozbase/docs/mozlog_structured.rst b/testing/mozbase/docs/mozlog_structured.rst
index 44b7c169b833..4763fe08e67b 100644
--- a/testing/mozbase/docs/mozlog_structured.rst
+++ b/testing/mozbase/docs/mozlog_structured.rst
@@ -263,6 +263,8 @@ invoked as part of a command line for post-processing raw log files.
 .. autoclass:: MachFormatter
   :members:
 
+.. automodule:: mozlog.structured.formatters.tbplformatter
+
 .. autoclass:: TbplFormatter
   :members:
 

From 1397909531a87ed8ea36cce2905e9d01d14393f5 Mon Sep 17 00:00:00 2001
From: Jeff Gilbert 
Date: Thu, 14 Aug 2014 15:07:00 -0400
Subject: [PATCH 094/101] Bug 1053635 - Expose SharedSurfaceEGL::mImage.
 r=romaxa

---
 gfx/gl/SharedSurfaceEGL.cpp | 1 -
 gfx/gl/SharedSurfaceEGL.h   | 4 +++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/gfx/gl/SharedSurfaceEGL.cpp b/gfx/gl/SharedSurfaceEGL.cpp
index a16e4a7a0d09..8241f8554ff9 100644
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -86,7 +86,6 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
 SharedSurface_EGLImage::~SharedSurface_EGLImage()
 {
     mEGL->fDestroyImage(Display(), mImage);
-    mImage = 0;
 
     mGL->MakeCurrent();
     mGL->fDeleteTextures(1, &mProdTex);
diff --git a/gfx/gl/SharedSurfaceEGL.h b/gfx/gl/SharedSurfaceEGL.h
index 7c845ba7e152..8c3fec0cd9c4 100644
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -41,7 +41,9 @@ protected:
     GLLibraryEGL* const mEGL;
     const GLFormats mFormats;
     GLuint mProdTex;
-    EGLImage mImage;
+public:
+    const EGLImage mImage;
+protected:
     GLContext* mCurConsGL;
     GLuint mConsTex;
     nsRefPtr mGarbageBin;

From 980abb9677b49013e6edb38c7304b52c87a111af Mon Sep 17 00:00:00 2001
From: Ahmed Kachkach 
Date: Fri, 15 Aug 2014 09:26:00 -0400
Subject: [PATCH 095/101] Bug 1054304 - Correct test status for tests that do
 not call SimpleTest.finish(). r=chmanchester

---
 testing/mochitest/tests/SimpleTest/TestRunner.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/testing/mochitest/tests/SimpleTest/TestRunner.js b/testing/mochitest/tests/SimpleTest/TestRunner.js
index 362c91863f5a..c25bbaa15eb5 100644
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -698,8 +698,8 @@ TestRunner.testFinished = function(tests) {
         if (TestRunner.currentTestURL != TestRunner.getLoadedTestURL()) {
             TestRunner.structuredLogger.testStatus(TestRunner.currentTestURL,
                                                    TestRunner.getLoadedTestURL(),
-                                                   "ERROR",
-                                                   "OK",
+                                                   "FAIL",
+                                                   "PASS",
                                                    "finished in a non-clean fashion, probably" +
                                                    " because it didn't call SimpleTest.finish()",
                                                    {loaded_test_url: TestRunner.getLoadedTestURL()});

From 26e86cf868932969d807eae1cd8d742a37292787 Mon Sep 17 00:00:00 2001
From: Tom Schuster 
Date: Sat, 16 Aug 2014 18:53:15 +0200
Subject: [PATCH 096/101] Bug 1054322 - Start putting JSMSGs into categories.
 r=till

---
 js/src/js.msg                 | 488 ++++++++++++++++++----------------
 js/src/vm/Debugger.cpp        |   2 +-
 js/src/vm/StructuredClone.cpp |   2 +-
 3 files changed, 258 insertions(+), 234 deletions(-)

diff --git a/js/src/js.msg b/js/src/js.msg
index 515041078ce6..d03d1dfed3e9 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -48,7 +48,6 @@ MSG_DEF(JSMSG_MORE_ARGS_NEEDED,        3, JSEXN_TYPEERR, "{0} requires more than
 MSG_DEF(JSMSG_BAD_CHAR,                1, JSEXN_INTERNALERR, "invalid format character {0}")
 MSG_DEF(JSMSG_BAD_TYPE,                1, JSEXN_TYPEERR, "unknown type {0}")
 MSG_DEF(JSMSG_ALLOC_OVERFLOW,          0, JSEXN_INTERNALERR, "allocation size overflow")
-MSG_DEF(JSMSG_MISSING_HEXDIGITS,       0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'")
 MSG_DEF(JSMSG_INCOMPATIBLE_PROTO,      3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
 MSG_DEF(JSMSG_NO_CONSTRUCTOR,          1, JSEXN_TYPEERR, "{0} has no constructor")
 MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION,   1, JSEXN_TYPEERR, "{0} is not a scripted function")
@@ -65,12 +64,9 @@ MSG_DEF(JSMSG_TOO_DEEP,                1, JSEXN_INTERNALERR, "{0} nested too dee
 MSG_DEF(JSMSG_OVER_RECURSED,           0, JSEXN_INTERNALERR, "too much recursion")
 MSG_DEF(JSMSG_IN_NOT_OBJECT,           1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
 MSG_DEF(JSMSG_BAD_NEW_RESULT,          1, JSEXN_TYPEERR, "invalid new expression result {0}")
-MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED,    0, JSEXN_ERR, "Permission denied to access object")
-MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED,  1, JSEXN_ERR, "Permission denied to access property '{0}'")
 MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS,      1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
 MSG_DEF(JSMSG_BAD_BYTECODE,            1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
 MSG_DEF(JSMSG_BAD_RADIX,               0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36")
-MSG_DEF(JSMSG_PAREN_BEFORE_LET,        0, JSEXN_SYNTAXERR, "missing ( before let head")
 MSG_DEF(JSMSG_CANT_CONVERT,            1, JSEXN_ERR, "can't convert {0} to an integer")
 MSG_DEF(JSMSG_CYCLIC_VALUE,            1, JSEXN_TYPEERR, "cyclic {0} value")
 MSG_DEF(JSMSG_CANT_CONVERT_TO,         2, JSEXN_TYPEERR, "can't convert {0} to {1}")
@@ -78,99 +74,20 @@ MSG_DEF(JSMSG_NO_PROPERTIES,           1, JSEXN_TYPEERR, "{0} has no properties"
 MSG_DEF(JSMSG_DEAD_OBJECT,             0, JSEXN_TYPEERR, "can't access dead object")
 MSG_DEF(JSMSG_BYTECODE_TOO_BIG,        2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
 MSG_DEF(JSMSG_UNKNOWN_FORMAT,          1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
-MSG_DEF(JSMSG_TOO_MANY_CON_ARGS,       0, JSEXN_SYNTAXERR, "too many constructor arguments")
-MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS,       0, JSEXN_SYNTAXERR, "too many function arguments")
-MSG_DEF(JSMSG_BAD_DESTRUCT_DECL,       0, JSEXN_SYNTAXERR, "missing = in destructuring declaration")
-MSG_DEF(JSMSG_BAD_DESTRUCT_ASS,        0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator")
-MSG_DEF(JSMSG_PAREN_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing ) after let head")
-MSG_DEF(JSMSG_CURLY_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing } after let block")
-MSG_DEF(JSMSG_MISSING_PAREN,           0, JSEXN_SYNTAXERR, "unterminated parenthetical")
-MSG_DEF(JSMSG_UNTERM_CLASS,            0, JSEXN_SYNTAXERR, "unterminated character class")
-MSG_DEF(JSMSG_BAD_CLASS_RANGE,         0, JSEXN_SYNTAXERR, "invalid range in character class")
 MSG_DEF(JSMSG_BAD_REGEXP_FLAG,         1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
 MSG_DEF(JSMSG_CANT_OPEN,               2, JSEXN_ERR, "can't open {0}: {1}")
 MSG_DEF(JSMSG_TOO_MANY_FUN_APPLY_ARGS, 0, JSEXN_RANGEERR, "arguments array passed to Function.prototype.apply is too large")
-MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN,   0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
 MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE,       0, JSEXN_INTERNALERR, "data are to big to encode")
 MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE,  1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range")
 MSG_DEF(JSMSG_SPREAD_TOO_LARGE,        0, JSEXN_RANGEERR, "array too large due to spread operand(s)")
-MSG_DEF(JSMSG_SOURCE_TOO_LONG,         0, JSEXN_RANGEERR, "source is too long")
 MSG_DEF(JSMSG_BAD_WEAKMAP_KEY,         0, JSEXN_TYPEERR, "cannot use the given object as a weak map key")
 MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC,        0, JSEXN_INTERNALERR, "bad script XDR magic number")
-MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL,     0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
-MSG_DEF(JSMSG_MISSING_FORMAL,          0, JSEXN_SYNTAXERR, "missing formal parameter")
-MSG_DEF(JSMSG_PAREN_AFTER_FORMAL,      0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
-MSG_DEF(JSMSG_CURLY_BEFORE_BODY,       0, JSEXN_SYNTAXERR, "missing { before function body")
-MSG_DEF(JSMSG_CURLY_AFTER_BODY,        0, JSEXN_SYNTAXERR, "missing } after function body")
-MSG_DEF(JSMSG_PAREN_BEFORE_COND,       0, JSEXN_SYNTAXERR, "missing ( before condition")
-MSG_DEF(JSMSG_PAREN_AFTER_COND,        0, JSEXN_SYNTAXERR, "missing ) after condition")
-MSG_DEF(JSMSG_BAD_DUP_ARGS,            0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context")
-MSG_DEF(JSMSG_NAME_AFTER_DOT,          0, JSEXN_SYNTAXERR, "missing name after . operator")
-MSG_DEF(JSMSG_BRACKET_IN_INDEX,        0, JSEXN_SYNTAXERR, "missing ] in index expression")
 MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED,     1, JSEXN_ERR, "Permission denied to define accessor property '{0}'")
-MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing ( before switch expression")
-MSG_DEF(JSMSG_PAREN_AFTER_SWITCH,      0, JSEXN_SYNTAXERR, "missing ) after switch expression")
-MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing { before switch body")
-MSG_DEF(JSMSG_COLON_AFTER_CASE,        0, JSEXN_SYNTAXERR, "missing : after case label")
-MSG_DEF(JSMSG_WHILE_AFTER_DO,          0, JSEXN_SYNTAXERR, "missing while after do-loop body")
-MSG_DEF(JSMSG_PAREN_AFTER_FOR,         0, JSEXN_SYNTAXERR, "missing ( after for")
-MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT,     0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
-MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND,     0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
-MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL,    0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
-MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        0, JSEXN_SYNTAXERR, "missing { before try block")
-MSG_DEF(JSMSG_CURLY_AFTER_TRY,         0, JSEXN_SYNTAXERR, "missing } after try block")
-MSG_DEF(JSMSG_PAREN_BEFORE_CATCH,      0, JSEXN_SYNTAXERR, "missing ( before catch")
-MSG_DEF(JSMSG_CATCH_IDENTIFIER,        0, JSEXN_SYNTAXERR, "missing identifier in catch")
-MSG_DEF(JSMSG_PAREN_AFTER_CATCH,       0, JSEXN_SYNTAXERR, "missing ) after catch")
-MSG_DEF(JSMSG_CURLY_BEFORE_CATCH,      0, JSEXN_SYNTAXERR, "missing { before catch block")
-MSG_DEF(JSMSG_CURLY_AFTER_CATCH,       0, JSEXN_SYNTAXERR, "missing } after catch block")
-MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    0, JSEXN_SYNTAXERR, "missing { before finally block")
-MSG_DEF(JSMSG_CURLY_AFTER_FINALLY,     0, JSEXN_SYNTAXERR, "missing } after finally block")
-MSG_DEF(JSMSG_CATCH_OR_FINALLY,        0, JSEXN_SYNTAXERR, "missing catch or finally after try")
-MSG_DEF(JSMSG_PAREN_BEFORE_WITH,       0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
-MSG_DEF(JSMSG_PAREN_AFTER_WITH,        0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
-MSG_DEF(JSMSG_CURLY_IN_COMPOUND,       0, JSEXN_SYNTAXERR, "missing } in compound statement")
-MSG_DEF(JSMSG_NO_VARIABLE_NAME,        0, JSEXN_SYNTAXERR, "missing variable name")
-MSG_DEF(JSMSG_COLON_IN_COND,           0, JSEXN_SYNTAXERR, "missing : in conditional expression")
-MSG_DEF(JSMSG_PAREN_AFTER_ARGS,        0, JSEXN_SYNTAXERR, "missing ) after argument list")
-MSG_DEF(JSMSG_BRACKET_AFTER_LIST,      0, JSEXN_SYNTAXERR, "missing ] after element list")
-MSG_DEF(JSMSG_COLON_AFTER_ID,          0, JSEXN_SYNTAXERR, "missing : after property id")
-MSG_DEF(JSMSG_CURLY_AFTER_LIST,        0, JSEXN_SYNTAXERR, "missing } after property list")
-MSG_DEF(JSMSG_PAREN_IN_PAREN,          0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
-MSG_DEF(JSMSG_SEMI_BEFORE_STMNT,       0, JSEXN_SYNTAXERR, "missing ; before statement")
-MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR,    0, JSEXN_SYNTAXERR, "missing } in template string")
-MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
 MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,         0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?")
-MSG_DEF(JSMSG_TOO_MANY_DEFAULTS,       0, JSEXN_SYNTAXERR, "more than one switch default")
-MSG_DEF(JSMSG_TOO_MANY_CASES,          0, JSEXN_INTERNALERR, "too many switch cases")
-MSG_DEF(JSMSG_BAD_SWITCH,              0, JSEXN_SYNTAXERR, "invalid switch statement")
-MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE,        0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
-MSG_DEF(JSMSG_CATCH_AFTER_GENERAL,     0, JSEXN_SYNTAXERR, "catch after unconditional catch")
-MSG_DEF(JSMSG_CATCH_WITHOUT_TRY,       0, JSEXN_SYNTAXERR, "catch without try")
-MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY,     0, JSEXN_SYNTAXERR, "finally without try")
-MSG_DEF(JSMSG_LABEL_NOT_FOUND,         0, JSEXN_SYNTAXERR, "label not found")
-MSG_DEF(JSMSG_TOUGH_BREAK,             0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch")
-MSG_DEF(JSMSG_BAD_CONTINUE,            0, JSEXN_SYNTAXERR, "continue must be inside loop")
-MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD,     1, JSEXN_SYNTAXERR, "{0} not in function")
-MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
-MSG_DEF(JSMSG_VAR_HIDES_ARG,           1, JSEXN_TYPEERR, "variable {0} redeclares argument")
 MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS,     0, JSEXN_REFERENCEERR, "invalid assignment left-hand side")
-MSG_DEF(JSMSG_BAD_OPERAND,             1, JSEXN_SYNTAXERR, "invalid {0} operand")
-MSG_DEF(JSMSG_BAD_PROP_ID,             0, JSEXN_SYNTAXERR, "invalid property id")
-MSG_DEF(JSMSG_RESERVED_ID,             1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
-MSG_DEF(JSMSG_SYNTAX_ERROR,            0, JSEXN_SYNTAXERR, "syntax error")
-MSG_DEF(JSMSG_MISSING_BINARY_DIGITS,   0, JSEXN_SYNTAXERR, "missing binary digits after '0b'")
-MSG_DEF(JSMSG_BAD_PROTOTYPE,           1, JSEXN_TYPEERR,   "'prototype' property of {0} is not an object")
-MSG_DEF(JSMSG_MISSING_EXPONENT,        0, JSEXN_SYNTAXERR, "missing exponent")
+MSG_DEF(JSMSG_BAD_PROTOTYPE,           1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object")
 MSG_DEF(JSMSG_OUT_OF_MEMORY,           0, JSEXN_ERR, "out of memory")
-MSG_DEF(JSMSG_UNTERMINATED_STRING,     0, JSEXN_SYNTAXERR, "unterminated string literal")
-MSG_DEF(JSMSG_TOO_MANY_PARENS,         0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
-MSG_DEF(JSMSG_UNTERMINATED_COMMENT,    0, JSEXN_SYNTAXERR, "unterminated comment")
-MSG_DEF(JSMSG_UNTERMINATED_REGEXP,     0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
 MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE,  0, JSEXN_TYPEERR, "bad cloned function scope chain")
-MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS,    0, JSEXN_SYNTAXERR, "missing octal digits after '0o'")
-MSG_DEF(JSMSG_ILLEGAL_CHARACTER,       0, JSEXN_SYNTAXERR, "illegal character")
-MSG_DEF(JSMSG_BAD_OCTAL,               1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
 MSG_DEF(JSMSG_RESULTING_STRING_TOO_LARGE, 0, JSEXN_RANGEERR, "repeat count must be less than infinity and not overflow maximum string size")
 MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,      1, JSEXN_INTERNALERR, "uncaught exception: {0}")
 MSG_DEF(JSMSG_PRECISION_RANGE,         1, JSEXN_RANGEERR, "precision {0} out of range")
@@ -179,210 +96,317 @@ MSG_DEF(JSMSG_BAD_ARRAY_LENGTH,        0, JSEXN_RANGEERR, "invalid array length"
 MSG_DEF(JSMSG_BAD_APPLY_ARGS,          1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array")
 MSG_DEF(JSMSG_REDECLARED_VAR,          2, JSEXN_TYPEERR, "redeclaration of {0} {1}")
 MSG_DEF(JSMSG_UNDECLARED_VAR,          1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}")
-MSG_DEF(JSMSG_PROXY_REVOKED,           0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy")
 MSG_DEF(JSMSG_DEPRECATED_USAGE,        1, JSEXN_REFERENCEERR, "deprecated {0} usage")
 MSG_DEF(JSMSG_BAD_URI,                 0, JSEXN_URIERR, "malformed URI sequence")
 MSG_DEF(JSMSG_GETTER_ONLY,             0, JSEXN_TYPEERR, "setting a property that has only a getter")
-MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER,    0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
 MSG_DEF(JSMSG_UNDEFINED_PROP,          1, JSEXN_REFERENCEERR, "reference to undefined property {0}")
-MSG_DEF(JSMSG_USELESS_EXPR,            0, JSEXN_TYPEERR, "useless expression")
-MSG_DEF(JSMSG_REDECLARED_PARAM,        1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
-MSG_DEF(JSMSG_NEWREGEXP_FLAGGED,       0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
-MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS,     0, JSEXN_SYNTAXERR, "too many catch variables")
 MSG_DEF(JSMSG_NEGATIVE_REPETITION_COUNT, 0, JSEXN_RANGEERR, "repeat count must be non-negative")
-MSG_DEF(JSMSG_INVALID_FOR_OF_INIT,     0, JSEXN_SYNTAXERR, "for-of loop variable declaration may not have an initializer")
 MSG_DEF(JSMSG_INVALID_MAP_ITERABLE,    0, JSEXN_TYPEERR, "iterable for map should have array-like objects")
 MSG_DEF(JSMSG_NOT_A_CODEPOINT,         1, JSEXN_RANGEERR, "{0} is not a valid code point")
-MSG_DEF(JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION, 0, JSEXN_SYNTAXERR, "missing ] after array comprehension")
 MSG_DEF(JSMSG_NESTING_GENERATOR,       0, JSEXN_TYPEERR, "already executing generator")
-MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable")
 MSG_DEF(JSMSG_INVALID_NORMALIZE_FORM,  0, JSEXN_RANGEERR, "form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'")
-MSG_DEF(JSMSG_NOTHING_TO_REPEAT,       0, JSEXN_SYNTAXERR, "nothing to repeat")
-MSG_DEF(JSMSG_INVALID_GROUP,           0, JSEXN_SYNTAXERR, "invalid regexp group")
-MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern")
-MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER,    0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.")
-MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE,     0, JSEXN_TYPEERR, "invalid transferable array for structured clone")
-MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE,     0, JSEXN_TYPEERR, "duplicate transferable for structured clone")
-MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible")
-MSG_DEF(JSMSG_SYMBOL_TO_STRING,        0, JSEXN_TYPEERR, "can't convert symbol to string")
-MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so")
 MSG_DEF(JSMSG_INCOMPATIBLE_METHOD,     3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
-MSG_DEF(JSMSG_SYMBOL_TO_NUMBER,        0, JSEXN_TYPEERR, "can't convert symbol to number")
-MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true")
-MSG_DEF(JSMSG_BAD_INDEX,               0, JSEXN_RANGEERR, "invalid or out-of-range index")
-MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LET,0, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level 'let' declarations")
-MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP,       0, JSEXN_SYNTAXERR, "invalid for each loop")
 MSG_DEF(JSMSG_OBJECT_WATCH_DEPRECATED, 0, JSEXN_NONE, "Object.prototype.watch and unwatch are very slow, non-standard, and deprecated; use a getter/setter instead")
 MSG_DEF(JSMSG_TYPE_ERR_BAD_ARGS,       0, JSEXN_TYPEERR, "invalid arguments")
-MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_TYPEERR, "redeclaration of identifier '{0}' in catch")
-MSG_DEF(JSMSG_INTERNAL_INTL_ERROR,     0, JSEXN_ERR, "internal error while computing Intl data")
-MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR,    0, JSEXN_ERR, "internal error getting the default locale")
-MSG_DEF(JSMSG_TOO_MANY_LOCALS,         0, JSEXN_SYNTAXERR, "too many local variables")
-MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,      0, JSEXN_INTERNALERR, "array initialiser too large")
 MSG_DEF(JSMSG_BUFFER_TOO_SMALL,        0, JSEXN_INTERNALERR, "buffer too small")
 MSG_DEF(JSMSG_BAD_SURROGATE_CHAR,      1, JSEXN_TYPEERR, "bad surrogate character {0}")
 MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE,     1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
 MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR,     1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")
 MSG_DEF(JSMSG_USER_DEFINED_ERROR,      0, JSEXN_ERR, "JS_ReportError was called")
 MSG_DEF(JSMSG_WRONG_CONSTRUCTOR,       1, JSEXN_TYPEERR, "wrong constructor called for {0}")
-MSG_DEF(JSMSG_BAD_GENERATOR_RETURN,    1, JSEXN_TYPEERR, "generator function {0} returns a value")
-MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
 MSG_DEF(JSMSG_PROTO_SETTING_SLOW,      0, JSEXN_NONE, "mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create")
-MSG_DEF(JSMSG_IN_AFTER_FOR_NAME,       0, JSEXN_SYNTAXERR, "missing 'in' or 'of' after for")
-MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE,   2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value")
-MSG_DEF(JSMSG_OF_AFTER_FOR_NAME,       0, JSEXN_SYNTAXERR, "missing 'of' after for")
 MSG_DEF(JSMSG_BAD_GENERATOR_YIELD,     1, JSEXN_TYPEERR, "yield from closing generator {0}")
 MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX,    1, JSEXN_SYNTAXERR, "{0} expression must be parenthesized")
-MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE,     0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
-MSG_DEF(JSMSG_LET_COMP_BINDING,        0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
 MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE,      0, JSEXN_TYPEERR, "reduce of empty array with no initial value")
-MSG_DEF(JSMSG_BAD_SYMBOL,              1, JSEXN_TYPEERR, "{0} is not a well-known @@-symbol")
-MSG_DEF(JSMSG_BAD_INCOP_OPERAND,       0, JSEXN_REFERENCEERR, "invalid increment/decrement operand")
 MSG_DEF(JSMSG_UNEXPECTED_TYPE,         2, JSEXN_TYPEERR, "{0} is {1}")
-MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK,   0, JSEXN_SYNTAXERR, "let declaration not directly within block")
-MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE,   1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position")
 MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS,    0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties")
 MSG_DEF(JSMSG_MISSING_FUN_ARG,         2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}")
 MSG_DEF(JSMSG_JSON_BAD_PARSE,          3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data")
-MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined")
 MSG_DEF(JSMSG_NOT_NONNULL_OBJECT,      0, JSEXN_TYPEERR, "value is not a non-null object")
-MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
-MSG_DEF(JSMSG_STRICT_CODE_WITH,        0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements")
-MSG_DEF(JSMSG_DUPLICATE_PROPERTY,      1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
-MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
-MSG_DEF(JSMSG_BAD_STRICT_ASSIGN,       1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode")
-MSG_DEF(JSMSG_BAD_BINDING,             1, JSEXN_SYNTAXERR, "redefining {0} is deprecated")
 MSG_DEF(JSMSG_INVALID_DESCRIPTOR,      0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified")
 MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE,   1, JSEXN_TYPEERR, "{0} is not extensible")
 MSG_DEF(JSMSG_CANT_REDEFINE_PROP,      1, JSEXN_TYPEERR, "can't redefine non-configurable property '{0}'")
 MSG_DEF(JSMSG_CANT_APPEND_TO_ARRAY,    0, JSEXN_TYPEERR, "can't add elements past the end of an array if its length property is unwritable")
 MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length")
 MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length")
-MSG_DEF(JSMSG_TYPED_ARRAY_BAD_INDEX,   0, JSEXN_ERR, "invalid or out-of-range index")
-MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_ERR, "argument {0} must be >= 0")
-MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS,    0, JSEXN_ERR, "invalid arguments")
 MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION,    0, JSEXN_ERR, "call to Function() blocked by CSP")
 MSG_DEF(JSMSG_BAD_GET_SET_FIELD,       1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function")
-MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS,     3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}")
 MSG_DEF(JSMSG_THROW_TYPE_ERROR,        0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them")
 MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP,    0, JSEXN_TYPEERR, "toISOString property is not callable")
-MSG_DEF(JSMSG_BAD_PARSE_NODE,          0, JSEXN_INTERNALERR, "bad parse node")
 MSG_DEF(JSMSG_NOT_EXPECTED_TYPE,       3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}")
 MSG_DEF(JSMSG_CALLER_IS_STRICT,        0, JSEXN_TYPEERR, "access to strict mode caller function is censored")
 MSG_DEF(JSMSG_NEED_DEBUG_MODE,         0, JSEXN_ERR, "function can be called only in debug mode")
-MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 0, JSEXN_ERR, "strict mode code may not contain unparenthesized let expression statements")
-MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility")
-MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA,  1, JSEXN_INTERNALERR, "bad serialized structured data ({0})")
-MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE,     0, JSEXN_TYPEERR, "unsupported type for structured data")
-MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee")
-MSG_DEF(JSMSG_BAD_CLONE_VERSION,       0, JSEXN_ERR, "unsupported structured clone version")
 MSG_DEF(JSMSG_CANT_CLONE_OBJECT,       0, JSEXN_TYPEERR, "can't clone object")
-MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
-MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
-MSG_DEF(JSMSG_INVALID_FOR_IN_INIT,     0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer")
-MSG_DEF(JSMSG_MALFORMED_ESCAPE,        1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence")
-MSG_DEF(JSMSG_BAD_GENEXP_BODY,         1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression")
-MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT,   0, JSEXN_SYNTAXERR, "function statement requires a name")
-MSG_DEF(JSMSG_CCW_REQUIRED,            1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment")
-MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION,    0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null")
-MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null")
-MSG_DEF(JSMSG_DEBUG_NOT_LIVE,          1, JSEXN_ERR, "{0} is not live")
-MSG_DEF(JSMSG_DEBUG_OBJECT_WRONG_OWNER,0, JSEXN_TYPEERR, "Debugger.Object belongs to a different Debugger")
-MSG_DEF(JSMSG_DEBUG_OBJECT_PROTO,      0, JSEXN_TYPEERR, "Debugger.Object.prototype is not a valid Debugger.Object")
-MSG_DEF(JSMSG_DEBUG_LOOP,              0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger")
-MSG_DEF(JSMSG_DEBUG_NOT_IDLE,          0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack")
-MSG_DEF(JSMSG_DEBUG_BAD_OFFSET,        0, JSEXN_TYPEERR, "invalid script offset")
-MSG_DEF(JSMSG_DEBUG_BAD_LINE,          0, JSEXN_TYPEERR, "invalid line number")
-MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,     0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
-MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
 MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,        0, JSEXN_ERR, "call to eval() blocked by CSP")
-MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,   0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
-MSG_DEF(JSMSG_EMPTY_CONSEQUENT,        0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
 MSG_DEF(JSMSG_NOT_ITERABLE,            1, JSEXN_TYPEERR, "{0} is not iterable")
-MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL,  0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'url' property")
-MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'innermost' property without both 'url' and 'line' properties")
-MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment")
 MSG_DEF(JSMSG_PARAMETER_AFTER_REST,    0, JSEXN_SYNTAXERR, "parameter after rest parameter")
 MSG_DEF(JSMSG_NO_REST_NAME,            0, JSEXN_SYNTAXERR, "no parameter name after ...")
-MSG_DEF(JSMSG_ARGUMENTS_AND_REST,      0, JSEXN_SYNTAXERR, "'arguments' object may not be used in conjunction with a rest parameter")
 MSG_DEF(JSMSG_FUNCTION_ARGUMENTS_AND_REST, 0, JSEXN_ERR, "the 'arguments' property of a function with a rest parameter may not be used")
-MSG_DEF(JSMSG_REST_WITH_DEFAULT,       0, JSEXN_SYNTAXERR, "rest parameter may not have a default")
-MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default")
-MSG_DEF(JSMSG_YIELD_IN_DEFAULT,        0, JSEXN_SYNTAXERR, "yield in default expression")
-MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA,      2, JSEXN_NONE,      "{0} is being assigned a {1}, but already has one")
+MSG_DEF(JSMSG_ALREADY_HAS_PRAGMA,      2, JSEXN_NONE, "{0} is being assigned a {1}, but already has one")
 MSG_DEF(JSMSG_PAR_ARRAY_BAD_ARG,       0, JSEXN_RANGEERR, "invalid parallel method argument")
-MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT,     0, JSEXN_ERR, "variable has been optimized out")
 MSG_DEF(JSMSG_NEXT_RETURNED_PRIMITIVE, 0, JSEXN_TYPEERR, "iterator.next() returned a non-object value")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_CONFLICT, 0, JSEXN_ERR, "no conflict resolution function provided")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BOUNDS,0, JSEXN_ERR, "index in scatter vector out of bounds")
-MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE,    0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent")
-MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE,     0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
-MSG_DEF(JSMSG_CANT_REPORT_NEW,         0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object")
-MSG_DEF(JSMSG_CANT_REPORT_INVALID,     0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor")
-MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC,    0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable")
-MSG_DEF(JSMSG_CANT_DEFINE_NEW,         0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
-MSG_DEF(JSMSG_CANT_DEFINE_INVALID,     0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor")
-MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC,    0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable")
-MSG_DEF(JSMSG_INVALID_TRAP_RESULT,     2, JSEXN_TYPEERR, "trap {1} for {0} returned an invalid result")
-MSG_DEF(JSMSG_CANT_SKIP_NC,            0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property")
-MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE,  0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property")
-MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED,   0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter")
-MSG_DEF(JSMSG_CANT_SET_NW_NC,          0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property")
-MSG_DEF(JSMSG_CANT_SET_WO_SETTER,      0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter")
-MSG_DEF(JSMSG_DEBUG_BAD_REFERENT,      2, JSEXN_TYPEERR, "{0} does not refer to {1}")
-MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY,    3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required")
 MSG_DEF(JSMSG_UNWRAP_DENIED,           0, JSEXN_ERR, "permission denied to unwrap object")
-MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED,  3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}")
-MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument")
-MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG,    1, JSEXN_RANGEERR, "invalid language tag: {0}")
-MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER,  1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}")
-MSG_DEF(JSMSG_INVALID_OPTION_VALUE,    2, JSEXN_RANGEERR, "invalid value {1} for option {0}")
-MSG_DEF(JSMSG_INVALID_DIGITS_VALUE,    1, JSEXN_RANGEERR, "invalid digits value: {0}")
-MSG_DEF(JSMSG_INTL_OBJECT_REINITED,    0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor")
-MSG_DEF(JSMSG_INVALID_CURRENCY_CODE,   1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}")
-MSG_DEF(JSMSG_UNDEFINED_CURRENCY,      0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style")
-MSG_DEF(JSMSG_INVALID_TIME_ZONE,       1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}")
-MSG_DEF(JSMSG_DATE_NOT_FINITE,         0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()")
-MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL,  0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body")
-MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL,       1, JSEXN_TYPEERR, "asm.js type error: {0}")
-MSG_DEF(JSMSG_USE_ASM_LINK_FAIL,       1, JSEXN_TYPEERR, "asm.js link error: {0}")
-MSG_DEF(JSMSG_USE_ASM_TYPE_OK,         1, JSEXN_NONE,    "Successfully compiled asm.js code ({0})")
-MSG_DEF(JSMSG_BAD_ARROW_ARGS,          0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)")
-MSG_DEF(JSMSG_YIELD_IN_ARROW,          0, JSEXN_SYNTAXERR, "arrow function may not contain yield")
 MSG_DEF(JSMSG_WRONG_VALUE,             2, JSEXN_ERR, "expected {0} but found {1}")
 MSG_DEF(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, 1, JSEXN_ERR, "target for index {0} is not an integer")
-MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups")
-MSG_DEF(JSMSG_DEPRECATED_PRAGMA,       1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
-MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN,     1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment")
-MSG_DEF(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS, 0, JSEXN_ERR, "Invalid arguments")
-MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
-MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor")
-MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG,     0, JSEXN_ERR, "Type is too large to allocate")
 MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments")
 MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments")
-MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE,      2, JSEXN_ERR, "{0} is not a debuggee {1}")
-MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS,    0, JSEXN_TYPEERR, "invalid arguments")
-MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached")
-MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level")
-MSG_DEF(JSMSG_NO_IMPORT_NAME,          0, JSEXN_SYNTAXERR, "missing import name")
-MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD,  1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
-MSG_DEF(JSMSG_NO_BINDING_NAME,        0, JSEXN_SYNTAXERR, "missing binding name")
-MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list")
-MSG_DEF(JSMSG_FROM_AFTER_IMPORT_SPEC_SET, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import specifier set")
-MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
-MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM,  0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword")
-MSG_DEF(JSMSG_MODULES_NOT_IMPLEMENTED, 0, JSEXN_SYNTAXERR, "modules are not implemented yet")
-MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level")
-MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list")
-MSG_DEF(JSMSG_NO_EXPORT_NAME,          0, JSEXN_SYNTAXERR, "missing export name")
-MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
-MSG_DEF(JSMSG_INVALID_PROTOTYPE,       0, JSEXN_TYPEERR, "prototype field is not an object")
 MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL,     1, JSEXN_TYPEERR, "[[SetPrototypeOf]] failed on {0}")
 MSG_DEF(JSMSG_INVALID_ARG_TYPE,        3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}")
 MSG_DEF(JSMSG_TERMINATED,              1, JSEXN_ERR, "Script terminated by timeout at:\n{0}")
-MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}")
-MSG_DEF(JSMSG_PROXY_EXTENSIBILITY,     0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target")
-MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT,  0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object")
-MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined")
+
+// Frontend
+MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS,     3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}")
+MSG_DEF(JSMSG_ARGUMENTS_AND_REST,      0, JSEXN_SYNTAXERR, "'arguments' object may not be used in conjunction with a rest parameter")
+MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE,     0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
+MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,      0, JSEXN_INTERNALERR, "array initialiser too large")
+MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD,  1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
+MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
+MSG_DEF(JSMSG_BAD_ARROW_ARGS,          0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)")
+MSG_DEF(JSMSG_BAD_BINDING,             1, JSEXN_SYNTAXERR, "redefining {0} is deprecated")
+MSG_DEF(JSMSG_BAD_CONTINUE,            0, JSEXN_SYNTAXERR, "continue must be inside loop")
+MSG_DEF(JSMSG_BAD_DESTRUCT_ASS,        0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator")
+MSG_DEF(JSMSG_BAD_DESTRUCT_ASSIGN,     1, JSEXN_SYNTAXERR, "can't assign to {0} using destructuring assignment")
+MSG_DEF(JSMSG_BAD_DESTRUCT_DECL,       0, JSEXN_SYNTAXERR, "missing = in destructuring declaration")
+MSG_DEF(JSMSG_BAD_DUP_ARGS,            0, JSEXN_SYNTAXERR, "duplicate argument names not allowed in this context")
+MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP,       0, JSEXN_SYNTAXERR, "invalid for each loop")
+MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE,        0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
+MSG_DEF(JSMSG_BAD_GENERATOR_RETURN,    1, JSEXN_TYPEERR, "generator function {0} returns a value")
+MSG_DEF(JSMSG_BAD_GENEXP_BODY,         1, JSEXN_SYNTAXERR, "illegal use of {0} in generator expression")
+MSG_DEF(JSMSG_BAD_INCOP_OPERAND,       0, JSEXN_REFERENCEERR, "invalid increment/decrement operand")
+MSG_DEF(JSMSG_BAD_OCTAL,               1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
+MSG_DEF(JSMSG_BAD_OPERAND,             1, JSEXN_SYNTAXERR, "invalid {0} operand")
+MSG_DEF(JSMSG_BAD_PROP_ID,             0, JSEXN_SYNTAXERR, "invalid property id")
+MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD,     1, JSEXN_SYNTAXERR, "{0} not in function")
+MSG_DEF(JSMSG_BAD_STRICT_ASSIGN,       1, JSEXN_SYNTAXERR, "can't assign to {0} in strict mode")
+MSG_DEF(JSMSG_BAD_SWITCH,              0, JSEXN_SYNTAXERR, "invalid switch statement")
+MSG_DEF(JSMSG_BRACKET_AFTER_ARRAY_COMPREHENSION, 0, JSEXN_SYNTAXERR, "missing ] after array comprehension")
+MSG_DEF(JSMSG_BRACKET_AFTER_LIST,      0, JSEXN_SYNTAXERR, "missing ] after element list")
+MSG_DEF(JSMSG_BRACKET_IN_INDEX,        0, JSEXN_SYNTAXERR, "missing ] in index expression")
+MSG_DEF(JSMSG_CATCH_AFTER_GENERAL,     0, JSEXN_SYNTAXERR, "catch after unconditional catch")
+MSG_DEF(JSMSG_CATCH_IDENTIFIER,        0, JSEXN_SYNTAXERR, "missing identifier in catch")
+MSG_DEF(JSMSG_CATCH_OR_FINALLY,        0, JSEXN_SYNTAXERR, "missing catch or finally after try")
+MSG_DEF(JSMSG_CATCH_WITHOUT_TRY,       0, JSEXN_SYNTAXERR, "catch without try")
+MSG_DEF(JSMSG_COLON_AFTER_CASE,        0, JSEXN_SYNTAXERR, "missing : after case label")
+MSG_DEF(JSMSG_COLON_AFTER_ID,          0, JSEXN_SYNTAXERR, "missing : after property id")
+MSG_DEF(JSMSG_COLON_IN_COND,           0, JSEXN_SYNTAXERR, "missing : in conditional expression")
+MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR,   0, JSEXN_SYNTAXERR, "missing ] in computed property name")
+MSG_DEF(JSMSG_CONTRARY_NONDIRECTIVE,   1, JSEXN_SYNTAXERR, "'{0}' statement won't be enforced as a directive because it isn't in directive prologue position")
+MSG_DEF(JSMSG_CURLY_AFTER_BODY,        0, JSEXN_SYNTAXERR, "missing } after function body")
+MSG_DEF(JSMSG_CURLY_AFTER_CATCH,       0, JSEXN_SYNTAXERR, "missing } after catch block")
+MSG_DEF(JSMSG_CURLY_AFTER_FINALLY,     0, JSEXN_SYNTAXERR, "missing } after finally block")
+MSG_DEF(JSMSG_CURLY_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing } after let block")
+MSG_DEF(JSMSG_CURLY_AFTER_LIST,        0, JSEXN_SYNTAXERR, "missing } after property list")
+MSG_DEF(JSMSG_CURLY_AFTER_TRY,         0, JSEXN_SYNTAXERR, "missing } after try block")
+MSG_DEF(JSMSG_CURLY_BEFORE_BODY,       0, JSEXN_SYNTAXERR, "missing { before function body")
+MSG_DEF(JSMSG_CURLY_BEFORE_CATCH,      0, JSEXN_SYNTAXERR, "missing { before catch block")
+MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    0, JSEXN_SYNTAXERR, "missing { before finally block")
+MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing { before switch body")
+MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        0, JSEXN_SYNTAXERR, "missing { before try block")
+MSG_DEF(JSMSG_CURLY_IN_COMPOUND,       0, JSEXN_SYNTAXERR, "missing } in compound statement")
+MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword")
+MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration after 'import' keyword")
+MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
+MSG_DEF(JSMSG_DEPRECATED_OCTAL,        0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
+MSG_DEF(JSMSG_DEPRECATED_PRAGMA,       1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
+MSG_DEF(JSMSG_DUPLICATE_FORMAL,        1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
+MSG_DEF(JSMSG_DUPLICATE_LABEL,         0, JSEXN_SYNTAXERR, "duplicate label")
+MSG_DEF(JSMSG_DUPLICATE_PROPERTY,      1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
+MSG_DEF(JSMSG_EMPTY_CONSEQUENT,        0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
+MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level")
+MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY,     0, JSEXN_SYNTAXERR, "finally without try")
+MSG_DEF(JSMSG_FROM_AFTER_IMPORT_SPEC_SET, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import specifier set")
+MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER,    0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
+MSG_DEF(JSMSG_ILLEGAL_CHARACTER,       0, JSEXN_SYNTAXERR, "illegal character")
+MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level")
+MSG_DEF(JSMSG_INVALID_FOR_IN_INIT,     0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer")
+MSG_DEF(JSMSG_INVALID_FOR_OF_INIT,     0, JSEXN_SYNTAXERR, "for-of loop variable declaration may not have an initializer")
+MSG_DEF(JSMSG_IN_AFTER_FOR_NAME,       0, JSEXN_SYNTAXERR, "missing 'in' or 'of' after for")
+MSG_DEF(JSMSG_LABEL_NOT_FOUND,         0, JSEXN_SYNTAXERR, "label not found")
+MSG_DEF(JSMSG_LET_COMP_BINDING,        0, JSEXN_SYNTAXERR, "'let' is not a valid name for a comprehension variable")
+MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK,   0, JSEXN_SYNTAXERR, "let declaration not directly within block")
+MSG_DEF(JSMSG_MALFORMED_ESCAPE,        1, JSEXN_SYNTAXERR, "malformed {0} character escape sequence")
+MSG_DEF(JSMSG_MISSING_BINARY_DIGITS,   0, JSEXN_SYNTAXERR, "missing binary digits after '0b'")
+MSG_DEF(JSMSG_MISSING_EXPONENT,        0, JSEXN_SYNTAXERR, "missing exponent")
+MSG_DEF(JSMSG_MISSING_FORMAL,          0, JSEXN_SYNTAXERR, "missing formal parameter")
+MSG_DEF(JSMSG_MISSING_HEXDIGITS,       0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'")
+MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS,    0, JSEXN_SYNTAXERR, "missing octal digits after '0o'")
+MSG_DEF(JSMSG_MODULES_NOT_IMPLEMENTED, 0, JSEXN_SYNTAXERR, "modules are not implemented yet")
+MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM,  0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword")
+MSG_DEF(JSMSG_NAME_AFTER_DOT,          0, JSEXN_SYNTAXERR, "missing name after . operator")
+MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default")
+MSG_DEF(JSMSG_NO_BINDING_NAME,        0, JSEXN_SYNTAXERR, "missing binding name")
+MSG_DEF(JSMSG_NO_EXPORT_NAME,          0, JSEXN_SYNTAXERR, "missing export name")
+MSG_DEF(JSMSG_NO_IMPORT_NAME,          0, JSEXN_SYNTAXERR, "missing import name")
+MSG_DEF(JSMSG_NO_VARIABLE_NAME,        0, JSEXN_SYNTAXERR, "missing variable name")
+MSG_DEF(JSMSG_OF_AFTER_FOR_NAME,       0, JSEXN_SYNTAXERR, "missing 'of' after for")
+MSG_DEF(JSMSG_PAREN_AFTER_ARGS,        0, JSEXN_SYNTAXERR, "missing ) after argument list")
+MSG_DEF(JSMSG_PAREN_AFTER_CATCH,       0, JSEXN_SYNTAXERR, "missing ) after catch")
+MSG_DEF(JSMSG_PAREN_AFTER_COND,        0, JSEXN_SYNTAXERR, "missing ) after condition")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR,         0, JSEXN_SYNTAXERR, "missing ( after for")
+MSG_DEF(JSMSG_PAREN_AFTER_FORMAL,      0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL,    0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR_OF_ITERABLE, 0, JSEXN_SYNTAXERR, "missing ) after for-of iterable")
+MSG_DEF(JSMSG_PAREN_AFTER_LET,         0, JSEXN_SYNTAXERR, "missing ) after let head")
+MSG_DEF(JSMSG_PAREN_AFTER_SWITCH,      0, JSEXN_SYNTAXERR, "missing ) after switch expression")
+MSG_DEF(JSMSG_PAREN_AFTER_WITH,        0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
+MSG_DEF(JSMSG_PAREN_BEFORE_CATCH,      0, JSEXN_SYNTAXERR, "missing ( before catch")
+MSG_DEF(JSMSG_PAREN_BEFORE_COND,       0, JSEXN_SYNTAXERR, "missing ( before condition")
+MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL,     0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
+MSG_DEF(JSMSG_PAREN_BEFORE_LET,        0, JSEXN_SYNTAXERR, "missing ( before let head")
+MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH,     0, JSEXN_SYNTAXERR, "missing ( before switch expression")
+MSG_DEF(JSMSG_PAREN_BEFORE_WITH,       0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
+MSG_DEF(JSMSG_PAREN_IN_PAREN,          0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
+MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list")
+MSG_DEF(JSMSG_RC_AFTER_IMPORT_SPEC_LIST, 0, JSEXN_SYNTAXERR, "missing '}' after module specifier list")
+MSG_DEF(JSMSG_REDECLARED_CATCH_IDENTIFIER, 1, JSEXN_TYPEERR, "redeclaration of identifier '{0}' in catch")
+MSG_DEF(JSMSG_REDECLARED_PARAM,        1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
+MSG_DEF(JSMSG_RESERVED_ID,             1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
+MSG_DEF(JSMSG_REST_WITH_DEFAULT,       0, JSEXN_SYNTAXERR, "rest parameter may not have a default")
+MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LET,0, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level 'let' declarations")
+MSG_DEF(JSMSG_SELFHOSTED_UNBOUND_NAME, 0, JSEXN_TYPEERR, "self-hosted code may not contain unbound name lookups")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND,     0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT,     0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
+MSG_DEF(JSMSG_SEMI_BEFORE_STMNT,       0, JSEXN_SYNTAXERR, "missing ; before statement")
+MSG_DEF(JSMSG_SOURCE_TOO_LONG,         0, JSEXN_RANGEERR, "source is too long")
+MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 0, JSEXN_ERR, "strict mode code may not contain unparenthesized let expression statements")
+MSG_DEF(JSMSG_STRICT_CODE_WITH,        0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements")
+MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
+MSG_DEF(JSMSG_SYNTAX_ERROR,            0, JSEXN_SYNTAXERR, "syntax error")
+MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR,    0, JSEXN_SYNTAXERR, "missing } in template string")
+MSG_DEF(JSMSG_TOO_MANY_CASES,          0, JSEXN_INTERNALERR, "too many switch cases")
+MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS,     0, JSEXN_SYNTAXERR, "too many catch variables")
+MSG_DEF(JSMSG_TOO_MANY_CON_ARGS,       0, JSEXN_SYNTAXERR, "too many constructor arguments")
+MSG_DEF(JSMSG_TOO_MANY_DEFAULTS,       0, JSEXN_SYNTAXERR, "more than one switch default")
+MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS,       0, JSEXN_SYNTAXERR, "too many function arguments")
+MSG_DEF(JSMSG_TOO_MANY_LOCALS,         0, JSEXN_SYNTAXERR, "too many local variables")
+MSG_DEF(JSMSG_TOUGH_BREAK,             0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch")
+MSG_DEF(JSMSG_UNNAMED_FUNCTION_STMT,   0, JSEXN_SYNTAXERR, "function statement requires a name")
+MSG_DEF(JSMSG_UNTERMINATED_COMMENT,    0, JSEXN_SYNTAXERR, "unterminated comment")
+MSG_DEF(JSMSG_UNTERMINATED_REGEXP,     0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
+MSG_DEF(JSMSG_UNTERMINATED_STRING,     0, JSEXN_SYNTAXERR, "unterminated string literal")
+MSG_DEF(JSMSG_USELESS_EXPR,            0, JSEXN_TYPEERR, "useless expression")
+MSG_DEF(JSMSG_USE_ASM_DIRECTIVE_FAIL,  0, JSEXN_SYNTAXERR, "\"use asm\" is only meaningful in the Directive Prologue of a function body")
+MSG_DEF(JSMSG_VAR_HIDES_ARG,           1, JSEXN_TYPEERR, "variable {0} redeclares argument")
+MSG_DEF(JSMSG_WHILE_AFTER_DO,          0, JSEXN_SYNTAXERR, "missing while after do-loop body")
+MSG_DEF(JSMSG_YIELD_IN_ARROW,          0, JSEXN_SYNTAXERR, "arrow function may not contain yield")
+MSG_DEF(JSMSG_YIELD_IN_DEFAULT,        0, JSEXN_SYNTAXERR, "yield in default expression")
+
+// asm.js
+MSG_DEF(JSMSG_USE_ASM_TYPE_FAIL,       1, JSEXN_TYPEERR, "asm.js type error: {0}")
+MSG_DEF(JSMSG_USE_ASM_LINK_FAIL,       1, JSEXN_TYPEERR, "asm.js link error: {0}")
+MSG_DEF(JSMSG_USE_ASM_TYPE_OK,         1, JSEXN_NONE,    "Successfully compiled asm.js code ({0})")
+
+// Proxy
+MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE,   2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value")
+MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object's extensibility")
+MSG_DEF(JSMSG_CANT_DEFINE_INVALID,     0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor")
+MSG_DEF(JSMSG_CANT_DEFINE_NEW,         0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
+MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC,    0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable")
+MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible")
 MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC,     0, JSEXN_TYPEERR, "proxy can't report existing configurable property as non-configurable")
-MSG_DEF(JSMSG_COMP_PROP_UNTERM_EXPR,   0, JSEXN_SYNTAXERR, "missing ] in computed property name")
\ No newline at end of file
+MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE,     0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
+MSG_DEF(JSMSG_CANT_REPORT_INVALID,     0, JSEXN_TYPEERR, "proxy can't report an incompatible property descriptor")
+MSG_DEF(JSMSG_CANT_REPORT_NC_AS_NE,    0, JSEXN_TYPEERR, "proxy can't report a non-configurable own property as non-existent")
+MSG_DEF(JSMSG_CANT_REPORT_NEW,         0, JSEXN_TYPEERR, "proxy can't report a new property on a non-extensible object")
+MSG_DEF(JSMSG_CANT_REPORT_NE_AS_NC,    0, JSEXN_TYPEERR, "proxy can't report a non-existent property as non-configurable")
+MSG_DEF(JSMSG_CANT_SET_NW_NC,          0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property")
+MSG_DEF(JSMSG_CANT_SET_WO_SETTER,      0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter")
+MSG_DEF(JSMSG_CANT_SKIP_NC,            0, JSEXN_TYPEERR, "proxy can't skip a non-configurable property")
+MSG_DEF(JSMSG_INVALID_TRAP_RESULT,     2, JSEXN_TYPEERR, "trap {1} for {0} returned an invalid result")
+MSG_DEF(JSMSG_MUST_REPORT_SAME_VALUE,  0, JSEXN_TYPEERR, "proxy must report the same value for a non-writable, non-configurable property")
+MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED,   0, JSEXN_TYPEERR, "proxy must report undefined for a non-configurable accessor property without a getter")
+MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED,    0, JSEXN_ERR, "Permission denied to access object")
+MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED,  1, JSEXN_ERR, "Permission denied to access property '{0}'")
+MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT,  0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object")
+MSG_DEF(JSMSG_PROXY_EXTENSIBILITY,     0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target")
+MSG_DEF(JSMSG_PROXY_GETOWN_OBJORUNDEF, 0, JSEXN_TYPEERR, "proxy [[GetOwnProperty]] must return an object or undefined")
+MSG_DEF(JSMSG_PROXY_REVOKED,           0, JSEXN_TYPEERR, "illegal operation attempted on a revoked proxy")
+
+// Structured cloning
+MSG_DEF(JSMSG_SC_BAD_CLONE_VERSION,    0, JSEXN_ERR, "unsupported structured clone version")
+MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA,  1, JSEXN_INTERNALERR, "bad serialized structured data ({0})")
+MSG_DEF(JSMSG_SC_DUP_TRANSFERABLE,     0, JSEXN_TYPEERR, "duplicate transferable for structured clone")
+MSG_DEF(JSMSG_SC_NOT_TRANSFERABLE,     0, JSEXN_TYPEERR, "invalid transferable array for structured clone")
+MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE,     0, JSEXN_TYPEERR, "unsupported type for structured data")
+
+// Debugger
+MSG_DEF(JSMSG_ASSIGN_FUNCTION_OR_NULL, 1, JSEXN_TYPEERR, "value assigned to {0} must be a function or null")
+MSG_DEF(JSMSG_DEBUG_BAD_LINE,          0, JSEXN_TYPEERR, "invalid line number")
+MSG_DEF(JSMSG_DEBUG_BAD_OFFSET,        0, JSEXN_TYPEERR, "invalid script offset")
+MSG_DEF(JSMSG_DEBUG_BAD_REFERENT,      2, JSEXN_TYPEERR, "{0} does not refer to {1}")
+MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION,    0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null")
+MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee")
+MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED,      1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment")
+MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
+MSG_DEF(JSMSG_DEBUG_LOOP,              0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger")
+MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE,      2, JSEXN_ERR, "{0} is not a debuggee {1}")
+MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,     0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
+MSG_DEF(JSMSG_DEBUG_NOT_IDLE,          0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack")
+MSG_DEF(JSMSG_DEBUG_NOT_LIVE,          1, JSEXN_ERR, "{0} is not live")
+MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,   0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
+MSG_DEF(JSMSG_DEBUG_OBJECT_PROTO,      0, JSEXN_TYPEERR, "Debugger.Object.prototype is not a valid Debugger.Object")
+MSG_DEF(JSMSG_DEBUG_OBJECT_WRONG_OWNER,0, JSEXN_TYPEERR, "Debugger.Object belongs to a different Debugger")
+MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT,     0, JSEXN_ERR, "variable has been optimized out")
+MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
+MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment")
+MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY,    3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required")
+MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined")
+MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true")
+MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so")
+MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'innermost' property without both 'url' and 'line' properties")
+MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL,  0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'url' property")
+
+// Intl
+MSG_DEF(JSMSG_DATE_NOT_FINITE,         0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()")
+MSG_DEF(JSMSG_INTERNAL_INTL_ERROR,     0, JSEXN_ERR, "internal error while computing Intl data")
+MSG_DEF(JSMSG_INTL_OBJECT_NOT_INITED,  3, JSEXN_TYPEERR, "Intl.{0}.prototype.{1} called on value that's not an object initialized as a {2}")
+MSG_DEF(JSMSG_INTL_OBJECT_REINITED,    0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor")
+MSG_DEF(JSMSG_INVALID_CURRENCY_CODE,   1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}")
+MSG_DEF(JSMSG_INVALID_DIGITS_VALUE,    1, JSEXN_RANGEERR, "invalid digits value: {0}")
+MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG,    1, JSEXN_RANGEERR, "invalid language tag: {0}")
+MSG_DEF(JSMSG_INVALID_LOCALES_ELEMENT, 0, JSEXN_TYPEERR, "invalid element in locales argument")
+MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER,  1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}")
+MSG_DEF(JSMSG_INVALID_OPTION_VALUE,    2, JSEXN_RANGEERR, "invalid value {1} for option {0}")
+MSG_DEF(JSMSG_INVALID_TIME_ZONE,       1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}")
+MSG_DEF(JSMSG_UNDEFINED_CURRENCY,      0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style")
+
+// RegExp
+MSG_DEF(JSMSG_BAD_CLASS_RANGE,         0, JSEXN_SYNTAXERR, "invalid range in character class")
+MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern")
+MSG_DEF(JSMSG_INVALID_GROUP,           0, JSEXN_SYNTAXERR, "invalid regexp group")
+MSG_DEF(JSMSG_MISSING_PAREN,           0, JSEXN_SYNTAXERR, "unterminated parenthetical")
+MSG_DEF(JSMSG_NEWREGEXP_FLAGGED,       0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
+MSG_DEF(JSMSG_NOTHING_TO_REPEAT,       0, JSEXN_SYNTAXERR, "nothing to repeat")
+MSG_DEF(JSMSG_NUMBERS_OUT_OF_ORDER,    0, JSEXN_SYNTAXERR, "numbers out of order in {} quantifier.")
+MSG_DEF(JSMSG_TOO_MANY_PARENS,         0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
+MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN,   0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
+MSG_DEF(JSMSG_UNTERM_CLASS,            0, JSEXN_SYNTAXERR, "unterminated character class")
+
+// Self hosting
+MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR,    0, JSEXN_ERR, "internal error getting the default locale")
+MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP,1, JSEXN_ERR, "No such property on self-hosted object: {0}")
+
+// Typed object
+MSG_DEF(JSMSG_INVALID_PROTOTYPE,       0, JSEXN_TYPEERR, "prototype field is not an object")
+MSG_DEF(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS, 0, JSEXN_ERR, "Invalid arguments")
+MSG_DEF(JSMSG_TYPEDOBJECT_BAD_ARGS,    0, JSEXN_TYPEERR, "invalid arguments")
+MSG_DEF(JSMSG_TYPEDOBJECT_BINARYARRAY_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
+MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattached")
+MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor")
+MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG,     0, JSEXN_ERR, "Type is too large to allocate")
+
+// Typed array
+MSG_DEF(JSMSG_BAD_INDEX,               0, JSEXN_RANGEERR, "invalid or out-of-range index")
+MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS,    0, JSEXN_ERR, "invalid arguments")
+MSG_DEF(JSMSG_TYPED_ARRAY_BAD_INDEX,   0, JSEXN_ERR, "invalid or out-of-range index")
+MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_ERR, "argument {0} must be >= 0")
+
+// Reflect
+MSG_DEF(JSMSG_BAD_PARSE_NODE,          0, JSEXN_INTERNALERR, "bad parse node")
+
+// Symbol
+MSG_DEF(JSMSG_BAD_SYMBOL,              1, JSEXN_TYPEERR, "{0} is not a well-known @@-symbol")
+MSG_DEF(JSMSG_SYMBOL_TO_STRING,        0, JSEXN_TYPEERR, "can't convert symbol to string")
+MSG_DEF(JSMSG_SYMBOL_TO_NUMBER,        0, JSEXN_TYPEERR, "can't convert symbol to number")
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
index 1d9bb69a6cfe..237e687f49cc 100644
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2241,7 +2241,7 @@ Debugger::construct(JSContext *cx, unsigned argc, Value *vp)
             return ReportObjectRequired(cx);
         JSObject *argobj = &arg.toObject();
         if (!argobj->is()) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CCW_REQUIRED,
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_CCW_REQUIRED,
                                  "Debugger");
             return false;
         }
diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
index b381f7d79f2c..bc838cfbf235 100644
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1756,7 +1756,7 @@ JS_ReadStructuredClone(JSContext *cx, uint64_t *buf, size_t nbytes,
     CHECK_REQUEST(cx);
 
     if (version > JS_STRUCTURED_CLONE_VERSION) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_CLONE_VERSION);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SC_BAD_CLONE_VERSION);
         return false;
     }
     const JSStructuredCloneCallbacks *callbacks =

From c1e3d1c31d1a55f7524fbb0de85538929a35c247 Mon Sep 17 00:00:00 2001
From: Jonathan Kew 
Date: Sat, 16 Aug 2014 20:35:48 +0100
Subject: [PATCH 097/101] bug 1048752 followup 2 - another Windows non-unified
 build fix. no_r=me, bustage fix

---
 accessible/windows/msaa/nsWinUtils.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/accessible/windows/msaa/nsWinUtils.cpp b/accessible/windows/msaa/nsWinUtils.cpp
index 3cdfc75a669e..eed0e135666f 100644
--- a/accessible/windows/msaa/nsWinUtils.cpp
+++ b/accessible/windows/msaa/nsWinUtils.cpp
@@ -16,6 +16,7 @@
 #include "nsIArray.h"
 #include "nsIDocument.h"
 #include "nsIDocShellTreeItem.h"
+#include "nsIDOMElement.h"
 #include "nsXULAppAPI.h"
 
 using namespace mozilla;

From b112ee74ce13111ce133df5bb627695d55db180b Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Sat, 16 Aug 2014 13:13:13 -0700
Subject: [PATCH 098/101] Bug 1045948 - IonMonkey: Obviate LAllocation's tag
 bit. r=bhackett

---
 js/src/jit/LIR.h | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
index 534fc2ee3dbc..979a37d41652 100644
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -57,15 +57,15 @@ class LAllocation : public TempObject
 {
     uintptr_t bits_;
 
-    static const uintptr_t TAG_BIT = 1;
-    static const uintptr_t TAG_SHIFT = 0;
-    static const uintptr_t TAG_MASK = 1 << TAG_SHIFT;
+    // 3 bits gives us enough for an interesting set of Kinds and also fits
+    // within the alignment bits of pointers to Value, which are always
+    // 8-byte aligned.
     static const uintptr_t KIND_BITS = 3;
-    static const uintptr_t KIND_SHIFT = TAG_SHIFT + TAG_BIT;
+    static const uintptr_t KIND_SHIFT = 0;
     static const uintptr_t KIND_MASK = (1 << KIND_BITS) - 1;
 
   protected:
-    static const uintptr_t DATA_BITS = (sizeof(uint32_t) * 8) - KIND_BITS - TAG_BIT;
+    static const uintptr_t DATA_BITS = (sizeof(uint32_t) * 8) - KIND_BITS;
     static const uintptr_t DATA_SHIFT = KIND_SHIFT + KIND_BITS;
     static const uintptr_t DATA_MASK = (1 << DATA_BITS) - 1;
 
@@ -81,10 +81,6 @@ class LAllocation : public TempObject
     };
 
   protected:
-    bool isTagged() const {
-        return !!(bits_ & TAG_MASK);
-    }
-
     int32_t data() const {
         return int32_t(bits_) >> DATA_SHIFT;
     }
@@ -117,17 +113,15 @@ class LAllocation : public TempObject
         return new(alloc) LAllocation(other);
     }
 
-    // The value pointer must be rooted in MIR and have its low bit cleared.
+    // The value pointer must be rooted in MIR and have its low bits cleared.
     explicit LAllocation(const Value *vp) {
         bits_ = uintptr_t(vp);
-        JS_ASSERT(!isTagged());
-        bits_ |= TAG_MASK;
+        JS_ASSERT((bits_ & (KIND_MASK << KIND_SHIFT)) == 0);
+        bits_ |= CONSTANT_VALUE << KIND_SHIFT;
     }
     inline explicit LAllocation(AnyRegister reg);
 
     Kind kind() const {
-        if (isTagged())
-            return CONSTANT_VALUE;
         return (Kind)((bits_ >> KIND_SHIFT) & KIND_MASK);
     }
 
@@ -175,7 +169,7 @@ class LAllocation : public TempObject
 
     const Value *toConstant() const {
         JS_ASSERT(isConstantValue());
-        return reinterpret_cast(bits_ & ~TAG_MASK);
+        return reinterpret_cast(bits_ & ~(KIND_MASK << KIND_SHIFT));
     }
 
     bool operator ==(const LAllocation &other) const {

From 64aabd5f06d8f1bcfb60a3bd644a7e3c4df6a146 Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Sat, 16 Aug 2014 13:13:13 -0700
Subject: [PATCH 099/101] Bug 1045948 - IonMonkey: Eliminate
 LDefintion::PASSTHROUGH. r=bhackett

---
 js/src/jit/LIR.cpp                      |  2 -
 js/src/jit/LIR.h                        | 13 ++--
 js/src/jit/LiveRangeAllocator.cpp       | 92 ++++++++++++-------------
 js/src/jit/LiveRangeAllocator.h         |  3 +-
 js/src/jit/RegisterAllocator.cpp        | 18 +++--
 js/src/jit/StupidAllocator.cpp          |  6 +-
 js/src/jit/arm/Lowering-arm.cpp         | 18 +++--
 js/src/jit/mips/Lowering-mips.cpp       | 18 +++--
 js/src/jit/shared/Lowering-shared-inl.h | 24 -------
 js/src/jit/shared/Lowering-shared.h     |  4 --
 js/src/jit/x86/Lowering-x86.cpp         | 18 +++--
 11 files changed, 90 insertions(+), 126 deletions(-)

diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp
index a6280c35b75b..7c77e0c0a65c 100644
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -371,8 +371,6 @@ PrintDefinition(char *buf, size_t size, const LDefinition &def)
         cursor += JS_snprintf(cursor, end - cursor, ":%s", def.output()->toString());
     else if (def.policy() == LDefinition::MUST_REUSE_INPUT)
         cursor += JS_snprintf(cursor, end - cursor, ":tied(%u)", def.getReusedInput());
-    else if (def.policy() == LDefinition::PASSTHROUGH)
-        cursor += JS_snprintf(cursor, end - cursor, ":-");
 }
 
 const char *
diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
index 979a37d41652..779745134c9d 100644
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -279,6 +279,7 @@ class LUse : public LAllocation
     }
     uint32_t virtualRegister() const {
         uint32_t index = (data() >> VREG_SHIFT) & VREG_MASK;
+        JS_ASSERT(index != 0);
         return index;
     }
     uint32_t registerCode() const {
@@ -411,13 +412,7 @@ class LDefinition
 
         // One definition per instruction must re-use the first input
         // allocation, which (for now) must be a register.
-        MUST_REUSE_INPUT,
-
-        // This definition's virtual register is the same as another; this is
-        // for instructions which consume a register and silently define it as
-        // the same register. It is not legal to use this if doing so would
-        // change the type of the virtual register.
-        PASSTHROUGH
+        MUST_REUSE_INPUT
     };
 
     enum Type {
@@ -508,7 +503,9 @@ class LDefinition
         return type() == FLOAT32 || type() == DOUBLE || isSimdType();
     }
     uint32_t virtualRegister() const {
-        return (bits_ >> VREG_SHIFT) & VREG_MASK;
+        uint32_t index = (bits_ >> VREG_SHIFT) & VREG_MASK;
+        JS_ASSERT(index != 0);
+        return index;
     }
     LAllocation *output() {
         return &output_;
diff --git a/js/src/jit/LiveRangeAllocator.cpp b/js/src/jit/LiveRangeAllocator.cpp
index f99f1e7c8052..ae59aacfe365 100644
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -525,10 +525,10 @@ LiveRangeAllocator::init()
         for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
             for (size_t j = 0; j < ins->numDefs(); j++) {
                 LDefinition *def = ins->getDef(j);
-                if (def->policy() != LDefinition::PASSTHROUGH) {
-                    if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ false))
-                        return false;
-                }
+                if (def->isBogusTemp())
+                    continue;
+                if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ false))
+                    return false;
             }
 
             for (size_t j = 0; j < ins->numTemps(); j++) {
@@ -665,50 +665,50 @@ LiveRangeAllocator::buildLivenessInfo()
             }
 
             for (size_t i = 0; i < ins->numDefs(); i++) {
-                if (ins->getDef(i)->policy() != LDefinition::PASSTHROUGH) {
-                    LDefinition *def = ins->getDef(i);
+                LDefinition *def = ins->getDef(i);
+                if (def->isBogusTemp())
+                    continue;
 
-                    CodePosition from;
-                    if (def->policy() == LDefinition::FIXED && def->output()->isRegister() && forLSRA) {
-                        // The fixed range covers the current instruction so the
-                        // interval for the virtual register starts at the next
-                        // instruction. If the next instruction has a fixed use,
-                        // this can lead to unnecessary register moves. To avoid
-                        // special handling for this, assert the next instruction
-                        // has no fixed uses. defineFixed guarantees this by inserting
-                        // an LNop.
-                        JS_ASSERT(!NextInstructionHasFixedUses(block, *ins));
-                        AnyRegister reg = def->output()->toRegister();
-                        if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins).next()))
-                            return false;
-                        from = outputOf(*ins).next();
-                    } else {
-                        from = forLSRA ? inputOf(*ins) : outputOf(*ins);
-                    }
-
-                    if (def->policy() == LDefinition::MUST_REUSE_INPUT) {
-                        // MUST_REUSE_INPUT is implemented by allocating an output
-                        // register and moving the input to it. Register hints are
-                        // used to avoid unnecessary moves. We give the input an
-                        // LUse::ANY policy to avoid allocating a register for the
-                        // input.
-                        LUse *inputUse = ins->getOperand(def->getReusedInput())->toUse();
-                        JS_ASSERT(inputUse->policy() == LUse::REGISTER);
-                        JS_ASSERT(inputUse->usedAtStart());
-                        *inputUse = LUse(inputUse->virtualRegister(), LUse::ANY, /* usedAtStart = */ true);
-                    }
-
-                    LiveInterval *interval = vregs[def].getInterval(0);
-                    interval->setFrom(from);
-
-                    // Ensure that if there aren't any uses, there's at least
-                    // some interval for the output to go into.
-                    if (interval->numRanges() == 0) {
-                        if (!interval->addRangeAtHead(from, from.next()))
-                            return false;
-                    }
-                    live->remove(def->virtualRegister());
+                CodePosition from;
+                if (def->policy() == LDefinition::FIXED && def->output()->isRegister() && forLSRA) {
+                    // The fixed range covers the current instruction so the
+                    // interval for the virtual register starts at the next
+                    // instruction. If the next instruction has a fixed use,
+                    // this can lead to unnecessary register moves. To avoid
+                    // special handling for this, assert the next instruction
+                    // has no fixed uses. defineFixed guarantees this by inserting
+                    // an LNop.
+                    JS_ASSERT(!NextInstructionHasFixedUses(block, *ins));
+                    AnyRegister reg = def->output()->toRegister();
+                    if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins).next()))
+                        return false;
+                    from = outputOf(*ins).next();
+                } else {
+                    from = forLSRA ? inputOf(*ins) : outputOf(*ins);
                 }
+
+                if (def->policy() == LDefinition::MUST_REUSE_INPUT) {
+                    // MUST_REUSE_INPUT is implemented by allocating an output
+                    // register and moving the input to it. Register hints are
+                    // used to avoid unnecessary moves. We give the input an
+                    // LUse::ANY policy to avoid allocating a register for the
+                    // input.
+                    LUse *inputUse = ins->getOperand(def->getReusedInput())->toUse();
+                    JS_ASSERT(inputUse->policy() == LUse::REGISTER);
+                    JS_ASSERT(inputUse->usedAtStart());
+                    *inputUse = LUse(inputUse->virtualRegister(), LUse::ANY, /* usedAtStart = */ true);
+                }
+
+                LiveInterval *interval = vregs[def].getInterval(0);
+                interval->setFrom(from);
+
+                // Ensure that if there aren't any uses, there's at least
+                // some interval for the output to go into.
+                if (interval->numRanges() == 0) {
+                    if (!interval->addRangeAtHead(from, from.next()))
+                        return false;
+                }
+                live->remove(def->virtualRegister());
             }
 
             for (size_t i = 0; i < ins->numTemps(); i++) {
diff --git a/js/src/jit/LiveRangeAllocator.h b/js/src/jit/LiveRangeAllocator.h
index 2cec3e192783..7c9423fa9eec 100644
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -185,8 +185,6 @@ DefinitionCompatibleWith(LInstruction *ins, const LDefinition *def, LAllocation
         if (!alloc.isRegister() || !ins->numOperands())
             return false;
         return alloc == *ins->getOperand(def->getReusedInput());
-      case LDefinition::PASSTHROUGH:
-        return true;
       default:
         MOZ_ASSUME_UNREACHABLE("Unknown definition policy");
     }
@@ -490,6 +488,7 @@ class VirtualRegister
     }
     bool addInterval(LiveInterval *interval) {
         JS_ASSERT(interval->numRanges());
+        JS_ASSERT(interval->vreg() != 0);
 
         // Preserve ascending order for faster lookups.
         LiveInterval **found = nullptr;
diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp
index 9cdb08ca91a7..b1bbb0ce441f 100644
--- a/js/src/jit/RegisterAllocator.cpp
+++ b/js/src/jit/RegisterAllocator.cpp
@@ -53,14 +53,18 @@ AllocationIntegrityState::record()
             InstructionInfo &info = instructions[ins->id()];
 
             for (size_t k = 0; k < ins->numTemps(); k++) {
-                uint32_t vreg = ins->getTemp(k)->virtualRegister();
-                virtualRegisters[vreg] = ins->getTemp(k);
+                if (!ins->getTemp(k)->isBogusTemp()) {
+                    uint32_t vreg = ins->getTemp(k)->virtualRegister();
+                    virtualRegisters[vreg] = ins->getTemp(k);
+                }
                 if (!info.temps.append(*ins->getTemp(k)))
                     return false;
             }
             for (size_t k = 0; k < ins->numDefs(); k++) {
-                uint32_t vreg = ins->getDef(k)->virtualRegister();
-                virtualRegisters[vreg] = ins->getDef(k);
+                if (!ins->getDef(k)->isBogusTemp()) {
+                    uint32_t vreg = ins->getDef(k)->virtualRegister();
+                    virtualRegisters[vreg] = ins->getDef(k);
+                }
                 if (!info.outputs.append(*ins->getDef(k)))
                     return false;
             }
@@ -95,7 +99,7 @@ AllocationIntegrityState::check(bool populateSafepoints)
 
             for (size_t i = 0; i < ins->numDefs(); i++) {
                 LDefinition *def = ins->getDef(i);
-                JS_ASSERT_IF(def->policy() != LDefinition::PASSTHROUGH, !def->output()->isUse());
+                JS_ASSERT(!def->output()->isUse());
 
                 LDefinition oldDef = instructions[ins->id()].outputs[i];
                 JS_ASSERT_IF(oldDef.policy() == LDefinition::MUST_REUSE_INPUT,
@@ -132,6 +136,8 @@ AllocationIntegrityState::check(bool populateSafepoints)
             LSafepoint *safepoint = ins->safepoint();
             if (safepoint) {
                 for (size_t i = 0; i < ins->numTemps(); i++) {
+                    if (ins->getTemp(i)->isBogusTemp())
+                        continue;
                     uint32_t vreg = info.temps[i].virtualRegister();
                     LAllocation *alloc = ins->getTemp(i)->output();
                     if (!checkSafepointAllocation(ins, vreg, *alloc, populateSafepoints))
@@ -200,7 +206,7 @@ AllocationIntegrityState::checkIntegrity(LBlock *block, LInstruction *ins,
 
         for (size_t i = 0; i < ins->numDefs(); i++) {
             LDefinition *def = ins->getDef(i);
-            if (def->policy() == LDefinition::PASSTHROUGH)
+            if (def->isBogusTemp())
                 continue;
             if (info.outputs[i].virtualRegister() == vreg) {
                 JS_ASSERT(*def->output() == alloc);
diff --git a/js/src/jit/StupidAllocator.cpp b/js/src/jit/StupidAllocator.cpp
index 34d8a68ef293..d1e6aecd7abb 100644
--- a/js/src/jit/StupidAllocator.cpp
+++ b/js/src/jit/StupidAllocator.cpp
@@ -51,8 +51,7 @@ StupidAllocator::init()
         for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
             for (size_t j = 0; j < ins->numDefs(); j++) {
                 LDefinition *def = ins->getDef(j);
-                if (def->policy() != LDefinition::PASSTHROUGH)
-                    virtualRegisters[def->virtualRegister()] = def;
+                virtualRegisters[def->virtualRegister()] = def;
             }
 
             for (size_t j = 0; j < ins->numTemps(); j++) {
@@ -370,8 +369,7 @@ StupidAllocator::allocateForInstruction(LInstruction *ins)
     }
     for (size_t i = 0; i < ins->numDefs(); i++) {
         LDefinition *def = ins->getDef(i);
-        if (def->policy() != LDefinition::PASSTHROUGH)
-            allocateForDefinition(ins, def);
+        allocateForDefinition(ins, def);
     }
 
     // Allocate for remaining inputs which do not need to be in registers.
diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp
index 5d56e6a1f51f..a5d6ab164640 100644
--- a/js/src/jit/arm/Lowering-arm.cpp
+++ b/js/src/jit/arm/Lowering-arm.cpp
@@ -107,15 +107,14 @@ LIRGeneratorARM::visitBox(MBox *box)
     if (vreg >= MAX_VIRTUAL_REGISTERS)
         return false;
 
-    // Note that because we're using PASSTHROUGH, we do not change the type of
+    // Note that because we're using BogusTemp(), we do not change the type of
     // the definition. We also do not define the first output as "TYPE",
     // because it has no corresponding payload at (vreg + 1). Also note that
     // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. PASSTHROUGH definitions are
+    // definition, this is only for clarity. BogusTemp() definitions are
     // ignored.
     lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
-                               LDefinition::PASSTHROUGH));
+    lir->setDef(1, LDefinition::BogusTemp());
     box->setVirtualRegister(vreg);
     return add(lir);
 }
@@ -148,12 +147,11 @@ LIRGeneratorARM::visitUnbox(MUnbox *unbox)
     if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
         return false;
 
-    // Note that PASSTHROUGH here is illegal, since types and payloads form two
-    // separate intervals. If the type becomes dead before the payload, it
-    // could be used as a Value without the type being recoverable. Unbox's
-    // purpose is to eagerly kill the definition of a type tag, so keeping both
-    // alive (for the purpose of gcmaps) is unappealing. Instead, we create a
-    // new virtual register.
+    // Types and payloads form two separate intervals. If the type becomes dead
+    // before the payload, it could be used as a Value without the type being
+    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
+    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
+    // Instead, we create a new virtual register.
     return defineReuseInput(lir, unbox, 0);
 }
 
diff --git a/js/src/jit/mips/Lowering-mips.cpp b/js/src/jit/mips/Lowering-mips.cpp
index 6cf79daf57b5..8912c576507c 100644
--- a/js/src/jit/mips/Lowering-mips.cpp
+++ b/js/src/jit/mips/Lowering-mips.cpp
@@ -109,15 +109,14 @@ LIRGeneratorMIPS::visitBox(MBox *box)
     if (vreg >= MAX_VIRTUAL_REGISTERS)
         return false;
 
-    // Note that because we're using PASSTHROUGH, we do not change the type of
+    // Note that because we're using BogusTemp(), we do not change the type of
     // the definition. We also do not define the first output as "TYPE",
     // because it has no corresponding payload at (vreg + 1). Also note that
     // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. PASSTHROUGH definitions are
+    // definition, this is only for clarity. BogusTemp() definitions are
     // ignored.
     lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
-                               LDefinition::PASSTHROUGH));
+    lir->setDef(1, LDefinition::BogusTemp());
     box->setVirtualRegister(vreg);
     return add(lir);
 }
@@ -151,12 +150,11 @@ LIRGeneratorMIPS::visitUnbox(MUnbox *unbox)
     if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
         return false;
 
-    // Note that PASSTHROUGH here is illegal, since types and payloads form two
-    // separate intervals. If the type becomes dead before the payload, it
-    // could be used as a Value without the type being recoverable. Unbox's
-    // purpose is to eagerly kill the definition of a type tag, so keeping both
-    // alive (for the purpose of gcmaps) is unappealing. Instead, we create a
-    // new virtual register.
+    // Types and payloads form two separate intervals. If the type becomes dead
+    // before the payload, it could be used as a Value without the type being
+    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
+    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
+    // Instead, we create a new virtual register.
     return defineReuseInput(lir, unbox, 0);
 }
 
diff --git a/js/src/jit/shared/Lowering-shared-inl.h b/js/src/jit/shared/Lowering-shared-inl.h
index a5067650b788..f2280705c8de 100644
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -225,30 +225,6 @@ LIRGeneratorShared::redefine(MDefinition *def, MDefinition *as)
     return true;
 }
 
-bool
-LIRGeneratorShared::defineAs(LInstruction *outLir, MDefinition *outMir, MDefinition *inMir)
-{
-    uint32_t vreg = inMir->virtualRegister();
-    LDefinition::Policy policy = LDefinition::PASSTHROUGH;
-
-    if (outMir->type() == MIRType_Value) {
-#ifdef JS_NUNBOX32
-        outLir->setDef(TYPE_INDEX,
-                       LDefinition(vreg + VREG_TYPE_OFFSET, LDefinition::TYPE, policy));
-        outLir->setDef(PAYLOAD_INDEX,
-                       LDefinition(vreg + VREG_DATA_OFFSET, LDefinition::PAYLOAD, policy));
-#elif JS_PUNBOX64
-        outLir->setDef(0, LDefinition(vreg, LDefinition::BOX, policy));
-#else
-# error "Unexpected boxing type"
-#endif
-    } else {
-        outLir->setDef(0, LDefinition(vreg, LDefinition::TypeFrom(inMir->type()), policy));
-    }
-    outLir->setMir(outMir);
-    return redefine(outMir, inMir);
-}
-
 bool
 LIRGeneratorShared::ensureDefined(MDefinition *mir)
 {
diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h
index 76af4c047b5b..adbfe3c2d93b 100644
--- a/js/src/jit/shared/Lowering-shared.h
+++ b/js/src/jit/shared/Lowering-shared.h
@@ -153,10 +153,6 @@ class LIRGeneratorShared : public MDefinitionVisitorDefaultNYI
     // virtual register as |as|.
     inline bool redefine(MDefinition *ins, MDefinition *as);
 
-    // Defines an IR's output as the same as another IR. This is similar to
-    // redefine(), but used when creating new LIR.
-    inline bool defineAs(LInstruction *outLir, MDefinition *outMir, MDefinition *inMir);
-
     TempAllocator &alloc() const {
         return graph.alloc();
     }
diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp
index ac7b8912a7f0..05f948770f3a 100644
--- a/js/src/jit/x86/Lowering-x86.cpp
+++ b/js/src/jit/x86/Lowering-x86.cpp
@@ -100,15 +100,14 @@ LIRGeneratorX86::visitBox(MBox *box)
     if (vreg >= MAX_VIRTUAL_REGISTERS)
         return false;
 
-    // Note that because we're using PASSTHROUGH, we do not change the type of
+    // Note that because we're using BogusTemp(), we do not change the type of
     // the definition. We also do not define the first output as "TYPE",
     // because it has no corresponding payload at (vreg + 1). Also note that
     // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. PASSTHROUGH definitions are
+    // definition, this is only for clarity. BogusTemp() definitions are
     // ignored.
     lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
-                               LDefinition::PASSTHROUGH));
+    lir->setDef(1, LDefinition::BogusTemp());
     box->setVirtualRegister(vreg);
     return add(lir);
 }
@@ -141,12 +140,11 @@ LIRGeneratorX86::visitUnbox(MUnbox *unbox)
     if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
         return false;
 
-    // Note that PASSTHROUGH here is illegal, since types and payloads form two
-    // separate intervals. If the type becomes dead before the payload, it
-    // could be used as a Value without the type being recoverable. Unbox's
-    // purpose is to eagerly kill the definition of a type tag, so keeping both
-    // alive (for the purpose of gcmaps) is unappealing. Instead, we create a
-    // new virtual register.
+    // Types and payloads form two separate intervals. If the type becomes dead
+    // before the payload, it could be used as a Value without the type being
+    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
+    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
+    // Instead, we create a new virtual register.
     return defineReuseInput(lir, unbox, 0);
 }
 

From 852da845205df11076d4ab42856672cc10577f6c Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Sat, 16 Aug 2014 13:13:14 -0700
Subject: [PATCH 100/101] Bug 1045948 - IonMonkey: Make bogus LAllocations have
 an all-zeros bit pattern. r=bhackett

---
 js/src/jit/BacktrackingAllocator.h    |  2 +-
 js/src/jit/LIR.cpp                    | 11 +++++++---
 js/src/jit/LIR.h                      | 29 +++++++++++++++------------
 js/src/jit/LinearScan.cpp             |  2 +-
 js/src/jit/LiveRangeAllocator.cpp     |  2 +-
 js/src/jit/LiveRangeAllocator.h       |  6 +++---
 js/src/jit/Lowering.cpp               |  2 --
 js/src/jit/RegisterAllocator.cpp      |  6 ++++--
 js/src/jit/shared/Lowering-shared.cpp |  8 ++++----
 9 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h
index 7a18fb9fde1d..595e7382186b 100644
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -82,7 +82,7 @@ class BacktrackingVirtualRegister : public VirtualRegister
         canonicalSpill_ = alloc;
     }
     const LAllocation *canonicalSpill() const {
-        return canonicalSpill_.isUse() ? nullptr : &canonicalSpill_;
+        return canonicalSpill_.isBogus() ? nullptr : &canonicalSpill_;
     }
 
     void setCanonicalSpillExclude(CodePosition pos) {
diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp
index 7c77e0c0a65c..43de591e4885 100644
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -362,9 +362,7 @@ PrintDefinition(char *buf, size_t size, const LDefinition &def)
     char *cursor = buf;
     char *end = buf + size;
 
-    if (def.virtualRegister())
-        cursor += JS_snprintf(cursor, end - cursor, "v%u", def.virtualRegister());
-
+    cursor += JS_snprintf(cursor, end - cursor, "v%u", def.virtualRegister());
     cursor += JS_snprintf(cursor, end - cursor, "<%s>", TypeChars[def.type()]);
 
     if (def.policy() == LDefinition::FIXED)
@@ -378,6 +376,10 @@ LDefinition::toString() const
 {
     // Not reentrant!
     static char buf[40];
+
+    if (isBogusTemp())
+        return "bogus";
+
     PrintDefinition(buf, sizeof(buf), *this);
     return buf;
 }
@@ -416,6 +418,9 @@ LAllocation::toString() const
     // Not reentrant!
     static char buf[40];
 
+    if (isBogus())
+        return "bogus";
+
     switch (kind()) {
       case LAllocation::CONSTANT_VALUE:
       case LAllocation::CONSTANT_INDEX:
diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
index 779745134c9d..bca1b3c3b6e6 100644
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -71,9 +71,9 @@ class LAllocation : public TempObject
 
   public:
     enum Kind {
-        USE,            // Use of a virtual register, with physical allocation policy.
         CONSTANT_VALUE, // Constant js::Value.
         CONSTANT_INDEX, // Constant arbitrary index.
+        USE,            // Use of a virtual register, with physical allocation policy.
         GPR,            // General purpose register.
         FPU,            // Floating-point register.
         STACK_SLOT,     // Stack slot.
@@ -103,7 +103,9 @@ class LAllocation : public TempObject
 
   public:
     LAllocation() : bits_(0)
-    { }
+    {
+        JS_ASSERT(isBogus());
+    }
 
     static LAllocation *New(TempAllocator &alloc) {
         return new(alloc) LAllocation();
@@ -115,6 +117,7 @@ class LAllocation : public TempObject
 
     // The value pointer must be rooted in MIR and have its low bits cleared.
     explicit LAllocation(const Value *vp) {
+        JS_ASSERT(vp);
         bits_ = uintptr_t(vp);
         JS_ASSERT((bits_ & (KIND_MASK << KIND_SHIFT)) == 0);
         bits_ |= CONSTANT_VALUE << KIND_SHIFT;
@@ -125,6 +128,9 @@ class LAllocation : public TempObject
         return (Kind)((bits_ >> KIND_SHIFT) & KIND_MASK);
     }
 
+    bool isBogus() const {
+        return bits_ == 0;
+    }
     bool isUse() const {
         return kind() == USE;
     }
@@ -328,11 +334,6 @@ class LConstantIndex : public LAllocation
     { }
 
   public:
-    // Used as a placeholder for inputs that can be ignored.
-    static LConstantIndex Bogus() {
-        return LConstantIndex(0);
-    }
-
     static LConstantIndex FromIndex(uint32_t index) {
         return LConstantIndex(index);
     }
@@ -399,9 +400,6 @@ class LDefinition
     // unless the policy specifies that an input can be re-used and that input
     // is a stack slot.
     enum Policy {
-        // A random register of an appropriate class will be assigned.
-        REGISTER,
-
         // The policy is predetermined by the LAllocation attached to this
         // definition. The allocation may be:
         //   * A register, which may not appear as any fixed temporary.
@@ -410,6 +408,9 @@ class LDefinition
         // Register allocation will not modify a fixed allocation.
         FIXED,
 
+        // A random register of an appropriate class will be assigned.
+        REGISTER,
+
         // One definition per instruction must re-use the first input
         // allocation, which (for now) must be a register.
         MUST_REUSE_INPUT
@@ -462,10 +463,12 @@ class LDefinition
     }
 
     LDefinition() : bits_(0)
-    { }
+    {
+        JS_ASSERT(isBogusTemp());
+    }
 
     static LDefinition BogusTemp() {
-        return LDefinition(GENERAL, LConstantIndex::Bogus());
+        return LDefinition();
     }
 
     Policy policy() const {
@@ -517,7 +520,7 @@ class LDefinition
         return policy() == FIXED;
     }
     bool isBogusTemp() const {
-        return isFixed() && output()->isConstantIndex();
+        return isFixed() && output()->isBogus();
     }
     void setVirtualRegister(uint32_t index) {
         JS_ASSERT(index < VREG_MASK);
diff --git a/js/src/jit/LinearScan.cpp b/js/src/jit/LinearScan.cpp
index 9f5ed2f195e1..d691d56fac44 100644
--- a/js/src/jit/LinearScan.cpp
+++ b/js/src/jit/LinearScan.cpp
@@ -84,7 +84,7 @@ LinearScanAllocator::allocateRegisters()
     // Iterate through all intervals in ascending start order.
     CodePosition prevPosition = CodePosition::MIN;
     while ((current = unhandled.dequeue()) != nullptr) {
-        JS_ASSERT(current->getAllocation()->isUse());
+        JS_ASSERT(current->getAllocation()->isBogus());
         JS_ASSERT(current->numRanges() > 0);
 
         if (mir->shouldCancel("LSRA Allocate Registers (main loop)"))
diff --git a/js/src/jit/LiveRangeAllocator.cpp b/js/src/jit/LiveRangeAllocator.cpp
index ae59aacfe365..2594cbc19407 100644
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -1080,7 +1080,7 @@ LiveInterval::toString() const
         cursor += n;
     }
 
-    if (alloc_.kind() != LAllocation::USE) {
+    if (!alloc_.isBogus()) {
         n = JS_snprintf(cursor, end - cursor, " has(%s)", alloc_.toString());
         if (n < 0) return "???";
         cursor += n;
diff --git a/js/src/jit/LiveRangeAllocator.h b/js/src/jit/LiveRangeAllocator.h
index 7c9423fa9eec..e3e7753539ac 100644
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -52,7 +52,7 @@ class Requirement
       : kind_(FIXED),
         allocation_(fixed)
     {
-        JS_ASSERT(fixed == LAllocation() || !fixed.isUse());
+        JS_ASSERT(!fixed.isBogus() && !fixed.isUse());
     }
 
     // Only useful as a hint, encodes where the fixed requirement is used to
@@ -62,7 +62,7 @@ class Requirement
         allocation_(fixed),
         position_(at)
     {
-        JS_ASSERT(fixed == LAllocation() || !fixed.isUse());
+        JS_ASSERT(!fixed.isBogus() && !fixed.isUse());
     }
 
     Requirement(uint32_t vreg, CodePosition at)
@@ -76,7 +76,7 @@ class Requirement
     }
 
     LAllocation allocation() const {
-        JS_ASSERT(!allocation_.isUse());
+        JS_ASSERT(!allocation_.isBogus() && !allocation_.isUse());
         return allocation_;
     }
 
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 4c88da4a235c..1b707e1618fc 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2581,8 +2581,6 @@ LIRGenerator::visitInArray(MInArray *ins)
     LAllocation object;
     if (ins->needsNegativeIntCheck())
         object = useRegister(ins->object());
-    else
-        object = LConstantIndex::Bogus();
 
     LInArray *lir = new(alloc()) LInArray(useRegister(ins->elements()),
                                           useRegisterOrConstant(ins->index()),
diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp
index b1bbb0ce441f..49650d81ee14 100644
--- a/js/src/jit/RegisterAllocator.cpp
+++ b/js/src/jit/RegisterAllocator.cpp
@@ -575,8 +575,10 @@ RegisterAllocator::dumpInstructions()
                     fprintf(stderr, " [temp %s]", temp->toString());
             }
 
-            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next())
-                fprintf(stderr, " [use %s]", alloc->toString());
+            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
+                if (!alloc->isBogus())
+                    fprintf(stderr, " [use %s]", alloc->toString());
+            }
 
             fprintf(stderr, "\n");
         }
diff --git a/js/src/jit/shared/Lowering-shared.cpp b/js/src/jit/shared/Lowering-shared.cpp
index b93c6ba669c5..3cbc05eb1d34 100644
--- a/js/src/jit/shared/Lowering-shared.cpp
+++ b/js/src/jit/shared/Lowering-shared.cpp
@@ -136,10 +136,10 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
         // constants, including known types, we record a dummy placeholder,
         // since we can recover the same information, much cleaner, from MIR.
         if (ins->isConstant() || ins->isUnused()) {
-            *type = LConstantIndex::Bogus();
-            *payload = LConstantIndex::Bogus();
+            *type = LAllocation();
+            *payload = LAllocation();
         } else if (ins->type() != MIRType_Value) {
-            *type = LConstantIndex::Bogus();
+            *type = LAllocation();
             *payload = use(ins, LUse(LUse::KEEPALIVE));
         } else {
             *type = useType(ins, LUse::KEEPALIVE);
@@ -187,7 +187,7 @@ LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKi
         LAllocation *a = snapshot->getEntry(index++);
 
         if (def->isUnused()) {
-            *a = LConstantIndex::Bogus();
+            *a = LAllocation();
             continue;
         }
 

From 8abfa775a1991880498d21c3258879ea3a8755cf Mon Sep 17 00:00:00 2001
From: Dan Gohman 
Date: Sat, 16 Aug 2014 13:13:14 -0700
Subject: [PATCH 101/101] Bug 1045948 - IonMonkey: Make LAllocation's data
 unsigned r=bhackett

---
 js/src/jit/LIR.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
index bca1b3c3b6e6..f73a5cc80a22 100644
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -81,16 +81,16 @@ class LAllocation : public TempObject
     };
 
   protected:
-    int32_t data() const {
-        return int32_t(bits_) >> DATA_SHIFT;
+    uint32_t data() const {
+        return uint32_t(bits_) >> DATA_SHIFT;
     }
-    void setData(int32_t data) {
-        JS_ASSERT(int32_t(data) <= int32_t(DATA_MASK));
+    void setData(uint32_t data) {
+        JS_ASSERT(data <= DATA_MASK);
         bits_ &= ~(DATA_MASK << DATA_SHIFT);
         bits_ |= (data << DATA_SHIFT);
     }
     void setKindAndData(Kind kind, uint32_t data) {
-        JS_ASSERT(int32_t(data) <= int32_t(DATA_MASK));
+        JS_ASSERT(data <= DATA_MASK);
         bits_ = (uint32_t(kind) << KIND_SHIFT) | data << DATA_SHIFT;
     }