Changes FromJSVal to take a JS::HandleValue instead of JS::Value.

JS::HandleValue is basically a wrapper around a JS::Value that is safe
for exact stack rooting and moving GC.
I've tried to keep this changeset rather small and isolated and
therefore create additional JS::Rooted<T> values at some places where
the function should eventually directly take a JS::Handle<T>.
The functions "CallFunction" and "CallFunctionVoid" put their arguments
inside a JS::AutoValueVector because this will be passed directly to
"CallFunction_" with ESR31.

Refs #2462
Refs #2415

This was SVN commit r15517.
This commit is contained in:
Yves 2014-07-12 19:08:39 +00:00
parent cfa59fc4e1
commit db9c20e0a9
8 changed files with 141 additions and 104 deletions

View File

@ -55,12 +55,13 @@ JSFunctionSpec JSI_IGUIObject::JSI_methods[] =
JSBool JSI_IGUIObject::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
{
JSAutoRequest rq(cx);
IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
if (!e)
return JS_FALSE;
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
JS::RootedValue idval(cx);
if (!JS_IdToValue(cx, id, idval.address()))
return JS_FALSE;
std::string propName;
@ -304,8 +305,9 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JS::HandleObject obj, JS::Hand
if (!e)
return JS_FALSE;
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
JSAutoRequest rq(cx);
JS::RootedValue idval(cx);
if (!JS_IdToValue(cx, id, idval.address()))
return JS_FALSE;
std::string propName;

View File

@ -26,7 +26,7 @@
#define NUMBERED_LIST_BALANCED(z, i, data) BOOST_PP_COMMA_IF(i) data##i
// Some other things
#define TYPED_ARGS(z, i, data) , T##i a##i
#define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, i < args.length() ? args[i] : JS::UndefinedValue(), a##i)) return false;
#define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, i < args.length() ? args.handleAt(i) : JS::UndefinedHandleValue, a##i)) return false;
// List-generating macros, named roughly after their first list item
#define TYPENAME_T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, typename T) // "typename T0, typename T1, "

View File

@ -30,7 +30,7 @@
// Implicit type conversions often hide bugs, so warn about them
#define WARN_IF_NOT(c, v) STMT(if (!(c)) { JS_ReportWarning(cx, "Script value conversion check failed: %s (got type %s)", #c, JS_GetTypeName(cx, JS_TypeOfValue(cx, v))); })
template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, jsval v, bool& out)
template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, JS::HandleValue v, bool& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isBoolean(), v);
@ -38,7 +38,7 @@ template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, jsval v, bool& o
return true;
}
template<> bool ScriptInterface::FromJSVal<float>(JSContext* cx, jsval v, float& out)
template<> bool ScriptInterface::FromJSVal<float>(JSContext* cx, JS::HandleValue v, float& out)
{
JSAutoRequest rq(cx);
double tmp;
@ -49,7 +49,7 @@ template<> bool ScriptInterface::FromJSVal<float>(JSContext* cx, jsval v, float&
return true;
}
template<> bool ScriptInterface::FromJSVal<double>(JSContext* cx, jsval v, double& out)
template<> bool ScriptInterface::FromJSVal<double>(JSContext* cx, JS::HandleValue v, double& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isNumber(), v);
@ -58,7 +58,7 @@ template<> bool ScriptInterface::FromJSVal<double>(JSContext* cx, jsval v, doubl
return true;
}
template<> bool ScriptInterface::FromJSVal<i32>(JSContext* cx, jsval v, i32& out)
template<> bool ScriptInterface::FromJSVal<i32>(JSContext* cx, JS::HandleValue v, i32& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isNumber(), v);
@ -67,7 +67,7 @@ template<> bool ScriptInterface::FromJSVal<i32>(JSContext* cx, jsval v, i32& out
return true;
}
template<> bool ScriptInterface::FromJSVal<u32>(JSContext* cx, jsval v, u32& out)
template<> bool ScriptInterface::FromJSVal<u32>(JSContext* cx, JS::HandleValue v, u32& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isNumber(), v);
@ -76,7 +76,7 @@ template<> bool ScriptInterface::FromJSVal<u32>(JSContext* cx, jsval v, u32& out
return true;
}
template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, jsval v, u16& out)
template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, JS::HandleValue v, u16& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isNumber(), v);
@ -85,7 +85,7 @@ template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, jsval v, u16& out
return true;
}
template<> bool ScriptInterface::FromJSVal<u8>(JSContext* cx, jsval v, u8& out)
template<> bool ScriptInterface::FromJSVal<u8>(JSContext* cx, JS::HandleValue v, u8& out)
{
JSAutoRequest rq(cx);
u16 tmp;
@ -96,7 +96,7 @@ template<> bool ScriptInterface::FromJSVal<u8>(JSContext* cx, jsval v, u8& out)
return true;
}
template<> bool ScriptInterface::FromJSVal<long>(JSContext* cx, jsval v, long& out)
template<> bool ScriptInterface::FromJSVal<long>(JSContext* cx, JS::HandleValue v, long& out)
{
i64 tmp;
bool ok = JS::ToInt64(cx, v, &tmp);
@ -104,7 +104,7 @@ template<> bool ScriptInterface::FromJSVal<long>(JSContext* cx, jsval v, long& o
return ok;
}
template<> bool ScriptInterface::FromJSVal<unsigned long>(JSContext* cx, jsval v, unsigned long& out)
template<> bool ScriptInterface::FromJSVal<unsigned long>(JSContext* cx, JS::HandleValue v, unsigned long& out)
{
u64 tmp;
bool ok = JS::ToUint64(cx, v, &tmp);
@ -115,7 +115,7 @@ template<> bool ScriptInterface::FromJSVal<unsigned long>(JSContext* cx, jsval v
// see comment below (where the same preprocessor condition is used)
#if MSC_VERSION && ARCH_AMD64
template<> bool ScriptInterface::FromJSVal<size_t>(JSContext* cx, jsval v, size_t& out)
template<> bool ScriptInterface::FromJSVal<size_t>(JSContext* cx, JS::HandleValue v, size_t& out)
{
int tmp;
if(!FromJSVal<int>(cx, v, tmp))
@ -126,7 +126,7 @@ template<> bool ScriptInterface::FromJSVal<size_t>(JSContext* cx, jsval v, size_
return true;
}
template<> bool ScriptInterface::FromJSVal<ssize_t>(JSContext* cx, jsval v, ssize_t& out)
template<> bool ScriptInterface::FromJSVal<ssize_t>(JSContext* cx, JS::HandleValue v, ssize_t& out)
{
int tmp;
if(!FromJSVal<int>(cx, v, tmp))
@ -139,19 +139,19 @@ template<> bool ScriptInterface::FromJSVal<ssize_t>(JSContext* cx, jsval v, ssiz
#endif
template<> bool ScriptInterface::FromJSVal<CScriptVal>(JSContext* UNUSED(cx), jsval v, CScriptVal& out)
template<> bool ScriptInterface::FromJSVal<CScriptVal>(JSContext* UNUSED(cx), JS::HandleValue v, CScriptVal& out)
{
out = v;
out = v.get();
return true;
}
template<> bool ScriptInterface::FromJSVal<CScriptValRooted>(JSContext* cx, jsval v, CScriptValRooted& out)
template<> bool ScriptInterface::FromJSVal<CScriptValRooted>(JSContext* cx, JS::HandleValue v, CScriptValRooted& out)
{
out = CScriptValRooted(cx, v);
return true;
}
template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, jsval v, std::wstring& out)
template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, JS::HandleValue v, std::wstring& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v), v); // allow implicit number conversions
@ -166,7 +166,7 @@ template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, jsval v,
return true;
}
template<> bool ScriptInterface::FromJSVal<Path>(JSContext* cx, jsval v, Path& out)
template<> bool ScriptInterface::FromJSVal<Path>(JSContext* cx, JS::HandleValue v, Path& out)
{
std::wstring string;
if (!FromJSVal(cx, v, string))
@ -175,7 +175,7 @@ template<> bool ScriptInterface::FromJSVal<Path>(JSContext* cx, jsval v, Path& o
return true;
}
template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, jsval v, std::string& out)
template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, JS::HandleValue v, std::string& out)
{
JSAutoRequest rq(cx);
WARN_IF_NOT(v.isString() || v.isNumber(), v); // allow implicit number conversions
@ -190,17 +190,17 @@ template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, jsval v,
return true;
}
template<> bool ScriptInterface::FromJSVal<CStr8>(JSContext* cx, jsval v, CStr8& out)
template<> bool ScriptInterface::FromJSVal<CStr8>(JSContext* cx, JS::HandleValue v, CStr8& out)
{
return ScriptInterface::FromJSVal(cx, v, static_cast<std::string&>(out));
}
template<> bool ScriptInterface::FromJSVal<CStrW>(JSContext* cx, jsval v, CStrW& out)
template<> bool ScriptInterface::FromJSVal<CStrW>(JSContext* cx, JS::HandleValue v, CStrW& out)
{
return ScriptInterface::FromJSVal(cx, v, static_cast<std::wstring&>(out));
}
template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, jsval v, Entity& out)
template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, JS::HandleValue v, Entity& out)
{
JSAutoRequest rq(cx);
if (!v.isObject())
@ -377,7 +377,7 @@ template<typename T> static void ToJSVal_vector(JSContext* cx, JS::Value& ret, c
ret = JS::ObjectValue(*obj);
}
template<typename T> static bool FromJSVal_vector(JSContext* cx, jsval v, std::vector<T>& out)
template<typename T> static bool FromJSVal_vector(JSContext* cx, JS::HandleValue v, std::vector<T>& out)
{
JSAutoRequest rq(cx);
JSObject* obj;
@ -411,7 +411,7 @@ template<typename T> static bool FromJSVal_vector(JSContext* cx, jsval v, std::v
{ \
ToJSVal_vector(cx, ret, val); \
} \
template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, jsval v, std::vector<T>& out) \
template<> bool ScriptInterface::FromJSVal<std::vector<T> >(JSContext* cx, JS::HandleValue v, std::vector<T>& out) \
{ \
return FromJSVal_vector(cx, v, out); \
}
@ -430,7 +430,7 @@ template<> void ScriptInterface::ToJSVal<std::vector<IComponent*> >(JSContext* c
ToJSVal_vector(cx, ret, val);
}
template<> bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx, jsval v, std::vector<Entity>& out)
template<> bool ScriptInterface::FromJSVal<std::vector<Entity> >(JSContext* cx, JS::HandleValue v, std::vector<Entity>& out)
{
return FromJSVal_vector(cx, v, out);
}

View File

@ -428,15 +428,16 @@ void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
jsval excn;
if (JS_GetPendingException(cx, &excn) && excn.isObject())
{
JS::RootedObject excnObj(cx, &excn.toObject());
// TODO: this violates the docs ("The error reporter callback must not reenter the JSAPI.")
// Hide the exception from EvaluateScript
JSExceptionState* excnState = JS_SaveExceptionState(cx);
JS_ClearPendingException(cx);
jsval rval;
JS::RootedValue rval(cx);
const char dumpStack[] = "this.stack.trimRight().replace(/^/mg, ' ')"; // indent each line
if (JS_EvaluateScript(cx, &excn.toObject(), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, &rval))
if (JS_EvaluateScript(cx, &excn.toObject(), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, rval.address()))
{
std::string stackTrace;
if (ScriptInterface::FromJSVal(cx, rval, stackTrace))
@ -468,7 +469,7 @@ JSBool print(JSContext* cx, uint argc, jsval* vp)
for (uint i = 0; i < args.length(); ++i)
{
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, args[i], str))
if (!ScriptInterface::FromJSVal(cx, args.handleAt(i), str))
return JS_FALSE;
debug_printf(L"%ls", str.c_str());
}
@ -487,7 +488,7 @@ JSBool logmsg(JSContext* cx, uint argc, jsval* vp)
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, args[0], str))
if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str))
return JS_FALSE;
LOGMESSAGE(L"%ls", str.c_str());
args.rval().setUndefined();
@ -504,7 +505,7 @@ JSBool warn(JSContext* cx, uint argc, jsval* vp)
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, args[0], str))
if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str))
return JS_FALSE;
LOGWARNING(L"%ls", str.c_str());
args.rval().setUndefined();
@ -521,7 +522,7 @@ JSBool error(JSContext* cx, uint argc, jsval* vp)
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, args[0], str))
if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str))
return JS_FALSE;
LOGERROR(L"%ls", str.c_str());
args.rval().setUndefined();
@ -551,7 +552,7 @@ JSBool ProfileStart(JSContext* cx, uint argc, jsval* vp)
if (args.length() >= 1)
{
std::string str;
if (!ScriptInterface::FromJSVal(cx, args[0], str))
if (!ScriptInterface::FromJSVal(cx, args.handleAt(0), str))
return JS_FALSE;
typedef boost::flyweight<
@ -967,11 +968,13 @@ JSObject* ScriptInterface::CreateCustomObject(const std::string & typeName)
bool ScriptInterface::CallFunctionVoid(jsval val, const char* name)
{
jsval jsRet;
return CallFunction_(val, name, 0, NULL, jsRet);
JSAutoRequest rq(m->m_cx);
JS::RootedValue jsRet(m->m_cx);
JS::RootedValue val1(m->m_cx, val);
return CallFunction_(val1, name, 0, NULL, &jsRet);
}
bool ScriptInterface::CallFunction_(jsval val, const char* name, uint argc, jsval* argv, jsval& ret)
bool ScriptInterface::CallFunction_(JS::HandleValue val, const char* name, uint argc, jsval* argv, JS::MutableHandleValue ret)
{
JSAutoRequest rq(m->m_cx);
JS::RootedObject obj(m->m_cx);
@ -984,7 +987,7 @@ bool ScriptInterface::CallFunction_(jsval val, const char* name, uint argc, jsva
if (!JS_HasProperty(m->m_cx, obj, name, &found) || !found)
return JS_FALSE;
bool ok = JS_CallFunctionName(m->m_cx, obj, name, argc, argv, &ret);
bool ok = JS_CallFunctionName(m->m_cx, obj, name, argc, argv, ret.address());
return ok;
}
@ -1266,25 +1269,25 @@ bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path)
bool ScriptInterface::Eval(const char* code)
{
jsval rval;
return Eval_(code, rval);
JS::RootedValue rval(m->m_cx);
return Eval_(code, &rval);
}
bool ScriptInterface::Eval_(const char* code, jsval& rval)
bool ScriptInterface::Eval_(const char* code, JS::MutableHandleValue rval)
{
JSAutoRequest rq(m->m_cx);
utf16string codeUtf16(code, code+strlen(code));
bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, rval.address());
return ok;
}
bool ScriptInterface::Eval_(const wchar_t* code, jsval& rval)
bool ScriptInterface::Eval_(const wchar_t* code, JS::MutableHandleValue rval)
{
JSAutoRequest rq(m->m_cx);
utf16string codeUtf16(code, code+wcslen(code));
bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, rval.address());
return ok;
}

