0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-29 07:18:20 +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
:JS::Rooted<JSFunction *>
{
operator JSObject *() const;
explicit operator script() const;
value operator()(const object &, const JS::HandleValueArray &args) const;
value operator()(const object &) const;
string display_name() const;
string name() const;
// new function
function(JS::AutoObjectVector &stack,
const JS::CompileOptions &opts,
@ -38,8 +44,9 @@ struct function
const std::vector<std::string> &args,
const std::string &src);
function(JSFunction *const &);
explicit function(const value &);
function(JSFunction *const &);
function(JSFunction &);
function();
function(function &&) noexcept;
function(const function &) = delete;
@ -72,6 +79,20 @@ noexcept
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
function::function(const value &val)
:JS::Rooted<JSFunction *>
@ -81,25 +102,53 @@ function::function(const value &val)
}
{
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
function::function(JSFunction *const &func)
:JS::Rooted<JSFunction *>{*cx, func}
function::operator script()
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
name(const function &f)
{
return JS_GetFunctionId(f);
return f.name();
}
inline string
display_name(const function &f)
{
return JS_GetFunctionDisplayId(f);
return f.display_name();
}
} // namespace js

View file

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

View file

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

View file

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

View file

@ -46,8 +46,9 @@ struct string
string(const char *const &, const size_t &len);
explicit string(const std::string &);
string(const char *const &);
string(JSString *const &);
string(const value &);
string(JSString *const &);
string(JSString &);
string();
string(string &&) noexcept;
string(const string &) = delete;
@ -81,11 +82,10 @@ noexcept
}
inline
string::string(const value &val)
string::string(JSString &val)
:JS::Rooted<JSString *>
{
*cx,
JS::ToString(*cx, val)?: throw type_error("Failed to convert value to string")
*cx, &val
}
{
}
@ -95,7 +95,16 @@ string::string(JSString *const &val)
:JS::Rooted<JSString *>
{
*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(JSObject &);
value(JSString *const &);
value(JSFunction *const &);
value(JS::Symbol *const &);
value(const JS::Value &);
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::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>
value::value(const JS::Handle<T> &h)
: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
value::value(const jsid &val)
:JS::Rooted<JS::Value>{*cx}