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;
}
void
XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal,
                                 nsISupports* aNative)
{
    // We allow for calling this more than once. This feature is used by
    // nsXPConnect::InitClassesWithNewWrappedGlobal.

    mGlobalJSObject = aGlobal;
    mScriptObjectPrincipal = nsnull;

    // Try to find the native global object. If we didn't receive it explicitly,
    // we might be able to find it in the private slot.
    nsISupports* native = aNative;
    if (!native &&
        !(~js::GetObjectJSClass(aGlobal)->flags & (JSCLASS_HAS_PRIVATE |
                                                   JSCLASS_PRIVATE_IS_NSISUPPORTS)))
    {
        // Get the private. It might be a WN, in which case we dig deeper.
        native = (nsISupports*)xpc_GetJSPrivate(aGlobal);
        nsCOMPtr<nsIXPConnectWrappedNative> wn = do_QueryInterface(native);
        if (wn)
            native = static_cast<XPCWrappedNative*>(native)->GetIdentityObject();
    }

    // Now init our script object principal, if the new global has one.
    nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(native);
    mScriptObjectPrincipal = sop;

    // Lookup 'globalObject.Object.prototype' for our wrapper's proto
    JSObject *objectPrototype =
        JS_GetObjectPrototype(ccx.GetJSContext(), aGlobal);
    if (objectPrototype)
        mPrototypeJSObject = objectPrototype;
    else
        NS_ERROR("Can't get globalObject.Object.prototype");

    // Clear the no helper wrapper prototype object so that a new one
    // gets created if needed.
    mPrototypeNoHelper = nsnull;
}