Bug 779611 - reland parts 5-8 - port WebGLTexture, WebGLBuffer, WebGLFramebuffer, WebGLRenderbuffer, WebGLShader, WebGLProgram to WebIDL bindings - r=bz
authorBenoit Jacob <bjacob@mozilla.com>
Thu, 04 Oct 2012 16:35:54 -0400
changeset 115584 e619280855e5f91edb92d7c2e7f52ea215dd7679
parent 115583 0ea0cfc7f6f4acec3c6174828e8ecfeafac14bce
child 115585 d7c8896af07ae086a779aa880eb1770616996a82
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersbz
bugs779611
milestone18.0a1
Bug 779611 - reland parts 5-8 - port WebGLTexture, WebGLBuffer, WebGLFramebuffer, WebGLRenderbuffer, WebGLShader, WebGLProgram to WebIDL bindings - r=bz
content/canvas/src/Makefile.in
content/canvas/src/WebGLBuffer.cpp
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextNotSupported.cpp
content/canvas/src/WebGLContextUtils.h
content/canvas/src/WebGLFramebuffer.cpp
content/canvas/src/WebGLProgram.cpp
content/canvas/src/WebGLRenderbuffer.cpp
content/canvas/src/WebGLShader.cpp
content/canvas/src/WebGLTexture.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
dom/webidl/WebGLRenderingContext.webidl
js/xpconnect/src/dom_quickstubs.qsconf
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -38,32 +38,38 @@ CPPSRCS	= \
 	DocumentRendererParent.cpp \
 	DocumentRendererChild.cpp \
 	ImageData.cpp \
 	$(NULL)
 
 ifdef MOZ_WEBGL
 
 CPPSRCS += \
+	WebGLBuffer.cpp \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextReporter.cpp \
 	WebGLContextValidate.cpp \
-	WebGLTexelConversions.cpp \
 	WebGLElementArrayCache.cpp \
 	WebGLExtensionBase.cpp \
 	WebGLExtensionCompressedTextureATC.cpp \
 	WebGLExtensionCompressedTexturePVRTC.cpp \
 	WebGLExtensionCompressedTextureS3TC.cpp \
 	WebGLExtensionDepthTexture.cpp \
 	WebGLExtensionLoseContext.cpp \
 	WebGLExtensionStandardDerivatives.cpp \
 	WebGLExtensionTextureFilterAnisotropic.cpp \
 	WebGLExtensionTextureFloat.cpp \
+	WebGLFramebuffer.cpp \
+	WebGLProgram.cpp \
+	WebGLRenderbuffer.cpp \
+	WebGLShader.cpp \
+	WebGLTexelConversions.cpp \
+	WebGLTexture.cpp \
 	$(NULL)
 
 DEFINES += -DUSE_ANGLE
 USE_ANGLE=1
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLBuffer.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLBuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLBufferBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLBuffer)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLBuffer)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLBuffer)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 #include "WebGLExtensions.h"
+#include "WebGLContextUtils.h"
 
 #include "nsIConsoleService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIClassInfoImpl.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsError.h"
 #include "nsIGfxInfo.h"
@@ -1009,17 +1010,17 @@ bool WebGLContext::IsExtensionSupported(
 
 static bool
 CompareWebGLExtensionName(const nsACString& name, const char *other)
 {
     return name.Equals(other, nsCaseInsensitiveCStringComparator());
 }
 
 JSObject*
-WebGLContext::GetExtension(JSContext *cx, const nsAString& aName)
+WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv)
 {
     if (!IsContextStable())
         return nullptr;
 
     NS_LossyConvertUTF16toASCII name(aName);
 
     WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
 
@@ -1096,24 +1097,17 @@ WebGLContext::GetExtension(JSContext *cx
                 break;
             default:
                 MOZ_ASSERT(false, "should not get there.");
         }
         mExtensions.EnsureLengthAtLeast(ext + 1);
         mExtensions[ext] = obj;
     }
 
-    // step 4: return the extension as a JS object
-    JS::Value v;
-    JSObject* wrapper = GetWrapper();
-    JSAutoCompartment ac(cx, wrapper);
-    if (!WrapNewBindingObject(cx, wrapper, mExtensions[ext], &v)) {
-        return nullptr;
-    }
-    return &v.toObject();
+    return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv);
 }
 
 void
 WebGLContext::ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect)
 {
     MakeContextCurrent();
 
     bool initializeColorBuffer = 0 != (mask & LOCAL_GL_COLOR_BUFFER_BIT);
@@ -1391,82 +1385,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   // If the exact way we cast to nsISupports here ever changes, fix our
   // PreCreate hook!
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports,
                                    nsICanvasRenderingContextInternal)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF(WebGLBuffer)
-NS_IMPL_RELEASE(WebGLBuffer)
-
-DOMCI_DATA(WebGLBuffer, WebGLBuffer)
-
-NS_INTERFACE_MAP_BEGIN(WebGLBuffer)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLBuffer)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLBuffer)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(WebGLTexture)
-NS_IMPL_RELEASE(WebGLTexture)
-
-DOMCI_DATA(WebGLTexture, WebGLTexture)
-
-NS_INTERFACE_MAP_BEGIN(WebGLTexture)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLTexture)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLTexture)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(WebGLProgram)
-NS_IMPL_RELEASE(WebGLProgram)
-
-DOMCI_DATA(WebGLProgram, WebGLProgram)
-
-NS_INTERFACE_MAP_BEGIN(WebGLProgram)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLProgram)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLProgram)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(WebGLShader)
-NS_IMPL_RELEASE(WebGLShader)
-
-DOMCI_DATA(WebGLShader, WebGLShader)
-
-NS_INTERFACE_MAP_BEGIN(WebGLShader)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLShader)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLShader)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(WebGLFramebuffer)
-NS_IMPL_RELEASE(WebGLFramebuffer)
-
-DOMCI_DATA(WebGLFramebuffer, WebGLFramebuffer)
-
-NS_INTERFACE_MAP_BEGIN(WebGLFramebuffer)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLFramebuffer)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLFramebuffer)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(WebGLRenderbuffer)
-NS_IMPL_RELEASE(WebGLRenderbuffer)
-
-DOMCI_DATA(WebGLRenderbuffer, WebGLRenderbuffer)
-
-NS_INTERFACE_MAP_BEGIN(WebGLRenderbuffer)
-  NS_INTERFACE_MAP_ENTRY(nsIWebGLRenderbuffer)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLRenderbuffer)
-NS_INTERFACE_MAP_END
-
 // WebGLUniformLocation
 
 NS_IMPL_ADDREF(WebGLUniformLocation)
 NS_IMPL_RELEASE(WebGLUniformLocation)
 
 NS_INTERFACE_MAP_BEGIN(WebGLUniformLocation)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -1500,29 +1428,16 @@ NS_IMPL_RELEASE(WebGLActiveInfo)
 DOMCI_DATA(WebGLActiveInfo, WebGLActiveInfo)
 
 NS_INTERFACE_MAP_BEGIN(WebGLActiveInfo)
   NS_INTERFACE_MAP_ENTRY(nsIWebGLActiveInfo)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLActiveInfo)
 NS_INTERFACE_MAP_END
 
-#define NAME_NOT_SUPPORTED(base) \
-NS_IMETHODIMP base::GetName(WebGLuint *aName) \
-{ return NS_ERROR_NOT_IMPLEMENTED; } \
-NS_IMETHODIMP base::SetName(WebGLuint aName) \
-{ return NS_ERROR_NOT_IMPLEMENTED; }
-
-NAME_NOT_SUPPORTED(WebGLTexture)
-NAME_NOT_SUPPORTED(WebGLBuffer)
-NAME_NOT_SUPPORTED(WebGLProgram)
-NAME_NOT_SUPPORTED(WebGLShader)
-NAME_NOT_SUPPORTED(WebGLFramebuffer)
-NAME_NOT_SUPPORTED(WebGLRenderbuffer)
-
 /* readonly attribute WebGLint size; */
 NS_IMETHODIMP
 WebGLActiveInfo::GetSize(WebGLint *aSize)
 {
     *aSize = mSize;
     return NS_OK;
 }
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -626,17 +626,17 @@ public:
         if (!IsContextStable())
             return 0;
         return mHeight;
     }
         
     JSObject *GetContextAttributes(ErrorResult &rv);
     bool IsContextLost() const { return !IsContextStable(); }
     void GetSupportedExtensions(dom::Nullable< nsTArray<nsString> > &retval);
-    JSObject* GetExtension(JSContext* ctx, const nsAString& aName);
+    JSObject* GetExtension(JSContext* ctx, const nsAString& aName, ErrorResult& rv);
     void ActiveTexture(WebGLenum texture);
     void AttachShader(WebGLProgram* program, WebGLShader* shader);
     void BindAttribLocation(WebGLProgram* program, WebGLuint location,
                             const nsAString& name);
     void BindBuffer(WebGLenum target, WebGLBuffer* buf);
     void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb);
     void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb);
     void BindTexture(WebGLenum target, WebGLTexture *tex);
@@ -1387,16 +1387,21 @@ protected:
         return mAlreadyGeneratedWarnings < 32;
     }
 
     uint64_t mLastUseIndex;
 
     void LoseOldestWebGLContextIfLimitExceeded();
     void UpdateLastUseIndex();
 
+    template <typename WebGLObjectType>
+    JS::Value WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
+    template <typename WebGLObjectType>
+    JSObject* WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *, ErrorResult& rv) const;
+
 #ifdef XP_MACOSX
     // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
     // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
     // these objects at high frequency. Having WebGLContext's hold one such object seems fine,
     // because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
     // If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
     ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
 #endif
@@ -1487,31 +1492,31 @@ struct WebGLVertexAttribData {
     }
 
     GLuint actualStride() const {
         if (stride) return stride;
         return size * componentSize();
     }
 };
 
-// NOTE: When this class is switched to new DOM bindings, update the
-// (then-slow) WrapObject calls in GetParameter and GetVertexAttrib.
 class WebGLBuffer MOZ_FINAL
-    : public nsIWebGLBuffer
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLBuffer>
     , public LinkedListElement<WebGLBuffer>
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
 public:
     WebGLBuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
         , mByteLength(0)
         , mTarget(LOCAL_GL_NONE)
     {
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mContext->gl->fGenBuffers(1, &mGLName);
         mContext->mBuffers.insertBack(this);
     }
 
     ~WebGLBuffer() {
         DeleteOnce();
     }
@@ -1553,51 +1558,59 @@ public:
         if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
             mCache->BufferSubData(pos, ptr, update_size_in_bytes);
     }
 
     bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
         return mCache->Validate(type, max_allowed, first, count);
     }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLBUFFER
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer)
 
 protected:
 
     WebGLuint mGLName;
     bool mHasEverBeenBound;
     GLuint mByteLength;
     GLenum mTarget;
 
     nsAutoPtr<WebGLElementArrayCache> mCache;
 };
 
 // NOTE: When this class is switched to new DOM bindings, update the (then-slow)
 // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
 class WebGLTexture MOZ_FINAL
-    : public nsIWebGLTexture
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLTexture>
     , public LinkedListElement<WebGLTexture>
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
 public:
     WebGLTexture(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
         , mTarget(0)
         , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
         , mMagFilter(LOCAL_GL_LINEAR)
         , mWrapS(LOCAL_GL_REPEAT)
         , mWrapT(LOCAL_GL_REPEAT)
         , mFacesCount(0)
         , mMaxLevelWithCustomImages(0)
         , mHaveGeneratedMipmap(false)
         , mFakeBlackStatus(DoNotNeedFakeBlack)
     {
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mContext->gl->fGenTextures(1, &mGLName);
         mContext->mTextures.insertBack(this);
     }
 
     ~WebGLTexture() {
         DeleteOnce();
     }
@@ -1609,18 +1622,24 @@ public:
         LinkedListElement<WebGLTexture>::remove(); // remove from mContext->mTextures
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
     GLenum Target() const { return mTarget; }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLTEXTURE
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLTexture)
 
 protected:
 
     friend class WebGLContext;
     friend class WebGLFramebuffer;
 
     bool mHasEverBeenBound;
     WebGLuint mGLName;
@@ -2075,32 +2094,34 @@ struct WebGLUniformInfo {
             default:
                 NS_ABORT(); // should never get here
                 return 0;
         }
     }
 };
 
 class WebGLShader MOZ_FINAL
-    : public nsIWebGLShader
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLShader>
     , public LinkedListElement<WebGLShader>
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
     friend class WebGLContext;
     friend class WebGLProgram;
 
 public:
     WebGLShader(WebGLContext *context, WebGLenum stype)
         : WebGLContextBoundObject(context)
         , mType(stype)
         , mNeedsTranslation(true)
         , mAttribMaxNameLength(0)
         , mCompileStatus(false)
     {
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mGLName = mContext->gl->fCreateShader(mType);
         mContext->mShaders.insertBack(this);
     }
 
     ~WebGLShader() {
         DeleteOnce();
     }
