diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index 71cc9e9786..b8efb32a3b 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -239,6 +239,9 @@ struct ScriptInterface_impl JSContext* m_cx; JSObject* m_glob; // global scope object JSObject* m_nativeScope; // native function scope object + + typedef std::map ScriptValCache; + ScriptValCache m_ScriptValCache; }; namespace @@ -529,6 +532,9 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh ScriptInterface_impl::~ScriptInterface_impl() { + // Important: this must come before JS_DestroyContext because CScriptValRooted needs the context to unroot the values! + // TODO: Check again when SpiderMonkey is upgraded and when/if CScriptValRooted gets replaces by JS::Heap. + m_ScriptValCache.clear(); JS_DestroyContext(m_cx); } @@ -610,6 +616,12 @@ ScriptInterface::CxPrivate* ScriptInterface::GetScriptInterfaceAndCBData(JSConte return pCxPrivate; } +CScriptValRooted ScriptInterface::GetCachedValue(CACHED_VAL valueIdentifier) +{ + return m->m_ScriptValCache[valueIdentifier]; +} + + bool ScriptInterface::LoadGlobalScripts() { // Ignore this failure in tests @@ -629,9 +641,9 @@ bool ScriptInterface::LoadGlobalScripts() } jsval proto; if (JS_GetProperty(m->m_cx, JS_GetGlobalObject(m->m_cx), "Vector2Dprototype", &proto)) - vector2Dprototype = CScriptValRooted(m->m_cx, proto); + m->m_ScriptValCache[CACHE_VECTOR2DPROTO] = CScriptValRooted(m->m_cx, proto); if (JS_GetProperty(m->m_cx, JS_GetGlobalObject(m->m_cx), "Vector3Dprototype", &proto)) - vector3Dprototype = CScriptValRooted(m->m_cx, proto); + m->m_ScriptValCache[CACHE_VECTOR3DPROTO] = CScriptValRooted(m->m_cx, proto); return true; } diff --git a/source/scriptinterface/ScriptInterface.h b/source/scriptinterface/ScriptInterface.h index e5b88798ce..8aa569a28f 100644 --- a/source/scriptinterface/ScriptInterface.h +++ b/source/scriptinterface/ScriptInterface.h @@ -91,8 +91,6 @@ public: */ static shared_ptr CreateRuntime(int runtimeSize = DEFAULT_RUNTIME_SIZE); - CScriptValRooted vector2Dprototype; - CScriptValRooted vector3Dprototype; /** * Constructor. @@ -130,6 +128,9 @@ public: */ bool LoadGlobalScripts(); + enum CACHED_VAL { CACHE_VECTOR2DPROTO, CACHE_VECTOR3DPROTO }; + CScriptValRooted GetCachedValue(CACHED_VAL valueIdentifier); + /** * Replace the default JS random number geenrator with a seeded, network-sync'd one. */ diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index f902a00775..5e87a5ba20 100644 --- a/source/simulation2/scripting/EngineScriptConversions.cpp +++ b/source/simulation2/scripting/EngineScriptConversions.cpp @@ -165,7 +165,7 @@ template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const C { // apply the Vector3D prototype to the return value; ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); - JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->vector3Dprototype.get()), NULL); + JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->GetCachedValue(ScriptInterface::CACHE_VECTOR3DPROTO).get()), NULL); if (!obj) return JSVAL_VOID; @@ -202,7 +202,7 @@ template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const C { // apply the Vector2D prototype to the return value ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); - JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->vector2Dprototype.get()), NULL); + JSObject* obj = JS_NewObject(cx, NULL, JSVAL_TO_OBJECT(pCxPrivate->pScriptInterface->GetCachedValue(ScriptInterface::CACHE_VECTOR2DPROTO).get()), NULL); if (!obj) return JSVAL_VOID;