Fixes a crash introduced in fd187f466f by ensuring that the CScriptValRooted values are destroyed before calling JS_DestroyContext.

I've tested the performance on Combat Demo (Huge) again with the code
from #2394.
It's very close but probably a little bit lower (hard to tell because
it's so close).

Closes #2408
Refs #2394

This was SVN commit r14705.
This commit is contained in:
Yves 2014-01-30 13:21:36 +00:00
parent b9eea330d0
commit bab3a08643
3 changed files with 19 additions and 6 deletions

View File

@ -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<ScriptInterface::CACHED_VAL, CScriptValRooted> 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<T>.
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;
}

View File

@ -91,8 +91,6 @@ public:
*/
static shared_ptr<ScriptRuntime> 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.
*/

View File

@ -165,7 +165,7 @@ template<> jsval ScriptInterface::ToJSVal<CFixedVector3D>(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<CFixedVector2D>(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;