0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-07-03 09:18:19 +02:00

ircd::js: Improve various type conversions and constructions.

This commit is contained in:
Jason Volk 2016-10-22 21:08:04 -07:00
parent 83fbbc6462
commit f8600a562a
6 changed files with 130 additions and 16 deletions

View file

@ -28,9 +28,15 @@ namespace js {
struct function struct function
:JS::Rooted<JSFunction *> :JS::Rooted<JSFunction *>
{ {
operator JSObject *() const;
explicit operator script() const;
value operator()(const object &, const JS::HandleValueArray &args) const; value operator()(const object &, const JS::HandleValueArray &args) const;
value operator()(const object &) const; value operator()(const object &) const;
string display_name() const;
string name() const;
// new function // new function
function(JS::AutoObjectVector &stack, function(JS::AutoObjectVector &stack,
const JS::CompileOptions &opts, const JS::CompileOptions &opts,
@ -38,8 +44,9 @@ struct function
const std::vector<std::string> &args, const std::vector<std::string> &args,
const std::string &src); const std::string &src);
function(JSFunction *const &);
explicit function(const value &); explicit function(const value &);
function(JSFunction *const &);
function(JSFunction &);
function(); function();
function(function &&) noexcept; function(function &&) noexcept;
function(const function &) = delete; function(const function &) = delete;
@ -72,6 +79,20 @@ noexcept
return *this; return *this;
} }
inline
function::function(JSFunction &func)
:JS::Rooted<JSFunction *>{*cx, &func}
{
}
inline
function::function(JSFunction *const &func)
:JS::Rooted<JSFunction *>{*cx, func}
{
if(unlikely(!get()))
throw internal_error("NULL function");
}
inline inline
function::function(const value &val) function::function(const value &val)
:JS::Rooted<JSFunction *> :JS::Rooted<JSFunction *>
@ -81,25 +102,53 @@ function::function(const value &val)
} }
{ {
if(!get()) if(!get())
throw type_error("Value is not an Function"); throw type_error("value is not a function");
}
inline string
function::name()
const
{
const auto ret(JS_GetFunctionId(*this));
return ret? string(ret) : string("<unnamed>");
}
inline string
function::display_name()
const
{
const auto ret(JS_GetFunctionDisplayId(*this));
return ret? string(ret) : string("<anonymous>");
} }
inline inline
function::function(JSFunction *const &func) function::operator script()
:JS::Rooted<JSFunction *>{*cx, func} const
{ {
return JS_GetFunctionScript(*cx, *this);
}
inline
function::operator JSObject *()
const
{
const auto ret(JS_GetFunctionObject(get()));
if(unlikely(!ret))
throw type_error("function cannot cast to Object");
return ret;
} }
inline string inline string
name(const function &f) name(const function &f)
{ {
return JS_GetFunctionId(f); return f.name();
} }
inline string inline string
display_name(const function &f) display_name(const function &f)
{ {
return JS_GetFunctionDisplayId(f); return f.display_name();
} }
} // namespace js } // namespace js

View file

@ -64,12 +64,12 @@ inline JSVersion version(const char *const &v) { return JS_StringToVersion(v);
#include "string.h" #include "string.h"
#include "id.h" #include "id.h"
#include "object.h" #include "object.h"
#include "script.h"
#include "function.h" #include "function.h"
#include "vector.h" #include "vector.h"
#include "priv.h" #include "priv.h"
#include "get.h" #include "get.h"
#include "call.h" #include "call.h"
#include "script.h"
#include "for_each.h" #include "for_each.h"
#include "debug.h" #include "debug.h"
#include "trap.h" #include "trap.h"

View file

@ -34,8 +34,12 @@ struct object
object(const JSClass *const &, const object &proto); object(const JSClass *const &, const object &proto);
object(const JSClass *const &); object(const JSClass *const &);
object(const JS::MutableHandleObject &h): object{h.get()} {}
object(const JS::HandleObject &h): object{h.get()} {}
explicit object(const value &);
object(JSFunction *const &);
object(JSObject *const &); object(JSObject *const &);
object(const value &); object(JSObject &);
object(); object();
object(object &&) noexcept; object(object &&) noexcept;
object(const object &) = delete; object(const object &) = delete;
@ -44,7 +48,11 @@ struct object
inline inline
object::object() object::object()
:JS::Rooted<JSObject *>{*cx} :JS::Rooted<JSObject *>
{
*cx,
JS_NewPlainObject(*cx)
}
{ {
} }
@ -65,6 +73,20 @@ noexcept
return *this; return *this;
} }
inline
object::object(JSObject &obj)
:JS::Rooted<JSObject *>{*cx, &obj}
{
}
inline
object::object(JSObject *const &obj)
:JS::Rooted<JSObject *>{*cx, obj}
{
if(unlikely(!get()))
throw internal_error("NULL object");
}
inline inline
object::object(const value &val) object::object(const value &val)
:JS::Rooted<JSObject *>{*cx} :JS::Rooted<JSObject *>{*cx}
@ -74,9 +96,15 @@ object::object(const value &val)
} }
inline inline
object::object(JSObject *const &obj) object::object(JSFunction *const &val)
:JS::Rooted<JSObject *>{*cx, obj} :JS::Rooted<JSObject *>
{ {
*cx,
val? JS_GetFunctionObject(val) : nullptr
}
{
if(unlikely(!get()))
throw type_error("Function cannot convert to Object");
} }
inline inline

