bad2:
JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,             JSClass *clasp, JSNative constructor, uintN nargs,             JSPropertySpec *ps, JSFunctionSpec *fs,             JSPropertySpec *static_ps, JSFunctionSpec *static_fs){    JSAtom *atom;    JSObject *proto, *ctor;    jsval cval, rval;    JSBool named;    JSFunction *fun;    CHECK_REQUEST(cx);    atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);    if (!atom)        return NULL;    /* Create a prototype object for this class. */    proto = js_NewObject(cx, clasp, parent_proto, obj);    if (!proto)        return NULL;    if (!constructor) {        /* Lacking a constructor, name the prototype (e.g., Math). */        named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),                                    OBJECT_TO_JSVAL(proto),                                    NULL, NULL, 0, NULL);        if (!named)            goto bad;        ctor = proto;    } else {        /* Define the constructor function in obj's scope. */        fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);        named = (fun != NULL);        if (!fun)            goto bad;        /*         * Remember the class this function is a constructor for so that         * we know to create an object of this class when we call the         * constructor.         */        fun->clasp = clasp;        /*         * Optionally construct the prototype object, before the class has         * been fully initialized.  Allow the ctor to replace proto with a         * different object, as is done for operator new -- and as at least         * XML support requires.         */        ctor = fun->object;        if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {            cval = OBJECT_TO_JSVAL(ctor);            if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))                goto bad;            if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto)                proto = JSVAL_TO_OBJECT(rval);        }        /* Connect constructor and prototype by named properties. */        if (!js_SetClassPrototype(cx, ctor, proto,                                  JSPROP_READONLY | JSPROP_PERMANENT)) {            goto bad;        }        /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */        if (OBJ_GET_CLASS(cx, ctor) == clasp) {            /* XXXMLM - this fails in framesets that are writing over             *           themselves!             * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor));             */            OBJ_SET_PROTO(cx, ctor, proto);        }    }    /* Add properties and methods to the prototype and the constructor. */    if ((ps && !JS_DefineProperties(cx, proto, ps)) ||        (fs && !JS_DefineFunctions(cx, proto, fs)) ||        (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) ||        (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) {        goto bad;    }    return proto;bad:    if (named)        (void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval);    cx->newborn[GCX_OBJECT] = NULL;    return NULL;}