Exact stack rooting for CParamNode

Refs #2415
Refs #2462

This was SVN commit r15944.
This commit is contained in:
Yves 2014-11-09 11:08:53 +00:00
parent 9040f8a3d3
commit 8e2d514228
4 changed files with 48 additions and 25 deletions

View File

@ -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);
} }

View File

@ -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

View File

@ -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()

View File

@ -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;