@@ -2146,18 +2167,24 @@ public:
     }
 
     void SetTranslationFailure(const nsCString& msg) {
         mTranslationLog.Assign(msg); 
     }
 
     const nsCString& TranslationLog() const { return mTranslationLog; }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLSHADER
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLShader)
 
 protected:
 
     WebGLuint mGLName;
     WebGLenum mType;
     nsString mSource;
     nsCString mTranslationLog; // The translation log should contain only ASCII characters
     bool mNeedsTranslation;
@@ -2199,31 +2226,31 @@ static bool SplitLastSquareBracket(nsACS
     string.EndWriting();
     string.SetLength(s - string_start);
     return true;
 }
 
 typedef nsDataHashtable<nsCStringHashKey, nsCString> CStringMap;
 typedef nsDataHashtable<nsCStringHashKey, WebGLUniformInfo> CStringToUniformInfoMap;
 
-// NOTE: When this class is switched to new DOM bindings, update the
-// (then-slow) WrapObject call in GetParameter.
 class WebGLProgram MOZ_FINAL
-    : public nsIWebGLProgram
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLProgram>
     , public LinkedListElement<WebGLProgram>
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
 public:
     WebGLProgram(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mLinkStatus(false)
         , mGeneration(0)
         , mAttribMaxNameLength(0)
     {
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mGLName = mContext->gl->fCreateProgram();
         mContext->mPrograms.insertBack(this);
     }
 
     ~WebGLProgram() {
         DeleteOnce();
     }
@@ -2457,52 +2484,57 @@ public:
         // if there is a bracket and it's not [0], then we're not an array, we're just an entry in an array
         if (hadBracketPart && !bracketPart.EqualsLiteral("[0]")) {
             info.isArray = false;
             info.arraySize = 1;
         }
         return info;
     }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLPROGRAM
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLProgram)
 
 protected:
 
     WebGLuint mGLName;
     bool mLinkStatus;
     // attached shaders of the program object
     nsTArray<WebGLRefPtr<WebGLShader> > mAttachedShaders;
     CheckedUint32 mGeneration;
 
     // post-link data
     std::vector<bool> mAttribsInUse;
     nsAutoPtr<CStringMap> mIdentifierMap, mIdentifierReverseMap;
     nsAutoPtr<CStringToUniformInfoMap> mUniformInfoMap;
     int mAttribMaxNameLength;
 };
 
-// NOTE: When this class is switched to new DOM bindings, update the (then-slow)
-// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
 class WebGLRenderbuffer MOZ_FINAL
-    : public nsIWebGLRenderbuffer
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLRenderbuffer>
     , public LinkedListElement<WebGLRenderbuffer>
     , public WebGLRectangleObject
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
 public:
     WebGLRenderbuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mInternalFormat(0)
         , mInternalFormatForGL(0)
         , mHasEverBeenBound(false)
         , mInitialized(false)
     {
-
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mContext->gl->fGenRenderbuffers(1, &mGLName);
         mContext->mRenderbuffers.insertBack(this);
     }
 
     ~WebGLRenderbuffer() {
         DeleteOnce();
     }
@@ -2550,18 +2582,24 @@ public:
                 return 4*pixels;
             default:
                 break;
         }
         NS_ABORT();
         return 0;
     }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLRENDERBUFFER
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLRenderbuffer)
 
 protected:
 
     WebGLuint mGLName;
     WebGLenum mInternalFormat;
     WebGLenum mInternalFormatForGL;
     bool mHasEverBeenBound;
     bool mInitialized;
@@ -2709,33 +2747,33 @@ public:
             }
         }
 
         NS_ABORT(); // should never get there
         return false;
     }
 };
 
-// NOTE: When this class is switched to new DOM bindings, update the
-// (then-slow) WrapObject call in GetParameter.
 class WebGLFramebuffer MOZ_FINAL
-    : public nsIWebGLFramebuffer
+    : public nsISupports
     , public WebGLRefCountedObject<WebGLFramebuffer>
     , public LinkedListElement<WebGLFramebuffer>
     , public WebGLContextBoundObject
