0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-25 23:14:13 +01:00

ircd::js: Add handle typedefs in object wrappers to clean up arguments.

This commit is contained in:
Jason Volk 2016-10-24 22:14:39 -07:00
parent 87eee25953
commit fd0f925459
15 changed files with 153 additions and 98 deletions

View file

@ -27,23 +27,23 @@ namespace js {
value
call(const object &obj,
const JS::HandleFunction &func,
const JS::HandleValueArray &args = JS::HandleValueArray::empty());
const function::handle &func,
const vector<value>::handle &args = {});
value
call(const object &obj,
const JS::HandleValue &val,
const JS::HandleValueArray &args = JS::HandleValueArray::empty());
const value::handle &val,
const vector<value>::handle &args = {});
value
call(const object &obj,
const char *const &name,
const JS::HandleValueArray &args = JS::HandleValueArray::empty());
const vector<value>::handle &args = {});
value
call(const object &obj,
const std::string &name,
const JS::HandleValueArray &args = JS::HandleValueArray::empty());
const vector<value>::handle &args = {});
} // namespace js
} // namespace ircd

View file

@ -25,8 +25,8 @@
namespace ircd {
namespace js {
void del(const JS::HandleObject &obj, const id &id);
void del(const JS::HandleObject &src, const char *const path);
void del(const object::handle &obj, const id::handle &id);
void del(const object::handle &src, const char *const path);
} // namespace js
} // namespace ircd

View file

