Ticket #5636: TryPersistentRooted.patch

File TryPersistentRooted.patch, 7.5 KB (added by elexis, 4 years ago)

This patch demonstrates that the same bug is also triggered when using PersistentRootedValue instead of JS::HeapValue

  • source/lobby/IXmppClient.h

    public:  
    5353    virtual void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5454    virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5555    virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5656    virtual void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5757
    58     virtual JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface) = 0;
     58    virtual void GuiPollNewMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue value) = 0;
    5959    virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0;
    6060    virtual bool GuiPollHasPlayerListUpdate() = 0;
    6161
    6262    virtual void SendMUCMessage(const std::string& message) = 0;
    6363    virtual void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID) = 0;
  • source/lobby/XmppClient.cpp

    XmppClient::XmppClient(const ScriptInter  
    9191      m_isConnected(false),
    9292      m_sessionManager(nullptr),
    9393      m_certStatus(gloox::CertStatus::CertOk),
    9494      m_PlayerMapUpdate(false)
    9595{
    96     if (m_ScriptInterface)
    97         JS_AddExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), XmppClient::Trace, this);
    98 
    9996    // Read lobby configuration from default.cfg
    10097    std::string sXpartamupp;
    10198    std::string sEchelon;
    10299    CFG_GET_VAL("lobby.server", m_server);
    103100    CFG_GET_VAL("lobby.xpartamupp", sXpartamupp);
    XmppClient::~XmppClient()  
    188185        glooxwrapper::Tag::free(t);
    189186    for (const glooxwrapper::Tag* const& t : m_BoardList)
    190187        glooxwrapper::Tag::free(t);
    191188    for (const glooxwrapper::Tag* const& t : m_Profile)
    192189        glooxwrapper::Tag::free(t);
    193 
    194     if (m_ScriptInterface)
    195         JS_RemoveExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), XmppClient::Trace, this);
    196 }
    197 
    198 void XmppClient::TraceMember(JSTracer* trc)
    199 {
    200     for (JS::Heap<JS::Value>& guiMessage : m_GuiMessageQueue)
    201         JS_CallValueTracer(trc, &guiMessage, "m_GuiMessageQueue");
    202 
    203     for (JS::Heap<JS::Value>& guiMessage : m_HistoricGuiMessages)
    204         JS_CallValueTracer(trc, &guiMessage, "m_HistoricGuiMessages");
    205190}
    206191
    207192/// Network
    208193void XmppClient::connect()
    209194{
    void XmppClient::CreateGUIMessage(  
    680665        "time", static_cast<double>(time));
    681666
    682667    JS::RootedObject messageObj(cx, message.toObjectOrNull());
    683668    SetGUIMessageProperty(cx, messageObj, args...);
    684669    m_ScriptInterface->FreezeObject(message, true);
    685     m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
     670    m_GuiMessageQueue.push_back(JS::PersistentRootedValue(cx, message));
    686671}
    687672
    688673bool XmppClient::GuiPollHasPlayerListUpdate()
    689674{
    690675    bool hasUpdate = m_PlayerMapUpdate;
    691676    m_PlayerMapUpdate = false;
    692677    return hasUpdate;
    693678}
    694679
    695 JS::Value XmppClient::GuiPollNewMessage(const ScriptInterface& scriptInterface)
     680void XmppClient::GuiPollNewMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue value)
    696681{
    697682    if (m_GuiMessageQueue.empty())
    698         return JS::UndefinedValue();
     683    {
     684        value.setUndefined();
     685        return;
     686    }
    699687
    700688    JSContext* cx = scriptInterface.GetContext();
    701689    JSAutoRequest rq(cx);
    702690
    703691    JS::RootedValue message(cx, m_GuiMessageQueue.front());
    JS::Value XmppClient::GuiPollNewMessage(  
    706694    JS::RootedValue messageCopy(cx);
    707695    if (JS_StructuredClone(cx, message, &messageCopy, nullptr, nullptr))
    708696    {
    709697        scriptInterface.SetProperty(messageCopy, "historic", true);
    710698        scriptInterface.FreezeObject(messageCopy, true);
    711         m_HistoricGuiMessages.push_back(JS::Heap<JS::Value>(messageCopy));
     699        m_HistoricGuiMessages.push_back(JS::PersistentRootedValue(cx, messageCopy));
    712700    }
    713701    else
    714702        LOGERROR("Could not clone historic lobby GUI message!");
    715703
    716     return message;
     704    value.set(message);
    717705}
    718706
    719707JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface)
    720708{
    721709    JSContext* cx = scriptInterface.GetContext();
    JS::Value XmppClient::GuiPollHistoricMes  
    723711
    724712    JS::RootedValue ret(cx);
    725713    ScriptInterface::CreateArray(cx, &ret);
    726714
    727715    int j = 0;
    728     for (const JS::Heap<JS::Value>& message : m_HistoricGuiMessages)
    729         scriptInterface.SetPropertyInt(ret, j++, message);
     716    for (const JS::PersistentRootedValue& message : m_HistoricGuiMessages)
     717    {
     718        JS::RootedValue messageVal(cx, message);
     719        scriptInterface.SetPropertyInt(ret, j++, messageVal);
     720    }
    730721
    731722    return ret;
    732723}
    733724
    734725/**
  • source/lobby/XmppClient.h

    private:  
    6161public:
    6262    // Basic
    6363    XmppClient(const ScriptInterface* scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, const int historyRequestSize = 0, const bool regOpt = false);
    6464    virtual ~XmppClient();
    6565
    66     // JS::Heap is better for GC performance than JS::PersistentRooted
    67     static void Trace(JSTracer *trc, void *data)
    68     {
    69         static_cast<XmppClient*>(data)->TraceMember(trc);
    70     }
    71 
    72     void TraceMember(JSTracer *trc);
    73 
    7466    // Network
    7567    void connect();
    7668    void disconnect();
    7769    bool isConnected();
    7870    void recv();
    protected:  
    148140    /* Session Handler */
    149141    virtual void handleSessionAction(gloox::Jingle::Action action, glooxwrapper::Jingle::Session& session, const glooxwrapper::Jingle::Session::Jingle& jingle);
    150142    virtual void handleSessionInitiation(glooxwrapper::Jingle::Session& session, const glooxwrapper::Jingle::Session::Jingle& jingle);
    151143
    152144public:
    153     JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface);
     145    void GuiPollNewMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue value);
    154146    JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface);
    155147    bool GuiPollHasPlayerListUpdate();
    156148    void SendMUCMessage(const std::string& message);
    157149
    158150protected:
    private:  
    186178    /// Profile data
    187179    std::vector<const glooxwrapper::Tag*> m_Profile;
    188180    /// ScriptInterface to root the values
    189181    const ScriptInterface* m_ScriptInterface;
    190182    /// Queue of messages for the GUI
    191     std::deque<JS::Heap<JS::Value> > m_GuiMessageQueue;
     183    std::deque<JS::PersistentRootedValue > m_GuiMessageQueue;
    192184    /// Cache of all GUI messages received since the login
    193     std::vector<JS::Heap<JS::Value> > m_HistoricGuiMessages;
     185    std::vector<JS::PersistentRootedValue > m_HistoricGuiMessages;
    194186    /// Current room subject/topic.
    195187    std::wstring m_Subject;
    196188};
    197189
    198190#endif // XMPPCLIENT_H
  • source/lobby/scripting/JSInterface_Lobby.cpp

    bool JSI_Lobby::LobbyGuiPollHasPlayerLis  
    246246JS::Value JSI_Lobby::LobbyGuiPollNewMessage(ScriptInterface::CxPrivate* pCxPrivate)
    247247{
    248248    if (!g_XmppClient)
    249249        return JS::UndefinedValue();
    250250
    251     return g_XmppClient->GuiPollNewMessage(*(pCxPrivate->pScriptInterface));
     251    JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
     252    JSAutoRequest rq(cx);
     253
     254    JS::RootedValue message(cx);
     255    g_XmppClient->GuiPollNewMessage(*(pCxPrivate->pScriptInterface), &message);
     256
     257    return message;
    252258}
    253259
    254260JS::Value JSI_Lobby::LobbyGuiPollHistoricMessages(ScriptInterface::CxPrivate* pCxPrivate)
    255261{
    256262    if (!g_XmppClient)