mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
Improve JS Exception handling.
- Check for pending exceptions after function calls and script executions. - Call LOGERROR instead of JS_ReportError when there is a conversion error in FromJSVal, since that can only be called from C++ (where JS errors don't really make sense). Instead, C++ callers of FromJSVal should handle the failure and, themselves, either report an error or simply do something else. - Wrap JS_ReportError since that makes updating it later easier. This isn't a systematical fix since ToJSVal also ought return a boolean for failures, and we probably should trigger errors instead of warnings on 'implicit' conversions, rather a preparation diff. Part of the SM52 migration, stage: SM45 compatible (actually SM52 incompatible, too). Based on a patch by: Itms Comments by: Vladislavbelov, Stan` Refs #742, #4893 Differential Revision: https://code.wildfiregames.com/D3093 This was SVN commit r24187.
This commit is contained in:
@@ -69,7 +69,7 @@ template <typename R>
|
||||
struct ScriptInterface_NativeWrapper
|
||||
{
|
||||
template<typename F, typename... Ts>
|
||||
static void call(const ScriptInterface::Request& rq, JS::MutableHandleValue rval, F fptr, Ts... params)
|
||||
static void call(const ScriptRequest& rq, JS::MutableHandleValue rval, F fptr, Ts... params)
|
||||
{
|
||||
ScriptInterface::AssignOrToJSValUnrooted<R>(rq, rval, fptr(ScriptInterface::GetScriptInterfaceAndCBData(rq.cx), params...));
|
||||
}
|
||||
@@ -80,7 +80,7 @@ template <>
|
||||
struct ScriptInterface_NativeWrapper<void>
|
||||
{
|
||||
template<typename F, typename... Ts>
|
||||
static void call(const ScriptInterface::Request& rq, JS::MutableHandleValue UNUSED(rval), F fptr, Ts... params)
|
||||
static void call(const ScriptRequest& rq, JS::MutableHandleValue UNUSED(rval), F fptr, Ts... params)
|
||||
{
|
||||
fptr(ScriptInterface::GetScriptInterfaceAndCBData(rq.cx), params...);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ template <typename R, typename TC>
|
||||
struct ScriptInterface_NativeMethodWrapper
|
||||
{
|
||||
template<typename F, typename... Ts>
|
||||
static void call(const ScriptInterface::Request& rq, JS::MutableHandleValue rval, TC* c, F fptr, Ts... params)
|
||||
static void call(const ScriptRequest& rq, JS::MutableHandleValue rval, TC* c, F fptr, Ts... params)
|
||||
{
|
||||
ScriptInterface::AssignOrToJSValUnrooted<R>(rq, rval, (c->*fptr)(params...));
|
||||
}
|
||||
@@ -102,7 +102,7 @@ template <typename TC>
|
||||
struct ScriptInterface_NativeMethodWrapper<void, TC>
|
||||
{
|
||||
template<typename F, typename... Ts>
|
||||
static void call(const ScriptInterface::Request& UNUSED(rq), JS::MutableHandleValue UNUSED(rval), TC* c, F fptr, Ts... params)
|
||||
static void call(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue UNUSED(rval), TC* c, F fptr, Ts... params)
|
||||
{
|
||||
(c->*fptr)(params...);
|
||||
}
|
||||
@@ -114,12 +114,12 @@ struct ScriptInterface_NativeMethodWrapper<void, TC>
|
||||
bool ScriptInterface::call(JSContext* cx, uint argc, JS::Value* vp) \
|
||||
{ \
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
|
||||
ScriptInterface::Request rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
|
||||
JS::RootedValue rval(rq.cx); \
|
||||
ScriptInterface_NativeWrapper<R>::template call<R( ScriptInterface::CmptPrivate* T0_TAIL_MAYBE_REF(z,i)) T0_TAIL(z,i)>(rq, &rval, fptr A0_TAIL(z,i)); \
|
||||
args.rval().set(rval); \
|
||||
return !ScriptInterface::IsExceptionPending(rq); \
|
||||
return !ScriptException::IsPending(rq); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
@@ -130,14 +130,14 @@ BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
bool ScriptInterface::callMethod(JSContext* cx, uint argc, JS::Value* vp) \
|
||||
{ \
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
|
||||
ScriptInterface::Request rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
TC* c = ScriptInterface::GetPrivate<TC>(rq, args, CLS); \
|
||||
if (! c) return false; \
|
||||
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
|
||||
JS::RootedValue rval(rq.cx); \
|
||||
ScriptInterface_NativeMethodWrapper<R, TC>::template call<R (TC::*)(T0_MAYBE_REF(z,i)) T0_TAIL(z,i)>(rq, &rval, c, fptr A0_TAIL(z,i)); \
|
||||
args.rval().set(rval); \
|
||||
return !ScriptInterface::IsExceptionPending(rq); \
|
||||
return !ScriptException::IsPending(rq); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
@@ -148,27 +148,27 @@ BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
bool ScriptInterface::callMethodConst(JSContext* cx, uint argc, JS::Value* vp) \
|
||||
{ \
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp); \
|
||||
ScriptInterface::Request rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
|
||||
TC* c = ScriptInterface::GetPrivate<TC>(rq, args, CLS); \
|
||||
if (! c) return false; \
|
||||
BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
|
||||
JS::RootedValue rval(rq.cx); \
|
||||
ScriptInterface_NativeMethodWrapper<R, TC>::template call<R (TC::*)(T0_MAYBE_REF(z,i)) const T0_TAIL(z,i)>(rq, &rval, c, fptr A0_TAIL(z,i)); \
|
||||
args.rval().set(rval); \
|
||||
return !ScriptInterface::IsExceptionPending(rq); \
|
||||
return !ScriptException::IsPending(rq); \
|
||||
}
|
||||
BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
|
||||
#undef OVERLOADS
|
||||
|
||||
template<int i, typename T, typename... Ts>
|
||||
static void AssignOrToJSValHelper(const ScriptInterface::Request& rq, JS::AutoValueVector& argv, const T& a, const Ts&... params)
|
||||
static void AssignOrToJSValHelper(const ScriptRequest& rq, JS::AutoValueVector& argv, const T& a, const Ts&... params)
|
||||
{
|
||||
ScriptInterface::AssignOrToJSVal(rq, argv[i], a);
|
||||
AssignOrToJSValHelper<i+1>(rq, argv, params...);
|
||||
}
|
||||
|
||||
template<int i, typename... Ts>
|
||||
static void AssignOrToJSValHelper(const ScriptInterface::Request& UNUSED(rq), JS::AutoValueVector& UNUSED(argv))
|
||||
static void AssignOrToJSValHelper(const ScriptRequest& UNUSED(rq), JS::AutoValueVector& UNUSED(argv))
|
||||
{
|
||||
cassert(sizeof...(Ts) == 0);
|
||||
// Nop, for terminating the template recursion.
|
||||
@@ -177,7 +177,7 @@ static void AssignOrToJSValHelper(const ScriptInterface::Request& UNUSED(rq), JS
|
||||
template<typename R, typename... Ts>
|
||||
bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, R& ret, const Ts&... params) const
|
||||
{
|
||||
ScriptInterface::Request rq(this);
|
||||
ScriptRequest rq(this);
|
||||
JS::RootedValue jsRet(rq.cx);
|
||||
JS::AutoValueVector argv(rq.cx);
|
||||
argv.resize(sizeof...(Ts));
|
||||
@@ -190,7 +190,7 @@ bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, R& ret
|
||||
template<typename R, typename... Ts>
|
||||
bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::Rooted<R>* ret, const Ts&... params) const
|
||||
{
|
||||
ScriptInterface::Request rq(this);
|
||||
ScriptRequest rq(this);
|
||||
JS::MutableHandle<R> jsRet(ret);
|
||||
JS::AutoValueVector argv(rq.cx);
|
||||
argv.resize(sizeof...(Ts));
|
||||
@@ -201,7 +201,7 @@ bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::Ro
|
||||
template<typename R, typename... Ts>
|
||||
bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::MutableHandle<R> ret, const Ts&... params) const
|
||||
{
|
||||
ScriptInterface::Request rq(this);
|
||||
ScriptRequest rq(this);
|
||||
JS::AutoValueVector argv(rq.cx);
|
||||
argv.resize(sizeof...(Ts));
|
||||
AssignOrToJSValHelper<0>(rq, argv, params...);
|
||||
@@ -212,7 +212,7 @@ bool ScriptInterface::CallFunction(JS::HandleValue val, const char* name, JS::Mu
|
||||
template<typename... Ts>
|
||||
bool ScriptInterface::CallFunctionVoid(JS::HandleValue val, const char* name, const Ts&... params) const
|
||||
{
|
||||
ScriptInterface::Request rq(this);
|
||||
ScriptRequest rq(this);
|
||||
JS::RootedValue jsRet(rq.cx);
|
||||
JS::AutoValueVector argv(rq.cx);
|
||||
argv.resize(sizeof...(Ts));
|
||||
|
||||
Reference in New Issue
Block a user