@ -29,13 +29,13 @@ using closure_id = std::function<void (const id &)>;
using closure_key_val = std::function<void (const value &, const value &)>;
using closure_mutable_key_val = std::function<void (const value &, value &)>;
void for_each(const object &, const closure_id &);
void for_each(const object &, const closure_key_val &);
void for_each(object &, const closure_mutable_key_val &);
void for_each(object::handle, const closure_id &);
void for_each(object::handle, const closure_key_val &);
void for_each(object::handle_mutable, const closure_mutable_key_val &);
inline void
for_each(object &obj,
for_each(object::handle_mutable obj,
const closure_mutable_key_val &closure)
{
for_each(obj, [&obj, &closure]
@ -48,7 +48,7 @@ for_each(object &obj,
}
inline void
for_each(const object &obj,
for_each(object::handle obj,
const closure_key_val &closure)
{
for_each(obj, [&obj, &closure]
@ -61,7 +61,7 @@ for_each(const object &obj,
}
inline void
for_each(const object &obj,
for_each(object::handle obj,
const closure_id &closure)
{
JS::Rooted<JS::IdVector> props(*cx, JS::IdVector(cx->ptr()));

View file

@ -32,6 +32,9 @@ string name(const JSFunction &);
struct function
:JS::Rooted<JSFunction *>
{
using handle = JS::HandleFunction;
using handle_mutable = JS::MutableHandleFunction;
operator JSObject *() const;
explicit operator script() const;
explicit operator string() const;

View file

@ -25,8 +25,8 @@
namespace ircd {
namespace js {
value get(const JS::HandleObject &obj, const id &id);
value get(const JS::HandleObject &src, const char *const path);
value get(const object::handle &obj, const id &id);
value get(const object::handle &src, const char *const path);
} // namespace js
} // namespace ircd

View file

@ -25,8 +25,8 @@
namespace ircd {
namespace js {
bool has(const JS::HandleObject &obj, const id &id);
bool has(const JS::HandleObject &src, const char *const path);
bool has(const object::handle &obj, const id::handle &id);
bool has(const object::handle &src, const char *const path);
} // namespace js
} // namespace ircd

View file

@ -28,6 +28,9 @@ namespace js {
struct id
:JS::Rooted<jsid>
{
using handle = JS::HandleId;
using handle_mutable = JS::MutableHandleId;
id(const JSProtoKey &);
id(const uint32_t &);
id(const jsid &);

View file

@ -28,14 +28,17 @@ namespace js {
struct object
:JS::Rooted<JSObject *>
{
using handle = JS::HandleObject;
using handle_mutable = JS::MutableHandleObject;
operator JS::Value() const;
// new object
object(const JSClass *const &, const object &proto);
object(const JSClass *const &);
object(const JS::MutableHandleObject &h): object{h.get()} {}
object(const JS::HandleObject &h): object{h.get()} {}
object(const object::handle_mutable &h): object{h.get()} {}
object(const object::handle &h): object{h.get()} {}
explicit object(const value &);
object(JSFunction *const &);
object(JSObject *const &);

View file

@ -28,6 +28,9 @@ namespace js {
struct script
:JS::Rooted<JSScript *>
{
using handle = JS::HandleScript;
using handle_mutable = JS::MutableHandleScript;
value operator()(JS::AutoObjectVector &stack) const;
value operator()() const;

View file

@ -25,8 +25,8 @@
namespace ircd {
namespace js {
void set(const JS::HandleObject &obj, const id &id, const value &val);
void set(const JS::HandleObject &src, const char *const path, const value &val);
void set(const object::handle &obj, const id::handle &id, const value &val);
void set(const object::handle &src, const char *const path, const value &val);
} // namespace js
} // namespace ircd

View file

@ -28,6 +28,9 @@ namespace js {
struct string
:JS::Rooted<JSString *>
{
using handle = JS::HandleString;
using handle_mutable = JS::MutableHandleString;
// SpiderMonkey may use utf-16/char16_t strings; these will help you then
static size_t convert(const char16_t *const &, char *const &buf, const size_t &max);
static std::string convert(const char16_t *const &);

View file

@ -31,14 +31,14 @@ class trap
std::unique_ptr<JSClass> _class;
// Override these to define JS objects in C
virtual JS::Value on_add(const JSObject &, const jsid &, const JS::Value &);
virtual JS::Value on_set(const JSObject &, const jsid &, const JS::Value &);
virtual JS::Value on_get(const JSObject &, const jsid &, const JS::Value &);
virtual bool on_del(const JSObject &, const jsid &);
virtual bool on_has(const JSObject &, const jsid &);
virtual bool on_enu(const JSObject &);
virtual value on_call(const JSObject &, const JS::CallArgs &);
virtual void on_ctor(object &, const JS::CallArgs &);
virtual value on_call(object::handle, const args &);
virtual value on_set(object::handle, id::handle, value::handle);
virtual value on_get(object::handle, id::handle, value::handle);
virtual void on_add(object::handle, id::handle, value::handle);
virtual bool on_del(object::handle, id::handle);
virtual bool on_has(object::handle, id::handle);
virtual bool on_enu(object::handle);
virtual void on_ctor(object &, const args &);
private:
void host_exception(const char *fmt, ...) const AFP(2, 3);

View file

@ -34,6 +34,9 @@ std::string native(const JSString *const &);
struct value
:JS::Rooted<JS::Value>
{
using handle = JS::HandleValue;
using handle_mutable = JS::MutableHandleValue;
explicit operator JSType() const;
explicit operator std::string() const;

View file

@ -27,11 +27,47 @@ namespace js {
template<class T>
struct vector
:JS::AutoVectorRooter<T>
{
using jsapi_type = T;
using local_type = T;
vector(const size_t &size)
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
this->resize(size);
}
vector()
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
}
vector(vector &&other) noexcept
:JS::AutoVectorRooter<jsapi_type>{*cx}
{
this->reserve(other.length());
for(auto &t : other)
this->infallibleAppend(t);
other.clear();
}
};
template<>
struct vector<value>
:JS::AutoVectorRooter<JS::Value>
{
using jsapi_type = JS::Value;
using local_type = value;
struct handle
:JS::HandleValueArray
{
using JS::HandleValueArray::HandleValueArray;
handle(): JS::HandleValueArray{JS::HandleValueArray::empty()} {}
};
// Construct vector from initializer list of raw `JS::Value`
// ex: JS::Value a; vector foo {{ a, a, ... }};
vector(const std::initializer_list<jsapi_type> &list)

View file

@ -211,15 +211,15 @@ noexcept try
{
assert(&our(c) == cx);
auto ca(JS::CallArgsFromVp(argc, argv));
object that(ca.callee());
const struct args args(argc, argv);
object that(args.callee());
auto &trap(from(that));
trap.debug("ctor: '%s'", trap.name().c_str());
object ret(JS_NewObjectForConstructor(*cx, &trap.jsclass(), ca));
trap.on_ctor(ret, ca);
ca.rval().set(ret);
object ret(JS_NewObjectForConstructor(*cx, &trap.jsclass(), args));
trap.on_ctor(ret, args);
args.rval().set(ret);
return true;
}
catch(const jserror &e)
@ -243,9 +243,9 @@ noexcept try
{
assert(&our(c) == cx);
auto ca(JS::CallArgsFromVp(argc, argv));
object that(ca.computeThis(c));
object func(ca.callee());
const struct args args(argc, argv);
object that(args.computeThis(c));
object func(args.callee());
auto &trap_that(from(that));
auto &trap_func(from(func));
@ -253,7 +253,7 @@ noexcept try
trap_that.debug("call: '%s'", trap_func.name().c_str());
trap_func.debug("call");
ca.rval().set(trap_func.on_call(*func.get(), ca));
args.rval().set(trap_func.on_call(func, args));
return true;
}
catch(const jserror &e)
@ -278,7 +278,7 @@ noexcept try
auto &trap(from(obj));
trap.debug("enu");
return trap.on_enu(*obj.get());
return trap.on_enu(obj);
}
catch(const jserror &e)
{
@ -303,7 +303,7 @@ noexcept try
auto &trap(from(obj));
trap.debug("has: '%s'", string(id).c_str());
*resolved = trap.on_has(*obj.get(), id.get());
*resolved = trap.on_has(obj, id);
return true;
}
catch(const jserror &e)
@ -331,7 +331,7 @@ noexcept try
auto &trap(from(obj));
trap.debug("del: '%s'", string(id).c_str());
if(trap.on_del(*obj.get(), id.get()))
if(trap.on_del(obj, id))
res.succeed();
return true;
@ -361,7 +361,8 @@ noexcept try
auto &trap(from(obj));
trap.debug("get: '%s'", string(id).c_str());
val.set(trap.on_get(*obj.get(), id.get(), val));
const value ret(trap.on_get(obj, id, val));
val.set(ret.get());
return true;
}
catch(const jserror &e)
@ -390,7 +391,8 @@ noexcept try
auto &trap(from(obj));
trap.debug("set: '%s'", string(id).c_str());
val.set(trap.on_set(*obj.get(), id.get(), val));
const value ret(trap.on_set(obj, id, val));
val.set(ret.get());
if(!val.isUndefined())
res.succeed();
@ -421,7 +423,7 @@ noexcept try
auto &trap(from(obj));
trap.debug("add: '%s'", string(id).c_str());
trap.on_add(*obj.get(), id.get(), val.get());
trap.on_add(obj, id, val);
return true;
}
catch(const jserror &e)
@ -546,59 +548,58 @@ const
void
ircd::js::trap::on_ctor(object &obj,
const JS::CallArgs &)
const args &)
{
}
ircd::js::value
ircd::js::trap::on_call(const JSObject &,
const JS::CallArgs &)
{
return {};
}
bool
ircd::js::trap::on_enu(const JSObject &obj)
{
return false;
}
bool
ircd::js::trap::on_has(const JSObject &obj,
const jsid &id)
{
return false;
}
bool
ircd::js::trap::on_del(const JSObject &obj,
const jsid &id)
ircd::js::trap::on_enu(object::handle)
{
return true;
}
JS::Value
ircd::js::trap::on_get(const JSObject &obj,
const jsid &id,
const JS::Value &val)
bool
ircd::js::trap::on_has(object::handle,
id::handle)
{
return false;
}
bool
ircd::js::trap::on_del(object::handle,
id::handle)
{
return true;
}
void
ircd::js::trap::on_add(object::handle,
id::handle,
value::handle)
{
}
ircd::js::value
ircd::js::trap::on_get(object::handle,
id::handle,
value::handle val)
{
return val;
}
JS::Value
ircd::js::trap::on_set(const JSObject &obj,
const jsid &id,
const JS::Value &val)
ircd::js::value
ircd::js::trap::on_set(object::handle,
id::handle,
value::handle val)
{
return val;
}
JS::Value
ircd::js::trap::on_add(const JSObject &obj,
const jsid &id,
const JS::Value &val)
ircd::js::value
ircd::js::trap::on_call(object::handle,
const args &)
{
return val;
return {};
}
///////////////////////////////////////////////////////////////////////////////
@ -737,8 +738,8 @@ const
ircd::js::value
ircd::js::call(const object &obj,
const JS::HandleFunction &func,
const JS::HandleValueArray &args)
const function::handle &func,
const vector<value>::handle &args)
{
value ret;
if(!JS_CallFunction(*cx, obj, func, args, &ret))
@ -749,8 +750,8 @@ ircd::js::call(const object &obj,
ircd::js::value
ircd::js::call(const object &obj,
const JS::HandleValue &val,
const JS::HandleValueArray &args)
const value::handle &val,
const vector<value>::handle &args)
{
value ret;
if(!JS_CallFunctionValue(*cx, obj, val, args, &ret))
@ -762,7 +763,7 @@ ircd::js::call(const object &obj,
ircd::js::value
ircd::js::call(const object &obj,
const char *const &name,
const JS::HandleValueArray &args)
const vector<value>::handle &args)
{
value ret;
if(!JS_CallFunctionName(*cx, obj, name, args, &ret))
@ -774,7 +775,7 @@ ircd::js::call(const object &obj,
ircd::js::value
ircd::js::call(const object &obj,
const std::string &name,
const JS::HandleValueArray &args)
const vector<value>::handle &args)
{
return call(obj, name.c_str(), args);
}
@ -785,7 +786,7 @@ ircd::js::call(const object &obj,
//
void
ircd::js::del(const JS::HandleObject &src,
ircd::js::del(const object::handle &src,
const char *const path)
{
value val;
@ -812,8 +813,8 @@ ircd::js::del(const JS::HandleObject &src,
}
void
ircd::js::del(const JS::HandleObject &obj,
const id &id)
ircd::js::del(const object::handle &obj,
const id::handle &id)
{
JS::ObjectOpResult res;
if(!JS_DeletePropertyById(*cx, obj, id, res))
@ -829,7 +830,7 @@ ircd::js::del(const JS::HandleObject &obj,
//
void
ircd::js::set(const JS::HandleObject &src,
ircd::js::set(const object::handle &src,
const char *const path,
const value &val)
{
@ -862,8 +863,8 @@ ircd::js::set(const JS::HandleObject &src,
}
void
ircd::js::set(const JS::HandleObject &obj,
const id &id,
ircd::js::set(const object::handle &obj,
const id::handle &id,
const value &val)
{
if(!JS_SetPropertyById(*cx, obj, id, val))
@ -876,7 +877,7 @@ ircd::js::set(const JS::HandleObject &obj,
//
ircd::js::value
ircd::js::get(const JS::HandleObject &src,
ircd::js::get(const object::handle &src,
const char *const path)
{
value ret;
@ -899,7 +900,7 @@ ircd::js::get(const JS::HandleObject &src,
}
ircd::js::value
ircd::js::get(const JS::HandleObject &obj,
ircd::js::get(const object::handle &obj,
const id &id)
{
value ret;
@ -915,7 +916,7 @@ ircd::js::get(const JS::HandleObject &obj,
//
bool
ircd::js::has(const JS::HandleObject &src,
ircd::js::has(const object::handle &src,
const char *const path)
{
bool ret(true);
@ -945,8 +946,8 @@ ircd::js::has(const JS::HandleObject &src,
}
bool
ircd::js::has(const JS::HandleObject &obj,
const id &id)
ircd::js::has(const object::handle &obj,
const id::handle &id)
{
bool ret;
if(!JS_HasPropertyById(*cx, obj, id, &ret))