Bug 585199 - Implement WebGLActiveInfo, remove NativeJSContext, adapt WebGL code to that - r=vladimir a=blocking2.0
authorBenoit Jacob <bjacob@mozilla.com>
Mon, 23 Aug 2010 17:03:49 -0400
changeset 51421 33a6231b3e80f74cd92963f363d2ad76dc3d15f2
parent 51420 6774a67212e0c1c0abbda00688bab76f56d293fe
child 51422 13f3a8d7af4f9c833df055ba628accd955fb26c8
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladimir, blocking2
bugs585199
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 585199 - Implement WebGLActiveInfo, remove NativeJSContext, adapt WebGL code to that - r=vladimir a=blocking2.0
configure.in
content/canvas/src/Makefile.in
content/canvas/src/NativeJSContext.cpp
content/canvas/src/NativeJSContext.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/canvas/nsICanvasRenderingContextWebGL.idl
--- a/configure.in
+++ b/configure.in
@@ -5212,17 +5212,17 @@ cairo-cocoa)
     LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL'
     MOZ_FS_LAYOUT=bundle
     MOZ_WEBGL=1
     ;;
 
 cairo-android)
     AC_DEFINE(MOZ_WIDGET_ANDROID)
     MOZ_WIDGET_TOOLKIT=android
-    MOZ_WEBGL=
+    MOZ_WEBGL=1
     ;;
 
 esac
 
 if test "$MOZ_ENABLE_XREMOTE"; then
     AC_DEFINE(MOZ_ENABLE_XREMOTE)
 fi
 
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -71,17 +71,16 @@ endif
 
 ifdef MOZ_WEBGL
 
 CPPSRCS += \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextValidate.cpp \
-	NativeJSContext.cpp \
 	$(NULL)
 
 # We can't build ANGLE on linux-64 until build bug 560894 and related
 # are fixed.
 ifneq ($(OS_ARCH)_$(OS_TEST),Linux_x86_64)
 DEFINES += -DUSE_ANGLE
 endif
 
