[gjs/wip/ptomato/mozjs38: 5/5] WIP - mozjs38
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs38: 5/5] WIP - mozjs38
- Date: Tue, 10 Jan 2017 05:50:46 +0000 (UTC)
commit 3eaa082adcdc1efbf2735b5832e0e7d02b3c5b36
Author: Philip Chimento <philip chimento gmail com>
Date: Mon Jan 9 21:49:04 2017 -0800
WIP - mozjs38
configure.ac | 2 +-
gi/arg.cpp | 23 ++--
gi/boxed.cpp | 59 ++++----
gi/closure.cpp | 2 +-
gi/enumeration.cpp | 3 +-
gi/function.cpp | 56 +++----
gi/function.h | 2 +-
gi/fundamental.cpp | 144 +++++++++---------
gi/interface.cpp | 50 +++---
gi/ns.cpp | 67 ++++-----
gi/object.cpp | 163 +++++++++++---------
gi/param.cpp | 38 ++---
gi/repo.cpp | 76 ++++-----
gi/union.cpp | 120 +++++++-------
gjs/byteArray.cpp | 19 ++-
gjs/context.cpp | 5 +-
gjs/coverage.cpp | 16 +-
gjs/importer.cpp | 325 +++++++++++++--------------------------
gjs/jsapi-constructor-proxy.cpp | 25 ++--
gjs/jsapi-dynamic-class.cpp | 9 +-
gjs/jsapi-util-string.cpp | 11 +-
gjs/jsapi-util.cpp | 26 ++--
gjs/jsapi-util.h | 26 ++--
gjs/jsapi-wrapper.h | 2 +-
gjs/runtime.cpp | 14 +-
gjs/stack.cpp | 10 +-
26 files changed, 583 insertions(+), 710 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 84adfe7..61ae200 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,7 +58,7 @@ GOBJECT_INTROSPECTION_REQUIRE([1.41.4])
GOBJECT_REQUIREMENT="gobject-2.0 >= glib_required_version"
gjs_base_packages="$GOBJECT_REQUIREMENT gio-2.0"
-common_packages="gthread-2.0 gio-2.0 >= glib_required_version mozjs-31"
+common_packages="gthread-2.0 gio-2.0 >= glib_required_version mozjs-38"
gjs_packages="gobject-introspection-1.0 libffi $common_packages"
gjs_cairo_packages="cairo cairo-gobject $common_packages"
gjs_gtk_packages="gtk+-3.0 >= 3.20"
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 8f6ba96..d6f9c3c 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -574,7 +574,7 @@ gjs_array_from_strv(JSContext *context,
for (i = 0; strv[i] != NULL; i++) {
elems.growBy(1);
- if (!gjs_string_from_utf8(context, strv[i], -1, elems.handleAt(i)))
+ if (!gjs_string_from_utf8(context, strv[i], -1, elems[i]))
return false;
}
@@ -959,7 +959,7 @@ gjs_array_from_flat_gvalue_array(JSContext *context,
for (i = 0; i < length; i ++) {
GValue *gvalue = &values[i];
- result = gjs_value_from_g_value(context, elems.handleAt(i), gvalue);
+ result = gjs_value_from_g_value(context, elems[i], gvalue);
if (!result)
break;
}
@@ -2156,8 +2156,7 @@ gjs_array_from_g_list (JSContext *context,
arg.v_pointer = list->data;
elems.growBy(1);
- if (!gjs_value_from_g_argument(context, elems.handleAt(i),
- param_info, &arg,
+ if (!gjs_value_from_g_argument(context, elems[i], param_info, &arg,
true))
return false;
++i;
@@ -2167,8 +2166,7 @@ gjs_array_from_g_list (JSContext *context,
arg.v_pointer = slist->data;
elems.growBy(1);
- if (!gjs_value_from_g_argument(context, elems.handleAt(i),
- param_info, &arg,
+ if (!gjs_value_from_g_argument(context, elems[i], param_info, &arg,
true))
return false;
++i;
@@ -2225,8 +2223,8 @@ gjs_array_from_carray_internal (JSContext *context,
#define ITERATE(type) \
for (i = 0; i < length; i++) { \
arg.v_##type = *(((g##type*)array) + i); \
- if (!gjs_value_from_g_argument(context, elems.handleAt(i), \
- param_info, &arg, true)) \
+ if (!gjs_value_from_g_argument(context, elems[i], param_info, \
+ &arg, true)) \
return false; \
}
@@ -2285,8 +2283,8 @@ gjs_array_from_carray_internal (JSContext *context,
for (i = 0; i < length; i++) {
arg.v_pointer = ((char*)array) + (struct_size * i);
- if (!gjs_value_from_g_argument(context, elems.handleAt(i),
- param_info, &arg, true))
+ if (!gjs_value_from_g_argument(context, elems[i], param_info,
+ &arg, true))
return false;
}
@@ -2441,7 +2439,7 @@ gjs_array_from_zero_terminated_c_array (JSContext *context,
for (i = 0; array[i]; i++) { \
arg.v_##type = array[i]; \
elems.growBy(1); \
- if (!gjs_value_from_g_argument(context, elems.handleAt(i), \
+ if (!gjs_value_from_g_argument(context, elems[i], \
param_info, &arg, true)) \
return false; \
} \
@@ -2531,8 +2529,7 @@ gjs_object_from_g_hash (JSContext *context,
return true;
}
- JS::RootedObject obj(context,
- JS_NewObject(context, NULL, JS::NullPtr(), JS::NullPtr()));
+ JS::RootedObject obj(context, JS_NewObject(context, NULL));
if (obj == NULL)
return false;
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index da6eea1..bb5ca19 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -110,24 +110,25 @@ gjs_define_static_methods(JSContext *context,
* if id was resolved.
*/
static bool
-boxed_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+boxed_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Boxed *priv;
- char *name;
- bool ret = false;
+ g_autofree char *name = NULL;
- if (!gjs_get_string_id(context, id, &name))
- return true; /* not resolved, but no error */
+ 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, obj.get(), priv);
if (priv == NULL)
- goto out; /* wrong class */
+ return false; /* wrong class */
if (priv->gboxed == NULL) {
/* We are the prototype, so look for methods and other class properties */
@@ -155,10 +156,12 @@ boxed_new_resolve(JSContext *context,
if (gjs_define_function(context, obj, priv->gtype,
(GICallableInfo *)method_info) == NULL) {
g_base_info_unref( (GIBaseInfo*) method_info);
- goto out;
+ return false;
}
- objp.set(obj); /* we defined the prop in object_proto */
+ *resolved = true;
+ } else {
+ *resolved = false;
}
g_base_info_unref( (GIBaseInfo*) method_info);
@@ -171,12 +174,9 @@ boxed_new_resolve(JSContext *context,
* see any changes made from C. So we use the get/set prop
* hooks, not this resolve hook.
*/
+ *resolved = false;
}
- ret = true;
-
- out:
- g_free(name);
- return ret;
+ return true;
}
/* Check to see if JS::Value passed in is another Boxed object of the same,
@@ -842,8 +842,8 @@ define_boxed_class_fields (JSContext *context,
bool result;
result = JS_DefineProperty(context, proto, field_name, JS::NullHandleValue,
- JSPROP_PERMANENT | JSPROP_SHARED,
- boxed_field_getter, boxed_field_setter);
+ JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_PROPOP_ACCESSORS,
+ (JSNative) boxed_field_getter, (JSNative) boxed_field_setter);
g_base_info_unref ((GIBaseInfo *)field);
@@ -873,10 +873,10 @@ boxed_trace(JSTracer *tracer,
if (priv == NULL)
return;
- JS_CallHeapIdTracer(tracer, &priv->zero_args_constructor_name,
- "Boxed::zero_args_constructor_name");
- JS_CallHeapIdTracer(tracer, &priv->default_constructor_name,
- "Boxed::default_constructor_name");
+ JS_CallIdTracer(tracer, &priv->zero_args_constructor_name,
+ "Boxed::zero_args_constructor_name");
+ JS_CallIdTracer(tracer, &priv->default_constructor_name,
+ "Boxed::default_constructor_name");
}
/* The bizarre thing about this vtable is that it applies to both
@@ -891,15 +891,14 @@ boxed_trace(JSTracer *tracer,
struct JSClass gjs_boxed_class = {
"GObject_Boxed",
JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE |
JSCLASS_HAS_RESERVED_SLOTS(1),
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) boxed_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ boxed_resolve,
+ NULL, /* convert */
boxed_finalize,
NULL, /* call */
NULL, /* hasInstance */
diff --git a/gi/closure.cpp b/gi/closure.cpp
index 829a436..7925835 100644
--- a/gi/closure.cpp
+++ b/gi/closure.cpp
@@ -338,7 +338,7 @@ gjs_closure_trace(GClosure *closure,
if (c->obj == NULL)
return;
- JS_CallHeapObjectTracer(tracer, &c->obj, "signal connection");
+ JS_CallObjectTracer(tracer, &c->obj, "signal connection");
}
GClosure*
diff --git a/gi/enumeration.cpp b/gi/enumeration.cpp
index d73622e..9d0eeb4 100644
--- a/gi/enumeration.cpp
+++ b/gi/enumeration.cpp
@@ -165,8 +165,7 @@ gjs_define_enumeration(JSContext *context,
enum_name = g_base_info_get_name( (GIBaseInfo*) info);
- JS::RootedObject enum_obj(context, JS_NewObject(context, NULL, JS::NullPtr(),
- global));
+ JS::RootedObject enum_obj(context, JS_NewObject(context, NULL, global));
if (enum_obj == NULL) {
g_error("Could not create enumeration %s.%s",
g_base_info_get_namespace( (GIBaseInfo*) info),
diff --git a/gi/function.cpp b/gi/function.cpp
index 76aa885..6476e27 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -83,14 +83,6 @@ gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline)
trampoline->ref_count--;
if (trampoline->ref_count == 0) {
- JSContext *context = trampoline->context;
-
- if (!trampoline->is_vfunc) {
- JS_BeginRequest(context);
- JS::RemoveValueRoot(context, &trampoline->js_function);
- JS_EndRequest(context);
- }
-
g_callable_info_free_closure(trampoline->info, trampoline->closure);
g_base_info_unref( (GIBaseInfo*) trampoline->info);
g_free (trampoline->param_types);
@@ -261,15 +253,14 @@ gjs_callback_closure(ffi_cif *cif,
goto out;
jsargs.growBy(1);
- if (!gjs_value_from_explicit_array(context, jsargs.handleAt(n_jsargs++),
+ if (!gjs_value_from_explicit_array(context, jsargs[n_jsargs++],
&type_info, (GArgument*) args[i], length.toInt32()))
goto out;
break;
}
case PARAM_NORMAL:
jsargs.growBy(1);
- if (!gjs_value_from_g_argument(context,
- jsargs.handleAt(n_jsargs++),
+ if (!gjs_value_from_g_argument(context, jsargs[n_jsargs++],
&type_info,
(GArgument *) args[i], false))
goto out;
@@ -454,9 +445,7 @@ gjs_callback_trampoline_new(JSContext *context,
trampoline->context = context;
trampoline->info = callable_info;
g_base_info_ref((GIBaseInfo*)trampoline->info);
- trampoline->js_function = function;
- if (!is_vfunc)
- JS::AddValueRoot(context, &trampoline->js_function);
+ trampoline->js_function.init(context, function);
/* Analyze param types and directions, similarly to init_cached_function_data */
n_args = g_callable_info_get_n_args(trampoline->info);
@@ -1010,7 +999,7 @@ gjs_invoke_c_function(JSContext *context,
did_throw_gerror = false;
}
- if (!js_rval.empty())
+ if (js_rval)
js_rval.ref().setUndefined();
/* Only process return values if the function didn't throw */
@@ -1040,9 +1029,9 @@ gjs_invoke_c_function(JSContext *context,
&arg_type_info,
&out_arg_cvalues[array_length_pos],
true);
- if (!arg_failed && !js_rval.empty()) {
+ if (!arg_failed && js_rval) {
arg_failed = !gjs_value_from_explicit_array(context,
- return_values.handleAt(next_rval),
+ return_values[next_rval],
&return_info,
&return_gargument,
length.toInt32());
@@ -1056,9 +1045,9 @@ gjs_invoke_c_function(JSContext *context,
&return_gargument))
failed = true;
} else {
- if (!js_rval.empty())
+ if (js_rval)
arg_failed = !gjs_value_from_g_argument(context,
- return_values.handleAt(next_rval),
+ return_values[next_rval],
&return_info, &return_gargument,
true);
/* Free GArgument, the JS::Value should have ref'd or copied it */
@@ -1173,7 +1162,7 @@ release:
array_length_pos = g_type_info_get_array_length(&arg_type_info);
- if (!js_rval.empty()) {
+ if (js_rval) {
if (array_length_pos >= 0) {
GIArgInfo array_length_arg;
GITypeInfo array_length_type_info;
@@ -1187,14 +1176,14 @@ release:
true);
if (!arg_failed) {
arg_failed = !gjs_value_from_explicit_array(context,
- return_values.handleAt(next_rval),
+ return_values[next_rval],
&arg_type_info,
arg,
array_length.toInt32());
}
} else {
arg_failed = !gjs_value_from_g_argument(context,
- return_values.handleAt(next_rval),
+ return_values[next_rval],
&arg_type_info,
arg,
true);
@@ -1267,7 +1256,7 @@ release:
* on its own, otherwise return a JavaScript array with
* [return value, out arg 1, out arg 2, ...]
*/
- if (!js_rval.empty()) {
+ if (js_rval) {
if (function->js_out_argc == 1) {
js_rval.ref().set(return_values[0]);
} else {
@@ -1317,8 +1306,7 @@ function_call(JSContext *context,
return true; /* we are the prototype, or have the wrong class */
/* COMPAT: mozilla::Maybe gains a much more usable API in future versions */
- mozilla::Maybe<JS::MutableHandleValue> m_retval;
- m_retval.construct(&retval);
+ mozilla::Maybe<JS::MutableHandleValue> m_retval(mozilla::Some<JS::MutableHandleValue>(&retval));
success = gjs_invoke_c_function(context, priv, object, js_argv, m_retval,
NULL);
if (success)
@@ -1463,13 +1451,13 @@ struct JSClass gjs_function_class = {
"GIRepositoryFunction", /* means "new GIRepositoryFunction()" works */
JSCLASS_HAS_PRIVATE |
JSCLASS_BACKGROUND_FINALIZE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ NULL, /* resolve */
+ NULL, /* convert */
function_finalize,
function_call
};
@@ -1687,7 +1675,7 @@ function_new(JSContext *context,
}
JS::RootedObject function(context,
- JS_NewObject(context, &gjs_function_class, JS::NullPtr(), global));
+ JS_NewObject(context, &gjs_function_class, global));
if (function == NULL) {
gjs_debug(GJS_DEBUG_GFUNCTION, "Failed to construct function");
return NULL;
@@ -1768,7 +1756,7 @@ gjs_invoke_c_function_uncached(JSContext *context,
/* COMPAT: mozilla::Maybe gains a much more usable API in future versions */
mozilla::Maybe<JS::MutableHandleValue> m_rval;
- m_rval.construct(rval);
+ m_rval.emplace(rval);
result = gjs_invoke_c_function(context, &function, obj, args, m_rval, NULL);
uninit_cached_function_data (&function);
return result;
diff --git a/gi/function.h b/gi/function.h
index 234b551..8732bbd 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -45,7 +45,7 @@ typedef struct {
gint ref_count;
JSContext *context;
GICallableInfo *info;
- JS::Heap<JS::Value> js_function;
+ JS::PersistentRootedValue js_function;
ffi_cif cif;
ffi_closure *closure;
GIScopeType scope;
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 56c7121..68905c6 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -224,11 +224,11 @@ find_fundamental_constructor(JSContext *context,
/**/
static bool
-fundamental_instance_new_resolve_interface(JSContext *context,
- JS::HandleObject obj,
- JS::MutableHandleObject objp,
- Fundamental *proto_priv,
- char *name)
+fundamental_instance_resolve_interface(JSContext *context,
+ JS::HandleObject obj,
+ bool *resolved,
+ Fundamental *proto_priv,
+ char *name)
{
GIFunctionInfo *method_info;
bool ret;
@@ -263,7 +263,7 @@ fundamental_instance_new_resolve_interface(JSContext *context,
if (gjs_define_function(context, obj,
proto_priv->gtype,
(GICallableInfo *) method_info)) {
- objp.set(obj);
+ *resolved = true;
} else {
ret = false;
}
@@ -278,22 +278,22 @@ fundamental_instance_new_resolve_interface(JSContext *context,
}
/*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
*/
static bool
-fundamental_instance_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+fundamental_instance_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
FundamentalInstance *priv;
- char *name;
- bool ret = false;
+ g_autofree char *name = NULL;
- if (!gjs_get_string_id(context, id, &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,
@@ -301,71 +301,70 @@ fundamental_instance_new_resolve(JSContext *context,
name, obj.get(), priv);
if (priv == NULL)
- goto out; /* wrong class */
+ return false; /* wrong class */
- if (priv->prototype == NULL) {
- /* We are the prototype, so look for methods and other class properties */
- Fundamental *proto_priv = (Fundamental *) priv;
- GIFunctionInfo *method_info;
+ if (priv->prototype != NULL) {
+ /* 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;
+ }
- method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
- name);
+ /* We are the prototype, so look for methods and other class properties */
+ Fundamental *proto_priv = (Fundamental *) priv;
+ GIFunctionInfo *method_info;
- if (method_info != NULL) {
- const char *method_name;
+ method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info,
+ name);
+
+ if (method_info != NULL) {
+ const char *method_name;
#if GJS_VERBOSE_ENABLE_GI_USAGE
- _gjs_log_info_usage((GIBaseInfo *) method_info);
+ _gjs_log_info_usage((GIBaseInfo *) 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);
-
- /* we do not define deprecated methods in the prototype */
- if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
- gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
- "Ignoring definition of deprecated method %s in prototype %s.%s",
- method_name,
- g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
- g_base_info_get_name((GIBaseInfo *) proto_priv->info));
- g_base_info_unref((GIBaseInfo *) method_info);
- ret = true;
- goto out;
- }
+ if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
+ method_name = g_base_info_get_name((GIBaseInfo *) method_info);
+ /* we do not define deprecated methods in the prototype */
+ if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) {
gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
- "Defining method %s in prototype for %s.%s",
+ "Ignoring definition of deprecated method %s in prototype %s.%s",
method_name,
g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
g_base_info_get_name((GIBaseInfo *) proto_priv->info));
+ g_base_info_unref((GIBaseInfo *) method_info);
+ *resolved = false;
+ return true;
+ }
- if (gjs_define_function(context, obj, proto_priv->gtype,
- method_info) == NULL) {
- g_base_info_unref((GIBaseInfo *) method_info);
- goto out;
- }
+ gjs_debug(GJS_DEBUG_GFUNDAMENTAL,
+ "Defining method %s in prototype for %s.%s",
+ method_name,
+ g_base_info_get_namespace((GIBaseInfo *) proto_priv->info),
+ g_base_info_get_name((GIBaseInfo *) proto_priv->info));
- objp.set(obj);
+ if (gjs_define_function(context, obj, proto_priv->gtype,
+ method_info) == NULL) {
+ g_base_info_unref((GIBaseInfo *) method_info);
+ return false;
}
- g_base_info_unref((GIBaseInfo *) method_info);
+ *resolved = true;
}
- ret = fundamental_instance_new_resolve_interface(context, obj, objp,
- proto_priv, name);
+ g_base_info_unref((GIBaseInfo *) method_info);
} 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;
}
- ret = true;
- out:
- g_free(name);
- return ret;
+ return fundamental_instance_resolve_interface(context, obj, resolved,
+ proto_priv, name);
}
static bool
@@ -381,7 +380,7 @@ fundamental_invoke_constructor(FundamentalInstance *priv,
if (!gjs_object_require_property_value(context, obj, NULL,
constructor_const, &js_constructor) ||
- priv->prototype->constructor_name == JSID_VOID) {
+ priv->prototype->constructor_name.get() == JSID_VOID) {
gjs_throw (context,
"Couldn't find a constructor for type %s.%s",
g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info),
@@ -517,8 +516,8 @@ fundamental_trace(JSTracer *tracer,
if (priv == NULL)
return;
- JS_CallHeapIdTracer(tracer, &priv->constructor_name,
- "Fundamental::constructor_name");
+ JS_CallIdTracer(tracer, &priv->constructor_name,
+ "Fundamental::constructor_name");
}
/* The bizarre thing about this vtable is that it applies to both
@@ -537,15 +536,14 @@ fundamental_trace(JSTracer *tracer,
*/
struct JSClass gjs_fundamental_instance_class = {
"GFundamental_Object",
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) fundamental_instance_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ fundamental_instance_resolve,
+ NULL, /* convert */
fundamental_finalize,
NULL, /* call */
NULL, /* hasInstance */
diff --git a/gi/interface.cpp b/gi/interface.cpp
index 0347812..51f6574 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -105,30 +105,31 @@ gjs_define_static_methods(JSContext *context,
}
static bool
-interface_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+interface_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Interface *priv;
- char *name;
- bool ret = false;
+ g_autofree char *name = NULL;
GIFunctionInfo *method_info;
- if (!gjs_get_string_id(context, id, &name))
+ if (!gjs_get_string_id(context, id, &name)) {
+ *resolved = false;
return true;
+ }
priv = priv_from_js(context, obj);
if (priv == NULL)
- goto out;
+ return false;
/* If we have no GIRepository information then this interface was defined
* from within GJS. In that case, it has no properties that need to be
* resolved from within C code, as interfaces cannot inherit. */
if (priv->info == NULL) {
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name);
@@ -139,34 +140,33 @@ interface_new_resolve(JSContext *context,
priv->gtype,
(GICallableInfo*)method_info) == NULL) {
g_base_info_unref((GIBaseInfo*)method_info);
- goto out;
+ return false;
}
- objp.set(obj);
+ *resolved = true;
+ } else {
+ *resolved = false;
}
g_base_info_unref((GIBaseInfo*)method_info);
+ } else {
+ *resolved = false;
}
- ret = true;
-
- out:
- g_free (name);
- return ret;
+ return true;
}
struct JSClass gjs_interface_class = {
"GObject_Interface",
JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE |
JSCLASS_BACKGROUND_FINALIZE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) interface_new_resolve,
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ interface_resolve,
+ NULL, /* convert */
interface_finalize
};
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 2930db7..3ebbf17 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -48,26 +48,27 @@ GJS_DEFINE_PRIV_FROM_JS(Ns, gjs_ns_class)
* if id was resolved.
*/
static bool
-ns_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+ns_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Ns *priv;
- char *name;
+ g_autofree char *name = NULL;
GIRepository *repo;
GIBaseInfo *info;
- bool ret = false;
bool defined;
- if (!gjs_get_string_id(context, id, &name))
+ if (!gjs_get_string_id(context, id, &name)) {
+ *resolved = false;
return true; /* not resolved, but no error */
+ }
/* let Object.prototype resolve these */
if (strcmp(name, "valueOf") == 0 ||
strcmp(name, "toString") == 0) {
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
priv = priv_from_js(context, obj);
@@ -76,20 +77,18 @@ ns_new_resolve(JSContext *context,
name, obj.get(), priv);
if (priv == NULL) {
- ret = true; /* we are the prototype, or have the wrong class */
- goto out;
+ *resolved = false; /* we are the prototype, or have the wrong class */
+ return true;
}
- JS_BeginRequest(context);
+ JSAutoRequest ar(context);
repo = g_irepository_get_default();
info = g_irepository_find_by_name(repo, priv->gi_namespace, name);
if (info == NULL) {
- /* No property defined, but no error either, so return true */
- JS_EndRequest(context);
- ret = true;
- goto out;
+ *resolved = false; /* No property defined, but no error either */
+ return true;
}
gjs_debug(GJS_DEBUG_GNAMESPACE,
@@ -98,23 +97,19 @@ ns_new_resolve(JSContext *context,
g_base_info_get_name(info),
g_base_info_get_namespace(info));
- if (gjs_define_info(context, obj, info, &defined)) {
- g_base_info_unref(info);
- if (defined)
- objp.set(obj); /* we defined the property in this object */
- ret = true;
- } else {
+ if (!gjs_define_info(context, obj, info, &defined)) {
gjs_debug(GJS_DEBUG_GNAMESPACE,
"Failed to define info '%s'",
g_base_info_get_name(info));
g_base_info_unref(info);
+ return false;
}
- JS_EndRequest(context);
- out:
- g_free(name);
- return ret;
+ /* we defined the property in this object */
+ g_base_info_unref(info);
+ *resolved = true;
+ return true;
}
static bool
@@ -157,15 +152,14 @@ ns_finalize(JSFreeOp *fop,
*/
struct JSClass gjs_ns_class = {
"GIRepositoryNamespace",
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) ns_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ ns_resolve,
+ NULL, /* convert */
ns_finalize
};
@@ -221,8 +215,7 @@ ns_new(JSContext *context,
gjs_ns_class.name, prototype);
}
- JS::RootedObject ns(context, JS_NewObject(context, &gjs_ns_class,
- JS::NullPtr(), global));
+ JS::RootedObject ns(context, JS_NewObject(context, &gjs_ns_class, global));
if (ns == NULL)
g_error("No memory to create ns object");
diff --git a/gi/object.cpp b/gi/object.cpp
index 7855747..09daea9 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -23,6 +23,7 @@
#include <config.h>
+#include <deque>
#include <memory>
#include <stack>
#include <string.h>
@@ -95,6 +96,11 @@ static GHashTable *class_init_properties;
static GjsKeepAlive keep_alive_list;
+static bool weak_pointer_callback = false;
+/* Use std::deque here instead of std::vector so that elements don't have to
+ * get moved around when the storage size changes */
+static std::deque<GObject *> weak_pointer_list;
+
extern struct JSClass gjs_object_instance_class;
static GThread *gjs_eval_thread;
static volatile gint pending_idle_toggles;
@@ -603,20 +609,20 @@ find_vfunc_on_parents(GIObjectInfo *info,
}
static bool
-object_instance_new_resolve_no_info(JSContext *context,
- JS::HandleObject obj,
- JS::MutableHandleObject objp,
- ObjectInstance *priv,
- char *name)
+object_instance_resolve_no_info(JSContext *context,
+ JS::HandleObject obj,
+ bool *resolved,
+ ObjectInstance *priv,
+ char *name)
{
GIFunctionInfo *method_info;
bool ret;
- GType *interfaces;
guint n_interfaces;
guint i;
ret = true;
- interfaces = g_type_interfaces(priv->gtype, &n_interfaces);
+ *resolved = false; /* technically we shouldn't touch this if returning false? */
+ g_autofree GType *interfaces = g_type_interfaces(priv->gtype, &n_interfaces);
for (i = 0; i < n_interfaces; i++) {
GIBaseInfo *base_info;
GIInterfaceInfo *iface_info;
@@ -641,7 +647,8 @@ object_instance_new_resolve_no_info(JSContext *context,
if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
if (gjs_define_function(context, obj, priv->gtype,
(GICallableInfo *)method_info)) {
- objp.set(obj);
+ *resolved = true;
+ ret = true;
} else {
ret = false;
}
@@ -651,7 +658,6 @@ object_instance_new_resolve_no_info(JSContext *context,
}
}
- g_free(interfaces);
return ret;
}
@@ -661,18 +667,19 @@ object_instance_new_resolve_no_info(JSContext *context,
* if id was resolved.
*/
static bool
-object_instance_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+object_instance_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
GIFunctionInfo *method_info;
ObjectInstance *priv;
- char *name;
- bool ret = false;
+ g_autofree char *name = NULL;
- if (!gjs_get_string_id(context, id, &name))
+ if (!gjs_get_string_id(context, id, &name)) {
+ *resolved = false;
return true; /* not resolved, but no error */
+ }
priv = priv_from_js(context, obj);
@@ -695,21 +702,20 @@ object_instance_new_resolve(JSContext *context,
* will run afterwards will fail because of the "priv == NULL"
* check there.
*/
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
if (priv->gobj != NULL) {
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
/* If we have no GIRepository information (we're a JS GObject subclass),
* we need to look at exposing interfaces. Look up our interfaces through
* GType data, and then hope that *those* are introspectable. */
if (priv->info == NULL) {
- ret = object_instance_new_resolve_no_info(context, obj, objp, priv, name);
- goto out;
+ return object_instance_resolve_no_info(context, obj, resolved, priv, name);
}
if (g_str_has_prefix (name, "vfunc_")) {
@@ -737,15 +743,14 @@ object_instance_new_resolve(JSContext *context,
* prototypal inheritance take over. */
if (defined_by_parent && is_vfunc_unchanged(vfunc, priv->gtype)) {
g_base_info_unref((GIBaseInfo *)vfunc);
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
gjs_define_function(context, obj, priv->gtype, vfunc);
- objp.set(obj);
+ *resolved = true;
g_base_info_unref((GIBaseInfo *)vfunc);
- ret = true;
- goto out;
+ return true;
}
/* If the vfunc wasn't found, fall through, back to normal
@@ -772,38 +777,33 @@ object_instance_new_resolve(JSContext *context,
* this could be done better. See
* https://bugzilla.gnome.org/show_bug.cgi?id=632922
*/
- if (method_info == NULL) {
- ret = object_instance_new_resolve_no_info(context, obj, objp,
- priv, name);
- goto out;
- } else {
+ if (method_info == NULL)
+ return object_instance_resolve_no_info(context, obj, resolved, priv, name);
+
#if GJS_VERBOSE_ENABLE_GI_USAGE
- _gjs_log_info_usage((GIBaseInfo*) method_info);
+ _gjs_log_info_usage((GIBaseInfo*) method_info);
#endif
- if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
- gjs_debug(GJS_DEBUG_GOBJECT,
- "Defining method %s in prototype for %s (%s.%s)",
- g_base_info_get_name( (GIBaseInfo*) method_info),
- g_type_name(priv->gtype),
- g_base_info_get_namespace( (GIBaseInfo*) priv->info),
- g_base_info_get_name( (GIBaseInfo*) priv->info));
-
- if (gjs_define_function(context, obj, priv->gtype, method_info) == NULL) {
- g_base_info_unref( (GIBaseInfo*) method_info);
- goto out;
- }
+ if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
+ gjs_debug(GJS_DEBUG_GOBJECT,
+ "Defining method %s in prototype for %s (%s.%s)",
+ g_base_info_get_name( (GIBaseInfo*) method_info),
+ g_type_name(priv->gtype),
+ g_base_info_get_namespace( (GIBaseInfo*) priv->info),
+ g_base_info_get_name( (GIBaseInfo*) priv->info));
- objp.set(obj); /* we defined the prop in obj */
+ if (gjs_define_function(context, obj, priv->gtype, method_info) == NULL) {
+ g_base_info_unref( (GIBaseInfo*) method_info);
+ return false;
}
- g_base_info_unref( (GIBaseInfo*) method_info);
+ *resolved = true; /* we defined the prop in obj */
+ } else {
+ *resolved = false;
}
- ret = true;
- out:
- g_free(name);
- return ret;
+ g_base_info_unref( (GIBaseInfo*) method_info);
+ return true;
}
static void
@@ -1209,16 +1209,7 @@ wrapped_gobj_toggle_notify(gpointer data,
g_error("toggling up object %s that's already queued to toggle up\n",
G_OBJECT_TYPE_NAME(gobj));
}
- if (is_sweeping) {
- if (JS_IsAboutToBeFinalized(ensure_heap_wrapper(gobj))) {
- /* Ouch, the JS object is dead already. Disassociate the GObject
- * and hope the GObject dies too.
- */
- disassociate_js_gobject(gobj);
- }
- } else {
- handle_toggle_up(gobj);
- }
+ handle_toggle_up(gobj);
} else {
queue_toggle_idle(gobj, TOGGLE_UP);
}
@@ -1287,6 +1278,34 @@ init_object_private (JSContext *context,
}
static void
+update_heap_wrapper_weak_pointers(JSRuntime *rt,
+ gpointer data)
+{
+ for (auto iter = weak_pointer_list.begin(); iter != weak_pointer_list.end();
+ iter++) {
+ GObject *gobj = *iter;
+ auto heap_wrapper = ensure_heap_wrapper(gobj);
+ JS_UpdateWeakPointerAfterGC(heap_wrapper);
+
+ if (heap_wrapper == NULL) {
+ /* Ouch, the JS object is dead already. Disassociate the GObject
+ * and hope the GObject dies too.
+ */
+ disassociate_js_gobject(gobj);
+ iter = weak_pointer_list.erase(iter);
+ }
+ }
+}
+
+static void
+ensure_weak_pointer_callback(JSContext *cx)
+{
+ if (!weak_pointer_callback)
+ JS_AddWeakPointerCallback(JS_GetRuntime(cx),
+ update_heap_wrapper_weak_pointers, NULL);
+}
+
+static void
associate_js_gobject (JSContext *context,
JS::HandleObject object,
GObject *gobj)
@@ -1296,6 +1315,8 @@ associate_js_gobject (JSContext *context,
priv = priv_from_js(context, object);
priv->gobj = gobj;
+ ensure_weak_pointer_callback(context);
+
g_assert(peek_js_obj(gobj) == NULL);
set_js_obj(gobj, object);
@@ -1882,15 +1903,14 @@ to_string_func(JSContext *context,
struct JSClass gjs_object_instance_class = {
"GObject_Object",
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
object_instance_get_prop,
object_instance_set_prop,
- JS_EnumerateStub,
- (JSResolveOp) object_instance_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ NULL, /* enumerate */
+ object_instance_resolve,
+ NULL, /* convert */
object_instance_finalize,
NULL,
NULL,
@@ -2131,7 +2151,7 @@ static void
set_js_obj(GObject *gobj,
JSObject *obj)
{
- ensure_heap_wrapper(gobj)->set(obj);
+ *ensure_heap_wrapper(gobj) = obj;
}
static void
@@ -2544,8 +2564,7 @@ gjs_object_constructor (GType type,
if (n_construct_properties) {
guint i;
- JS::RootedObject props_hash(context,
- JS_NewObject(context, NULL, JS::NullPtr(), JS::NullPtr()));
+ JS::RootedObject props_hash(context, JS_NewObject(context, NULL));
for (i = 0; i < n_construct_properties; i++)
jsobj_set_gproperty(context, props_hash,
@@ -3126,7 +3145,7 @@ bool
gjs_define_private_gi_stuff(JSContext *cx,
JS::MutableHandleObject module)
{
- module.set(JS_NewObject(cx, NULL, JS::NullPtr(), JS::NullPtr()));
+ module.set(JS_NewObject(cx, NULL));
return JS_DefineFunctions(cx, module, &module_funcs[0]);
}
diff --git a/gi/param.cpp b/gi/param.cpp
index 1b18150..9bcd911 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -45,20 +45,19 @@ extern struct JSClass gjs_param_class;
GJS_DEFINE_PRIV_FROM_JS(Param, gjs_param_class)
/*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
*/
static bool
-param_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+param_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
GIObjectInfo *info = NULL;
GIFunctionInfo *method_info;
Param *priv;
- char *name;
+ g_autofree char *name = NULL;
bool ret = false;
if (!gjs_get_string_id(context, id, &name))
@@ -68,14 +67,15 @@ param_new_resolve(JSContext *context,
if (priv != NULL) {
/* instance, not prototype */
- ret = true;
- goto out;
+ *resolved = false;
+ return true;
}
info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM);
method_info = g_object_info_find_method(info, name);
if (method_info == NULL) {
+ *resolved = false;
ret = true;
goto out;
}
@@ -93,14 +93,13 @@ param_new_resolve(JSContext *context,
goto out;
}
- objp.set(obj); /* we defined the prop in obj */
+ *resolved = true; /* we defined the prop in obj */
}
g_base_info_unref( (GIBaseInfo*) method_info);
ret = true;
out:
- g_free(name);
if (info != NULL)
g_base_info_unref( (GIBaseInfo*)info);
@@ -145,15 +144,14 @@ param_finalize(JSFreeOp *fop,
struct JSClass gjs_param_class = {
"GObject_ParamSpec",
JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE |
JSCLASS_BACKGROUND_FINALIZE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) param_new_resolve,
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ param_resolve,
+ NULL, /* convert */
param_finalize
};
diff --git a/gi/repo.cpp b/gi/repo.cpp
index dff585e..e450284 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -145,44 +145,42 @@ resolve_namespace_object(JSContext *context,
}
/*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
*/
static bool
-repo_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+repo_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Repo *priv;
- char *name;
- bool ret = true;
+ g_autofree char *name = NULL;
- if (!gjs_get_string_id(context, id, &name))
+ if (!gjs_get_string_id(context, id, &name)) {
+ *resolved = false;
return true; /* not resolved, but no error */
+ }
/* let Object.prototype resolve these */
if (strcmp(name, "valueOf") == 0 ||
- strcmp(name, "toString") == 0)
- goto out;
+ strcmp(name, "toString") == 0) {
+ *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, obj.get(), priv);
if (priv == NULL) /* we are the prototype, or have the wrong class */
- goto out;
+ return false;
- if (!resolve_namespace_object(context, obj, id, name)) {
- ret = false;
- } else {
- objp.set(obj); /* store the object we defined the prop in */
- }
+ if (!resolve_namespace_object(context, obj, id, name))
+ return false;
- out:
- g_free(name);
- return ret;
+ *resolved = true;
+ return true;
}
GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(repo)
@@ -209,15 +207,14 @@ repo_finalize(JSFreeOp *fop,
*/
struct JSClass gjs_repo_class = {
"GIRepository", /* means "new GIRepository()" works */
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) repo_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ repo_resolve,
+ NULL, /* convert */
repo_finalize
};
@@ -233,8 +230,6 @@ static JSObject*
repo_new(JSContext *context)
{
Repo *priv;
- JSObject *versions;
- JSObject *private_ns;
bool found;
JS::RootedObject global(context, gjs_get_import_global(context));
@@ -273,7 +268,7 @@ repo_new(JSContext *context)
}
JS::RootedObject repo(context,
- JS_NewObject(context, &gjs_repo_class, JS::NullPtr(), global));
+ JS_NewObject(context, &gjs_repo_class, global));
if (repo == NULL) {
gjs_throw(context, "No memory to create repo object");
return NULL;
@@ -289,22 +284,17 @@ repo_new(JSContext *context)
gjs_debug_lifecycle(GJS_DEBUG_GREPO,
"repo constructor, obj %p priv %p", repo.get(), priv);
- versions = JS_NewObject(context, NULL, JS::NullPtr(), global);
+ JS::RootedObject versions(context, JS_NewObject(context, NULL, global));
JS::RootedId versions_name(context,
gjs_context_get_const_string(context, GJS_STRING_GI_VERSIONS));
- JS_DefinePropertyById(context, repo,
- versions_name,
- JS::ObjectValue(*versions),
- NULL, NULL,
+ JS_DefinePropertyById(context, repo, versions_name, versions,
JSPROP_PERMANENT);
- private_ns = JS_NewObject(context, NULL, JS::NullPtr(), global);
+ JS::RootedObject private_ns(context, JS_NewObject(context, NULL, global));
JS::RootedId private_ns_name(context,
gjs_context_get_const_string(context, GJS_STRING_PRIVATE_NS_MARKER));
- JS_DefinePropertyById(context, repo,
- private_ns_name,
- JS::ObjectValue(*private_ns),
- NULL, NULL, JSPROP_PERMANENT);
+ JS_DefinePropertyById(context, repo, private_ns_name, private_ns,
+ JSPROP_PERMANENT);
/* FIXME - hack to make namespaces load, since
* gobject-introspection does not yet search a path properly.
diff --git a/gi/union.cpp b/gi/union.cpp
index 38a1405..984eb1c 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -50,81 +50,82 @@ extern struct JSClass gjs_union_class;
GJS_DEFINE_PRIV_FROM_JS(Union, gjs_union_class)
/*
- * The *objp out parameter, on success, should be null to indicate that id
- * was not resolved; and non-null, referring to obj or one of its prototypes,
- * if id was resolved.
+ * The *resolved out parameter, on success, should be false to indicate that id
+ * was not resolved; and true if id was resolved.
*/
static bool
-union_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+union_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Union *priv;
- char *name;
- bool ret = true;
+ g_autofree char *name = NULL;
- if (!gjs_get_string_id(context, id, &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, obj.get(), priv);
- if (priv == NULL) {
- ret = false; /* wrong class */
- goto out;
+ if (priv == NULL)
+ return false; /* wrong class */
+
+ if (priv->gboxed != NULL) {
+ /* 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 (priv->gboxed == NULL) {
- /* We are the prototype, so look for methods and other class properties */
- GIFunctionInfo *method_info;
+ /* We are the prototype, so look for methods and other class properties */
+ GIFunctionInfo *method_info;
- method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
- name);
+ method_info = g_union_info_find_method((GIUnionInfo*) priv->info,
+ name);
- if (method_info != NULL) {
- const char *method_name;
+ if (method_info != NULL) {
+ const char *method_name;
#if GJS_VERBOSE_ENABLE_GI_USAGE
- _gjs_log_info_usage((GIBaseInfo*) method_info);
+ _gjs_log_info_usage((GIBaseInfo*) 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 union proto */
- if (gjs_define_function(context, obj,
- g_registered_type_info_get_g_type(priv->info),
- method_info) == NULL) {
- g_base_info_unref( (GIBaseInfo*) method_info);
- ret = false;
- goto out;
- }
-
- objp.set(obj); /* we defined the prop in object_proto */
+ 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 union proto */
+ if (gjs_define_function(context, obj,
+ g_registered_type_info_get_g_type(priv->info),
+ method_info) == NULL) {
+ g_base_info_unref( (GIBaseInfo*) method_info);
+ return false;
}
- g_base_info_unref( (GIBaseInfo*) method_info);
+ *resolved = true; /* we defined the prop in object_proto */
+ } else {
+ *resolved = false;
}
+
+ g_base_info_unref( (GIBaseInfo*) method_info);
} 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;
}
- out:
- g_free(name);
- return ret;
+ return true;
}
static void*
@@ -287,15 +288,14 @@ to_string_func(JSContext *context,
*/
struct JSClass gjs_union_class = {
"GObject_Union",
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- (JSResolveOp) union_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ union_resolve,
+ NULL, /* convert */
union_finalize
};
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index 78e6a18..f60d4bf 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -57,13 +57,13 @@ struct JSClass gjs_byte_array_class = {
"ByteArray",
JSCLASS_HAS_PRIVATE |
JSCLASS_BACKGROUND_FINALIZE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
(JSPropertyOp)byte_array_get_prop,
(JSStrictPropertyOp)byte_array_set_prop,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
+ NULL, /* enumerate */
+ NULL, /* resolve */
+ NULL, /* convert */
byte_array_finalize
};
@@ -531,7 +531,7 @@ byte_array_new(JSContext *context)
JS::RootedObject proto(context, byte_array_get_prototype(context));
JS::RootedObject array(context,
- JS_NewObjectWithGivenProto(context, &gjs_byte_array_class, proto, JS::NullPtr()));
+ JS_NewObjectWithGivenProto(context, &gjs_byte_array_class, proto));
priv = g_slice_new0(ByteArrayInstance);
@@ -607,8 +607,9 @@ from_string_func(JSContext *context,
GError *error;
const char16_t *u16_chars;
gsize u16_len;
+ JS::AutoCheckCannotGC nogc;
- u16_chars = JS_GetStringCharsAndLength(context, argv[0].toString(), &u16_len);
+ u16_chars = JS_GetTwoByteStringCharsAndLength(context, nogc, argv[0].toString(), &u16_len);
if (u16_chars == NULL)
return false;
@@ -741,7 +742,7 @@ gjs_byte_array_from_byte_array (JSContext *context,
JS::RootedObject proto(context, byte_array_get_prototype(context));
JS::RootedObject object(context,
- JS_NewObjectWithGivenProto(context, &gjs_byte_array_class, proto, JS::NullPtr()));
+ JS_NewObjectWithGivenProto(context, &gjs_byte_array_class, proto));
if (!object) {
gjs_throw(context, "failed to create byte array");
@@ -829,7 +830,7 @@ gjs_define_byte_array_stuff(JSContext *context,
{
JSObject *prototype;
- module.set(JS_NewObject(context, NULL, JS::NullPtr(), JS::NullPtr()));
+ module.set(JS_NewObject(context, NULL));
prototype = JS_InitClass(context, module, JS::NullPtr(),
&gjs_byte_array_class,
diff --git a/gjs/context.cpp b/gjs/context.cpp
index fe74d17..7d80621 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -78,6 +78,7 @@ struct _GjsContext {
guint auto_gc_id;
+ /* FIXME - array of PersistentRooted<jsid>? */
jsid const_strings[GJS_STRING_LAST];
};
@@ -371,7 +372,7 @@ static void
gjs_context_tracer(JSTracer *trc, void *data)
{
GjsContext *gjs_context = reinterpret_cast<GjsContext *>(data);
- JS_CallHeapObjectTracer(trc, &gjs_context->global, "GJS global object");
+ JS_CallObjectTracer(trc, &gjs_context->global, "GJS global object");
}
static void
@@ -494,7 +495,7 @@ gjs_context_constructed(GObject *object)
if (!JS_DefineFunctions(js_context->context, global, &global_funcs[0]))
g_error("Failed to define properties on the global object");
- js_context->global.set(global);
+ js_context->global = global;
JS_AddExtraGCRootsTracer(js_context->runtime, gjs_context_tracer, js_context);
gjs_define_constructor_proxy_factory(js_context->context);
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index 2ab8b48..e847179 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -1261,13 +1261,13 @@ gjs_coverage_init(GjsCoverage *self)
static JSClass coverage_global_class = {
"GjsCoverageGlobal",
JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(GJS_GLOBAL_SLOT_LAST),
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ NULL, /* resolve */
+ NULL, /* convert */
NULL, /* finalize */
NULL, /* call */
NULL, /* hasInstance */
@@ -1497,7 +1497,7 @@ coverage_statistics_tracer(JSTracer *trc, void *data)
GjsCoverage *coverage = (GjsCoverage *) data;
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
- JS_CallHeapObjectTracer(trc, &priv->coverage_statistics, "coverage_statistics");
+ JS_CallObjectTracer(trc, &priv->coverage_statistics, "coverage_statistics");
}
/* This function is mainly used in the tests in order to fiddle with
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 9f96f5c..02809cc 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -213,7 +213,7 @@ seal_import(JSContext *cx,
if (!JS_DefineProperty(cx, descr.object(), name, descr.value(),
descr.attributes() | JSPROP_PERMANENT,
- descr.getter(), descr.setter())) {
+ (JSNative) descr.getter(), (JSNative) descr.setter())) {
gjs_debug(GJS_DEBUG_IMPORTER,
"Failed to redefine attributes to seal '%s' in importer",
name);
@@ -313,12 +313,6 @@ import_native_file(JSContext *context,
GJS_MODULE_PROP_FLAGS);
}
-static JSObject *
-create_module_object(JSContext *context)
-{
- return JS_NewObject(context, NULL, JS::NullPtr(), JS::NullPtr());
-}
-
static bool
import_file(JSContext *context,
const char *name,
@@ -380,14 +374,13 @@ load_module_init(JSContext *context,
}
}
- JS::RootedObject module_obj(context, create_module_object(context));
+ JS::RootedObject module_obj(context, JS_NewObject(context, NULL));
file = g_file_new_for_commandline_arg(full_path);
if (!import_file (context, "__init__", file, module_obj))
goto out;
if (!JS_DefinePropertyById(context, in_object,
- module_init_name, JS::ObjectValue(*module_obj),
- NULL, NULL,
+ module_init_name, module_obj,
GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT))
goto out;
@@ -399,10 +392,9 @@ load_module_init(JSContext *context,
static void
load_module_elements(JSContext *cx,
JS::HandleObject in_object,
- ImporterIterator *iter,
+ JS::AutoIdVector& prop_ids,
const char *init_path)
{
- size_t ix, length;
JS::RootedObject module_obj(cx, load_module_init(cx, in_object, init_path));
if (module_obj == NULL)
@@ -412,14 +404,9 @@ load_module_elements(JSContext *cx,
if (!ids)
return;
- for (ix = 0, length = ids.length(); ix < length; ix++) {
- char *name;
- if (!gjs_get_string_id(cx, ids[ix], &name))
- continue;
-
- /* Pass ownership of name */
- g_ptr_array_add(iter->elements, name);
- }
+ /* Is this allowed?? */
+ jsid vector_ref = ids[0];
+ prop_ids.append(&vector_ref, ids.length());
}
static bool
@@ -431,7 +418,7 @@ import_file_on_module(JSContext *context,
bool retval = false;
char *full_path = NULL;
- JS::RootedObject module_obj(context, create_module_object(context));
+ JS::RootedObject module_obj(context, JS_NewObject(context, NULL));
if (!define_import(context, obj, module_obj, name))
goto out;
@@ -664,201 +651,108 @@ do_import(JSContext *context,
return result;
}
-static ImporterIterator *
-importer_iterator_new(void)
-{
- ImporterIterator *iter;
-
- iter = g_slice_new0(ImporterIterator);
-
- iter->elements = g_ptr_array_new();
- iter->index = 0;
-
- return iter;
-}
-
-static void
-importer_iterator_free(ImporterIterator *iter)
-{
- g_ptr_array_foreach(iter->elements, (GFunc)g_free, NULL);
- g_ptr_array_free(iter->elements, true);
- g_slice_free(ImporterIterator, iter);
-}
-
-/*
- * Like JSEnumerateOp, but enum provides contextual information as follows:
- *
- * JSENUMERATE_INIT: allocate private enum struct in state_p, return number
- * of elements in *id_p
- * JSENUMERATE_NEXT: return next property id in *id_p, and if no new property
- * free state_p and set to JS::NullValue()
- * JSENUMERATE_DESTROY : destroy state_p
- *
- * Note that in a for ... in loop, this will be called first on the object,
+/* Note that in a for ... in loop, this will be called first on the object,
* then on its prototype.
- *
*/
static bool
-importer_new_enumerate(JSContext *context,
- JS::HandleObject object,
- JSIterateOp enum_op,
- JS::MutableHandleValue statep,
- JS::MutableHandleId idp)
+importer_enumerate(JSContext *context,
+ JS::HandleObject object,
+ JS::AutoIdVector& properties)
{
- ImporterIterator *iter;
+ Importer *priv;
+ guint32 search_path_len;
+ guint32 i;
- switch (enum_op) {
- case JSENUMERATE_INIT_ALL:
- case JSENUMERATE_INIT: {
- Importer *priv;
- JS::RootedObject search_path(context);
- guint32 search_path_len;
- guint32 i;
+ priv = priv_from_js(context, object);
- statep.setNull();
+ if (!priv)
+ /* we are enumerating the prototype properties */
+ return true;
- idp.set(INT_TO_JSID(0));
+ JS::RootedObject search_path(context);
+ JS::RootedId search_path_name(context,
+ gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH));
+ if (!gjs_object_require_property_value(context, object, "importer",
+ search_path_name, &search_path))
+ return false;
- priv = priv_from_js(context, object);
+ if (!JS_IsArrayObject(context, search_path)) {
+ gjs_throw(context, "searchPath property on importer is not an array");
+ return false;
+ }
- if (!priv)
- /* we are enumerating the prototype properties */
- return true;
+ if (!JS_GetArrayLength(context, search_path, &search_path_len)) {
+ gjs_throw(context, "searchPath array has no length");
+ return false;
+ }
- JS::RootedId search_path_name(context,
- gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH));
- if (!gjs_object_require_property_value(context, object, "importer",
- search_path_name, &search_path))
- return false;
+ JS::RootedValue elem(context);
+ for (i = 0; i < search_path_len; ++i) {
+ char *dirname = NULL;
+ char *init_path;
+ const char *filename;
+ GDir *dir = NULL;
- if (!JS_IsArrayObject(context, search_path)) {
- gjs_throw(context, "searchPath property on importer is not an array");
+ elem.setUndefined();
+ if (!JS_GetElement(context, search_path, i, &elem)) {
+ /* this means there was an exception, while elem.isUndefined()
+ * means no element found
+ */
return false;
}
- if (!JS_GetArrayLength(context, search_path, &search_path_len)) {
- gjs_throw(context, "searchPath array has no length");
+ if (elem.isUndefined())
+ continue;
+
+ if (!elem.isString()) {
+ gjs_throw(context, "importer searchPath contains non-string");
return false;
}
- iter = importer_iterator_new();
-
- JS::RootedValue elem(context);
- for (i = 0; i < search_path_len; ++i) {
- char *dirname = NULL;
- char *init_path;
- const char *filename;
- GDir *dir = NULL;
-
- elem = JS::UndefinedValue();
- if (!JS_GetElement(context, search_path, i, &elem)) {
- /* this means there was an exception, while elem.isUndefined()
- * means no element found
- */
- importer_iterator_free(iter);
- return false;
- }
-
- if (elem.isUndefined())
- continue;
-
- if (!elem.isString()) {
- gjs_throw(context, "importer searchPath contains non-string");
- importer_iterator_free(iter);
- return false;
- }
-
- if (!gjs_string_to_utf8(context, elem, &dirname)) {
- importer_iterator_free(iter);
- return false; /* Error message already set */
- }
-
- init_path = g_build_filename(dirname, MODULE_INIT_FILENAME,
- NULL);
-
- load_module_elements(context, object, iter, init_path);
-
- g_free(init_path);
-
- dir = g_dir_open(dirname, 0, NULL);
-
- if (!dir) {
- g_free(dirname);
- continue;
- }
-
- while ((filename = g_dir_read_name(dir))) {
- char *full_path;
+ if (!gjs_string_to_utf8(context, elem, &dirname)) {
+ return false; /* Error message already set */
+ }
- /* skip hidden files and directories (.svn, .git, ...) */
- if (filename[0] == '.')
- continue;
+ init_path = g_build_filename(dirname, MODULE_INIT_FILENAME, NULL);
- /* skip module init file */
- if (strcmp(filename, MODULE_INIT_FILENAME) == 0)
- continue;
+ load_module_elements(context, object, properties, init_path);
- full_path = g_build_filename(dirname, filename, NULL);
+ g_free(init_path);
- if (g_file_test(full_path, G_FILE_TEST_IS_DIR)) {
- g_ptr_array_add(iter->elements, g_strdup(filename));
- } else {
- if (g_str_has_suffix(filename, "." G_MODULE_SUFFIX) ||
- g_str_has_suffix(filename, ".js")) {
- g_ptr_array_add(iter->elements,
- g_strndup(filename, strlen(filename) - 3));
- }
- }
-
- g_free(full_path);
- }
- g_dir_close(dir);
+ dir = g_dir_open(dirname, 0, NULL);
+ if (!dir) {
g_free(dirname);
+ continue;
}
- statep.set(JS::PrivateValue(context));
+ while ((filename = g_dir_read_name(dir))) {
+ char *full_path;
- idp.set(INT_TO_JSID(iter->elements->len));
-
- break;
- }
-
- case JSENUMERATE_NEXT: {
- if (statep.isNull()) /* Iterating prototype */
- return true;
-
- iter = (ImporterIterator*) statep.get().toPrivate();
-
- if (iter->index < iter->elements->len) {
- JS::RootedValue element_val(context);
- if (!gjs_string_from_utf8(context,
- (const char*) g_ptr_array_index(iter->elements,
- iter->index++),
- -1,
- &element_val))
- return false;
-
- if (!JS_ValueToId(context, element_val, idp))
- return false;
+ /* skip hidden files and directories (.svn, .git, ...) */
+ if (filename[0] == '.')
+ continue;
- break;
- }
- /* else fall through to destroying the iterator */
- }
+ /* skip module init file */
+ if (strcmp(filename, MODULE_INIT_FILENAME) == 0)
+ continue;
- case JSENUMERATE_DESTROY: {
- if (!statep.isNull()) {
- iter = (ImporterIterator*) statep.get().toPrivate();
+ full_path = g_build_filename(dirname, filename, NULL);
- importer_iterator_free(iter);
+ if (g_file_test(full_path, G_FILE_TEST_IS_DIR)) {
+ properties.append(gjs_intern_string_to_id(context, filename));
+ } else if (g_str_has_suffix(filename, "." G_MODULE_SUFFIX) ||
+ g_str_has_suffix(filename, ".js")) {
+ g_autofree char *filename_noext =
+ g_strndup(filename, strlen(filename) - 3);
+ properties.append(gjs_intern_string_to_id(context, filename_noext));
+ }
- statep.setNull();
+ g_free(full_path);
}
- }
+ g_dir_close(dir);
- default:
- ;
+ g_free(dirname);
}
return true;
@@ -870,19 +764,20 @@ importer_new_enumerate(JSContext *context,
* if id was resolved.
*/
static bool
-importer_new_resolve(JSContext *context,
- JS::HandleObject obj,
- JS::HandleId id,
- JS::MutableHandleObject objp)
+importer_resolve(JSContext *context,
+ JS::HandleObject obj,
+ JS::HandleId id,
+ bool *resolved)
{
Importer *priv;
- char *name;
- bool ret = true;
+ g_autofree char *name = NULL;
jsid module_init_name;
module_init_name = gjs_context_get_const_string(context, GJS_STRING_MODULE_INIT);
- if (id == module_init_name)
+ if (id == module_init_name) {
+ *resolved = false;
return true;
+ }
if (!gjs_get_string_id(context, id, &name))
return false;
@@ -890,26 +785,27 @@ importer_new_resolve(JSContext *context,
/* let Object.prototype resolve these */
if (strcmp(name, "valueOf") == 0 ||
strcmp(name, "toString") == 0 ||
- strcmp(name, "__iterator__") == 0)
- goto out;
+ strcmp(name, "__iterator__") == 0) {
+ *resolved = false;
+ return true;
+ }
priv = priv_from_js(context, obj);
gjs_debug_jsprop(GJS_DEBUG_IMPORTER,
"Resolve prop '%s' hook obj %p priv %p",
name, obj.get(), priv);
- if (priv == NULL) /* we are the prototype, or have the wrong class */
- goto out;
- JS_BeginRequest(context);
- if (do_import(context, obj, priv, name)) {
- objp.set(obj);
- } else {
- ret = false;
+ if (priv == NULL) {
+ /* we are the prototype, or have the wrong class */
+ *resolved = false;
+ return true;
}
- JS_EndRequest(context);
- out:
- g_free(name);
- return ret;
+ JSAutoRequest ar(context);
+ if (!do_import(context, obj, priv, name))
+ return false;
+
+ *resolved = true;
+ return true;
}
GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(importer)
@@ -936,16 +832,14 @@ importer_finalize(JSFreeOp *fop,
*/
struct JSClass gjs_importer_class = {
"GjsFileImporter",
- JSCLASS_HAS_PRIVATE |
- JSCLASS_NEW_RESOLVE |
- JSCLASS_NEW_ENUMERATE,
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- (JSEnumerateOp) importer_new_enumerate, /* needs cast since it's the new enumerate signature */
- (JSResolveOp) importer_new_resolve, /* needs cast since it's the new resolve signature */
- JS_ConvertStub,
+ JSCLASS_HAS_PRIVATE,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, // FIXME FIXME importer_enumerate,
+ importer_resolve,
+ NULL, /* convert */
importer_finalize
};
@@ -1002,7 +896,7 @@ importer_new(JSContext *context,
}
JS::RootedObject importer(context,
- JS_NewObject(context, &gjs_importer_class, JS::NullPtr(), global));
+ JS_NewObject(context, &gjs_importer_class, global));
if (importer == NULL)
g_error("No memory to create importer importer");
@@ -1179,7 +1073,6 @@ gjs_define_root_importer_object(JSContext *context,
gjs_context_get_const_string(context, GJS_STRING_IMPORTS));
if (!JS_DefinePropertyById(context, in_object,
imports_name, importer,
- NULL, NULL,
GJS_MODULE_PROP_FLAGS)) {
gjs_debug(GJS_DEBUG_IMPORTER, "DefineProperty imports on %p failed",
in_object.get());
diff --git a/gjs/jsapi-constructor-proxy.cpp b/gjs/jsapi-constructor-proxy.cpp
index d0a795d..5c7a728 100644
--- a/gjs/jsapi-constructor-proxy.cpp
+++ b/gjs/jsapi-constructor-proxy.cpp
@@ -31,11 +31,8 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wmismatched-tags"
-#pragma clang diagnostic ignored "-Winconsistent-missing-override"
-#endif /* __clang__ */
-#include "jsproxy.h"
+#pragma GCC diagnostic ignored "-Wswitch-enum"
+#include "js/Proxy.h"
#pragma GCC diagnostic pop
/* This code exposes a __private_GjsConstructorProxy function to JS, which is
@@ -91,16 +88,15 @@ class GjsConstructorHandler : public js::DirectProxyHandler {
}
public:
- GjsConstructorHandler() : js::DirectProxyHandler(&constructor_proxy_family)
- {
- setHasPrototype(true);
- }
+ GjsConstructorHandler()
+ : js::DirectProxyHandler(&constructor_proxy_family, true /* hasPrototype */)
+ { }
bool
getPrototypeOf(JSContext *cx,
JS::HandleObject proxy,
JS::MutableHandleObject proto_p)
- override
+ const override
{
proto_p.set(proto(proxy));
return true;
@@ -111,7 +107,7 @@ public:
void
finalize(JSFreeOp *fop,
JSObject *proxy)
- override
+ const override
{
GJS_DEC_COUNTER(constructor_proxy);
gjs_debug_lifecycle(GJS_DEBUG_PROXY,
@@ -150,14 +146,15 @@ create_gjs_constructor_proxy(JSContext *cx,
return false;
}
- js::ProxyOptions options;
+ // FIXME FIXME does this still work??
+ //js::ProxyOptions options;
/* "true" makes the proxy callable, otherwise the "call" and "construct"
* traps are ignored */
- options.selectDefaultClass(true);
+ //options.selectDefaultClass(true);
JS::RootedObject proxy(cx,
js::NewProxyObject(cx, &GjsConstructorHandler::singleton(), args[0],
- &args[1].toObject(), nullptr, options));
+ &args[1].toObject(), nullptr));
/* We stick this extra object into one of the proxy object's "extra slots",
* even though it is private data of the proxy handler. This is because
* proxy handlers cannot have trace callbacks. The proxy object does have a
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index e53efcf..c219195 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -107,18 +107,15 @@ gjs_init_class_dynamic(JSContext *context,
goto out;
if (!JS_DefineProperty(context, constructor, "prototype", prototype,
- JSPROP_PERMANENT | JSPROP_READONLY,
- JS_PropertyStub, JS_StrictPropertyStub))
+ JSPROP_PERMANENT | JSPROP_READONLY))
goto out;
- if (!JS_DefineProperty(context, prototype, "constructor", constructor,
- 0, JS_PropertyStub, JS_StrictPropertyStub))
+ if (!JS_DefineProperty(context, prototype, "constructor", constructor, 0))
goto out;
/* The constructor defined by JS_InitClass has no property attributes, but this
is a more useful default for gjs */
if (!JS_DefineProperty(context, in_object, class_name, constructor,
- GJS_MODULE_PROP_FLAGS,
- JS_PropertyStub, JS_StrictPropertyStub))
+ GJS_MODULE_PROP_FLAGS))
goto out;
res = true;
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index 6143b47..509413f 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -191,7 +191,12 @@ gjs_string_get_char16_data(JSContext *context,
goto out;
}
- js_data = JS_GetStringCharsAndLength(context, value.toString(), len_p);
+ /* Scope for nogc */
+ {
+ JS::AutoCheckCannotGC nogc;
+ js_data = JS_GetTwoByteStringCharsAndLength(context, nogc,
+ value.toString(), len_p);
+ }
if (js_data == NULL)
goto out;
@@ -231,7 +236,9 @@ gjs_string_to_ucs4(JSContext *cx,
size_t utf16_len;
GError *error = NULL;
- const char16_t *utf16 = JS_GetStringCharsAndLength(cx, str, &utf16_len);
+ JS::AutoCheckCannotGC nogc;
+ const char16_t *utf16 = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
+ &utf16_len);
if (utf16 == NULL) {
gjs_throw(cx, "Failed to get UTF-16 string data");
return false;
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index decac55..9229d62 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -47,13 +47,13 @@ gjs_util_error_quark (void)
static JSClass global_class = {
"GjsGlobal",
JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(GJS_GLOBAL_SLOT_LAST),
- JS_PropertyStub,
- JS_DeletePropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
+ NULL, /* addProperty */
+ NULL, /* deleteProperty */
+ NULL, /* getProperty */
+ NULL, /* setProperty */
+ NULL, /* enumerate */
+ NULL, /* resolve */
+ NULL, /* convert */
NULL, /* finalize */
NULL, /* call */
NULL, /* hasInstance */
@@ -88,9 +88,8 @@ gjs_init_context_standard (JSContext *context,
*
* setExtraWarnings: Report warnings to error reporter function.
*/
- JS::ContextOptionsRef(context)
- .setDontReportUncaught(true)
- .setExtraWarnings(extra_warnings);
+ JS::ContextOptionsRef(context).setDontReportUncaught(true);
+ JS::RuntimeOptionsRef(context).setExtraWarnings(extra_warnings);
if (!g_getenv("GJS_DISABLE_JIT")) {
gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
@@ -100,8 +99,6 @@ gjs_init_context_standard (JSContext *context,
.setAsmJS(true);
}
- JS_SetErrorReporter(context, gjs_error_reporter);
-
compartment_options.setVersion(JSVERSION_LATEST);
global.set(JS_NewGlobalObject(context, &global_class, NULL,
JS::FireOnNewGlobalHook, compartment_options));
@@ -379,7 +376,8 @@ gjs_string_readable (JSContext *context,
size_t i, len;
const char16_t *uchars;
- uchars = JS_GetStringCharsAndLength(context, string, &len);
+ JS::AutoCheckCannotGC nogc;
+ uchars = JS_GetTwoByteStringCharsAndLength(context, nogc, string, &len);
for (i = 0; i < len; i++) {
char16_t c = uchars[i];
@@ -871,7 +869,7 @@ gjs_eval_with_scope(JSContext *context,
JS::RootedObject eval_obj(context, object);
if (!eval_obj)
- eval_obj = JS_NewObject(context, NULL, JS::NullPtr(), JS::NullPtr());
+ eval_obj = JS_NewObject(context, NULL);
JS::CompileOptions options(context);
options.setUTF8(true)
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 7564865..bf10128 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -176,24 +176,24 @@ _GJS_DEFINE_PROTO_FULL(tn, cn, NULL, gtype, flags)
extern JSPropertySpec gjs_##cname##_proto_props[]; \
extern JSFunctionSpec gjs_##cname##_proto_funcs[]; \
static void gjs_##cname##_finalize(JSFreeOp *fop, JSObject *obj); \
-static bool gjs_##cname##_new_resolve(JSContext *context, \
- JSObject *obj, \
- JS::Value id, \
- JSObject **objp) \
+static bool gjs_##cname##_resolve(JSContext *context, \
+ JS::HandleObject obj, \
+ JS::HandleId id, \
+ bool *resolved) \
{ \
+ *resolved = false; \
return true; \
} \
static struct JSClass gjs_##cname##_class = { \
type_name, \
- JSCLASS_HAS_PRIVATE | \
- JSCLASS_NEW_RESOLVE | jsclass_flags, \
- JS_PropertyStub, \
- JS_DeletePropertyStub, \
- JS_PropertyStub, \
- JS_StrictPropertyStub, \
- JS_EnumerateStub,\
- (JSResolveOp) gjs_##cname##_new_resolve, \
- JS_ConvertStub, \
+ JSCLASS_HAS_PRIVATE | jsclass_flags, \
+ NULL, /* addProperty */ \
+ NULL, /* deleteProperty */ \
+ NULL, /* getProperty */ \
+ NULL, /* setProperty */ \
+ NULL, /* enumerate */ \
+ gjs_##cname##_resolve, \
+ NULL, /* convert */ \
gjs_##cname##_finalize \
}; \
JS::Value \
diff --git a/gjs/jsapi-wrapper.h b/gjs/jsapi-wrapper.h
index f4f57e2..1b3cb3e 100644
--- a/gjs/jsapi-wrapper.h
+++ b/gjs/jsapi-wrapper.h
@@ -35,6 +35,6 @@
#pragma GCC system_header
#endif
#include <jsapi.h>
-#include <js/OldDebugAPI.h> /* Needed by some bits */
+#include <js/Conversions.h>
#endif /* GJS_JSAPI_WRAPPER_H */
diff --git a/gjs/runtime.cpp b/gjs/runtime.cpp
index 816dbce..2f69271 100644
--- a/gjs/runtime.cpp
+++ b/gjs/runtime.cpp
@@ -169,13 +169,10 @@ static JSLocaleCallbacks gjs_locale_callbacks =
static void
gjs_finalize_callback(JSFreeOp *fop,
JSFinalizeStatus status,
- bool isCompartment)
+ bool isCompartment,
+ void *user_data)
{
- JSRuntime *runtime;
- RuntimeData *data;
-
- runtime = fop->runtime();
- data = (RuntimeData*) JS_GetRuntimePrivate(runtime);
+ RuntimeData *data = static_cast<RuntimeData *>(user_data);
/* Implementation note for mozjs 24:
sweeping happens in two phases, in the first phase all
@@ -259,7 +256,7 @@ gjs_runtime_for_current_thread(void)
if (!runtime) {
g_assert(gjs_is_inited);
- runtime = JS_NewRuntime(32*1024*1024 /* max bytes */, JS_USE_HELPER_THREADS);
+ runtime = JS_NewRuntime(32*1024*1024 /* max bytes */);
if (runtime == NULL)
g_error("Failed to create javascript runtime");
@@ -269,7 +266,8 @@ gjs_runtime_for_current_thread(void)
JS_SetNativeStackQuota(runtime, 1024*1024);
JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff);
JS_SetLocaleCallbacks(runtime, &gjs_locale_callbacks);
- JS_SetFinalizeCallback(runtime, gjs_finalize_callback);
+ JS_AddFinalizeCallback(runtime, gjs_finalize_callback, data);
+ JS_SetErrorReporter(runtime, gjs_error_reporter);
g_private_set(&thread_runtime, runtime);
}
diff --git a/gjs/stack.cpp b/gjs/stack.cpp
index 7dba9b1..45ef4fd 100644
--- a/gjs/stack.cpp
+++ b/gjs/stack.cpp
@@ -66,17 +66,17 @@ gjs_context_get_frame_info(JSContext *context,
JS::RootedObject err_obj(context, JS_New(context, constructor,
JS::HandleValueArray::empty()));
- if (!stack.empty() &&
+ if (stack &&
!gjs_object_get_property_const(context, err_obj, GJS_STRING_STACK,
stack.ref()))
return false;
- if (!fileName.empty() &&
+ if (fileName &&
!gjs_object_get_property_const(context, err_obj, GJS_STRING_FILENAME,
fileName.ref()))
return false;
- if (!lineNumber.empty() &&
+ if (lineNumber &&
!gjs_object_get_property_const(context, err_obj, GJS_STRING_LINE_NUMBER,
lineNumber.ref()))
return false;
@@ -95,8 +95,8 @@ gjs_context_print_stack_stderr(GjsContext *context)
/* Stderr is locale encoding, so we use string_to_filename here */
/* COMPAT: mozilla::Maybe gains a much more usable API in future versions */
- mozilla::Maybe<JS::MutableHandleValue> m_stack, m_file, m_line;
- m_stack.construct(&v_stack);
+ mozilla::Maybe<JS::MutableHandleValue> m_stack(mozilla::Some<JS::MutableHandleValue>(&v_stack)),
+ m_file, m_line;
if (!gjs_context_get_frame_info(cx, m_stack, m_file, m_line) ||
!gjs_string_to_filename(cx, v_stack, &stack)) {
g_printerr("No stack trace available\n");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]