Commit d0719b4f authored by Iain Lane's avatar Iain Lane

New upstream version 1.53.3

parents 4ba9ffaa 9bbbf6ad
Version 1.53.2
--------------
- The `Template` parameter passed to `GObject.registerClass()` now accepts
file:/// URIs as well as resource:/// URIs and byte arrays.
- New API: `gjs_get_js_version()` returns a string identifying the version of
the underlying SpiderMonkey JS engine. The interpreter executable has also
gained a `--jsversion` argument which will print this string.
- Several fixes for memory efficiency and performance.
- Once again we welcomed contributions from a number of first-time contributors!
- Closed bugs and merge requests:
* Add support for file:/// uri to glade template [#108, !41, Jesus Bermudez,
Philip Chimento]
* Reduce memory overhead of g_object_weak_ref() [#144, !122, Carlos Garnacho,
Philip Chimento]
* gjs: JS_GetContextPrivate(): gjs-console killed by SIGSEGV [#148, !121,
Philip Chimento]
* Use compacting GC on RSS size growth [#151, !133, Carlos Garnacho]
* Segfault on enumeration of GjSFileImporter properties when a searchpath
entry contains a symlink [#154, !144, Ole Jørgen Brønner]
* Compare linter jobs to correct base [#156, !140, Claudio André]
* Various maintenance [!141, Philip Chimento]
* Support interface signal handlers [!142, Tomasz Miąsko]
* Remove unnecessary inline [!145, Emmanuele Bassi]
* Add badges to the readme [!146, !147, Claudio André]
* Fix debug logging [!148, Philip Chimento]
* CI: add a GC zeal test [!149, Claudio André]
Version 1.53.1
--------------
......
[![Build Status](https://gitlab.gnome.org/GNOME/gjs/badges/master/build.svg)](https://gitlab.gnome.org/GNOME/gjs/pipelines)
[![coverage report](https://gitlab.gnome.org/GNOME/gjs/badges/master/coverage.svg)](https://gnome.pages.gitlab.gnome.org/gjs/)
[![Coverage report](https://gitlab.gnome.org/GNOME/gjs/badges/master/coverage.svg)](https://gnome.pages.gitlab.gnome.org/gjs/)
[![Contributors](https://img.shields.io/github/contributors/GNOME/gjs.svg)](https://gitlab.gnome.org/GNOME/gjs/graphs/master)
[![LoC](https://tokei.rs/b1/github/GNOME/gjs?category=code)](https://gitlab.gnome.org/GNOME/gjs/tree/master)
[![Last commit](https://img.shields.io/github/last-commit/GNOME/gjs.svg)](https://gitlab.gnome.org/GNOME/gjs/commits/master)
[![Search hit](https://img.shields.io/github/search/GNOME/gjs/goto.svg?label=github%20hits)](https://github.com/search?utf8=%E2%9C%93&q=gjs&type=)
[![License](https://img.shields.io/badge/License-LGPL%20v2%2B-blue.svg)](https://gitlab.gnome.org/GNOME/gjs/blob/master/COPYING)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitlab.gnome.org/GNOME/gjs/blob/master/COPYING)
......
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for gjs 1.53.1.
# Generated by GNU Autoconf 2.69 for gjs 1.53.3.
#
# Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=gjs>.
#
......@@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gjs'
PACKAGE_TARNAME='gjs'
PACKAGE_VERSION='1.53.1'
PACKAGE_STRING='gjs 1.53.1'
PACKAGE_VERSION='1.53.3'
PACKAGE_STRING='gjs 1.53.3'
PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=gjs'
PACKAGE_URL='https://wiki.gnome.org/Projects/Gjs'
......@@ -1451,7 +1451,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures gjs 1.53.1 to adapt to many kinds of systems.
\`configure' configures gjs 1.53.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
......@@ -1521,7 +1521,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of gjs 1.53.1:";;
short | recursive ) echo "Configuration of gjs 1.53.3:";;
esac
cat <<\_ACEOF
......@@ -1700,7 +1700,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
gjs configure 1.53.1
gjs configure 1.53.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
......@@ -2251,7 +2251,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by gjs $as_me 1.53.1, which was
It was created by gjs $as_me 1.53.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
......@@ -3114,7 +3114,7 @@ fi
# Define the identity of the package.
PACKAGE='gjs'
VERSION='1.53.1'
VERSION='1.53.3'
cat >>confdefs.h <<_ACEOF
......@@ -3341,10 +3341,10 @@ ac_config_headers="$ac_config_headers config.h"
GJS_VERSION=15301
GJS_VERSION=15303
$as_echo "#define GJS_VERSION (1 * 100 + 53) * 100 + 1" >>confdefs.h
$as_echo "#define GJS_VERSION (1 * 100 + 53) * 100 + 3" >>confdefs.h
GETTEXT_PACKAGE=gjs
......@@ -23346,7 +23346,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by gjs $as_me 1.53.1, which was
This file was extended by gjs $as_me 1.53.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
......@@ -23417,7 +23417,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
gjs config.status 1.53.1
gjs config.status 1.53.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
......
......@@ -3,7 +3,7 @@
m4_define(pkg_major_version, 1)
m4_define(pkg_minor_version, 53)
m4_define(pkg_micro_version, 1)
m4_define(pkg_micro_version, 3)
m4_define(pkg_version, pkg_major_version.pkg_minor_version.pkg_micro_version)
m4_define(pkg_int_version, (pkg_major_version * 100 + pkg_minor_version) * 100 + pkg_micro_version)
......
......@@ -1244,7 +1244,7 @@ throw_invalid_argument(JSContext *context,
gjs_throw(context, "Expected type %s for %s but got type '%s'",
type_tag_to_human_string(arginfo),
display_name, gjs_get_type_name(value));
display_name, JS::InformalValueTypeName(value));
g_free(display_name);
}
......@@ -1796,7 +1796,7 @@ gjs_value_to_g_argument(JSContext *context,
if (arg->v_pointer == NULL) {
gjs_debug(GJS_DEBUG_GFUNCTION,
"conversion of JSObject %p type %s to type %s failed",
&value.toObject(), gjs_get_type_name(value),
&value.toObject(), JS::InformalValueTypeName(value),
g_base_info_get_name ((GIBaseInfo *)interface_info));
/* gjs_throw should have been called already */
......@@ -1836,7 +1836,7 @@ gjs_value_to_g_argument(JSContext *context,
} else {
gjs_debug(GJS_DEBUG_GFUNCTION,
"JSObject type '%s' is neither null nor an object",
gjs_get_type_name(value));
JS::InformalValueTypeName(value));
wrong = true;
report_type_mismatch = true;
}
......
......@@ -118,67 +118,63 @@ boxed_resolve(JSContext *context,
JS::HandleId id,
bool *resolved)
{
Boxed *priv;
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p",
name.get(), obj.get(), priv);
Boxed *priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook, obj %s, priv %p",
gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(),
priv);
if (priv == nullptr)
return false; /* wrong class */
if (priv->gboxed == NULL) {
/* We are the prototype, so look for methods and other class properties */
GIFunctionInfo *method_info;
method_info = g_struct_info_find_method((GIStructInfo*) priv->info,
name);
if (priv->gboxed) {
/* We are an instance, not a prototype, so look for
* per-instance props that we want to define on the
* JSObject. Generally we do not want to cache these in JS, we
* want to always pull them from the C object, or JS would not
* see any changes made from C. So we use the get/set prop
* hooks, not this resolve hook.
*/
*resolved = false;
return true;
}
if (method_info != NULL) {
const char *method_name;
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
/* We are the prototype, so look for methods and other class properties */
GIFunctionInfo *method_info = g_struct_info_find_method(priv->info, name);
if (!method_info) {
*resolved = false;
return true;
}
#if GJS_VERBOSE_ENABLE_GI_USAGE
_gjs_log_info_usage((GIBaseInfo*) method_info);
_gjs_log_info_usage(method_info);
#endif
if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
method_name = g_base_info_get_name( (GIBaseInfo*) method_info);
gjs_debug(GJS_DEBUG_GBOXED,
"Defining method %s in prototype for %s.%s",
method_name,
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
/* obj is the Boxed prototype */
if (gjs_define_function(context, obj, priv->gtype,
(GICallableInfo *)method_info) == NULL) {
g_base_info_unref( (GIBaseInfo*) method_info);
return false;
}
*resolved = true;
} else {
*resolved = false;
}
if (g_function_info_get_flags(method_info) & GI_FUNCTION_IS_METHOD) {
const char *method_name = g_base_info_get_name(method_info);
gjs_debug(GJS_DEBUG_GBOXED,
"Defining method %s in prototype for %s.%s",
method_name,
g_base_info_get_namespace( (GIBaseInfo*) priv->info),
g_base_info_get_name( (GIBaseInfo*) priv->info));
/* obj is the Boxed prototype */
if (!gjs_define_function(context, obj, priv->gtype, method_info)) {
g_base_info_unref( (GIBaseInfo*) method_info);
return false;
}
*resolved = true;
} else {
/* We are an instance, not a prototype, so look for
* per-instance props that we want to define on the
* JSObject. Generally we do not want to cache these in JS, we
* want to always pull them from the C object, or JS would not
* see any changes made from C. So we use the get/set prop
* hooks, not this resolve hook.
*/
*resolved = false;
}
g_base_info_unref(method_info);
return true;
}
......@@ -272,7 +268,6 @@ boxed_init_from_props(JSContext *context,
priv->field_map = get_field_map(priv->info);
JS::RootedValue value(context);
JS::RootedId prop_id(context);
for (ix = 0, length = ids.length(); ix < length; ix++) {
GIFieldInfo *field_info;
GjsAutoJSChar name;
......@@ -289,9 +284,9 @@ boxed_init_from_props(JSContext *context,
/* ids[ix] is reachable because props is rooted, but require_property
* doesn't know that */
prop_id = ids[ix];
if (!gjs_object_require_property(context, props, "property list",
prop_id, &value))
JS::HandleId::fromMarkedLocation(ids[ix].address()),
&value))
return false;
if (!boxed_set_field_from_value(context, priv, field_info, value))
......@@ -370,15 +365,14 @@ boxed_new(JSContext *context,
} else if (priv->can_allocate_directly) {
boxed_new_direct(priv);
} else if (priv->default_constructor >= 0) {
bool retval;
/* for simplicity, we simply delegate all the work to the actual JS constructor
function (which we retrieve from the JS constructor, that is, Namespace.BoxedType,
or object.constructor, given that object was created with the right prototype */
JS::RootedId default_constructor_name(context, priv->default_constructor_name);
retval = boxed_invoke_constructor(context, obj,
default_constructor_name, args);
return retval;
/* for simplicity, we simply delegate all the work to the actual JS
* constructor function (which we retrieve from the JS constructor,
* that is, Namespace.BoxedType, or object.constructor, given that
* object was created with the right prototype. The ID is traced from
* the object, so it's OK to create a handle from it. */
return boxed_invoke_constructor(context, obj,
JS::HandleId::fromMarkedLocation(priv->default_constructor_name.address()),
args);
} else {
gjs_throw(context, "Unable to construct struct type %s since it has no default constructor and cannot be allocated directly",
g_base_info_get_name((GIBaseInfo*) priv->info));
......@@ -831,23 +825,17 @@ define_boxed_class_fields(JSContext *cx,
* error message. If we omitted fields or defined them read-only
* we'd:
*
* - Storing a new property for a non-accessible field
* - Store a new property for a non-accessible field
* - Silently do nothing when writing a read-only field
*
* Which is pretty confusing if the only reason a field isn't
* writable is language binding or memory-management restrictions.
*
* We just go ahead and define the fields immediately for the
* class; doing it lazily in boxed_new_resolve() would be possible
* class; doing it lazily in boxed_resolve() would be possible
* as well if doing it ahead of time caused to much start-up
* memory overhead.
*/
if (n_fields > 256) {
g_warning("Only defining the first 256 fields in boxed type '%s'",
g_base_info_get_name ((GIBaseInfo *)priv->info));
n_fields = 256;
}
for (i = 0; i < n_fields; i++) {
GIFieldInfo *field = g_struct_info_get_field (priv->info, i);
const char *field_name = g_base_info_get_name ((GIBaseInfo *)field);
......
......@@ -200,6 +200,14 @@ gjs_callback_closure(ffi_cif *cif,
g_assert(trampoline);
gjs_callback_trampoline_ref(trampoline);
if (G_UNLIKELY(!gjs_closure_is_valid(trampoline->js_function))) {
warn_about_illegal_js_callback(trampoline, "during shutdown",
"destroying a Clutter actor or GTK widget with ::destroy signal "
"connected, or using the destroy(), dispose(), or remove() vfuncs");
gjs_callback_trampoline_unref(trampoline);
return;
}
context = gjs_closure_get_context(trampoline->js_function);
if (G_UNLIKELY(_gjs_context_is_sweeping(context))) {
warn_about_illegal_js_callback(trampoline, "during garbage collection",
......@@ -944,7 +952,7 @@ gjs_invoke_c_function(JSContext *context,
g_base_info_get_namespace( (GIBaseInfo*) function->info),
g_base_info_get_name( (GIBaseInfo*) function->info),
g_base_info_get_name( (GIBaseInfo*) &arg_info),
gjs_get_type_name(current_arg));
JS::InformalValueTypeName(current_arg));
failed = true;
break;
}
......
......@@ -301,17 +301,11 @@ fundamental_instance_resolve(JSContext *context,
bool *resolved)
{
FundamentalInstance *priv;
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL,
"Resolve prop '%s' hook obj %p priv %p",
name.get(), obj.get(), priv);
"Resolve prop '%s' hook, obj %s, priv %p",
gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), priv);
if (priv == nullptr)
return false; /* wrong class */
......@@ -328,6 +322,12 @@ fundamental_instance_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
/* We are the prototype, so look for methods and other class properties */
Fundamental *proto_priv = (Fundamental *) priv;
GIFunctionInfo *method_info;
......
......@@ -113,14 +113,8 @@ interface_resolve(JSContext *context,
bool *resolved)
{
Interface *priv;
GjsAutoJSChar name;
GIFunctionInfo *method_info;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
priv = priv_from_js(context, obj);
if (priv == nullptr)
......@@ -134,6 +128,12 @@ interface_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name);
if (method_info != NULL) {
......
......@@ -69,22 +69,22 @@ ns_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GNAMESPACE,
"Resolve prop '%s' hook obj %p priv %p",
name.get(), obj.get(), priv);
"Resolve prop '%s' hook, obj %s, priv %p",
gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), priv);
if (priv == NULL) {
*resolved = false; /* we are the prototype, or have the wrong class */
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
repo = g_irepository_get_default();
info = g_irepository_find_by_name(repo, priv->gi_namespace, name);
......
This diff is collapsed.
......@@ -61,6 +61,8 @@ bool gjs_typecheck_is_object(JSContext *context,
void gjs_object_prepare_shutdown(void);
void gjs_object_clear_toggles(void);
void gjs_object_shutdown_toggle_queue(void);
void gjs_object_context_dispose_notify(void *data,
GObject *where_the_object_was);
void gjs_object_define_static_methods(JSContext *context,
JS::HandleObject constructor,
......
......@@ -58,22 +58,21 @@ param_resolve(JSContext *context,
GIObjectInfo *info = NULL;
GIFunctionInfo *method_info;
Param *priv;
GjsAutoJSChar name;
bool ret = false;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
priv = priv_from_js(context, obj);
if (priv != NULL) {
/* instance, not prototype */
*resolved = false;
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM);
method_info = g_object_info_find_method(info, name);
......
......@@ -175,15 +175,9 @@ repo_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GREPO, "Resolve prop '%s' hook obj %p priv %p",
name.get(), obj.get(), priv);
gjs_debug_jsprop(GJS_DEBUG_GREPO, "Resolve prop '%s' hook, obj %s, priv %p",
gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), priv);
if (priv == NULL) {
/* we are the prototype, or have the wrong class */
......@@ -191,6 +185,12 @@ repo_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true;
}
if (!resolve_namespace_object(context, obj, id, name)) {
return false;
}
......
......@@ -60,17 +60,9 @@ union_resolve(JSContext *context,
JS::HandleId id,
bool *resolved)
{
Union *priv;
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p",
name.get(), obj.get(), priv);
Union *priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook, obj %s, priv %p",
gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), priv);
if (priv == nullptr)
return false; /* wrong class */
......@@ -87,6 +79,12 @@ union_resolve(JSContext *context,
return true;
}
GjsAutoJSChar name;
if (!gjs_get_string_id(context, id, &name)) {
*resolved = false;
return true; /* not resolved, but no error */
}
/* We are the prototype, so look for methods and other class properties */
GIFunctionInfo *method_info;
......
This diff is collapsed.
......@@ -36,6 +36,7 @@ static char *coverage_output_path = NULL;
static char *profile_output_path = nullptr;
static char *command = NULL;
static gboolean print_version = false;
static gboolean print_js_version = false;
static bool enable_profiler = false;
static gboolean parse_profile_arg(const char *, const char *, void *, GError **);
......@@ -43,6 +44,8 @@ static gboolean parse_profile_arg(const char *, const char *, void *, GError **)
/* Keep in sync with entries in check_script_args_for_stray_gjs_args() */
static GOptionEntry entries[] = {
{ "version", 0, 0, G_OPTION_ARG_NONE, &print_version, "Print GJS version and exit" },
{ "jsversion", 0, 0, G_OPTION_ARG_NONE, &print_js_version,
"Print version of the JS engine and exit" },
{ "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
{ "coverage-prefix", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &coverage_prefixes, "Add the prefix PREFIX to the list of files to generate coverage info for", "PREFIX" },
{ "coverage-output", 0, 0, G_OPTION_ARG_STRING, &coverage_output_path, "Write coverage output to a directory DIR. This option is mandatory when using --coverage-path", "DIR", },
......@@ -244,6 +247,7 @@ main(int argc, char **argv)
coverage_output_path = NULL;
command = NULL;
print_version = false;
print_js_version = false;
g_option_context_set_ignore_unknown_options(context, false);
g_option_context_set_help_enabled(context, true);
if (!g_option_context_parse_strv(context, &gjs_argv, &error))
......@@ -256,6 +260,11 @@ main(int argc, char **argv)
exit(0);
}
if (print_js_version) {
g_print("%s\n", gjs_get_js_version());
exit(0);
}
gjs_argc = g_strv_length(gjs_argv);
if (command != NULL) {
script = command;
......
......@@ -516,6 +516,8 @@ gjs_context_constructed(GObject *object)
g_mutex_unlock (&contexts_lock);
setup_dump_heap();
g_object_weak_ref(object, gjs_object_context_dispose_notify, nullptr);
}
static void
......@@ -1077,3 +1079,16 @@ gjs_context_get_profiler(GjsContext *self)
{
return self->profiler;
}
/**
* gjs_get_js_version:
*
* Returns the underlying version of the JS engine.
*
* Returns: a string
*/
const char *
gjs_get_js_version(void)
{
return JS_GetImplementationVersion();
}
......@@ -102,6 +102,9 @@ bool gjs_profiler_chain_signal(GjsContext *context,
GJS_EXPORT
void gjs_dumpstack (void);
GJS_EXPORT
const char *gjs_get_js_version(void);
G_END_DECLS
#endif /* __GJS_CONTEXT_H__ */
This diff is collapsed.
......@@ -248,10 +248,12 @@ public:
m_data = data;
m_root = new JS::PersistentRooted<T>(m_cx, thing);
auto gjs_cx = static_cast<GjsContext *>(JS_GetContextPrivate(m_cx));
g_assert(GJS_IS_CONTEXT(gjs_cx));
g_object_weak_ref(G_OBJECT(gjs_cx), on_context_destroy, this);
m_has_weakref = true;
if (notify) {
auto gjs_cx = static_cast<GjsContext *>(JS_GetContextPrivate(m_cx));
g_assert(GJS_IS_CONTEXT(gjs_cx));
g_object_weak_ref(G_OBJECT(gjs_cx), on_context_destroy, this);
m_has_weakref = true;
}
}
/* You can only assign directly to the GjsMaybeOwned wrapper in the
......
......@@ -24,6 +24,9 @@
#include <config.h>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <string.h>
#include "jsapi-util.h"
......@@ -362,6 +365,142 @@ gjs_intern_string_to_id(JSContext *cx,
{
JSAutoRequest ar(cx);
JS::RootedString str(cx, JS_AtomizeAndPinString(cx, string));
JS::RootedId id(cx, INTERNED_STRING_TO_JSID(cx, str));
return id;
return INTERNED_STRING_TO_JSID(cx, str);
}
static std::string
gjs_debug_flat_string(JSFlatString *fstr)
{
JSLinearString *str = js::FlatStringToLinearString(fstr);
size_t len = js::GetLinearStringLength(str);
JS::AutoCheckCannotGC nogc;
if (js::LinearStringHasLatin1Chars(str)) {
const JS::Latin1Char *chars = js::GetLatin1LinearStringChars(nogc, str);
return std::string(reinterpret_cast<const char *>(chars), len);
}
std::ostringstream out;
const char16_t *chars = js::GetTwoByteLinearStringChars(nogc, str);
for (size_t ix = 0; ix < len; ix++) {
char16_t c = chars[ix];
if (c == '\n')
out << "\\n";
else if (c == '\t')
out << "\\t";
else if (c >= 32 && c < 127)
out << c;
else if (c <= 255)
out << "\\x" << std::setfill('0') << std::setw(2) << unsigned(c);
else
out << "\\x" << std::setfill('0') << std::setw(4) << unsigned(c);
}
return out.str();
}
std::string
gjs_debug_string(JSString *str)
{
if (!JS_StringIsFlat(str)) {
std::ostringstream out("<non-flat string of length ");
out << JS_GetStringLength(str) << '>';
return out.str();
}
return gjs_debug_flat_string(JS_ASSERT_STRING_IS_FLAT(str));
}
std::string
gjs_debug_symbol(JS::Symbol * const sym)
{
/* This is OK because JS::GetSymbolCode() and JS::GetSymbolDescription()
* can't cause a garbage collection */
JS::HandleSymbol handle = JS::HandleSymbol::fromMarkedLocation(&sym);
JS::SymbolCode code = JS::GetSymbolCode(handle);
JSString *descr = JS::GetSymbolDescription(handle);
if (size_t(code) < JS::WellKnownSymbolLimit)
return gjs_debug_string(descr);
std::ostringstream out;