From 34b1920e7b6d3b155d048580851b881ba1f55227 Mon Sep 17 00:00:00 2001 From: wraitii Date: Mon, 3 May 2021 16:07:26 +0000 Subject: [PATCH] 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. --- source/graphics/MapReader.h | 7 +- source/graphics/tests/test_LOSTexture.h | 3 +- source/gui/CGUI.h | 3 +- source/gui/CGUISetting.cpp | 3 +- source/gui/ObjectTypes/CText.cpp | 1 - source/i18n/scripting/JSInterface_L10n.cpp | 2 +- source/network/StunClient.cpp | 2 - source/pch/gui/precompiled.h | 3 +- source/ps/World.h | 4 +- source/ps/scripting/JSInterface_ConfigDB.cpp | 2 +- source/ps/scripting/JSInterface_Debug.cpp | 4 +- .../ps/scripting/JSInterface_UserReport.cpp | 4 +- .../ps/scripting/JSInterface_VisualReplay.cpp | 4 +- source/renderer/Renderer.cpp | 1 - source/scriptinterface/ScriptForward.h | 13 ++- source/scriptinterface/ScriptInterface.cpp | 15 ++-- source/scriptinterface/ScriptInterface.h | 29 +------ source/scriptinterface/ScriptRequest.h | 83 +++++++++++++++++++ source/simulation2/system/ParamNode.cpp | 2 +- .../scripting/JSInterface_Sound.cpp | 4 +- 20 files changed, 127 insertions(+), 62 deletions(-) create mode 100644 source/scriptinterface/ScriptRequest.h diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index f7c6e5b08d..a3c0ba0765 100644 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -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 @@ -24,7 +24,7 @@ #include "lib/res/handle.h" #include "ps/CStr.h" #include "ps/FileIo.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptTypes.h" #include "simulation2/system/Entity.h" class CObjectEntry; @@ -38,10 +38,11 @@ class CTriggerManager; class CSimulation2; class CSimContext; class CTerrainTextureEntry; -class ScriptInterface; class CGameView; class CXMLReader; class CMapGenerator; +class ScriptContext; +class ScriptInterface; class CMapReader : public CMapIO { diff --git a/source/graphics/tests/test_LOSTexture.h b/source/graphics/tests/test_LOSTexture.h index ad946e72fc..ea7de2bfb2 100644 --- a/source/graphics/tests/test_LOSTexture.h +++ b/source/graphics/tests/test_LOSTexture.h @@ -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 @@ -19,7 +19,6 @@ #include "graphics/LOSTexture.h" #include "lib/timer.h" -#include "scriptinterface/ScriptInterface.h" #include "simulation2/Simulation2.h" #include "simulation2/helpers/Los.h" diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index 80c1d51453..c0a295f6d7 100644 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -32,7 +32,7 @@ #include "maths/Size2D.h" #include "maths/Vector2D.h" #include "ps/XML/Xeromyces.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptForward.h" #include #include @@ -47,7 +47,6 @@ class IGUIObject; struct SGUIImageEffects; struct SGUIScrollBarStyle; -namespace js { class BaseProxyHandler; } class GUIProxyProps; using map_pObjects = std::map; diff --git a/source/gui/CGUISetting.cpp b/source/gui/CGUISetting.cpp index f6ced0f97c..1823bbb8f7 100644 --- a/source/gui/CGUISetting.cpp +++ b/source/gui/CGUISetting.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 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 @@ -21,6 +21,7 @@ #include "gui/CGUI.h" #include "ps/CLogger.h" +#include "scriptinterface/ScriptInterface.h" template diff --git a/source/gui/ObjectTypes/CText.cpp b/source/gui/ObjectTypes/CText.cpp index cfd52adb74..4a802759fb 100644 --- a/source/gui/ObjectTypes/CText.cpp +++ b/source/gui/ObjectTypes/CText.cpp @@ -22,7 +22,6 @@ #include "gui/CGUI.h" #include "gui/CGUIScrollBarVertical.h" #include "gui/CGUIText.h" -#include "scriptinterface/ScriptInterface.h" CText::CText(CGUI& pGUI) : IGUIObject(pGUI), diff --git a/source/i18n/scripting/JSInterface_L10n.cpp b/source/i18n/scripting/JSInterface_L10n.cpp index 51b9d0bae3..cfea5f2560 100644 --- a/source/i18n/scripting/JSInterface_L10n.cpp +++ b/source/i18n/scripting/JSInterface_L10n.cpp @@ -23,7 +23,7 @@ #include "lib/utf8.h" #include "ps/CLogger.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" namespace JSI_L10n { diff --git a/source/network/StunClient.cpp b/source/network/StunClient.cpp index cb673c60cd..75c4853248 100644 --- a/source/network/StunClient.cpp +++ b/source/network/StunClient.cpp @@ -19,7 +19,6 @@ #include "precompiled.h" #include "StunClient.h" -#include "scriptinterface/ScriptInterface.h" #include #include @@ -44,7 +43,6 @@ #include "lib/sysdep/os/win/wposix/wtime.h" #endif -#include "scriptinterface/ScriptInterface.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" #include "ps/CStr.h" diff --git a/source/pch/gui/precompiled.h b/source/pch/gui/precompiled.h index ba2d7c6bd3..5c703e93c5 100644 --- a/source/pch/gui/precompiled.h +++ b/source/pch/gui/precompiled.h @@ -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 @@ -26,6 +26,5 @@ #include "gui/CGUI.h" #include "gui/ObjectBases/IGUIObject.h" #include "ps/CStr.h" -#include "scriptinterface/ScriptInterface.h" #endif // CONFIG_ENABLE_PCH diff --git a/source/ps/World.h b/source/ps/World.h index 2ad9feaa3e..f5d3e8b983 100644 --- a/source/ps/World.h +++ b/source/ps/World.h @@ -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 @@ -25,7 +25,6 @@ #define INCLUDED_WORLD #include "ps/Errors.h" -#include "scriptinterface/ScriptInterface.h" #ifndef ERROR_GROUP_GAME_DEFINED #define ERROR_GROUP_GAME_DEFINED @@ -39,6 +38,7 @@ class CUnitManager; class CTerrain; class CStrW; class CMapReader; +class ScriptContext; /** * CWorld is a general data class containing whatever is needed to accurately represent the world. diff --git a/source/ps/scripting/JSInterface_ConfigDB.cpp b/source/ps/scripting/JSInterface_ConfigDB.cpp index 8832917e15..91d0cfdbb9 100644 --- a/source/ps/scripting/JSInterface_ConfigDB.cpp +++ b/source/ps/scripting/JSInterface_ConfigDB.cpp @@ -22,7 +22,7 @@ #include "ps/ConfigDB.h" #include "ps/CLogger.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" #include #include diff --git a/source/ps/scripting/JSInterface_Debug.cpp b/source/ps/scripting/JSInterface_Debug.cpp index 86b8b20b34..92c5b5b7ae 100644 --- a/source/ps/scripting/JSInterface_Debug.cpp +++ b/source/ps/scripting/JSInterface_Debug.cpp @@ -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 @@ -23,7 +23,7 @@ #include "lib/svn_revision.h" #include "lib/debug.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" #include #include diff --git a/source/ps/scripting/JSInterface_UserReport.cpp b/source/ps/scripting/JSInterface_UserReport.cpp index a384f25dec..b6bd37f20f 100644 --- a/source/ps/scripting/JSInterface_UserReport.cpp +++ b/source/ps/scripting/JSInterface_UserReport.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 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 @@ -23,7 +23,7 @@ #include "ps/Pyrogenesis.h" #include "ps/UserReport.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" #include diff --git a/source/ps/scripting/JSInterface_VisualReplay.cpp b/source/ps/scripting/JSInterface_VisualReplay.cpp index c08753bdf9..747dbac426 100644 --- a/source/ps/scripting/JSInterface_VisualReplay.cpp +++ b/source/ps/scripting/JSInterface_VisualReplay.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 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 @@ -22,7 +22,7 @@ #include "ps/CStr.h" #include "ps/VisualReplay.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" namespace JSI_VisualReplay { diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 8cc71cd5ca..1d7f7486af 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -69,7 +69,6 @@ #include "renderer/TimeManager.h" #include "renderer/VertexBufferManager.h" #include "renderer/WaterManager.h" -#include "scriptinterface/ScriptInterface.h" #include #include diff --git a/source/scriptinterface/ScriptForward.h b/source/scriptinterface/ScriptForward.h index be80ad72cd..a897b89398 100644 --- a/source/scriptinterface/ScriptForward.h +++ b/source/scriptinterface/ScriptForward.h @@ -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; diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index 29f108a598..51e343b292 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -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 { diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index dd8eb8bbdd..a0aa1c96d6 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -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 @@ -59,34 +60,6 @@ extern thread_local shared_ptr 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) : 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. * diff --git a/source/scriptinterface/ScriptRequest.h b/source/scriptinterface/ScriptRequest.h new file mode 100644 index 0000000000..c23f212e9f --- /dev/null +++ b/source/scriptinterface/ScriptRequest.h @@ -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 . + */ + +#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 + +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) : ScriptRequest(*scriptInterface) {} + ~ScriptRequest(); + + JS::Value globalValue() const; + JSContext* cx; + JS::HandleObject glob; + JS::HandleObject nativeScope; +private: + JS::Realm* m_formerRealm; +}; + + +#endif // INCLUDED_SCRIPTREQUEST diff --git a/source/simulation2/system/ParamNode.cpp b/source/simulation2/system/ParamNode.cpp index 3e8aa74a2a..375b35f5d9 100644 --- a/source/simulation2/system/ParamNode.cpp +++ b/source/simulation2/system/ParamNode.cpp @@ -24,7 +24,7 @@ #include "ps/CStr.h" #include "ps/Filesystem.h" #include "ps/XML/Xeromyces.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" #include diff --git a/source/soundmanager/scripting/JSInterface_Sound.cpp b/source/soundmanager/scripting/JSInterface_Sound.cpp index fbf53f5576..b4cd190bd4 100644 --- a/source/soundmanager/scripting/JSInterface_Sound.cpp +++ b/source/soundmanager/scripting/JSInterface_Sound.cpp @@ -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 @@ -23,7 +23,7 @@ #include "maths/Vector3D.h" #include "ps/Filesystem.h" #include "scriptinterface/FunctionWrapper.h" -#include "scriptinterface/ScriptInterface.h" +#include "scriptinterface/ScriptRequest.h" #include "soundmanager/SoundManager.h" #include