1
0
forked from mirrors/0ad

Refactor all usage of RegisterFunction to ScriptFunction::Register

- Replace ScriptInterface::RegisterFunction with
ScriptFunction::Register
 - Mostly removing unused cmpPrivate*
 - Some usage introduces specific getters (mapgenerator, AIWorker,
XmppClient,...)
 - Several passthrough functions are simply removed in favour of calling
the original, reducing duplication
 - Make use of ScriptRequest/ScriptInterface capabilities where
relevant.
- Make JSI_* headers only expose necessary functions, lightening them
considerably and reducing duplication
 - Reuse namespaces in JSI_* implementations directly, reducing visual
noise there

Follows f3aedf88a6

Differential Revision: https://code.wildfiregames.com/D3626
This was SVN commit r24983.
This commit is contained in:
wraitii
2021-03-02 20:01:14 +00:00
parent 869076ebc5
commit cb346e207b
52 changed files with 820 additions and 1969 deletions
+43 -84
View File
@@ -17,6 +17,7 @@
#include "precompiled.h"
#include "FunctionWrapper.h"
#include "ScriptContext.h"
#include "ScriptExtraHeaders.h"
#include "ScriptInterface.h"
@@ -55,7 +56,6 @@ struct ScriptInterface_impl
{
ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptContext>& context);
~ScriptInterface_impl();
void Register(const char* name, JSNative fptr, uint nargs) const;
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted
// members have to be called before the context destructor.
@@ -176,107 +176,77 @@ bool error(JSContext* cx, uint argc, JS::Value* vp)
return true;
}
bool deepcopy(JSContext* cx, uint argc, JS::Value* vp)
JS::Value deepcopy(const ScriptRequest& rq, JS::HandleValue val)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (args.length() < 1)
if (val.isNullOrUndefined())
{
args.rval().setUndefined();
return true;
ScriptException::Raise(rq, "deepcopy requires one argument.");
return JS::UndefinedValue();
}
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
JS::RootedValue ret(cx);
if (!JS_StructuredClone(rq.cx, args[0], &ret, NULL, NULL))
return false;
args.rval().set(ret);
return true;
JS::RootedValue ret(rq.cx);
if (!JS_StructuredClone(rq.cx, val, &ret, NULL, NULL))
{
ScriptException::Raise(rq, "deepcopy StructureClone copy failed.");
return JS::UndefinedValue();
}
return ret;
}
bool deepfreeze(JSContext* cx, uint argc, JS::Value* vp)
JS::Value deepfreeze(const ScriptInterface& scriptInterface, JS::HandleValue val)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
if (args.length() != 1 || !args.get(0).isObject())
ScriptRequest rq(scriptInterface);
if (!val.isObject())
{
ScriptException::Raise(rq, "deepfreeze requires exactly one object as an argument.");
return false;
return JS::UndefinedValue();
}
ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->FreezeObject(args.get(0), true);
args.rval().set(args.get(0));
return true;
scriptInterface.FreezeObject(val, true);
return val;
}
bool ProfileStart(JSContext* cx, uint argc, JS::Value* vp)
void ProfileStart(const std::string& regionName)
{
const char* name = "(ProfileStart)";
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
if (args.length() >= 1)
{
std::string str;
if (!ScriptInterface::FromJSVal(rq, args[0], str))
return false;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
name = StringFlyweight(str).get().c_str();
}
if (!regionName.empty())
name = StringFlyweight(regionName).get().c_str();
if (CProfileManager::IsInitialised() && Threading::IsMainThread())
g_Profiler.StartScript(name);
g_Profiler2.RecordRegionEnter(name);
args.rval().setUndefined();
return true;
}
bool ProfileStop(JSContext* UNUSED(cx), uint argc, JS::Value* vp)
void ProfileStop()
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
if (CProfileManager::IsInitialised() && Threading::IsMainThread())
g_Profiler.Stop();
g_Profiler2.RecordRegionLeave();
args.rval().setUndefined();
return true;
}
bool ProfileAttribute(JSContext* cx, uint argc, JS::Value* vp)
void ProfileAttribute(const std::string& attr)
{
const char* name = "(ProfileAttribute)";
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
ScriptRequest rq(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface); \
if (args.length() >= 1)
{
std::string str;
if (!ScriptInterface::FromJSVal(rq, args[0], str))
return false;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
name = StringFlyweight(str).get().c_str();
}
if (!attr.empty())
name = StringFlyweight(attr).get().c_str();
g_Profiler2.RecordAttribute("%s", name);
args.rval().setUndefined();
return true;
}
// Math override functions:
@@ -336,18 +306,19 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh
JS_DefineProperty(m_cx, m_glob, "global", m_glob, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
// These first 4 actually use CallArgs & thus don't use ScriptFunction
JS_DefineFunction(m_cx, m_glob, "print", ::print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "log", ::logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "warn", ::warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "error", ::error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "clone", ::deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JS_DefineFunction(m_cx, m_glob, "deepfreeze", ::deepfreeze, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
ScriptFunction::Register<deepcopy>(m_cx, m_glob, "clone");
ScriptFunction::Register<deepfreeze>(m_cx, m_glob, "deepfreeze");
Register("ProfileStart", ::ProfileStart, 1);
Register("ProfileStop", ::ProfileStop, 0);
Register("ProfileAttribute", ::ProfileAttribute, 1);
m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
ScriptFunction::Register<&ProfileStart>(m_cx, m_nativeScope, "ProfileStart");
ScriptFunction::Register<&ProfileStop>(m_cx, m_nativeScope, "ProfileStop");
ScriptFunction::Register<&ProfileAttribute>(m_cx, m_nativeScope, "ProfileAttribute");
m_context->RegisterRealm(JS::GetObjectRealmOrNull(m_glob));
}
@@ -357,13 +328,6 @@ ScriptInterface_impl::~ScriptInterface_impl()
m_context->UnRegisterRealm(JS::GetObjectRealmOrNull(m_glob));
}
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs) const
{
JSAutoRealm autoRealm(m_cx, m_glob);
JS::RootedObject nativeScope(m_cx, m_nativeScope);
JS::RootedFunction func(m_cx, JS_DefineFunction(m_cx, nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT));
}
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptContext>& context) :
m(std::make_unique<ScriptInterface_impl>(nativeScopeName, context))
{
@@ -441,11 +405,6 @@ bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng)
return false;
}
void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs) const
{
m->Register(name, fptr, (uint)nargs);
}
JSContext* ScriptInterface::GetGeneralJSContext() const
{
return m->m_context->GetGeneralJSContext();