deleted file mode 100644
--- a/content/canvas/src/NativeJSContext.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "NativeJSContext.h"
-#include "nsServiceManagerUtils.h"
-#include "nsIJSRuntimeService.h"
-
-PRBool
-NativeJSContext::AddGCRoot(JSObject **aPtr, const char *aName)
-{
-  NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-
-  PRBool ok;
-  return ok = ::JS_AddNamedObjectRoot(ctx, aPtr, aName);
-}
-
-void
-NativeJSContext::ReleaseGCRoot(JSObject **aPtr)
-{
-  NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-  ::JS_RemoveObjectRoot(ctx, aPtr);
-}
deleted file mode 100644
--- a/content/canvas/src/NativeJSContext.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-#ifndef _NATIVEJSCONTEXT_H_
-#define _NATIVEJSCONTEXT_H_
-
-#include "nsDOMError.h"
-
-#include "nsIXPConnect.h"
-#include "nsContentUtils.h"
-
-#include "nsTArray.h"
-#include "nsAutoPtr.h"
-#include "jsapi.h"
-
-class JSObjectHelper;
-class nsIJSRuntimeService;
-
-class NativeJSContext {
-public:
-    NativeJSContext() {
-        error = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
-        if (NS_FAILED(error))
-            return;
-
-        if (!ncc) {
-            error = NS_ERROR_FAILURE;
-            return;
-        }
-
-        ctx = nsnull;
-
-        error = ncc->GetJSContext(&ctx);
-        if (NS_FAILED(error))
-            return;
-
-        JS_BeginRequest(ctx);
-
-        ncc->GetArgc(&argc);
-        ncc->GetArgvPtr(&argv);
-    }
-
-    ~NativeJSContext() {
-        if (NS_SUCCEEDED(error))
-            JS_EndRequest(ctx);
-    }
-
-    PRBool CheckArray (JSObject *obj, jsuint *sz) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        if (obj &&
-            ::JS_IsArrayObject(ctx, obj) &&
-            ::JS_GetArrayLength(ctx, obj, sz))
-            return PR_TRUE;
-        return PR_FALSE;
-    }
-
-    PRBool CheckArray (jsval val, jsuint *sz) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        if (!JSVAL_IS_NULL(val) &&
-            JSVAL_IS_OBJECT(val) &&
-            ::JS_IsArrayObject(ctx, JSVAL_TO_OBJECT(val)) &&
-            ::JS_GetArrayLength(ctx, JSVAL_TO_OBJECT(val), sz))
-            return PR_TRUE;
-        return PR_FALSE;
-    }
-
-    PRBool AddGCRoot (JSObject **aPtr, const char *aName);
-    void ReleaseGCRoot (JSObject **aPtr);
-
-    void SetRetVal (PRInt32 val) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        SetRetValAsJSVal(INT_TO_JSVAL(val));
-    }
-
-    void SetRetVal (PRUint32 val) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        SetRetValAsJSVal(UINT_TO_JSVAL(val));
-    }
-
-    void SetRetVal (double val) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        SetRetValAsJSVal(DOUBLE_TO_JSVAL(val));
-    }
-
-    void SetBoolRetVal (PRBool val) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        SetRetValAsJSVal(BOOLEAN_TO_JSVAL(val));
-    }
-
-    void SetRetVal (PRInt32 *vp, PRUint32 len) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-
-        if (!JS_EnterLocalRootScope(ctx))
-            return; // XXX ???
-
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = INT_TO_JSVAL(vp[i]);
-
-        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
-        SetRetVal(jsarr);
-
-        JS_LeaveLocalRootScope(ctx);
-    }
-
-    void SetRetVal (PRUint32 *vp, PRUint32 len) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-
-        if (!JS_EnterLocalRootScope(ctx))
-            return; // XXX ???
-
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = UINT_TO_JSVAL(vp[i]);
-
-        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
-        SetRetVal(jsarr);
-
-        JS_LeaveLocalRootScope(ctx);
-    }
-
-    void SetRetVal (double *dp, PRUint32 len) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-
-        if (!JS_EnterLocalRootScope(ctx))
-            return; // XXX ???
-
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = DOUBLE_TO_JSVAL(dp[i]);
-
-        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
-        SetRetVal(jsarr);
-
-        JS_LeaveLocalRootScope(ctx);
-    }
-
-    void SetRetVal (float *fp, PRUint32 len) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-
-        if (!JS_EnterLocalRootScope(ctx))
-            return; // XXX ???
-
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = DOUBLE_TO_JSVAL(fp[i]);
-
-        JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
-        SetRetVal(jsarr);
-
-        JS_LeaveLocalRootScope(ctx);
-    }
-
-    void SetRetValAsJSVal (jsval val) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        jsval *vp;
-        ncc->GetRetValPtr(&vp);
-        *vp = val;
-        ncc->SetReturnValueWasSet(PR_TRUE);
-    }
-
-    void SetRetVal (JSObject *obj) {
-        NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
-        SetRetValAsJSVal(OBJECT_TO_JSVAL(obj));
-    }
-
-    void SetRetVal (JSObjectHelper& objh);
-
-    nsAXPCNativeCallContext *ncc;
-    nsresult error;
-    JSContext *ctx;
-    PRUint32 argc;
-    jsval *argv;
-
-public:
-    // static JS helpers
-
-    static inline PRBool JSValToFloatArray (JSContext *ctx, jsval val,
-                                            jsuint cnt, float *array)
-    {
-        JSObject *arrayObj;
-        jsuint arrayLen;
-        jsval jv;
-        jsdouble dv;
-
-        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
-            arrayObj == NULL ||
-            !::JS_IsArrayObject(ctx, arrayObj) ||
-            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
-            (arrayLen < cnt))
-            return PR_FALSE;
-
-        for (jsuint i = 0; i < cnt; i++) {
-            ::JS_GetElement(ctx, arrayObj, i, &jv);
-            if (!::JS_ValueToNumber(ctx, jv, &dv))
-                return PR_FALSE;
-            array[i] = (float) dv;
-        }
-
-        return PR_TRUE;
-    }
-
-    static inline PRBool JSValToDoubleArray (JSContext *ctx, jsval val,
-                                             jsuint cnt, double *array)
-    {
-        JSObject *arrayObj;
-        jsuint arrayLen;
-        jsval jv;
-        jsdouble dv;
-
-        if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
-            arrayObj == NULL ||
-            !::JS_IsArrayObject(ctx, arrayObj) ||
-            !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
-            (arrayLen < cnt))
-            return PR_FALSE;
-
-        for (jsuint i = 0; i < cnt; i++) {
-            ::JS_GetElement(ctx, arrayObj, i, &jv);
-            if (!::JS_ValueToNumber(ctx, jv, &dv))
-                return PR_FALSE;
-            array[i] = dv;
-        }
-
-        return PR_TRUE;
-    }
-
-    static inline PRBool JSValToJSArrayAndLength (JSContext *ctx, jsval val,
-                                                  JSObject **outObj, jsuint *outLen)
-    {
-        JSObject *obj = nsnull;
-        jsuint len;
-        if (!::JS_ValueToObject(ctx, val, &obj) ||
-            obj == NULL ||
-            !::JS_IsArrayObject(ctx, obj) ||
-            !::JS_GetArrayLength(ctx, obj, &len))
-        {
-            return PR_FALSE;
-        }
-
-        *outObj = obj;
-        *outLen = len;
-
-        return PR_TRUE;
-    }
-
-    template<class T>
-    static nsresult JSValToSpecificInterface(JSContext *ctx, jsval val, T **out)
-    {
-        if (JSVAL_IS_NULL(val)) {
-            *out = nsnull;
-            return NS_OK;
-        }
-
-        if (!JSVAL_IS_OBJECT(val))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<nsISupports> isup;
-        nsresult rv = nsContentUtils::XPConnect()->WrapJS(ctx, JSVAL_TO_OBJECT(val),
-                                                          NS_GET_IID(nsISupports),
-                                                          getter_AddRefs(isup));
-        if (NS_FAILED(rv))
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        nsCOMPtr<T> obj = do_QueryInterface(isup);
-        if (!obj)
-            return NS_ERROR_DOM_SYNTAX_ERR;
-
-        NS_ADDREF(*out = obj.get());
-        return NS_OK;
-    }
-
-    static inline JSObject *ArrayToJSArray (JSContext *ctx,
-                                            const PRInt32 *vals,
-                                            const PRUint32 len)
-    {
-        // XXX handle ints that are too big to fit
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = INT_TO_JSVAL(vals[i]);
-        return JS_NewArrayObject(ctx, len, jsvector);
-    }
-
-    static inline JSObject *ArrayToJSArray (JSContext *ctx,
-                                            const PRUint32 *vals,
-                                            const PRUint32 len)
-    {
-        // XXX handle ints that are too big to fit
-        nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
-        for (PRUint32 i = 0; i < len; i++)
-            jsvector[i] = INT_TO_JSVAL(vals[i]);
-        return JS_NewArrayObject(ctx, len, jsvector);
-    }
-
-};
-
-class JSObjectHelper {
-    friend class NativeJSContext;
-public:
-    JSObjectHelper(NativeJSContext *jsctx)
-        : mCtx (jsctx)
-    {
-        mObject = JS_NewObject(mCtx->ctx, NULL, NULL, NULL);
-        if (!mObject)
-            return;
-
-        if (!mCtx->AddGCRoot(&mObject, "JSObjectHelperCanvas3D"))
-            mObject = nsnull;
-    }
-
-    ~JSObjectHelper() {
-        if (mObject && mCtx)
-            mCtx->ReleaseGCRoot(&mObject);
-    }
-
-    PRBool DefineProperty(const char *name, PRInt32 val) {
-        // XXX handle too big ints
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    PRBool DefineProperty(const char *name, PRUint32 val) {
-        // XXX handle too big ints
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL((int)val), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    PRBool DefineProperty(const char *name, double val) {
-        jsval dv = DOUBLE_TO_JSVAL(val);
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    PRBool DefineProperty(const char *name, JSObject *val) {
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, OBJECT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    // Blah.  We can't name this DefineProperty also because PRBool is the same as PRInt32
-    PRBool DefineBoolProperty(const char *name, PRBool val) {
-        if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JSVAL_TRUE : JSVAL_FALSE, NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    // We can't use ns*Substring, because we don't have internal linkage
-#if 0
-    PRBool DefineProperty(const char *name, const nsCSubstring& val) {
-        JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
-        if (!jsstr ||
-            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    PRBool DefineProperty(const char *name, const nsSubstring& val) {
-        JSString *jsstr = JS_NewUCStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
-        if (!jsstr ||
-            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-#endif
-
-    PRBool DefineProperty(const char *name, const char *val, PRUint32 len) {
-        JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val, len);
-        if (!jsstr ||
-            !JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
-            return PR_FALSE;
-        return PR_TRUE;
-    }
-
-    JSObject *Object() {
-        return mObject;
-    }
-
-protected:
-    NativeJSContext *mCtx;
-    JSObject *mObject;
-};
-
-inline void
-NativeJSContext::SetRetVal(JSObjectHelper& objh) {
-    SetRetValAsJSVal(OBJECT_TO_JSVAL(objh.mObject));
-}
-
-#endif
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -47,17 +47,16 @@
 #include "nsIXPConnect.h"
 #include "nsDOMError.h"
 
 #include "gfxContext.h"
 #include "gfxPattern.h"
 #include "gfxUtils.h"
 
 #include "CanvasUtils.h"
-#include "NativeJSContext.h"
 
 #include "GLContextProvider.h"
 
 #ifdef MOZ_SVG
 #include "nsSVGEffects.h"
 #endif
 
 #include "prenv.h"
@@ -647,16 +646,28 @@ DOMCI_DATA(WebGLUniformLocation, WebGLUn
 
 NS_INTERFACE_MAP_BEGIN(WebGLUniformLocation)
   NS_INTERFACE_MAP_ENTRY(WebGLUniformLocation)
   NS_INTERFACE_MAP_ENTRY(nsIWebGLUniformLocation)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLUniformLocation)
 NS_INTERFACE_MAP_END
 
+NS_IMPL_ADDREF(WebGLActiveInfo)
+NS_IMPL_RELEASE(WebGLActiveInfo)
+
+DOMCI_DATA(WebGLActiveInfo, WebGLActiveInfo)
+
+NS_INTERFACE_MAP_BEGIN(WebGLActiveInfo)
+  NS_INTERFACE_MAP_ENTRY(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)
@@ -669,8 +680,29 @@ NAME_NOT_SUPPORTED(WebGLRenderbuffer)
 NS_IMETHODIMP WebGLUniformLocation::GetLocation(WebGLint *aLocation)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 NS_IMETHODIMP WebGLUniformLocation::SetLocation(WebGLint aLocation)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
+
+/* readonly attribute WebGLint size; */
+NS_IMETHODIMP WebGLActiveInfo::GetSize(WebGLint *aSize)
+{
+    *aSize = mSize;
+    return NS_OK;
+}
+
+/* readonly attribute WebGLenum type; */
+NS_IMETHODIMP WebGLActiveInfo::GetType(WebGLenum *aType)
+{
+    *aType = mType;
+    return NS_OK;
+}
+
+/* readonly attribute DOMString name; */
+NS_IMETHODIMP WebGLActiveInfo::GetName(nsAString & aName)
+{
+    aName = mName;
+    return NS_OK;
+}
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -933,16 +933,52 @@ public:
 protected:
     WebGLObjectRefPtr<WebGLProgram> mProgram;
     PRUint32 mProgramGeneration;
     GLint mLocation;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WebGLUniformLocation, WEBGLUNIFORMLOCATION_PRIVATE_IID)
 
+#define WEBGLACTIVEINFO_PRIVATE_IID \
+    {0x90def5ec, 0xc672, 0x4ac3, {0xb8, 0x97, 0x04, 0xa2, 0x6d, 0xda, 0x66, 0xd7}}
+class WebGLActiveInfo :
+    public nsIWebGLActiveInfo
+{
+public:
+    NS_DECLARE_STATIC_IID_ACCESSOR(WEBGLACTIVEINFO_PRIVATE_IID)
+
+    WebGLActiveInfo(WebGLint size, WebGLenum type, const char *nameptr, PRUint32 namelength) :
+        mDeleted(PR_FALSE),
+        mSize(size),
+        mType(type)
+    {
+        mName.AssignASCII(nameptr, namelength);
+    }
+
+    void Delete() {
+        if (mDeleted)
+            return;
+        mDeleted = PR_TRUE;
+    }
+
+    PRBool Deleted() { return mDeleted; }
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIWEBGLACTIVEINFO
+protected:
+    PRBool mDeleted;
+    WebGLint mSize;
+    WebGLenum mType;
+    nsString mName;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(WebGLActiveInfo, WEBGLACTIVEINFO_PRIVATE_IID)
+
+
 /**
  ** Template implementations
  **/
 
 /* Helper function taking a BaseInterfaceType pointer and check that
  * it matches the required concrete implementation type (if it's
  * non-null), that it's not null/deleted unless we allowed it to, and
  * obtain a pointer to the concrete object.
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -47,17 +47,16 @@
 #include "gfxPlatform.h"
 //#include "nsIDOMHTMLCanvasElement.h"
 
 #include "nsContentUtils.h"
 #include "nsDOMError.h"
 #include "nsLayoutUtils.h"
 
 #include "CanvasUtils.h"
-#include "NativeJSContext.h"
 
 #include "jstypedarray.h"
 
 #if defined(USE_ANGLE)
 // shader translator
 #include "angle/ShaderLang.h"
 #endif
 
@@ -1106,20 +1105,16 @@ WebGLContext::FrontFace(WebGLenum mode)
 // returns an object: { size: ..., type: ..., name: ... }
 NS_IMETHODIMP
 WebGLContext::GetActiveAttrib(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLActiveInfo **retval)
 {
     WebGLuint progname;
     if (!GetGLName<WebGLProgram>("getActiveAttrib: program", pobj, &progname))
         return NS_OK;
 
-    NativeJSContext js;
-    if (NS_FAILED(js.error))
-        return js.error;
-
     MakeContextCurrent();
 
     GLint len = 0;
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &len);
     if (len == 0) {
         *retval = nsnull;
         return NS_OK;
     }
@@ -1129,22 +1124,19 @@ WebGLContext::GetActiveAttrib(nsIWebGLPr
     PRUint32 attrtype = 0;
 
     gl->fGetActiveAttrib(progname, index, len, &len, (GLint*) &attrsize, (WebGLuint*) &attrtype, name);
     if (attrsize == 0 || attrtype == 0) {
         *retval = nsnull;
         return NS_OK;
     }
 
-    JSObjectHelper retobj(&js);
-    retobj.DefineProperty("size", attrsize);
-    retobj.DefineProperty("type", attrtype);
-    retobj.DefineProperty("name", name, len);
-
-    js.SetRetVal(retobj);
+    WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(attrsize, attrtype, name.get(), len);
+
+    NS_ADDREF(*retval = retActiveInfo);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::GenerateMipmap(WebGLenum target)
 {
     if (!ValidateTextureTargetEnum(target, "generateMipmap"))
@@ -1164,20 +1156,16 @@ WebGLContext::GenerateMipmap(WebGLenum t
 
 NS_IMETHODIMP
 WebGLContext::GetActiveUniform(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLActiveInfo **retval)
 {
     WebGLuint progname;
     if (!GetGLName<WebGLProgram>("getActiveUniform: program", pobj, &progname))
         return NS_OK;
 
-    NativeJSContext js;
-    if (NS_FAILED(js.error))
-        return js.error;
-
     MakeContextCurrent();
 
     GLint len = 0;
     gl->fGetProgramiv(progname, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, &len);
     if (len == 0) {
         *retval = nsnull;
         return NS_OK;
     }
@@ -1207,22 +1195,19 @@ WebGLContext::GetActiveUniform(nsIWebGLP
     // specs that it seems probable that some ES implementers will overlook it. Since the work-around is quite cheap,
     // we do it unconditionally.
     if (attrsize > 1 && name[len-1] != ']') {
         name[len++] = '[';
         name[len++] = '0';
         name[len++] = ']';
     }
 
-    JSObjectHelper retobj(&js);
-    retobj.DefineProperty("size", attrsize);
-    retobj.DefineProperty("type", attrtype);
-    retobj.DefineProperty("name", name, len);
-
-    js.SetRetVal(retobj.Object());
+    WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(attrsize, attrtype, name.get(), len);
+
+    NS_ADDREF(*retval = retActiveInfo);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::GetAttachedShaders(nsIWebGLProgram *pobj, nsIVariant **retval)
 {
     WebGLProgram *prog;
@@ -2043,59 +2028,61 @@ WebGLContext::GetUniformLocation(nsIWebG
 
     nsRefPtr<nsIWebGLUniformLocation> loc = prog->GetUniformLocationObject(intlocation);
     *retval = loc.forget().get();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-WebGLContext::GetVertexAttrib(WebGLuint index, WebGLenum pname)
+WebGLContext::GetVertexAttrib(WebGLuint index, WebGLenum pname, nsIVariant **retval)
 {
-    NativeJSContext js;
-    if (NS_FAILED(js.error))
-        return js.error;
+    nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
+    NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
 
     MakeContextCurrent();
 
     switch (pname) {
         // int
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
         {
             PRInt32 i = 0;
             gl->fGetVertexAttribiv(index, pname, (GLint*) &i);
-            js.SetRetVal(i);
+            wrval->SetAsInt32(i);
         }
             break;
 
         case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
         {
             GLfloat fv[4] = { 0 };
             gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, fv);
-            js.SetRetVal(fv, 4);
+            wrval->SetAsArray(nsIDataType::VTYPE_FLOAT, nsnull,
+                              4, static_cast<void*>(fv));
         }
             break;
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED:
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
         {
             PRInt32 i = 0;
             gl->fGetVertexAttribiv(index, pname, (GLint*) &i);
-            js.SetBoolRetVal(PRBool(i));
+            wrval->SetAsBool(PRBool(i));
         }
             break;
 
         // not supported; doesn't make sense to return a pointer unless we have some kind of buffer object abstraction
         case LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER:
         default:
             return ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname);
     }
 
+    *retval = wrval.forget().get();
+
     return NS_OK;
 }
 
 /* GLuint getVertexAttribOffset (in GLuint index, in GLenum pname); */
 NS_IMETHODIMP
 WebGLContext::GetVertexAttribOffset(WebGLuint index, WebGLenum pname, WebGLuint *retval)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1411,16 +1411,18 @@ static nsDOMClassInfoData sClassInfoData
   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(WebGLUniformLocation, 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, nsPaintRequestListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ScrollAreaEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -3989,16 +3991,20 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(WebGLRenderbuffer, nsIWebGLRenderbuffer)
      DOM_CLASSINFO_MAP_ENTRY(nsIWebGLRenderbuffer)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(WebGLUniformLocation, nsIWebGLUniformLocation)
     DOM_CLASSINFO_MAP_ENTRY(nsIWebGLUniformLocation)
   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
  
   DOM_CLASSINFO_MAP_BEGIN(PaintRequestList, nsIDOMPaintRequestList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPaintRequestList)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -462,16 +462,17 @@ DOMCI_CLASS(ChromeWorker)
 DOMCI_CLASS(CanvasRenderingContextWebGL)
 DOMCI_CLASS(WebGLBuffer)
 DOMCI_CLASS(WebGLTexture)
 DOMCI_CLASS(WebGLProgram)
 DOMCI_CLASS(WebGLShader)
 DOMCI_CLASS(WebGLFramebuffer)
 DOMCI_CLASS(WebGLRenderbuffer)
 DOMCI_CLASS(WebGLUniformLocation)
+DOMCI_CLASS(WebGLActiveInfo)
 
 // WebGL Buffers
 DOMCI_CLASS(PaintRequest)
 DOMCI_CLASS(PaintRequestList)
 
 DOMCI_CLASS(ScrollAreaEvent)
 DOMCI_CLASS(PopStateEvent)
 
--- a/dom/interfaces/canvas/nsICanvasRenderingContextWebGL.idl
+++ b/dom/interfaces/canvas/nsICanvasRenderingContextWebGL.idl
@@ -694,17 +694,17 @@ interface nsICanvasRenderingContextWebGL
   DOMString getShaderSource(in nsIWebGLShader shader);
 
   nsIVariant getTexParameter(in WebGLenum target, in WebGLenum pname);
 
   nsIVariant getUniform(in nsIWebGLProgram program, in nsIWebGLUniformLocation location);
 
   nsIWebGLUniformLocation getUniformLocation (in nsIWebGLProgram program, in DOMString name);
 
-  void getVertexAttrib(in WebGLuint index, in WebGLenum pname);
+  nsIVariant getVertexAttrib(in WebGLuint index, in WebGLenum pname);
 
   // TBD
   // void glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, void** pointer);
   WebGLuint getVertexAttribOffset(in WebGLuint index, in WebGLenum pname);
 
   void hint(in WebGLenum target, in WebGLenum mode);
 
   WebGLboolean isBuffer(in nsIWebGLBuffer buffer);