View File

@ -328,7 +328,7 @@ public:
/**
* Convert a jsval to a C++ type. (This might trigger GC.)
*/
template<typename T> static bool FromJSVal(JSContext* cx, jsval val, T& ret);
template<typename T> static bool FromJSVal(JSContext* cx, const JS::HandleValue val, T& ret);
/**
* Convert a C++ type to a jsval. (This might trigger GC. The return
@ -397,9 +397,9 @@ public:
jsval ReadStructuredClone(const shared_ptr<StructuredClone>& ptr);
private:
bool CallFunction_(jsval val, const char* name, uint argc, jsval* argv, jsval& ret);
bool Eval_(const char* code, jsval& ret);
bool Eval_(const wchar_t* code, jsval& ret);
bool CallFunction_(JS::HandleValue val, const char* name, uint argc, jsval* argv, JS::MutableHandleValue ret);
bool Eval_(const char* code, JS::MutableHandleValue ret);
bool Eval_(const wchar_t* code, JS::MutableHandleValue ret);
bool SetGlobal_(const char* name, jsval value, bool replace);
bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly, bool enumerate);
bool SetProperty_(jsval obj, const wchar_t* name, jsval value, bool readonly, bool enumerate);
@ -447,8 +447,11 @@ public:
template<typename R>
bool ScriptInterface::CallFunction(jsval val, const char* name, R& ret)
{
jsval jsRet;
bool ok = CallFunction_(val, name, 0, NULL, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
bool ok = CallFunction_(val1, name, 0, NULL, &jsRet);
if (!ok)
return false;
return FromJSVal(GetContext(), jsRet, ret);
@ -457,85 +460,113 @@ bool ScriptInterface::CallFunction(jsval val, const char* name, R& ret)
template<typename T0>
bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0)
{
jsval jsRet;
jsval argv[1];
ToJSVal(GetContext(), argv[0], a0);
return CallFunction_(val, name, 1, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(1);
ToJSVal(cx, argv[0], a0);
return CallFunction_(val1, name, 1, argv.begin(), &jsRet);
}
template<typename T0, typename T1>
bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0, const T1& a1)
{
jsval jsRet;
jsval argv[2];
ToJSVal(GetContext(), argv[0], a0);
ToJSVal(GetContext(), argv[1], a1);
return CallFunction_(val, name, 2, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(2);
ToJSVal(cx, argv[0], a0);
ToJSVal(cx, argv[1], a1);
return CallFunction_(val1, name, 2, argv.begin(), &jsRet);
}
template<typename T0, typename T1, typename T2>
bool ScriptInterface::CallFunctionVoid(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2)
{
jsval jsRet;
jsval argv[3];
ToJSVal(GetContext(), argv[0], a0);
ToJSVal(GetContext(), argv[1], a1);
ToJSVal(GetContext(), argv[2], a2);
return CallFunction_(val, name, 3, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(3);
ToJSVal(cx, argv[0], a0);
ToJSVal(cx, argv[1], a1);
ToJSVal(cx, argv[2], a2);
return CallFunction_(val1, name, 3, argv.begin(), &jsRet);
}
template<typename T0, typename R>
bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, R& ret)
{
jsval jsRet;
jsval argv[1];
ToJSVal(GetContext(), argv[0], a0);
bool ok = CallFunction_(val, name, 1, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(1);
ToJSVal(cx, argv[0], a0);
bool ok = CallFunction_(val1, name, 1, argv.begin(), &jsRet);
if (!ok)
return false;
return FromJSVal(GetContext(), jsRet, ret);
return FromJSVal(cx, jsRet, ret);
}
template<typename T0, typename T1, typename R>
bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, R& ret)
{
jsval jsRet;
jsval argv[2];
ToJSVal(GetContext(), argv[0], a0);
ToJSVal(GetContext(), argv[1], a1);
bool ok = CallFunction_(val, name, 2, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(2);
ToJSVal(cx, argv[0], a0);
ToJSVal(cx, argv[1], a1);
bool ok = CallFunction_(val1, name, 2, argv.begin(), &jsRet);
if (!ok)
return false;
return FromJSVal(GetContext(), jsRet, ret);
return FromJSVal(cx, jsRet, ret);
}
template<typename T0, typename T1, typename T2, typename R>
bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2, R& ret)
{
jsval jsRet;
jsval argv[3];
ToJSVal(GetContext(), argv[0], a0);
ToJSVal(GetContext(), argv[1], a1);
ToJSVal(GetContext(), argv[2], a2);
bool ok = CallFunction_(val, name, 3, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(3);
ToJSVal(cx, argv[0], a0);
ToJSVal(cx, argv[1], a1);
ToJSVal(cx, argv[2], a2);
bool ok = CallFunction_(val1, name, 3, argv.begin(), &jsRet);
if (!ok)
return false;
return FromJSVal(GetContext(), jsRet, ret);
return FromJSVal(cx, jsRet, ret);
}
template<typename T0, typename T1, typename T2, typename T3, typename R>
bool ScriptInterface::CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2, const T3& a3, R& ret)
{
jsval jsRet;
jsval argv[4];
ToJSVal(GetContext(), argv[0], a0);
ToJSVal(GetContext(), argv[1], a1);
ToJSVal(GetContext(), argv[2], a2);
ToJSVal(GetContext(), argv[3], a3);
bool ok = CallFunction_(val, name, 4, argv, jsRet);
JSContext* cx = GetContext();
JSAutoRequest rq(cx);
JS::RootedValue jsRet(cx);
JS::RootedValue val1(cx, val);
JS::AutoValueVector argv(cx);
argv.resize(4);
ToJSVal(cx, argv[0], a0);
ToJSVal(cx, argv[1], a1);
ToJSVal(cx, argv[2], a2);
ToJSVal(cx, argv[3], a3);
bool ok = CallFunction_(val1, name, 4, argv.begin(), &jsRet);
if (!ok)
return false;
return FromJSVal(GetContext(), jsRet, ret);
return FromJSVal(cx, jsRet, ret);
}
template<typename T>
@ -592,8 +623,9 @@ bool ScriptInterface::GetPropertyInt(jsval obj, int name, T& out)
template<typename T, typename CHAR>
bool ScriptInterface::Eval(const CHAR* code, T& ret)
{
jsval rval;
if (! Eval_(code, rval))
JSAutoRequest rq(GetContext());
JS::RootedValue rval(GetContext());
if (! Eval_(code, &rval))
return false;
return FromJSVal(GetContext(), rval, ret);
}

View File

@ -52,8 +52,8 @@ class TestScriptConversions : public CxxTest::TestSuite
JSContext* cx = script.GetContext();
JSAutoRequest rq(cx);
JS::Value v1;
ScriptInterface::ToJSVal(cx, v1, value);
JS::RootedValue v1(cx);
ScriptInterface::ToJSVal(cx, v1.get(), value);
std::string source;
TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalForScopeChain(cx)), "uneval", CScriptVal(v1), source));
@ -62,7 +62,7 @@ class TestScriptConversions : public CxxTest::TestSuite
TS_ASSERT_STR_EQUALS(source, expected);
T v2 = T();
TS_ASSERT(ScriptInterface::FromJSVal(script.GetContext(), v1, v2));
TS_ASSERT(ScriptInterface::FromJSVal(cx, v1, v2));
TS_ASSERT_EQUALS(value, v2);
}
@ -163,8 +163,8 @@ public:
JSAutoRequest rq(cx);
float f = 0;
JS::Value testNANVal;
ScriptInterface::ToJSVal(cx, testNANVal, NAN);
JS::RootedValue testNANVal(cx);
ScriptInterface::ToJSVal(cx, testNANVal.get(), NAN);
TS_ASSERT(ScriptInterface::FromJSVal(cx, testNANVal, f));
TS_ASSERT(isnan(f));
}

View File

@ -91,7 +91,7 @@ template<> void ScriptInterface::ToJSVal<const CParamNode*>(JSContext* cx, JS::V
ret = JSVAL_VOID;
}
template<> bool ScriptInterface::FromJSVal<CColor>(JSContext* cx, jsval v, CColor& out)
template<> bool ScriptInterface::FromJSVal<CColor>(JSContext* cx, JS::HandleValue v, CColor& out)
{
if (!v.isObject())
FAIL("jsval not an object");
@ -142,7 +142,7 @@ template<> void ScriptInterface::ToJSVal<CColor>(JSContext* cx, JS::Value& ret,
ret = JS::ObjectValue(*obj);
}
template<> bool ScriptInterface::FromJSVal<fixed>(JSContext* cx, jsval v, fixed& out)
template<> bool ScriptInterface::FromJSVal<fixed>(JSContext* cx, JS::HandleValue v, fixed& out)
{
JSAutoRequest rq(cx);
double ret;
@ -159,7 +159,7 @@ template<> void ScriptInterface::ToJSVal<fixed>(JSContext* UNUSED(cx), JS::Value
ret = JS::NumberValue(val.ToDouble());
}
template<> bool ScriptInterface::FromJSVal<CFixedVector3D>(JSContext* cx, jsval v, CFixedVector3D& out)
template<> bool ScriptInterface::FromJSVal<CFixedVector3D>(JSContext* cx, JS::HandleValue v, CFixedVector3D& out)
{
if (!v.isObject())
return false; // TODO: report type error
@ -210,7 +210,7 @@ template<> void ScriptInterface::ToJSVal<CFixedVector3D>(JSContext* cx, JS::Valu
ret = JS::ObjectValue(*obj);
}
template<> bool ScriptInterface::FromJSVal<CFixedVector2D>(JSContext* cx, jsval v, CFixedVector2D& out)
template<> bool ScriptInterface::FromJSVal<CFixedVector2D>(JSContext* cx, JS::HandleValue v, CFixedVector2D& out)
{
JSAutoRequest rq(cx);
if (!v.isObject())

View File

@ -52,7 +52,7 @@
JSAutoRequest rq(scriptInterface.GetContext()); \
if (! JS_GetProperty(scriptInterface.GetContext(), obj, #name, prop.address())) \
return NULL; \
if (! ScriptInterface::FromJSVal(scriptInterface.GetContext(), prop.get(), name)) \
if (! ScriptInterface::FromJSVal(scriptInterface.GetContext(), prop, name)) \
return NULL; \
}