diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index bcba14db95..d32cb28743 100644 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -421,6 +421,8 @@ void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGU JSContext* cx = pGUI->GetScriptInterface()->GetContext(); JSAutoRequest rq(cx); + JS::RootedValue globalVal(cx, pGUI->GetGlobalObject()); + JS::RootedObject globalObj(cx, &globalVal.toObject()); const int paramCount = 1; const char* paramNames[paramCount] = { "mouse" }; @@ -433,16 +435,17 @@ void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGU char buf[64]; sprintf_s(buf, ARRAY_SIZE(buf), "__eventhandler%d (%s)", x++, Action.c_str()); - JSFunction* func = JS_CompileFunction(cx, JSVAL_TO_OBJECT(pGUI->GetGlobalObject()), - buf, paramCount, paramNames, Code.c_str(), Code.length(), CodeName.c_str(), 0); + JS::RootedFunction func(cx, JS_CompileFunction(cx, globalObj, + buf, paramCount, paramNames, Code.c_str(), Code.length(), CodeName.c_str(), 0)); if (!func) return; // JS will report an error message - - SetScriptHandler(Action, JS_GetFunctionObject(func)); + + JS::RootedObject funcObj(cx, JS_GetFunctionObject(func)); + SetScriptHandler(Action, funcObj); } -void IGUIObject::SetScriptHandler(const CStr& Action, JSObject* Function) +void IGUIObject::SetScriptHandler(const CStr& Action, JS::HandleObject Function) { m_ScriptHandlers[Action] = CScriptValRooted(m_pGUI->GetScriptInterface()->GetContext(), JS::ObjectValue(*Function)); } @@ -490,7 +493,7 @@ void IGUIObject::ScriptEvent(const CStr& Action) } } -void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argument) +void IGUIObject::ScriptEvent(const CStr& Action, JS::HandleValue Argument) { std::map::iterator it = m_ScriptHandlers.find(Action); if (it == m_ScriptHandlers.end()) @@ -499,12 +502,13 @@ void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argumen JSContext* cx = m_pGUI->GetScriptInterface()->GetContext(); JSAutoRequest rq(cx); - JSObject* object = GetJSObject(); - - jsval arg = Argument.get(); - - jsval result; - bool ok = JS_CallFunctionValue(cx, object, (*it).second.get(), 1, &arg, &result); + JS::AutoValueVector paramData(cx); + paramData.append(Argument.get()); + JS::RootedObject obj(cx, GetJSObject()); + // TODO: Check if this temporary root can be removed after SpiderMonkey 31 upgrade + JS::RootedValue tmpScriptHandler(cx, (*it).second.get()); + JS::RootedValue result(cx); + bool ok = JS_CallFunctionValue(cx, obj, tmpScriptHandler, paramData.length(), paramData.begin(), result.address()); if (!ok) { JS_ReportError(cx, "Errors executing script action \"%s\"", Action.c_str()); diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index b03d09aa83..45fa172057 100644 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -455,9 +455,9 @@ protected: * @param Action Name of action * @param Argument Argument to pass to action */ - void ScriptEvent(const CStr& Action, const CScriptValRooted& Argument); + void ScriptEvent(const CStr& Action, JS::HandleValue Argument); - void SetScriptHandler(const CStr& Action, JSObject* Function); + void SetScriptHandler(const CStr& Action, JS::HandleObject Function); /** * Inputes the object that is currently hovered, this function diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index 6e2cde0ee8..df982500ec 100644 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -256,7 +256,7 @@ void CMiniMap::FireWorldClickEvent(int button, int clicks) g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &coords); g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords, "x", x, false); g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords, "z", z, false); - ScriptEvent("worldclick", CScriptValRooted(cx, coords)); + ScriptEvent("worldclick", coords); UNUSED2(button); UNUSED2(clicks); diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index 9751089ad0..63647c8f55 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -334,8 +334,9 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Hand return JS_FALSE; } + JS::RootedObject vpObj(cx, &vp.toObject()); CStr eventName (CStr(propName.substr(2)).LowerCase()); - e->SetScriptHandler(eventName, &vp.toObject()); + e->SetScriptHandler(eventName, vpObj); return JS_TRUE; } @@ -628,7 +629,9 @@ JSBool JSI_IGUIObject::toString(JSContext* cx, uint argc, jsval* vp) JSAutoRequest rq(cx); JS::CallReceiver rec = JS::CallReceiverFromVp(vp); - IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); + JS::RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); + + IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, thisObj, &JSI_IGUIObject::JSI_class, NULL); if (!e) return JS_FALSE; @@ -645,7 +648,9 @@ JSBool JSI_IGUIObject::focus(JSContext* cx, uint argc, jsval* vp) JSAutoRequest rq(cx); JS::CallReceiver rec = JS::CallReceiverFromVp(vp); - IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); + JS::RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); + + IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, thisObj, &JSI_IGUIObject::JSI_class, NULL); if (!e) return JS_FALSE; @@ -661,7 +666,9 @@ JSBool JSI_IGUIObject::blur(JSContext* cx, uint argc, jsval* vp) JSAutoRequest rq(cx); JS::CallReceiver rec = JS::CallReceiverFromVp(vp); - IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); + JS::RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); + + IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, thisObj, &JSI_IGUIObject::JSI_class, NULL); if (!e) return JS_FALSE; @@ -677,7 +684,9 @@ JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, jsval* vp) JSAutoRequest rq(cx); JS::CallReceiver rec = JS::CallReceiverFromVp(vp); - IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL); + JS::RootedObject thisObj(cx, JS_THIS_OBJECT(cx, vp)); + + IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, thisObj, &JSI_IGUIObject::JSI_class, NULL); if (!e) return JS_FALSE;