This class introduces templates to conveniently wrap C++ functions in JSNative functions.
More...
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr> |
static bool | ToJSNative (JSContext *cx, unsigned argc, JS::Value *vp) |
| The meat of this file. More...
|
|
template<typename R , typename ... Args> |
static bool | Call (const ScriptRequest &rq, JS::HandleValue val, const char *name, R &ret, const Args &... args) |
| Call a JS function name, property of object val, with the arguments args. More...
|
|
template<typename ... Args> |
static bool | Call (const ScriptRequest &rq, JS::HandleValue val, const char *name, JS::MutableHandleValue ret, const Args &... args) |
|
template<typename ... Args> |
static bool | CallVoid (const ScriptRequest &rq, JS::HandleValue val, const char *name, const Args &... args) |
| Call a JS function name, property of object val, with the arguments args. More...
|
|
template<typename Callback > |
static JS::Value | RunGenerator (const ScriptRequest &rq, JS::HandleValue val, const char *name, JS::HandleValue arg, Callback yieldCallback) |
| Call a JS function name, property of object val, with the argument args. More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr> |
static JSFunctionSpec | Wrap (const char *name, const u16 flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) |
| Return a function spec from a C++ function. More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr> |
static JSFunction * | Create (const ScriptRequest &rq, const char *name, const u16 flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) |
| Return a JSFunction from a C++ function. More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr> |
static void | Register (const ScriptRequest &rq, const char *name, const u16 flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) |
| Register a function on the native scope (usually 'Engine'). More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr> |
static void | Register (JSContext *cx, JS::HandleObject scope, const char *name, const u16 flags=JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) |
| Register a function on. More...
|
|
|
template<size_t idx, typename T > |
static T | DoConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &wentOk) |
| DoConvertFromJS takes a type, a JS argument, and converts. More...
|
|
template<typename... T, size_t... idx> |
static std::tuple< T... > | DoConvertFromJS (std::index_sequence< idx... >, const ScriptRequest &rq, JS::CallArgs &args, bool &wentOk) |
| Wrapper: calls DoConvertFromJS for each element in T. More...
|
|
template<typename ... Types> |
static std::tuple< Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &wentOk, std::tuple< Types... > *) |
| ConvertFromJS is a wrapper around DoConvertFromJS, and handles specific cases for the first argument (ScriptRequest, ...). More...
|
|
template<typename ... Types> |
static std::tuple< const ScriptRequest &, Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &wentOk, std::tuple< const ScriptRequest &, Types... > *) |
|
template<typename ... Types> |
static std::tuple< const ScriptInterface &, Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &wentOk, std::tuple< const ScriptInterface &, Types... > *) |
|
template<auto callable, typename T , typename tuple > |
static args_info< decltype(callable)>::return_type | call (T *object, tuple &args) |
| Wrap std::apply for the case where we have an object method or a regular function. More...
|
|
template<typename... Types, size_t... idx> |
static void | ToJSValVector (std::index_sequence< idx... >, const ScriptRequest &rq, JS::MutableHandleValueVector argv, const Types &... params) |
| Converts any number of arguments to a JS::MutableHandleValueVector . More...
|
|
template<typename R , typename ... Args> |
static bool | Call_ (const ScriptRequest &rq, JS::HandleValue val, const char *name, R &ret, const Args &... args) |
| Wrapper around calling a JS function from C++. More...
|
|
This class introduces templates to conveniently wrap C++ functions in JSNative functions.
This is rather template heavy, so compilation times beware. The C++ code can have arbitrary arguments and arbitrary return types, so long as they can be converted to/from JS using Script::ToJSVal (FromJSVal respectively), and they are default-constructible (TODO: that can probably changed). (This could be a namespace, but I like being able to specify public/private).
template<typename R , typename ... Args>
static bool ScriptFunction::Call |
( |
const ScriptRequest & |
rq, |
|
|
JS::HandleValue |
val, |
|
|
const char * |
name, |
|
|
R & |
ret, |
|
|
const Args &... |
args |
|
) |
| |
|
inlinestatic |
Call a JS function name, property of object val, with the arguments args.
ret will be updated with the return value, if any.
- Returns
- the success (or failure) thereof.
template<typename R , typename ... Args>
static bool ScriptFunction::Call_ |
( |
const ScriptRequest & |
rq, |
|
|
JS::HandleValue |
val, |
|
|
const char * |
name, |
|
|
R & |
ret, |
|
|
const Args &... |
args |
|
) |
| |
|
inlinestaticprivate |
Wrapper around calling a JS function from C++.
Arguments are const& to avoid lvalue/rvalue issues, and so can't be used as out-parameters. In particular, the problem is that Rooted are deduced as Rooted, not Handle, and so can't be copied. This could be worked around with more templates, but it doesn't seem particularly worth doing.
template<typename ... Types>
static std::tuple< Types... > ScriptFunction::ConvertFromJS |
( |
const ScriptRequest & |
rq, |
|
|
JS::CallArgs & |
args, |
|
|
bool & |
wentOk, |
|
|
std::tuple< Types... > * |
|
|
) |
| |
|
inlinestaticprivate |
ConvertFromJS is a wrapper around DoConvertFromJS, and handles specific cases for the first argument (ScriptRequest, ...).
Trick: to unpack the types of the tuple as a parameter pack, we deduce them from the function signature. To do that, we want the tuple in the arguments, but we don't want to actually have to default-instantiate, so we'll pass a nullptr that's static_cast to what we want.
template<auto callable,
GetterFor< decltype(callable)> thisGetter = nullptr>
static bool ScriptFunction::ToJSNative |
( |
JSContext * |
cx, |
|
|
unsigned |
argc, |
|
|
JS::Value * |
vp |
|
) |
| |
|
inlinestatic |
The meat of this file.
This wraps a C++ function into a JSNative, so that it can be called from JS and manipulated in Spidermonkey. Most C++ functions can be directly wrapped, so long as their arguments are convertible from JS::Value and their return value is convertible to JS::Value (or void) The C++ function may optionally take const ScriptRequest& or ScriptInterface& as its first argument. The function may be an object method, in which case you need to pass an appropriate getter
Optimisation note: the ScriptRequest object is created even without arguments, as it's necessary for IsExceptionPending.
- Parameters
-
thisGetter | to get the object, if necessary. |
TODO: error handling isn't standard, and since this can call any C++ function, there's no simple obvious way to deal with it. For now we check for pending JS exceptions, but it would probably be nicer to standardise on something, or perhaps provide an "errorHandler" here.