forked from 0ad/0ad
Exact stack rooting for CParamNode
Refs #2415 Refs #2462 This was SVN commit r15944.
This commit is contained in:
parent
9040f8a3d3
commit
8e2d514228
@ -563,9 +563,10 @@ public:
|
|||||||
JS::RootedValue tmpEntityTemplates(cx); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade
|
JS::RootedValue tmpEntityTemplates(cx); // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade
|
||||||
m_ScriptInterface->Eval("({})", &tmpEntityTemplates);
|
m_ScriptInterface->Eval("({})", &tmpEntityTemplates);
|
||||||
|
|
||||||
|
JS::RootedValue val(cx);
|
||||||
for (size_t i = 0; i < templates.size(); ++i)
|
for (size_t i = 0; i < templates.size(); ++i)
|
||||||
{
|
{
|
||||||
JS::RootedValue val(cx, templates[i].second->ToJSVal(cx, false));
|
templates[i].second->ToJSVal(cx, false, &val);
|
||||||
m_ScriptInterface->SetProperty(tmpEntityTemplates, templates[i].first.c_str(), val, true);
|
m_ScriptInterface->SetProperty(tmpEntityTemplates, templates[i].first.c_str(), val, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ template<> void ScriptInterface::ToJSVal<IComponent*>(JSContext* cx, JS::Mutable
|
|||||||
template<> void ScriptInterface::ToJSVal<CParamNode>(JSContext* cx, JS::MutableHandleValue ret, CParamNode const& val)
|
template<> void ScriptInterface::ToJSVal<CParamNode>(JSContext* cx, JS::MutableHandleValue ret, CParamNode const& val)
|
||||||
{
|
{
|
||||||
JSAutoRequest rq(cx);
|
JSAutoRequest rq(cx);
|
||||||
ret.set(val.ToJSVal(cx, true));
|
val.ToJSVal(cx, true, ret);
|
||||||
|
|
||||||
// Prevent modifications to the object, so that it's safe to share between
|
// Prevent modifications to the object, so that it's safe to share between
|
||||||
// components and to reconstruct on deserialization
|
// components and to reconstruct on deserialization
|
||||||
|
@ -308,63 +308,85 @@ void CParamNode::ToXML(std::wostream& strm) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsval CParamNode::ToJSVal(JSContext* cx, bool cacheValue) const
|
void CParamNode::ToJSVal(JSContext* cx, bool cacheValue, JS::MutableHandleValue ret) const
|
||||||
{
|
{
|
||||||
if (cacheValue && !m_ScriptVal.uninitialised())
|
if (cacheValue && !m_ScriptVal.uninitialised())
|
||||||
return m_ScriptVal.get();
|
{
|
||||||
|
ret.set(m_ScriptVal.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
jsval val = ConstructJSVal(cx);
|
ConstructJSVal(cx, ret);
|
||||||
|
|
||||||
if (cacheValue)
|
if (cacheValue)
|
||||||
m_ScriptVal = CScriptValRooted(cx, val);
|
m_ScriptVal = CScriptValRooted(cx, ret);
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsval CParamNode::ConstructJSVal(JSContext* cx) const
|
void CParamNode::ConstructJSVal(JSContext* cx, JS::MutableHandleValue ret) const
|
||||||
{
|
{
|
||||||
JSAutoRequest rq(cx);
|
JSAutoRequest rq(cx);
|
||||||
if (m_Childs.empty())
|
if (m_Childs.empty())
|
||||||
{
|
{
|
||||||
// Empty node - map to undefined
|
// Empty node - map to undefined
|
||||||
if (m_Value.empty())
|
if (m_Value.empty())
|
||||||
return JSVAL_VOID;
|
{
|
||||||
|
ret.setUndefined();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Just a string
|
// Just a string
|
||||||
utf16string text(m_Value.begin(), m_Value.end());
|
utf16string text(m_Value.begin(), m_Value.end());
|
||||||
JSString* str = JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length());
|
JS::RootedString str(cx, JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length()));
|
||||||
if (str)
|
if (str)
|
||||||
return STRING_TO_JSVAL(str);
|
{
|
||||||
|
ret.setString(str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO: report error
|
// TODO: report error
|
||||||
return JSVAL_VOID;
|
ret.setUndefined();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Got child nodes - convert this node into a hash-table-style object:
|
// Got child nodes - convert this node into a hash-table-style object:
|
||||||
|
|
||||||
JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
|
JS::RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return JSVAL_VOID; // TODO: report error
|
{
|
||||||
|
ret.setUndefined();
|
||||||
|
return; // TODO: report error
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::RootedValue childVal(cx);
|
||||||
for (std::map<std::string, CParamNode>::const_iterator it = m_Childs.begin(); it != m_Childs.end(); ++it)
|
for (std::map<std::string, CParamNode>::const_iterator it = m_Childs.begin(); it != m_Childs.end(); ++it)
|
||||||
{
|
{
|
||||||
JS::RootedValue childVal(cx, it->second.ConstructJSVal(cx));
|
it->second.ConstructJSVal(cx, &childVal);
|
||||||
if (!JS_SetProperty(cx, obj, it->first.c_str(), childVal.address()))
|
if (!JS_SetProperty(cx, obj, it->first.c_str(), childVal.address()))
|
||||||
return JSVAL_VOID; // TODO: report error
|
{
|
||||||
|
ret.setUndefined();
|
||||||
|
return; // TODO: report error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the node has a string too, add that as an extra property
|
// If the node has a string too, add that as an extra property
|
||||||
if (!m_Value.empty())
|
if (!m_Value.empty())
|
||||||
{
|
{
|
||||||
utf16string text(m_Value.begin(), m_Value.end());
|
utf16string text(m_Value.begin(), m_Value.end());
|
||||||
JSString* str = JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length());
|
JS::RootedString str(cx, JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length()));
|
||||||
if (!str)
|
if (!str)
|
||||||
return JSVAL_VOID; // TODO: report error
|
{
|
||||||
JS::RootedValue childVal(cx, STRING_TO_JSVAL(str));
|
ret.setUndefined();
|
||||||
|
return; // TODO: report error
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::RootedValue childVal(cx, JS::StringValue(str));
|
||||||
if (!JS_SetProperty(cx, obj, "_string", childVal.address()))
|
if (!JS_SetProperty(cx, obj, "_string", childVal.address()))
|
||||||
return JSVAL_VOID; // TODO: report error
|
{
|
||||||
|
ret.setUndefined();
|
||||||
|
return; // TODO: report error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OBJECT_TO_JSVAL(obj);
|
ret.setObject(*obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CParamNode::ResetScriptVal()
|
void CParamNode::ResetScriptVal()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010 Wildfire Games.
|
/* Copyright (C) 2014 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -220,7 +220,7 @@ public:
|
|||||||
* The cache will be reset if *this* node is modified (e.g. by LoadXML),
|
* The cache will be reset if *this* node is modified (e.g. by LoadXML),
|
||||||
* but *not* if any child nodes are modified (so don't do that).
|
* but *not* if any child nodes are modified (so don't do that).
|
||||||
*/
|
*/
|
||||||
jsval ToJSVal(JSContext* cx, bool cacheValue) const;
|
void ToJSVal(JSContext* cx, bool cacheValue, JS::MutableHandleValue ret) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the names/nodes of the children of this node, ordered by name
|
* Returns the names/nodes of the children of this node, ordered by name
|
||||||
@ -247,7 +247,7 @@ private:
|
|||||||
|
|
||||||
void ResetScriptVal();
|
void ResetScriptVal();
|
||||||
|
|
||||||
jsval ConstructJSVal(JSContext* cx) const;
|
void ConstructJSVal(JSContext* cx, JS::MutableHandleValue ret) const;
|
||||||
|
|
||||||
std::wstring m_Value;
|
std::wstring m_Value;
|
||||||
ChildrenMap m_Childs;
|
ChildrenMap m_Childs;
|
||||||
|
Loading…
Reference in New Issue
Block a user