+    , public nsWrapperCache
 {
 public:
     WebGLFramebuffer(WebGLContext *context)
         : WebGLContextBoundObject(context)
         , mHasEverBeenBound(false)
         , mColorAttachment(LOCAL_GL_COLOR_ATTACHMENT0)
         , mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
         , mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
         , mDepthStencilAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
     {
+        SetIsDOMBinding();
         mContext->MakeContextCurrent();
         mContext->gl->fGenFramebuffers(1, &mGLName);
         mContext->mFramebuffers.insertBack(this);
     }
 
     ~WebGLFramebuffer() {
         DeleteOnce();
     }
@@ -2921,18 +2959,24 @@ public:
         if (mDepthStencilAttachment.Renderbuffer() == rb)
             FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
     }
 
     const WebGLRectangleObject *RectangleObject() {
         return mColorAttachment.RectangleObject();
     }
 
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBGLFRAMEBUFFER
+    WebGLContext *GetParentObject() const {
+        return Context();
+    }
+
+    virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
+
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLFramebuffer)
 
     bool CheckAndInitializeRenderbuffers()
     {
         // enforce WebGL section 6.5 which is WebGL-specific, hence OpenGL itself would not
         // generate the INVALID_FRAMEBUFFER_OPERATION that we need here
         if (HasDepthStencilConflict())
             return false;
         
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
+#include "WebGLContextUtils.h"
 
 #include "nsString.h"
 #include "nsDebug.h"
 
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 
@@ -2131,89 +2132,47 @@ WebGLContext::GetParameter(JSContext* cx
             if (!obj) {
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
             return JS::ObjectOrNullValue(obj);
         }
 
         case LOCAL_GL_ARRAY_BUFFER_BINDING:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBoundArrayBuffer.get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
         }
 
         case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBoundElementArrayBuffer.get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBoundElementArrayBuffer.get(), rv);
         }
 
         case LOCAL_GL_RENDERBUFFER_BINDING:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBoundRenderbuffer.get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
         }
 
         case LOCAL_GL_FRAMEBUFFER_BINDING:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBoundFramebuffer.get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
         }
 
         case LOCAL_GL_CURRENT_PROGRAM:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(), mCurrentProgram.get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
         }
 
         case LOCAL_GL_TEXTURE_BINDING_2D:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBound2DTextures[mActiveTexture].get(), &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv);
         }
 
         case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mBoundCubeMapTextures[mActiveTexture].get(),
-                                 &v)) {
-                rv = NS_ERROR_FAILURE;
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv);
         }
 
         default:
             ErrorInvalidEnumInfo("getParameter: parameter", pname);
     }
 
     return JS::NullValue();
 }
