Last active
October 7, 2023 23:13
-
-
Save jorendorff/74fc6833997bd83b226c507616dc588b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Template-based argument conversion in jsapi.h? | |
// First, to show what we're shooting for here... | |
namespace JS { | |
// The main entry point for getting object properties. Everything goes through here. | |
extern JS_PUBLIC_API(bool) | |
GetProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp); | |
// The helper template for automatically converting/rooting arguments of random types | |
// to the HandleObject and HandleId required for the above signature. | |
inline template <typename ObjectArg, typename IdArg> | |
bool | |
GetProperty(JSContext* cx, ObjectArg objArg, IdArg idArg, MutableHandleValue vp) | |
{ | |
// ArgumentHandler objects are fairly lightweight; | |
// they root and convert arguments as needed. | |
ArgumentHandler<ObjArg, JSObject*> obj(cx, objArg); | |
if (!obj.ok()) | |
return false; | |
ArgumentHandlerId<IdArg, jsid> id(cx, idArg); | |
if (!id.ok()) | |
return false; | |
return GetProperty(cx, obj.handle(), id.handle(), vp); | |
} | |
} | |
namespace JS { | |
// Implicit argument conversions ************************************************************** | |
// Template for implicitly converting a variety of argument types | |
// to various Handle<Target> types. | |
template <typename Arg, typename Target> struct ArgumentHandler; | |
// Handle<T> -> Handle<T>, a trivial conversion. | |
template <typename T> | |
struct ArgumentHandler<Handle<T>, T> | |
{ | |
Handle<T> h; | |
ArgumentHandler(JSContext*, Handle<T> arg) : h(arg) {} | |
bool ok() const { return true; } | |
Handle<T> handle() const { return h; } | |
}; | |
// Heap<T> -> Handle<T>, with automatic rooting. | |
template <typename T> | |
struct ArgumentHandler<Heap<T>, T> | |
{ | |
Rooted<T> root; | |
ArgumentHandlerObject(JSContext* cx, Heap<T> ptr) : root(cx, ptr) {} | |
bool ok() { return true; } | |
HandleObject handle() const { return robj; } | |
}; | |
extern JS_PUBLIC_API(bool) | |
CStringToId(JSContext* cx, const char* s, MutableHandleId out); | |
// const char* -> HandleId, a conversion that can fail with OOM. | |
template <> | |
struct ArgumentHandler<const char*, jsid> | |
{ | |
bool ok; | |
RootedId idroot; | |
ArgumentHandlerId(JSContext* cx, const char* s) : idroot(cx) { | |
ok = CStringToId(cx, s, &idroot); | |
} | |
bool ok() const { return ok; } | |
HandleId handle() const { return idroot; } | |
}; | |
// uint32_t -> HandleId, same deal. | |
template <> | |
struct ArgumentHandler<uint32_t, jsid> | |
{ | |
bool ok; | |
RootedId idroot; | |
ArgumentHandlerId(JSContext* cx, uint32_t index) : idroot(cx) { | |
ok = JS_IndexToId(cx, index, &idroot); | |
} | |
bool ok() const { return ok; } | |
HandleId handle() const { return idroot; } | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment