diff --git a/include/ircd/js/get.h b/include/ircd/js/get.h index f9fb70954..c67cc538d 100644 --- a/include/ircd/js/get.h +++ b/include/ircd/js/get.h @@ -25,7 +25,8 @@ namespace ircd { namespace js { -value get(const object::handle &obj, const id &id); +value get(const object::handle &obj, const reserved &id); +value get(const object::handle &obj, const id::handle &id); value get(const object::handle &src, const char *const path); } // namespace js diff --git a/include/ircd/js/js.h b/include/ircd/js/js.h index bdb5daad3..552157e3b 100644 --- a/include/ircd/js/js.h +++ b/include/ircd/js/js.h @@ -76,7 +76,6 @@ inline JSVersion version(const char *const &v) { return JS_StringToVersion(v); #include "script.h" #include "function.h" #include "function_literal.h" -#include "priv.h" #include "has.h" #include "get.h" #include "set.h" diff --git a/include/ircd/js/object.h b/include/ircd/js/object.h index 2d32fe2f4..f5a860a1b 100644 --- a/include/ircd/js/object.h +++ b/include/ircd/js/object.h @@ -49,10 +49,21 @@ struct object object(); }; +// Get the JSClass from which the trap can also be derived. +template const JSClass &jsclass(const object &); + +// Private data slot (trap must have flag JSCLASS_HAS_PRIVATE) +template T &priv(const object &); +template void priv(object &, void *const &); +template void priv(object &, const void *const &); + } // namespace basic using object = basic::object; using heap_object = basic::object; +using basic::priv; + +IRCD_STRONG_TYPEDEF(uint, reserved) // // Implementation @@ -145,6 +156,46 @@ const return this->get()? JS::ObjectValue(*this->get()) : JS::NullValue(); } +template +void +priv(object &obj, + const void *const &ptr) +{ + priv(obj, const_cast(ptr)); +} + +template +void +priv(object &obj, + void *const &ptr) +{ + JS_SetPrivate(obj, ptr); +} + +template +T & +priv(const object &obj) +{ + const auto &jsc(jsclass(obj)); + const auto ret(JS_GetInstancePrivate(*cx, obj, &jsc, nullptr)); + if(!ret) + throw error("Object has no private data"); + + return *reinterpret_cast(ret); +} + +template +const JSClass & +jsclass(const object &obj) +{ + const auto jsc(JS_GetClass(obj)); + if(unlikely(!jsc)) + throw error("Object has no JSClass"); + + return *const_cast(jsc); +} + } // namespace basic } // namespace js } // namespace ircd diff --git a/include/ircd/js/priv.h b/include/ircd/js/priv.h deleted file mode 100644 index bedbca6bc..000000000 --- a/include/ircd/js/priv.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2016 Charybdis Development Team - * Copyright (C) 2016 Jason Volk - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice is present in all copies. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once -#define HAVE_IRCD_JS_PRIV_H - -namespace ircd { -namespace js { - -IRCD_EXCEPTION(error, priv_error) - -template -T & -priv(const JS::HandleObject &obj, - const JSClass &jsc) -{ - const auto ret(JS_GetInstancePrivate(*cx, obj, &jsc, nullptr)); - if(!ret) - throw priv_error("Object has no private data"); - - return *static_cast(ret); -} - -template -T & -priv(const JS::HandleObject &obj) -{ - const auto jsc(JS_GetClass(obj)); - if(unlikely(!jsc)) - throw priv_error("Object has no JSClass"); - - return priv(obj, jsc); -} - -} // namespace js -} // namespace ircd diff --git a/include/ircd/js/set.h b/include/ircd/js/set.h index 16e712b1a..548a0fd08 100644 --- a/include/ircd/js/set.h +++ b/include/ircd/js/set.h @@ -25,6 +25,7 @@ namespace ircd { namespace js { +void set(const object::handle &obj, const reserved &slot, 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); diff --git a/include/ircd/js/value.h b/include/ircd/js/value.h index 87cfdc697..e94158b6d 100644 --- a/include/ircd/js/value.h +++ b/include/ircd/js/value.h @@ -36,6 +36,8 @@ template struct value :root { + IRCD_OVERLOAD(pointer) + explicit operator std::string() const; explicit operator double() const; explicit operator uint64_t() const; @@ -48,6 +50,7 @@ struct value template value(const root &r); template value(const JS::MutableHandle &h); template value(const JS::Handle &h); + value(pointer_t, void *const &); value(const std::string &); value(const char *const &); value(const nullptr_t &); @@ -189,6 +192,13 @@ value::value(const char *const &s) { } +template +value::value(pointer_t, + void *const &ptr) +:value::root::type{pointer_value(ptr)} +{ +} + template template value::value(const JS::Handle &h) diff --git a/ircd/js.cc b/ircd/js.cc index 8b07008d5..8ab5b735e 100644 --- a/ircd/js.cc +++ b/ircd/js.cc @@ -1042,6 +1042,14 @@ ircd::js::set(const object::handle &obj, throw jserror(jserror::pending); } +void +ircd::js::set(const object::handle &obj, + const reserved &slot, + const value &val) +{ + JS_SetReservedSlot(obj, slot, val); +} + /////////////////////////////////////////////////////////////////////////////// // // ircd/js/get.h @@ -1072,7 +1080,7 @@ ircd::js::get(const object::handle &src, ircd::js::value ircd::js::get(const object::handle &obj, - const id &id) + const id::handle &id) { value ret; if(!JS_GetPropertyById(*cx, obj, id, &ret) || undefined(ret)) @@ -1081,6 +1089,13 @@ ircd::js::get(const object::handle &obj, return ret; } +ircd::js::value +ircd::js::get(const object::handle &obj, + const reserved &slot) +{ + return JS_GetReservedSlot(obj, slot); +} + /////////////////////////////////////////////////////////////////////////////// // // ircd/js/has.h