@@ -2290,45 +2249,31 @@ WebGLContext::GetFramebufferAttachmentPa
 
     if (fba.Renderbuffer()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER));
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
             {
-                JS::Value v;
-                if (!dom::WrapObject(cx, GetWrapper(),
-                                     const_cast<WebGLRenderbuffer*>(fba.Renderbuffer()),
-                                     &v)) {
-                    rv.Throw(NS_ERROR_FAILURE);
-                    return JS::NullValue();
-                }
-                return v;
+                return WebGLObjectAsJSValue(cx, fba.Renderbuffer(), rv);
             }
 
             default:
                 ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: pname", pname);
                 return JS::NullValue();
         }
     } else if (fba.Texture()) {
         switch (pname) {
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                 return JS::NumberValue(uint32_t(LOCAL_GL_TEXTURE));
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
             {
-                JS::Value v;
-                if (!dom::WrapObject(cx, GetWrapper(),
-                                     const_cast<WebGLTexture*>(fba.Texture()),
-                                     &v)) {
-                    rv = NS_ERROR_FAILURE;
-                    return JS::NullValue();
-                }
-                return v;
+                return WebGLObjectAsJSValue(cx, fba.Texture(), rv);
             }
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
                 return JS::Int32Value(fba.TextureLevel());
 
             case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
                 return JS::Int32Value(fba.TextureCubeMapFace());
 
@@ -2854,23 +2799,17 @@ WebGLContext::GetVertexAttrib(JSContext*
     if (!ValidateAttribIndex(index, "getVertexAttrib"))
         return JS::NullValue();
 
     MakeContextCurrent();
 
     switch (pname) {
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
         {
-            JS::Value v;
-            if (!dom::WrapObject(cx, GetWrapper(),
-                                 mAttribBuffers[index].buf.get(), &v)) {
-                rv.Throw(NS_ERROR_FAILURE);
-                return JS::NullValue();
-            }
-            return v;
+            return WebGLObjectAsJSValue(cx, mAttribBuffers[index].buf.get(), rv);
         }
 
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
             return JS::Int32Value(mAttribBuffers[index].stride);
 
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
         {
--- a/content/canvas/src/WebGLContextNotSupported.cpp
+++ b/content/canvas/src/WebGLContextNotSupported.cpp
@@ -5,15 +5,9 @@
 
 #include "nsIDOMWebGLRenderingContext.h"
 #include "nsDOMClassInfoID.h"
 
 #define DUMMY(func,rtype)  nsresult func (rtype ** aResult) { return NS_ERROR_FAILURE; }
 
 DUMMY(NS_NewCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext)
 
-DOMCI_DATA(WebGLBuffer, void)
-DOMCI_DATA(WebGLTexture, void)
-DOMCI_DATA(WebGLProgram, void)
-DOMCI_DATA(WebGLShader, void)
-DOMCI_DATA(WebGLFramebuffer, void)
-DOMCI_DATA(WebGLRenderbuffer, void)
 DOMCI_DATA(WebGLActiveInfo, void)
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLContextUtils.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 WEBGLCONTEXTUTILS_H_
+#define WEBGLCONTEXTUTILS_H_
+
+#include "WebGLContext.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla {
+
+template <typename WebGLObjectType>
+JS::Value
+WebGLContext::WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *object, ErrorResult& rv) const
+{
+    if (!object) {
+        return JS::NullValue();
+    }
+    MOZ_ASSERT(this == object->Context());
+    JS::Value v;
+    JSObject* wrapper = GetWrapper();
+    JSAutoCompartment ac(cx, wrapper);
+    if (!dom::WrapNewBindingObject(cx, wrapper, const_cast<WebGLObjectType*>(object), &v)) {
+        rv.Throw(NS_ERROR_FAILURE);
+        return JS::NullValue();
+    }
+    return v;
+}
+
+template <typename WebGLObjectType>
+JSObject*
+WebGLContext::WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *object, ErrorResult& rv) const
+{
+    JS::Value v = WebGLObjectAsJSValue(cx, object, rv);
+    if (v.isNull()) {
+        return nullptr;
+    }
+    return &v.toObject();
+}
+
+} // namespace mozilla
+
+#endif // WEBGLCONTEXTUTILS_H_
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLFramebuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLFramebufferBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLFramebuffer)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLFramebuffer)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLFramebuffer)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLFramebuffer)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLProgram.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLProgram::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLProgramBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLProgram)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLProgram)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLProgram)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLProgram)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLRenderbuffer.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLRenderbuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLRenderbufferBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLRenderbuffer)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLRenderbuffer)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLRenderbuffer)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLRenderbuffer)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLShader.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLShader::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLShaderBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLShader)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLShader)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLShader)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLShader)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLTexture.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+
+using namespace mozilla;
+
+JSObject*
+WebGLTexture::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
+    return dom::WebGLTextureBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTexture)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLTexture)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLTexture)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLTexture)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
\ No newline at end of file
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1554,28 +1554,16 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(SimpleGestureEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(MathMLElement, Element, nsElementSH,
                                      ELEMENT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(WebGLBuffer, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLTexture, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLProgram, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLShader, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLFramebuffer, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(WebGLRenderbuffer, nsDOMGenericSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(WebGLActiveInfo, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(PaintRequest, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PaintRequestList, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
@@ -4211,40 +4199,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
     DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver,
                                         nsDOMTouchEvent::PrefEnabled())
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(WebGLBuffer, nsIWebGLBuffer)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLBuffer)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLTexture, nsIWebGLTexture)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLTexture)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLProgram, nsIWebGLProgram)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLProgram)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLShader, nsIWebGLShader)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLShader)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLFramebuffer, nsIWebGLFramebuffer)
-    DOM_CLASSINFO_MAP_ENTRY(nsIWebGLFramebuffer)
-  DOM_CLASSINFO_MAP_END
-
-  DOM_CLASSINFO_MAP_BEGIN(WebGLRenderbuffer, nsIWebGLRenderbuffer)
-     DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer)
-  DOM_CLASSINFO_MAP_END
-
   DOM_CLASSINFO_MAP_BEGIN(WebGLActiveInfo, nsIWebGLActiveInfo)
     DOM_CLASSINFO_MAP_ENTRY(nsIWebGLActiveInfo)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PaintRequest, nsIDOMPaintRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequest)
    DOM_CLASSINFO_MAP_END
  
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -442,22 +442,16 @@ DOMCI_CLASS(NotifyPaintEvent)
 
 DOMCI_CLASS(NotifyAudioAvailableEvent)
 
 DOMCI_CLASS(SimpleGestureEvent)
 
 DOMCI_CLASS(MathMLElement)
 
 // WebGL
