mirror of
https://github.com/matrix-construct/construct
synced 2025-03-14 05:20:17 +01:00
ircd::js: Add string literal constructor to prevent any alloc/copy/free.
This commit is contained in:
parent
fcc9cdee74
commit
5de2622bd1
4 changed files with 42 additions and 10 deletions
|
@ -25,8 +25,8 @@
|
|||
namespace ircd {
|
||||
namespace js {
|
||||
|
||||
void native_external_delete(const JSStringFinalizer *, char16_t *);
|
||||
extern JSStringFinalizer native_external_deleter;
|
||||
extern JSStringFinalizer native_external_delete; // calls `delete[]` on char16_t[]
|
||||
extern JSStringFinalizer native_external_static; // no-op for static/literal or self-managed
|
||||
|
||||
std::unique_ptr<char16_t[]> native_external_copy(const char *const &s, const size_t &len);
|
||||
std::unique_ptr<char16_t[]> native_external_copy(const char *const &s);
|
||||
|
|
|
@ -32,6 +32,7 @@ char16_t at(const JSString *const &, const size_t &);
|
|||
struct string
|
||||
:JS::Rooted<JSString *>
|
||||
{
|
||||
IRCD_OVERLOAD(literal)
|
||||
using handle = JS::HandleString;
|
||||
using handle_mutable = JS::MutableHandleString;
|
||||
|
||||
|
@ -47,6 +48,7 @@ struct string
|
|||
|
||||
char16_t operator[](const size_t &at) const;
|
||||
|
||||
string(literal_t, const char16_t *const &);
|
||||
string(const char16_t *const &, const size_t &len);
|
||||
string(const char16_t *const &);
|
||||
string(const std::u16string &);
|
||||
|
@ -145,7 +147,7 @@ string::string(const char *const &s,
|
|||
*cx, [&s, &len]
|
||||
{
|
||||
auto buf(native_external_copy(s, len));
|
||||
return JS_NewExternalString(*cx, buf.release(), len, &native_external_deleter);
|
||||
return JS_NewExternalString(*cx, buf.release(), len, &native_external_delete);
|
||||
}()
|
||||
}
|
||||
{
|
||||
|
@ -177,7 +179,7 @@ string::string(const char16_t *const &s,
|
|||
auto buf(std::make_unique<char16_t[]>(len+1));
|
||||
memcpy(buf.get(), s, len * 2);
|
||||
buf.get()[len] = char16_t(0);
|
||||
return JS_NewExternalString(*cx, buf.release(), len, &native_external_deleter);
|
||||
return JS_NewExternalString(*cx, buf.release(), len, &native_external_delete);
|
||||
}()
|
||||
}
|
||||
{
|
||||
|
@ -185,6 +187,19 @@ string::string(const char16_t *const &s,
|
|||
throw type_error("Failed to construct string from character array");
|
||||
}
|
||||
|
||||
inline
|
||||
string::string(literal_t,
|
||||
const char16_t *const &s)
|
||||
:JS::Rooted<JSString *>
|
||||
{
|
||||
*cx,
|
||||
JS_NewExternalString(*cx, s, std::char_traits<char16_t>::length(s), &native_external_static)
|
||||
}
|
||||
{
|
||||
if(unlikely(!get()))
|
||||
throw type_error("Failed to construct string from wide character literal");
|
||||
}
|
||||
|
||||
inline
|
||||
char16_t
|
||||
string::operator[](const size_t &pos)
|
||||
|
|
|
@ -207,7 +207,7 @@ value::value(const std::string &s)
|
|||
*cx, [&s]
|
||||
{
|
||||
auto buf(native_external_copy(s));
|
||||
const auto ret(JS_NewExternalString(*cx, buf.release(), s.size(), &native_external_deleter));
|
||||
const auto ret(JS_NewExternalString(*cx, buf.release(), s.size(), &native_external_delete));
|
||||
return JS::StringValue(ret);
|
||||
}()
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ value::value(const char *const &s)
|
|||
{
|
||||
const auto len(strlen(s));
|
||||
auto buf(native_external_copy(s, len));
|
||||
const auto ret(JS_NewExternalString(*cx, buf.release(), len, &native_external_deleter));
|
||||
const auto ret(JS_NewExternalString(*cx, buf.release(), len, &native_external_delete));
|
||||
return JS::StringValue(ret);
|
||||
}()
|
||||
}
|
||||
|
|
25
ircd/js.cc
25
ircd/js.cc
|
@ -1145,9 +1145,17 @@ const
|
|||
namespace ircd {
|
||||
namespace js {
|
||||
|
||||
JSStringFinalizer native_external_deleter
|
||||
void native_external_noop(const JSStringFinalizer *const fin, char16_t *const buf);
|
||||
void native_external_deleter(const JSStringFinalizer *const fin, char16_t *const buf);
|
||||
|
||||
JSStringFinalizer native_external_delete
|
||||
{
|
||||
native_external_delete
|
||||
native_external_deleter
|
||||
};
|
||||
|
||||
JSStringFinalizer native_external_static
|
||||
{
|
||||
native_external_noop
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
@ -1184,8 +1192,8 @@ ircd::js::native(const JSString *const &s,
|
|||
}
|
||||
|
||||
void
|
||||
ircd::js::native_external_delete(const JSStringFinalizer *const fin,
|
||||
char16_t *const buf)
|
||||
ircd::js::native_external_deleter(const JSStringFinalizer *const fin,
|
||||
char16_t *const buf)
|
||||
{
|
||||
log.debug("string delete (fin: %p buf: %p)",
|
||||
(const void *)fin,
|
||||
|
@ -1194,6 +1202,15 @@ ircd::js::native_external_delete(const JSStringFinalizer *const fin,
|
|||
delete[] buf;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::js::native_external_noop(const JSStringFinalizer *const fin,
|
||||
char16_t *const buf)
|
||||
{
|
||||
log.debug("string literal release (fin: %p buf: %p)",
|
||||
(const void *)fin,
|
||||
(const void *)buf);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ircd/js/error.h
|
||||
|
|
Loading…
Add table
Reference in a new issue