Changes our JSNative functions to use JS::CallReceiver/JS::CallArgs.

This is the new way for working with arguments in JSNative functions.
JS_THIS_VALUE, JS_ARGV, JS_SET_RVAL and direct access to vp or argc are
deprecated and will probably be removed in future versions of
SpiderMonkey.
CallArgs also takes care of proper rooting and you can get the values as
Handles or MutableHandles. The interface changes a little bit for ESR
31, but commiting this now still makes it easier and the changes shout
be straigtforward (search and replace more or less).

Refs #2462
Refs #2415

This was SVN commit r15516.
This commit is contained in:
Yves
2014-07-12 16:55:09 +00:00
parent 7a1b92bffc
commit cfa59fc4e1
5 changed files with 95 additions and 94 deletions
+1 -1
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 < argc ? JS_ARGV(cx, vp)[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[i] : JS::UndefinedValue(), 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, "
+4 -4
View File
@@ -92,12 +92,12 @@ struct ScriptInterface_NativeMethodWrapper<void, TC> {
#define OVERLOADS(z, i, data) \
template <typename R, TYPENAME_T0_HEAD(z,i) R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
JSBool ScriptInterface::call(JSContext* cx, uint argc, jsval* vp) { \
UNUSED2(argc); \
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
SCRIPT_PROFILE \
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
jsval rval = JSVAL_VOID; \
ScriptInterface_NativeWrapper<R>::call(cx, rval, fptr A0_TAIL(z,i)); \
JS_SET_RVAL(cx, vp, rval); \
args.rval().set(rval); \
return !ScriptInterface::IsExceptionPending(cx); \
}
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
@@ -107,7 +107,7 @@ BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
#define OVERLOADS(z, i, data) \
template <typename R, TYPENAME_T0_HEAD(z,i) JSClass* CLS, typename TC, R (TC::*fptr) ( T0(z,i) )> \
JSBool ScriptInterface::callMethod(JSContext* cx, uint argc, jsval* vp) { \
UNUSED2(argc); \
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
SCRIPT_PROFILE \
if (ScriptInterface::GetClass(JS_THIS_OBJECT(cx, vp)) != CLS) return false; \
TC* c = static_cast<TC*>(ScriptInterface::GetPrivate(JS_THIS_OBJECT(cx, vp))); \
@@ -115,7 +115,7 @@ BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
jsval rval = JSVAL_VOID; \
ScriptInterface_NativeMethodWrapper<R, TC>::call(cx, rval, c, fptr A0_TAIL(z,i)); \
JS_SET_RVAL(cx, vp, rval); \
args.rval().set(rval); \
return !ScriptInterface::IsExceptionPending(cx); \
}
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
+31 -27
View File
@@ -464,80 +464,82 @@ void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
JSBool print(JSContext* cx, uint argc, jsval* vp)
{
for (uint i = 0; i < argc; ++i)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
for (uint i = 0; i < args.length(); ++i)
{
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[i], str))
if (!ScriptInterface::FromJSVal(cx, args[i], str))
return JS_FALSE;
debug_printf(L"%ls", str.c_str());
}
fflush(stdout);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
JSBool logmsg(JSContext* cx, uint argc, jsval* vp)
{
if (argc < 1)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() < 1)
{
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
if (!ScriptInterface::FromJSVal(cx, args[0], str))
return JS_FALSE;
LOGMESSAGE(L"%ls", str.c_str());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
JSBool warn(JSContext* cx, uint argc, jsval* vp)
{
if (argc < 1)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() < 1)
{
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
if (!ScriptInterface::FromJSVal(cx, args[0], str))
return JS_FALSE;
LOGWARNING(L"%ls", str.c_str());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
JSBool error(JSContext* cx, uint argc, jsval* vp)
{
if (argc < 1)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() < 1)
{
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
std::wstring str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
if (!ScriptInterface::FromJSVal(cx, args[0], str))
return JS_FALSE;
LOGERROR(L"%ls", str.c_str());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
JSBool deepcopy(JSContext* cx, uint argc, jsval* vp)
{
if (argc < 1)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() < 1)
{
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
jsval ret;
if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret, NULL, NULL))
if (!JS_StructuredClone(cx, args[0], args.rval().address(), NULL, NULL))
return JS_FALSE;
JS_SET_RVAL(cx, vp, ret);
return JS_TRUE;
}
@@ -545,10 +547,11 @@ JSBool ProfileStart(JSContext* cx, uint argc, jsval* vp)
{
const char* name = "(ProfileStart)";
if (argc >= 1)
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() >= 1)
{
std::string str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
if (!ScriptInterface::FromJSVal(cx, args[0], str))
return JS_FALSE;
typedef boost::flyweight<
@@ -565,18 +568,19 @@ JSBool ProfileStart(JSContext* cx, uint argc, jsval* vp)
g_Profiler2.RecordRegionEnter(name);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
args.rval().setUndefined();
return JS_TRUE;
}
JSBool ProfileStop(JSContext* UNUSED(cx), uint UNUSED(argc), jsval* vp)
{
JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
g_Profiler.Stop();
g_Profiler2.RecordRegionLeave("(ProfileStop)");
JS_SET_RVAL(cx, vp, JSVAL_VOID);
rec.rval().setUndefined();
return JS_TRUE;
}
@@ -600,12 +604,12 @@ static double generate_uniform_real(boost::rand48& rng, double min, double max)
JSBool Math_random(JSContext* cx, uint UNUSED(argc), jsval* vp)
{
JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
double r;
if(!ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->MathRandom(r))
return JS_FALSE;
jsval rv = JS::NumberValue(r);
JS_SET_RVAL(cx, vp, rv);
rec.rval().setNumber(r);
return JS_TRUE;
}