forked from 0ad/0ad
Exact rooting for CallConstructor.
Refs #2415 Refs #2462 This was SVN commit r15601.
This commit is contained in:
parent
736d934107
commit
c818b8e475
@ -865,20 +865,21 @@ AutoGCRooter* ScriptInterface::ReplaceAutoGCRooter(AutoGCRooter* rooter)
|
||||
return ret;
|
||||
}
|
||||
|
||||
jsval ScriptInterface::CallConstructor(jsval ctor, uint argc, jsval argv)
|
||||
void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::AutoValueVector& argv, JS::MutableHandleValue out)
|
||||
{
|
||||
JSAutoRequest rq(m->m_cx);
|
||||
if (!ctor.isObject())
|
||||
{
|
||||
LOGERROR(L"CallConstructor: ctor is not an object");
|
||||
return JS::UndefinedValue();
|
||||
out.setNull();
|
||||
return;
|
||||
}
|
||||
|
||||
// Passing argc 0 and argv JSVAL_VOID causes a crash in mozjs24
|
||||
if (argc == 0)
|
||||
return JS::ObjectValue(*JS_New(m->m_cx, &ctor.toObject(), 0, NULL));
|
||||
if (argv.length() == 0)
|
||||
out.setObjectOrNull(JS_New(m->m_cx, &ctor.toObject(), 0, NULL));
|
||||
else
|
||||
return JS::ObjectValue(*JS_New(m->m_cx, &ctor.toObject(), argc, &argv));
|
||||
out.setObjectOrNull(JS_New(m->m_cx, &ctor.toObject(), argv.length(), argv.begin()));
|
||||
}
|
||||
|
||||
void ScriptInterface::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
|
||||
|
@ -136,9 +136,11 @@ public:
|
||||
|
||||
/**
|
||||
* Call a constructor function, equivalent to JS "new ctor(arg)".
|
||||
* @return The new object; or JSVAL_VOID on failure, and logs an error message
|
||||
* @param ctor An object that can be used as constructor
|
||||
* @param argv Constructor arguments
|
||||
* @param out The new object; On error an error message gets logged and out is Null (out.isNull() == true).
|
||||
*/
|
||||
jsval CallConstructor(jsval ctor, uint argc, jsval argv);
|
||||
void CallConstructor(JS::HandleValue ctor, JS::AutoValueVector& argv, JS::MutableHandleValue out);
|
||||
|
||||
/**
|
||||
* Call the named property on the given object, with void return type and 0 arguments
|
||||
|
@ -114,7 +114,7 @@ private:
|
||||
std::string constructor;
|
||||
JS::RootedValue objectWithConstructor(cx); // object that should contain the constructor function
|
||||
JS::RootedValue global(cx, m_ScriptInterface->GetGlobalObject());
|
||||
CScriptVal ctor;
|
||||
JS::RootedValue ctor(cx);
|
||||
if (!m_ScriptInterface->HasProperty(metadata, "moduleName"))
|
||||
{
|
||||
objectWithConstructor.set(m_ScriptInterface->GetGlobalObject());
|
||||
@ -135,8 +135,8 @@ private:
|
||||
}
|
||||
|
||||
// Get the constructor function from the loaded scripts
|
||||
if (!m_ScriptInterface->GetProperty(objectWithConstructor, constructor.c_str(), ctor)
|
||||
|| ctor.undefined())
|
||||
if (!m_ScriptInterface->GetProperty(objectWithConstructor, constructor.c_str(), &ctor)
|
||||
|| ctor.isNull())
|
||||
{
|
||||
LOGERROR(L"Failed to create AI player: %ls: can't find constructor '%hs'", path.string().c_str(), constructor.c_str());
|
||||
return false;
|
||||
@ -144,7 +144,7 @@ private:
|
||||
|
||||
m_ScriptInterface->GetProperty(metadata, "useShared", m_UseSharedComponent);
|
||||
|
||||
CScriptVal obj;
|
||||
JS::RootedValue obj(cx);
|
||||
|
||||
// Set up the data to pass as the constructor argument
|
||||
JS::RootedValue settings(cx);
|
||||
@ -156,9 +156,9 @@ private:
|
||||
|
||||
JS::AutoValueVector argv(cx);
|
||||
argv.append(settings.get());
|
||||
obj = m_ScriptInterface->CallConstructor(ctor.get(), argv.length(), argv.handleAt(0));
|
||||
m_ScriptInterface->CallConstructor(ctor, argv, &obj);
|
||||
|
||||
if (obj.undefined())
|
||||
if (obj.isNull())
|
||||
{
|
||||
LOGERROR(L"Failed to create AI player: %ls: error calling constructor '%hs'", path.string().c_str(), constructor.c_str());
|
||||
return false;
|
||||
@ -423,10 +423,12 @@ public:
|
||||
|
||||
JS::AutoValueVector argv(cx);
|
||||
argv.append(settings);
|
||||
m_SharedAIObj = CScriptValRooted(cx, m_ScriptInterface->CallConstructor(ctor, argv.length(), argv.handleAt(0)));
|
||||
// TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade
|
||||
JS::RootedValue tmpSharedAIObj(cx, m_SharedAIObj.get());
|
||||
m_ScriptInterface->CallConstructor(ctor, argv, &tmpSharedAIObj);
|
||||
m_SharedAIObj = CScriptValRooted(cx, tmpSharedAIObj);
|
||||
|
||||
|
||||
if (m_SharedAIObj.undefined())
|
||||
if (tmpSharedAIObj.isNull())
|
||||
{
|
||||
LOGERROR(L"Failed to create shared AI component: %ls: error calling constructor '%hs'", path.string().c_str(), "SharedScript");
|
||||
return false;
|
||||
|
@ -708,6 +708,9 @@ void CComponentManager::AddSystemComponents(bool skipScriptedComponents, bool sk
|
||||
|
||||
IComponent* CComponentManager::ConstructComponent(CEntityHandle ent, ComponentTypeId cid)
|
||||
{
|
||||
JSContext* cx = m_ScriptInterface.GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
std::map<ComponentTypeId, ComponentType>::const_iterator it = m_ComponentTypesById.find(cid);
|
||||
if (it == m_ComponentTypesById.end())
|
||||
{
|
||||
@ -729,11 +732,14 @@ IComponent* CComponentManager::ConstructComponent(CEntityHandle ent, ComponentTy
|
||||
std::map<entity_id_t, IComponent*>& emap2 = m_ComponentsByTypeId[cid];
|
||||
|
||||
// If this is a scripted component, construct the appropriate JS object first
|
||||
jsval obj = JSVAL_NULL;
|
||||
JS::RootedValue obj(cx);
|
||||
// TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade
|
||||
JS::RootedValue tmpCtor(cx, ct.ctor.get());
|
||||
if (ct.type == CT_Script)
|
||||
{
|
||||
obj = m_ScriptInterface.CallConstructor(ct.ctor.get(), 0, JSVAL_VOID);
|
||||
if (JSVAL_IS_VOID(obj))
|
||||
JS::AutoValueVector argv(cx); // TODO: With SpiderMonkey 31, we can pass JS::HandleValueArray::empty()
|
||||
m_ScriptInterface.CallConstructor(tmpCtor, argv, &obj);
|
||||
if (obj.isNull())
|
||||
{
|
||||
LOGERROR(L"Script component constructor failed");
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user