-DOMCI_CLASS(WebGLBuffer)
-DOMCI_CLASS(WebGLTexture)
-DOMCI_CLASS(WebGLProgram)
-DOMCI_CLASS(WebGLShader)
-DOMCI_CLASS(WebGLFramebuffer)
-DOMCI_CLASS(WebGLRenderbuffer)
 DOMCI_CLASS(WebGLActiveInfo)
 
 DOMCI_CLASS(PaintRequest)
 DOMCI_CLASS(PaintRequestList)
 
 DOMCI_CLASS(ScrollAreaEvent)
 
 DOMCI_CLASS(EventListenerInfo)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -337,16 +337,21 @@ DOMInterfaces = {
     'headerFile': 'mozilla/dom/TextEncoder.h',
     'implicitJSContext': [ 'encode' ],
 },
 
 'TextDecoder': {
     'headerFile': 'mozilla/dom/TextDecoder.h',
 },
 
+'WebGLBuffer': {
+   'nativeType': 'mozilla::WebGLBuffer',
+   'headerFile': 'WebGLContext.h'
+},
+
 'WebGLExtensionCompressedTextureATC': {
    'nativeType': 'mozilla::WebGLExtensionCompressedTextureATC',
    'headerFile': 'WebGLExtensions.h'
 },
 
 'WebGLExtensionCompressedTexturePVRTC': {
    'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC',
    'headerFile': 'WebGLExtensions.h'
@@ -377,30 +382,55 @@ DOMInterfaces = {
    'headerFile': 'WebGLExtensions.h'
 },
 
 'WebGLExtensionTextureFloat': {
    'nativeType': 'mozilla::WebGLExtensionTextureFloat',
    'headerFile': 'WebGLExtensions.h'
 },
 
+'WebGLFramebuffer': {
+   'nativeType': 'mozilla::WebGLFramebuffer',
+   'headerFile': 'WebGLContext.h'
+},
+
+'WebGLProgram': {
+   'nativeType': 'mozilla::WebGLProgram',
+   'headerFile': 'WebGLContext.h'
+},
+
+'WebGLRenderbuffer': {
+   'nativeType': 'mozilla::WebGLRenderbuffer',
+   'headerFile': 'WebGLContext.h'
+},
+
 'WebGLRenderingContext': {
   'nativeType': 'mozilla::WebGLContext',
   'headerFile': 'WebGLContext.h',
   'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
                          'getAttachedShaders' ],
   'implicitJSContext': [ 'texImage2D', 'texSubImage2D' ],
 },
 
+'WebGLShader': {
+   'nativeType': 'mozilla::WebGLShader',
+   'headerFile': 'WebGLContext.h'
+},
+
 'WebGLShaderPrecisionFormat': {
    'nativeType': 'mozilla::WebGLShaderPrecisionFormat',
    'headerFile': 'WebGLContext.h',
    'wrapperCache': False
 },
 
+'WebGLTexture': {
+   'nativeType': 'mozilla::WebGLTexture',
+   'headerFile': 'WebGLContext.h'
+},
+
 'WebGLUniformLocation': {
    'nativeType': 'mozilla::WebGLUniformLocation',
    'headerFile': 'WebGLContext.h',
    'wrapperCache': False
 },
 
 'XMLHttpRequest': [
 {
@@ -577,24 +607,12 @@ addExternalIface('SVGMatrix')
 addExternalIface('SVGNumber')
 addExternalIface('SVGPathSeg')
 addExternalIface('SVGPoint')
 addExternalIface('SVGTransform')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
 addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
                  headerFile='WebGLContext.h')
-addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
-                 headerFile='WebGLContext.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
                  headerFile='jsapi.h')
-addExternalIface('WebGLFramebuffer', nativeType='mozilla::WebGLFramebuffer',
-                 headerFile='WebGLContext.h')
-addExternalIface('WebGLProgram', nativeType='mozilla::WebGLProgram',
-                 headerFile='WebGLContext.h')
-addExternalIface('WebGLRenderbuffer', nativeType='mozilla::WebGLRenderbuffer',
-                 headerFile='WebGLContext.h')
-addExternalIface('WebGLShader', nativeType='mozilla::WebGLShader',
-                 headerFile='WebGLContext.h')
-addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
-                 headerFile='WebGLContext.h')
 addExternalIface('Window')
 addExternalIface('XULElement')
--- a/dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
+++ b/dom/interfaces/canvas/nsIDOMWebGLRenderingContext.idl
@@ -39,59 +39,16 @@ class Element;
 
 [ptr] native WebGLJSObjectPtr (JSObject);
 [ptr] native Element (mozilla::dom::Element);
 
 //
 // OpenGL object wrappers
 //
 