View file

@ -33,6 +33,7 @@ struct script
script(const JS::CompileOptions &opts, const std::string &src); // new script script(const JS::CompileOptions &opts, const std::string &src); // new script
script(JSScript *const &); script(JSScript *const &);
script(JSScript &);
script(); script();
script(script &&) noexcept; script(script &&) noexcept;
script(const script &) = delete; script(const script &) = delete;
@ -51,10 +52,18 @@ noexcept
{ {
} }
inline
script::script(JSScript &val)
:JS::Rooted<JSScript *>{*cx, &val}
{
}
inline inline
script::script(JSScript *const &val) script::script(JSScript *const &val)
:JS::Rooted<JSScript *>{*cx, val} :JS::Rooted<JSScript *>{*cx, val}
{ {
if(unlikely(!get()))
throw internal_error("NULL script");
} }
} // namespace js } // namespace js

View file

@ -46,8 +46,9 @@ struct string
string(const char *const &, const size_t &len); string(const char *const &, const size_t &len);
explicit string(const std::string &); explicit string(const std::string &);
string(const char *const &); string(const char *const &);
string(JSString *const &);
string(const value &); string(const value &);
string(JSString *const &);
string(JSString &);
string(); string();
string(string &&) noexcept; string(string &&) noexcept;
string(const string &) = delete; string(const string &) = delete;
@ -81,11 +82,10 @@ noexcept
} }
inline inline
string::string(const value &val) string::string(JSString &val)
:JS::Rooted<JSString *> :JS::Rooted<JSString *>
{ {
*cx, *cx, &val
JS::ToString(*cx, val)?: throw type_error("Failed to convert value to string")
} }
{ {
} }
@ -95,7 +95,16 @@ string::string(JSString *const &val)
:JS::Rooted<JSString *> :JS::Rooted<JSString *>
{ {
*cx, *cx,
likely(val)? val : JS_GetEmptyString(*rt) likely(val)? val : throw internal_error("NULL string")
}
{
}
string::string(const value &val)
:JS::Rooted<JSString *>
{
*cx,
JS::ToString(*cx, val)?: throw type_error("Failed to convert value to string")
} }
{ {
} }

View file

@ -54,10 +54,12 @@ struct value
value(const jsid &); value(const jsid &);
value(JSObject &); value(JSObject &);
value(JSString *const &); value(JSString *const &);
value(JSFunction *const &);
value(JS::Symbol *const &); value(JS::Symbol *const &);
value(const JS::Value &); value(const JS::Value &);
template<class T> value(const JS::Handle<T> &h); template<class T> value(const JS::Handle<T> &h);
template<class T> value(const JS::MutableHandle<T> &h);
template<class T> value(const JS::Rooted<T> &r); template<class T> value(const JS::Rooted<T> &r);
template<class T> value(const JS::PersistentRooted<T> &p); template<class T> value(const JS::PersistentRooted<T> &p);
@ -102,6 +104,12 @@ value::value(const JS::Rooted<T> &r)
{ {
} }
template<class T>
value::value(const JS::MutableHandle<T> &h)
:value(h.get())
{
}
template<class T> template<class T>
value::value(const JS::Handle<T> &h) value::value(const JS::Handle<T> &h)
:value(h.get()) :value(h.get())
@ -132,6 +140,17 @@ value::value(JSString *const &val)
{ {
} }
inline
value::value(JSFunction *const &val)
:JS::Rooted<JS::Value>{*cx}
{
auto *const obj(JS_GetFunctionObject(val));
if(unlikely(!obj))
throw type_error("Function cannot convert to Object");
set(JS::ObjectValue(*obj));
}
inline inline
value::value(const jsid &val) value::value(const jsid &val)
:JS::Rooted<JS::Value>{*cx} :JS::Rooted<JS::Value>{*cx}