1
0
forked from mirrors/0ad

Split ScriptRequest in its own header.

We often only need to include ScriptRequest.h and not the full
ScriptInterface.h

Differential Revision: https://code.wildfiregames.com/D3920
This was SVN commit r25366.
This commit is contained in:
wraitii
2021-05-03 16:07:26 +00:00
parent 0406c4dfde
commit 34b1920e7b
20 changed files with 127 additions and 62 deletions
+12 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -36,6 +36,17 @@
#include "js/TypeDecls.h"
// Complete with a few additional ones.
namespace JS
{
class HandleValueArray;
}
namespace js {
class BaseProxyHandler;
}
class ScriptContext;
class ScriptInterface;
class ScriptRequest;
+9 -6
View File
@@ -71,11 +71,18 @@ struct ScriptInterface_impl
JS::PersistentRootedObject m_nativeScope; // native function scope object
};
/**
* Constructor for ScriptRequest - here because it needs access into ScriptInterface_impl.
*/
ScriptRequest::ScriptRequest(const ScriptInterface& scriptInterface) :
cx(scriptInterface.m->m_cx), nativeScope(scriptInterface.m->m_nativeScope)
cx(scriptInterface.m->m_cx), glob(scriptInterface.m->m_glob), nativeScope(scriptInterface.m->m_nativeScope)
{
m_formerRealm = JS::EnterRealm(cx, scriptInterface.m->m_glob);
glob = JS::CurrentGlobalOrNull(cx);
}
ScriptRequest::~ScriptRequest()
{
JS::LeaveRealm(cx, m_formerRealm);
}
JS::Value ScriptRequest::globalValue() const
@@ -83,10 +90,6 @@ JS::Value ScriptRequest::globalValue() const
return JS::ObjectValue(*glob);
}
ScriptRequest::~ScriptRequest()
{
JS::LeaveRealm(cx, m_formerRealm);
}
namespace
{
+1 -28
View File
@@ -22,6 +22,7 @@
#include "maths/Fixed.h"
#include "ps/Errors.h"
#include "scriptinterface/ScriptExceptions.h"
#include "scriptinterface/ScriptRequest.h"
#include "scriptinterface/ScriptTypes.h"
#include <map>
@@ -59,34 +60,6 @@ extern thread_local shared_ptr<ScriptContext> g_ScriptContext;
namespace boost { namespace random { class rand48; } }
/**
* RAII structure which encapsulates an access to the context and compartment of a ScriptInterface.
* This struct provides:
* - a pointer to the context, while acting like JSAutoRequest
* - a pointer to the global object of the compartment, while acting like JSAutoRealm
*
* This way, getting and using those pointers is safe with respect to the GC
* and to the separation of compartments.
*/
class ScriptRequest
{
public:
ScriptRequest() = delete;
ScriptRequest(const ScriptRequest& rq) = delete;
ScriptRequest& operator=(const ScriptRequest& rq) = delete;
ScriptRequest(const ScriptInterface& scriptInterface);
ScriptRequest(const ScriptInterface* scriptInterface) : ScriptRequest(*scriptInterface) {}
ScriptRequest(shared_ptr<ScriptInterface> scriptInterface) : ScriptRequest(*scriptInterface) {}
~ScriptRequest();
JS::Value globalValue() const;
JSContext* cx;
JSObject* glob;
JS::HandleObject nativeScope;
private:
JS::Realm* m_formerRealm;
};
/**
* Abstraction around a SpiderMonkey JS::Realm.
*
+83
View File
@@ -0,0 +1,83 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SCRIPTREQUEST
#define INCLUDED_SCRIPTREQUEST
#include "scriptinterface/ScriptForward.h"
// Ignore warnings in SM headers.
#if GCC_VERSION || CLANG_VERSION
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#elif MSC_VERSION
# pragma warning(push, 1)
#endif
#include "js/RootingAPI.h"
#if GCC_VERSION || CLANG_VERSION
# pragma GCC diagnostic pop
#elif MSC_VERSION
# pragma warning(pop)
#endif
#include <memory>
class ScriptInterface;
/**
* Spidermonkey maintains some 'local' state via the JSContext* object.
* This object is an argument to most JSAPI functions.
* Furthermore, this state is Realm (~ global) dependent. For many reasons, including GC safety,
* The JSContext* Realm must be set up correctly when accessing it.
* 'Entering' and 'Leaving' realms must be done in a LIFO manner.
* SM recommends using JSAutoRealm, which provides an RAII option.
*
* ScriptRequest combines both of the above in a single convenient package,
* providing safe access to the JSContext*, the global object, and ensuring that the proper realm has been entered.
* Most scriptinterface/ functions will take a ScriptRequest, to ensure proper rooting. You may sometimes
* have to create one from a ScriptInterface.
*
* Be particularly careful when manipulating several script interfaces.
*/
class ScriptRequest
{
ScriptRequest() = delete;
ScriptRequest(const ScriptRequest& rq) = delete;
ScriptRequest& operator=(const ScriptRequest& rq) = delete;
public:
/**
* NB: the definitions are in scriptinterface.cpp, because these access members of the PImpled
* implementation of ScriptInterface, and that seemed more convenient.
*/
ScriptRequest(const ScriptInterface& scriptInterface);
ScriptRequest(const ScriptInterface* scriptInterface) : ScriptRequest(*scriptInterface) {}
ScriptRequest(std::shared_ptr<ScriptInterface> scriptInterface) : ScriptRequest(*scriptInterface) {}
~ScriptRequest();
JS::Value globalValue() const;
JSContext* cx;
JS::HandleObject glob;
JS::HandleObject nativeScope;
private:
JS::Realm* m_formerRealm;
};
#endif // INCLUDED_SCRIPTREQUEST