Split JS conversions from ScriptInterface.

All ToJSVal/FromJSVal definitions are put in a separate header.
Remove AssignOr[To/From]JSVal duplication.

The functions were already static so this is rather straightforward.

Follows 34b1920e7b and 2bae30c454

Differential Revision: https://code.wildfiregames.com/D3953
This was SVN commit r25428.
This commit is contained in:
wraitii
2021-05-13 09:43:33 +00:00
parent d798a2ec0e
commit 61e0aef0b4
40 changed files with 323 additions and 371 deletions
+9 -110
View File
@@ -21,6 +21,7 @@
#include "lib/file/vfs/vfs_path.h"
#include "maths/Fixed.h"
#include "ps/Errors.h"
#include "scriptinterface/ScriptConversions.h"
#include "scriptinterface/ScriptExceptions.h"
#include "scriptinterface/ScriptRequest.h"
#include "scriptinterface/ScriptTypes.h"
@@ -285,25 +286,6 @@ public:
bool Eval(const char* code, JS::MutableHandleValue out) const;
template<typename T> bool Eval(const char* code, T& out) const;
/**
* Convert a JS::Value to a C++ type. (This might trigger GC.)
*/
template<typename T> static bool FromJSVal(const ScriptRequest& rq, const JS::HandleValue val, T& ret);
/**
* Convert a C++ type to a JS::Value. (This might trigger GC. The return
* value must be rooted if you don't want it to be collected.)
* NOTE: We are passing the JS::Value by reference instead of returning it by value.
* The reason is a memory corruption problem that appears to be caused by a bug in Visual Studio.
* Details here: http://www.wildfiregames.com/forum/index.php?showtopic=17289&p=285921
*/
template<typename T> static void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue ret, T const& val);
/**
* Convert a named property of an object to a C++ type.
*/
template<typename T> static bool FromJSProperty(const ScriptRequest& rq, const JS::HandleValue val, const char* name, T& ret, bool strict = false);
/**
* MathRandom (this function) calls the random number generator assigned to this ScriptInterface instance and
* returns the generated number.
@@ -348,38 +330,6 @@ public:
return value;
}
/**
* Converts |a| if needed and assigns it to |handle|.
* This is meant for use in other templates where we want to use the same code for JS::RootedValue&/JS::HandleValue and
* other types. Note that functions are meant to take JS::HandleValue instead of JS::RootedValue&, but this implicit
* conversion does not work for templates (exact type matches required for type deduction).
* A similar functionality could also be implemented as a ToJSVal specialization. The current approach was preferred
* because "conversions" from JS::HandleValue to JS::MutableHandleValue are unusual and should not happen "by accident".
*/
template <typename T>
static void AssignOrToJSVal(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a);
/**
* The same as AssignOrToJSVal, but also allows JS::Value for T.
* In most cases it's not safe to use the plain (unrooted) JS::Value type, but this can happen quite
* easily with template functions. The idea is that the linker prints an error if AssignOrToJSVal is
* used with JS::Value. If the specialization for JS::Value should be allowed, you can use this
* "unrooted" version of AssignOrToJSVal.
*/
template <typename T>
static void AssignOrToJSValUnrooted(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a)
{
AssignOrToJSVal(rq, handle, a);
}
/**
* Converts |val| to T if needed or just returns it if it's a handle.
* This is meant for use in other templates where we want to use the same code for JS::HandleValue and
* other types.
*/
template <typename T>
static T AssignOrFromJSVal(const ScriptRequest& rq, const JS::HandleValue& val, bool& ret);
private:
static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj);
@@ -388,7 +338,7 @@ private:
static bool CreateObject_(const ScriptRequest& rq, JS::MutableHandleObject obj, const char* propertyName, const T& propertyValue, Args const&... args)
{
JS::RootedValue val(rq.cx);
AssignOrToJSVal(rq, &val, propertyValue);
Script::ToJSVal(rq, &val, propertyValue);
return CreateObject_(rq, obj, args...) && JS_DefineProperty(rq.cx, obj, propertyName, val, JSPROP_ENUMERATE);
}
@@ -413,63 +363,12 @@ private:
std::map<std::string, CustomType> m_CustomObjectTypes;
};
template<typename T>
inline void ScriptInterface::AssignOrToJSVal(const ScriptRequest& rq, JS::MutableHandleValue handle, const T& a)
{
ToJSVal(rq, handle, a);
}
template<>
inline void ScriptInterface::AssignOrToJSVal<JS::PersistentRootedValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::PersistentRootedValue& a)
{
handle.set(a);
}
template<>
inline void ScriptInterface::AssignOrToJSVal<JS::Heap<JS::Value> >(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::Heap<JS::Value>& a)
{
handle.set(a);
}
template<>
inline void ScriptInterface::AssignOrToJSVal<JS::RootedValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::RootedValue& a)
{
handle.set(a);
}
template <>
inline void ScriptInterface::AssignOrToJSVal<JS::HandleValue>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::HandleValue& a)
{
handle.set(a);
}
template <>
inline void ScriptInterface::AssignOrToJSValUnrooted<JS::Value>(const ScriptRequest& UNUSED(rq), JS::MutableHandleValue handle, const JS::Value& a)
{
handle.set(a);
}
template<typename T>
inline T ScriptInterface::AssignOrFromJSVal(const ScriptRequest& rq, const JS::HandleValue& val, bool& ret)
{
T retVal;
ret = FromJSVal(rq, val, retVal);
return retVal;
}
template<>
inline JS::HandleValue ScriptInterface::AssignOrFromJSVal<JS::HandleValue>(const ScriptRequest& UNUSED(rq), const JS::HandleValue& val, bool& ret)
{
ret = true;
return val;
}
template<typename T>
bool ScriptInterface::SetGlobal(const char* name, const T& value, bool replace, bool constant, bool enumerate)
{
ScriptRequest rq(this);
JS::RootedValue val(rq.cx);
AssignOrToJSVal(rq, &val, value);
Script::ToJSVal(rq, &val, value);
return SetGlobal_(name, val, replace, constant, enumerate);
}
@@ -478,7 +377,7 @@ bool ScriptInterface::SetProperty(JS::HandleValue obj, const char* name, const T
{
ScriptRequest rq(this);
JS::RootedValue val(rq.cx);
AssignOrToJSVal(rq, &val, value);
Script::ToJSVal(rq, &val, value);
return SetProperty_(obj, name, val, constant, enumerate);
}
@@ -487,7 +386,7 @@ bool ScriptInterface::SetProperty(JS::HandleValue obj, const wchar_t* name, cons
{
ScriptRequest rq(this);
JS::RootedValue val(rq.cx);
AssignOrToJSVal(rq, &val, value);
Script::ToJSVal(rq, &val, value);
return SetProperty_(obj, name, val, constant, enumerate);
}
@@ -496,7 +395,7 @@ bool ScriptInterface::SetPropertyInt(JS::HandleValue obj, int name, const T& val
{
ScriptRequest rq(this);
JS::RootedValue val(rq.cx);
AssignOrToJSVal(rq, &val, value);
Script::ToJSVal(rq, &val, value);
return SetPropertyInt_(obj, name, val, constant, enumerate);
}
@@ -513,7 +412,7 @@ bool ScriptInterface::GetProperty(const ScriptRequest& rq, JS::HandleValue obj,
JS::RootedValue val(rq.cx);
if (!GetProperty(rq, obj, name, &val))
return false;
return FromJSVal(rq, val, out);
return Script::FromJSVal(rq, val, out);
}
template<typename T>
@@ -529,7 +428,7 @@ bool ScriptInterface::GetPropertyInt(const ScriptRequest& rq, JS::HandleValue ob
JS::RootedValue val(rq.cx);
if (!GetPropertyInt(rq, obj, name, &val))
return false;
return FromJSVal(rq, val, out);
return Script::FromJSVal(rq, val, out);
}
@@ -540,7 +439,7 @@ bool ScriptInterface::Eval(const char* code, T& ret) const
JS::RootedValue rval(rq.cx);
if (!Eval(code, &rval))
return false;
return FromJSVal(rq, rval, ret);
return Script::FromJSVal(rq, rval, ret);
}
#endif // INCLUDED_SCRIPTINTERFACE