mirror of
https://github.com/matrix-construct/construct
synced 2024-10-01 21:28:53 +02:00
ircd::js: Improve various type conversions and constructions.
This commit is contained in:
parent
83fbbc6462
commit
f8600a562a
6 changed files with 130 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Reference in a new issue