static JSObject*
CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
                               JSObject* parentProto, JSClass* protoClass,
                               JSFunctionSpec* methods,
                               JSPropertySpec* properties,
                               ConstantSpec* constants)
{
  JSObject* ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto,
                                                  global);
  if (!ourProto) {
    return NULL;
  }

  if (methods && !JS_DefineFunctions(cx, ourProto, methods)) {
    return NULL;
  }

  if (properties && !JS_DefineProperties(cx, ourProto, properties)) {
    return NULL;
  }

  if (constants && !DefineConstants(cx, ourProto, constants)) {
    return NULL;
  }

  return ourProto;
}
JSBool
XPCWrappedNativeProto::Init(XPCCallContext& ccx,
                            const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
                            bool callPostCreatePrototype)
{
    nsIXPCScriptable *callback = scriptableCreateInfo ?
                                 scriptableCreateInfo->GetCallback() :
                                 nullptr;
    if (callback) {
        mScriptableInfo =
            XPCNativeScriptableInfo::Construct(ccx, scriptableCreateInfo);
        if (!mScriptableInfo)
            return false;
    }

    js::Class* jsclazz;

    if (mScriptableInfo) {
        const XPCNativeScriptableFlags& flags(mScriptableInfo->GetFlags());

        if (flags.AllowPropModsToPrototype()) {
            jsclazz = flags.WantCall() ?
                &XPC_WN_ModsAllowed_WithCall_Proto_JSClass :
                &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
        } else {
            jsclazz = flags.WantCall() ?
                &XPC_WN_NoMods_WithCall_Proto_JSClass :
                &XPC_WN_NoMods_NoCall_Proto_JSClass;
        }
    } else {
        jsclazz = &XPC_WN_NoMods_NoCall_Proto_JSClass;
    }

    JS::RootedObject parent(ccx, mScope->GetGlobalJSObject());
    JS::RootedObject proto(ccx, JS_GetObjectPrototype(ccx, parent));
    mJSProtoObject = JS_NewObjectWithUniqueType(ccx, js::Jsvalify(jsclazz),
                                                proto, parent);

    bool success = !!mJSProtoObject;
    if (success) {
        JS_SetPrivate(mJSProtoObject, this);
        if (callPostCreatePrototype)
            success = CallPostCreatePrototype(ccx);
    }

    DEBUG_ReportShadowedMembers(mSet, nullptr, this);

    return success;
}