-[scriptable, builtinclass, uuid(0df9f4ed-f5ff-4e51-a6ff-2bd9785a7639)]
-interface nsIWebGLTexture : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
-[scriptable, builtinclass, uuid(9eca9c32-8305-11de-b89b-000c29206271)]
-interface nsIWebGLBuffer : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
-[scriptable, builtinclass, uuid(a6a19e74-8305-11de-9ce9-000c29206271)]
-interface nsIWebGLProgram : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
-[scriptable, builtinclass, uuid(ac7440a4-8305-11de-807b-000c29206271)]
-interface nsIWebGLShader : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
-[scriptable, builtinclass, uuid(beea4b38-3094-4e8d-b6e6-8b21d07e8994)]
-interface nsIWebGLShaderArray : nsISupports
-{
-    readonly attribute unsigned long length;
-    nsIWebGLShader item(in unsigned long index);
-};
-
-[scriptable, builtinclass, uuid(bce8be60-8305-11de-9f3c-000c29206271)]
-interface nsIWebGLFramebuffer : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
-[scriptable, builtinclass, uuid(c82eacd0-8305-11de-9de9-000c29206271)]
-interface nsIWebGLRenderbuffer : nsISupports
-{
-  [noscript] attribute WebGLuint name;
-};
-
 [scriptable, builtinclass, uuid(a85d4fd0-5b9f-4cb8-aeee-5a2c5c5bad76)]
 interface nsIWebGLActiveInfo : nsISupports
 {
     readonly attribute WebGLint size;
     readonly attribute WebGLenum type;
     readonly attribute DOMString name;
 };
 
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -44,27 +44,33 @@ typedef float          GLclampf;
     boolean alpha = true;
     boolean depth = true;
     boolean stencil = false;
     boolean antialias = true;
     boolean premultipliedAlpha = true;
     boolean preserveDrawingBuffer = false;
     };*/
 
-interface WebGLBuffer;
+interface WebGLBuffer {
+};
 
-interface WebGLFramebuffer;
+interface WebGLFramebuffer {
+};
 
-interface WebGLProgram;
+interface WebGLProgram {
+};
 
-interface WebGLRenderbuffer;
+interface WebGLRenderbuffer {
+};
 
-interface WebGLShader;
+interface WebGLShader {
+};
 
-interface WebGLTexture;
+interface WebGLTexture {
+};
 
 interface WebGLUniformLocation {
 };
 
 interface WebGLActiveInfo;
 
 interface WebGLShaderPrecisionFormat {
     readonly attribute GLint rangeMin;
@@ -494,16 +500,17 @@ interface WebGLRenderingContext {
     readonly attribute GLsizei drawingBufferWidth;
     readonly attribute GLsizei drawingBufferHeight;
 
     [WebGLHandlesContextLoss, Throws] WebGLContextAttributes getContextAttributes();
     [WebGLHandlesContextLoss] boolean isContextLost();
 
     sequence<DOMString>? getSupportedExtensions();
 
+    [Throws]
     object? getExtension(DOMString name);
 
     void activeTexture(GLenum texture);
     void attachShader(WebGLProgram? program, WebGLShader? shader);
     void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
     void bindBuffer(GLenum target, WebGLBuffer? buffer);
     void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
     void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -456,23 +456,16 @@ irregularFilenames = {
     # stowaways
     'nsIDOMTextMetrics': 'nsIDOMCanvasRenderingContext2D',
     'nsIDOMCanvasGradient': 'nsIDOMCanvasRenderingContext2D',
     'nsIDOMCanvasPattern': 'nsIDOMCanvasRenderingContext2D',
     'nsIDOMImageData': 'nsIDOMCanvasRenderingContext2D',
 
     'nsIDOMBlob': 'nsIDOMFile',
 
-    'nsIWebGLTexture': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLBuffer': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLProgram': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLShader': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLShaderArray': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLFramebuffer': 'nsIDOMWebGLRenderingContext',
-    'nsIWebGLRenderbuffer': 'nsIDOMWebGLRenderingContext',
     'nsIWebGLActiveInfo': 'nsIDOMWebGLRenderingContext',
 
     'nsIIndexedDatabaseUsageCallback': 'nsIIndexedDatabaseManager',
 
     'nsIDOMTouch': 'nsIDOMTouchEvent',
     'nsIDOMTouchList': 'nsIDOMTouchEvent',
 
     'nsIDOMMutationRecord': 'nsIDOMMutationObserver',