Pyrogenesis  trunk
ScriptRequest.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_SCRIPTREQUEST
19 #define INCLUDED_SCRIPTREQUEST
20 
22 
23 // Ignore warnings in SM headers.
24 #if GCC_VERSION || CLANG_VERSION
25 # pragma GCC diagnostic push
26 # pragma GCC diagnostic ignored "-Wunused-parameter"
27 # pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
28 #elif MSC_VERSION
29 # pragma warning(push, 1)
30 #endif
31 
32 #include "js/RootingAPI.h"
33 
34 #if GCC_VERSION || CLANG_VERSION
35 # pragma GCC diagnostic pop
36 #elif MSC_VERSION
37 # pragma warning(pop)
38 #endif
39 
40 #include <memory>
41 
42 class ScriptInterface;
43 
44 /**
45  * Spidermonkey maintains some 'local' state via the JSContext* object.
46  * This object is an argument to most JSAPI functions.
47  * Furthermore, this state is Realm (~ global) dependent. For many reasons, including GC safety,
48  * The JSContext* Realm must be set up correctly when accessing it.
49  * 'Entering' and 'Leaving' realms must be done in a LIFO manner.
50  * SM recommends using JSAutoRealm, which provides an RAII option.
51  *
52  * ScriptRequest combines both of the above in a single convenient package,
53  * providing safe access to the JSContext*, the global object, and ensuring that the proper realm has been entered.
54  * Most scriptinterface/ functions will take a ScriptRequest, to ensure proper rooting. You may sometimes
55  * have to create one from a ScriptInterface.
56  *
57  * Be particularly careful when manipulating several script interfaces.
58  */
60 {
61  ScriptRequest() = delete;
62  ScriptRequest(const ScriptRequest& rq) = delete;
63  ScriptRequest& operator=(const ScriptRequest& rq) = delete;
64 public:
65  /**
66  * NB: the definitions are in scriptinterface.cpp, because these access members of the PImpled
67  * implementation of ScriptInterface, and that seemed more convenient.
68  */
69  ScriptRequest(const ScriptInterface& scriptInterface);
70  ScriptRequest(const ScriptInterface* scriptInterface) : ScriptRequest(*scriptInterface) {}
71  ScriptRequest(std::shared_ptr<ScriptInterface> scriptInterface) : ScriptRequest(*scriptInterface) {}
73 
74  /**
75  * Create a script request from a JSContext.
76  * This can be used to get the script interface in a JSNative function.
77  * In general, you shouldn't have to rely on this otherwise.
78  */
79  ScriptRequest(JSContext* cx);
80 
81  /**
82  * Return the scriptInterface active when creating this ScriptRequest.
83  * Note that this is multi-request safe: even if another ScriptRequest is created,
84  * it will point to the original scriptInterface, and thus can be used to re-enter the realm.
85  */
86  const ScriptInterface& GetScriptInterface() const;
87 
88  JS::Value globalValue() const;
89 
90  // Note that JSContext actually changes behind the scenes when creating another ScriptRequest for another realm,
91  // so be _very_ careful when juggling between different realms.
92  JSContext* cx;
93  JS::HandleObject glob;
94  JS::HandleObject nativeScope;
95 private:
97  JS::Realm* m_FormerRealm;
98 };
99 
100 
101 #endif // INCLUDED_SCRIPTREQUEST
JSContext * cx
Definition: ScriptRequest.h:92
JS::Realm * m_FormerRealm
Definition: ScriptRequest.h:97
const ScriptInterface & m_ScriptInterface
Definition: ScriptRequest.h:96
JS::Value globalValue() const
Definition: ScriptInterface.cpp:92
Config::Value_type Value
Definition: json_spirit_value.h:182
ScriptRequest(const ScriptInterface *scriptInterface)
Definition: ScriptRequest.h:70
JS::HandleObject glob
Definition: ScriptRequest.h:93
ScriptRequest(std::shared_ptr< ScriptInterface > scriptInterface)
Definition: ScriptRequest.h:71
const ScriptInterface & GetScriptInterface() const
Return the scriptInterface active when creating this ScriptRequest.
Definition: ScriptInterface.cpp:97
JS::HandleObject nativeScope
Definition: ScriptRequest.h:94
ScriptRequest & operator=(const ScriptRequest &rq)=delete
~ScriptRequest()
Definition: ScriptInterface.cpp:83
Abstraction around a SpiderMonkey JS::Realm.
Definition: ScriptInterface.h:71
ScriptRequest()=delete
Spidermonkey maintains some &#39;local&#39; state via the JSContext* object.
Definition: ScriptRequest.h:59