0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::js: Add object private/reserved getters and setters.

This commit is contained in:
Jason Volk 2016-10-29 05:15:36 -07:00
parent 213e4510b9
commit d0ec6497c7
7 changed files with 80 additions and 57 deletions

View file

@ -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

View file

@ -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"

View file

@ -49,10 +49,21 @@ struct object
object();
};
// Get the JSClass from which the trap can also be derived.
template<lifetime L> const JSClass &jsclass(const object<L> &);
// Private data slot (trap must have flag JSCLASS_HAS_PRIVATE)
template<class T, lifetime L> T &priv(const object<L> &);
template<lifetime L> void priv(object<L> &, void *const &);
template<lifetime L> void priv(object<L> &, const void *const &);
} // namespace basic
using object = basic::object<lifetime::stack>;
using heap_object = basic::object<lifetime::heap>;
using basic::priv;
IRCD_STRONG_TYPEDEF(uint, reserved)
//
// Implementation
@ -145,6 +156,46 @@ const
return this->get()? JS::ObjectValue(*this->get()) : JS::NullValue();
}
template<lifetime L>
void
priv(object<L> &obj,
const void *const &ptr)
{
priv(obj, const_cast<void *>(ptr));
}
template<lifetime L>
void
priv(object<L> &obj,
void *const &ptr)
{
JS_SetPrivate(obj, ptr);
}
template<class T,
lifetime L>
T &
priv(const object<L> &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<T *>(ret);
}
template<lifetime L>
const JSClass &
jsclass(const object<L> &obj)
{
const auto jsc(JS_GetClass(obj));
if(unlikely(!jsc))
throw error("Object has no JSClass");
return *const_cast<JSClass *>(jsc);
}
} // namespace basic
} // namespace js
} // namespace ircd

View file

@ -1,54 +0,0 @@
/*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
*
* 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<class T = void>
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<T *>(ret);
}
template<class T = void>
T &
priv(const JS::HandleObject &obj)
{
const auto jsc(JS_GetClass(obj));
if(unlikely(!jsc))
throw priv_error("Object has no JSClass");
return priv<T>(obj, jsc);
}
} // namespace js
} // namespace ircd

View file

@ -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);

View file

@ -36,6 +36,8 @@ template<lifetime L>
struct value
:root<JS::Value, L>
{
IRCD_OVERLOAD(pointer)
explicit operator std::string() const;
explicit operator double() const;
explicit operator uint64_t() const;
@ -48,6 +50,7 @@ struct value
template<class T, lifetime LL> value(const root<T, LL> &r);
template<class T> value(const JS::MutableHandle<T> &h);
template<class T> value(const JS::Handle<T> &h);
value(pointer_t, void *const &);
value(const std::string &);
value(const char *const &);
value(const nullptr_t &);
@ -189,6 +192,13 @@ value<L>::value(const char *const &s)
{
}
template<lifetime L>
value<L>::value(pointer_t,
void *const &ptr)
:value<L>::root::type{pointer_value(ptr)}
{
}
template<lifetime L>
template<class T>
value<L>::value(const JS::Handle<T> &h)

View file

@ -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