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
+81 -49
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);
}