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<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr, u16 flags = JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT> |
static JSFunctionSpec | Wrap (const char *name) |
| Return a function spec from a C++ function. More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr, u16 flags = JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT> |
static JSFunction * | Create (const ScriptRequest &rq, const char *name) |
| Return a JSFunction from a C++ function. More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr, u16 flags = JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT> |
static void | Register (const ScriptRequest &rq, const char *name) |
| Register a function on the native scope (usually 'Engine'). More...
|
|
template<auto callable, GetterFor< decltype(callable)> thisGetter = nullptr, u16 flags = JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT> |
static void | Register (JSContext *cx, JS::HandleObject scope, const char *name) |
| Register a function on. More...
|
|
|
template<size_t idx, typename T > |
static std::tuple< T > | DoConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &went_ok) |
| DoConvertFromJS takes a type, a JS argument, and converts. More...
|
|
template<size_t idx, typename T , typename V , typename ... Types> |
static std::tuple< T, V, Types... > | DoConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &went_ok) |
| Recursive wrapper: calls DoConvertFromJS for type T and recurses. More...
|
|
template<typename ... Types> |
static std::tuple< Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &went_ok, std::tuple< Types... > *) |
| ConvertFromJS is a wrapper around DoConvertFromJS, and serves to: More...
|
|
template<typename ... Types> |
static std::tuple< const ScriptRequest &, Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &went_ok, std::tuple< const ScriptRequest &, Types... > *) |
|
template<typename ... Types> |
static std::tuple< const ScriptInterface &, Types... > | ConvertFromJS (const ScriptRequest &rq, JS::CallArgs &args, bool &went_ok, 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<int i, typename T , typename... Ts> |
static void | AssignOrToJSValHelper (const ScriptRequest &rq, JS::MutableHandleValueVector argv, const T &a, const Ts &... params) |
| Recursive helper to call AssignOrToJSVal. More...
|
|
template<int i, typename... Ts> |
static void | AssignOrToJSValHelper (const ScriptRequest &rq, JS::MutableHandleValueVector argv) |
|
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 & |
went_ok, |
|
|
std::tuple< Types... > * |
|
|
) |
| |
|
inlinestaticprivate |
ConvertFromJS is a wrapper around DoConvertFromJS, and serves to:
- unwrap the tuple types as a parameter pack
- handle 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<size_t idx, typename T >
static std::tuple<T> ScriptFunction::DoConvertFromJS |
( |
const ScriptRequest & |
rq, |
|
|
JS::CallArgs & |
args, |
|
|
bool & |
went_ok |
|
) |
| |
|
inlinestaticprivate |
DoConvertFromJS takes a type, a JS argument, and converts.
The type T must be default constructible (except for HandleValue, which is handled specially). (possible) TODO: this could probably be changed if FromJSVal had a different signature.
- Parameters
-
went_ok | - true if the conversion succeeded and went_ok was true before, false otherwise. |
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.