[gjs: 7/16] js: Introduce annotations for using return values



commit 425b94d663e400b6dee9ed2ebd1c92738970b054
Author: Philip Chimento <philip chimento gmail com>
Date:   Sun Oct 28 20:16:43 2018 -0400

    js: Introduce annotations for using return values
    
    This introduces two annotations to functions. GJS_USE is a macro for GCC
    and Clang's "warn_unused_result" annotation, meaning that the return
    value of a function must not be ignored. This allows us to catch some
    cases where we are neglecting to do error checking.
    
    The second annotation is GJS_JSAPI_RETURN_CONVENTION which for now is
    identical to GJS_USE, but could be made into a custom annotation in the
    future which a static analyzer plugin could use to enforce further checks
    at compile time. The "JSAPI return convention" is valid on functions that
    return bool or a pointer type, and whose first parameter is JSContext*. If
    false or nullptr is returned, then an exception must be pending at return
    time on the passed-in JSContext. If true or a non-nullptr value is
    returned, then no exception must be pending.
    
    This commit only has the addition of the attributes, and a few fixes
    mandated by the autoformatter, so it can be reviewed "lightly".

 gi/arg.cpp                        |  35 ++++++-
 gi/arg.h                          |  14 +++
 gi/boxed.cpp                      |  19 ++++
 gi/boxed.h                        |   4 +
 gi/closure.h                      |   6 ++
 gi/enumeration.cpp                |   1 +
 gi/enumeration.h                  |   4 +
 gi/foreign.cpp                    |   3 +
 gi/foreign.h                      |   6 +-
 gi/function.cpp                   |  11 ++
 gi/function.h                     |   5 +
 gi/fundamental.cpp                |  13 +++
 gi/fundamental.h                  |   7 ++
 gi/gerror.cpp                     |   8 ++
 gi/gerror.h                       |   5 +
 gi/gobject.cpp                    |   1 +
 gi/gtype.cpp                      |   6 +-
 gi/gtype.h                        |   9 +-
 gi/interface.cpp                  |   3 +
 gi/interface.h                    |   4 +
 gi/ns.cpp                         |   3 +
 gi/ns.h                           |   3 +
 gi/object.cpp                     |   8 ++
 gi/object.h                       |  90 +++++++++++++++--
 gi/param.cpp                      |   2 +
 gi/param.h                        |   6 ++
 gi/private.cpp                    |   8 ++
 gi/private.h                      |   2 +
 gi/proxyutils.h                   |   2 +
 gi/repo.cpp                       |   8 ++
 gi/repo.h                         |  12 ++-
 gi/toggle.h                       |   7 +-
 gi/union.cpp                      |   3 +
 gi/union.h                        |   6 ++
 gi/value.cpp                      |   7 ++
 gi/value.h                        |   7 ++
 gjs/byteArray.cpp                 |   6 ++
 gjs/byteArray.h                   |   7 ++
 gjs/console.cpp                   |   2 +
 gjs/context-private.h             |   6 ++
 gjs/context.h                     |  62 +++++-------
 gjs/coverage.cpp                  |   8 ++
 gjs/coverage.h                    |   8 +-
 gjs/debugger.cpp                  |   2 +
 gjs/deprecation.cpp               |   1 +
 gjs/engine.cpp                    |   5 +
 gjs/global.cpp                    |  11 +-
 gjs/global.h                      |   3 +
 gjs/importer.cpp                  |  17 ++++
 gjs/importer.h                    |   4 +
 gjs/jsapi-class.h                 | 205 ++++++++++++++++++--------------------
 gjs/jsapi-dynamic-class.cpp       |   2 +
 gjs/jsapi-util-args.h             |  66 ++++--------
 gjs/jsapi-util-root.h             |  20 ++--
 gjs/jsapi-util-string.cpp         |  12 +--
 gjs/jsapi-util.cpp                |   2 +
 gjs/jsapi-util.h                  |  70 ++++++++-----
 gjs/macros.h                      |  27 +++++
 gjs/module.cpp                    |  11 +-
 gjs/module.h                      |   2 +
 gjs/native.h                      |   4 +
 gjs/profiler-private.h            |   2 +
 gjs/profiler.cpp                  |   1 +
 modules/cairo-context.cpp         |  34 +++++--
 modules/cairo-gradient.cpp        |   2 +
 modules/cairo-image-surface.cpp   |   6 ++
 modules/cairo-linear-gradient.cpp |   1 +
 modules/cairo-module.h            |   4 +
 modules/cairo-path.cpp            |   1 +
 modules/cairo-pattern.cpp         |   1 +
 modules/cairo-pdf-surface.cpp     |   1 +
 modules/cairo-private.h           |  34 +++++++
 modules/cairo-ps-surface.cpp      |   1 +
 modules/cairo-radial-gradient.cpp |   1 +
 modules/cairo-region.cpp          |  78 ++++++++-------
 modules/cairo-solid-pattern.cpp   |   3 +
 modules/cairo-surface-pattern.cpp |   6 +-
 modules/cairo-surface.cpp         |   4 +
 modules/cairo-svg-surface.cpp     |   1 +
 modules/console.cpp               |   4 +
 modules/console.h                 |   3 +
 modules/system.h                  |   3 +
 82 files changed, 784 insertions(+), 308 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 83d9b944..170bb913 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -80,6 +80,7 @@ _gjs_flags_value_is_valid(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 _gjs_enum_value_is_valid(JSContext  *context,
                          GIEnumInfo *enum_info,
@@ -115,6 +116,7 @@ _gjs_enum_value_is_valid(JSContext  *context,
     return found;
 }
 
+GJS_USE
 static bool
 _gjs_enum_uses_signed_type (GIEnumInfo *enum_info)
 {
@@ -132,6 +134,7 @@ _gjs_enum_uses_signed_type (GIEnumInfo *enum_info)
  * is found in g_value_set_enum/g_value_set_flags().
  */
 
+GJS_USE
 gint64
 _gjs_enum_from_int (GIEnumInfo *enum_info,
                     int         int_value)
@@ -143,6 +146,7 @@ _gjs_enum_from_int (GIEnumInfo *enum_info,
 }
 
 /* Here for symmetry, but result is the same for the two cases */
+GJS_USE
 static int
 _gjs_enum_to_int (GIEnumInfo *enum_info,
                   gint64      value)
@@ -153,6 +157,7 @@ _gjs_enum_to_int (GIEnumInfo *enum_info,
 /* Check if an argument of the given needs to be released if we created it
  * from a JS value to pass it into a function and aren't transfering ownership.
  */
+GJS_USE
 static bool
 type_needs_release (GITypeInfo *type_info,
                     GITypeTag   type_tag)
@@ -214,6 +219,7 @@ type_needs_release (GITypeInfo *type_info,
 /* Check if an argument of the given needs to be released if we obtained it
  * from out argument (or the return value), and we're transferring ownership
  */
+GJS_USE
 static bool
 type_needs_out_release(GITypeInfo *type_info,
                        GITypeTag   type_tag)
@@ -252,6 +258,7 @@ type_needs_out_release(GITypeInfo *type_info,
     return false;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_g_list(JSContext   *context,
                     JS::Value    array_value,
@@ -329,6 +336,7 @@ gjs_array_to_g_list(JSContext   *context,
     return true;
 }
 
+GJS_USE
 static GHashTable *
 create_hash_table_for_key_type(GITypeInfo  *key_param_info)
 {
@@ -346,6 +354,7 @@ create_hash_table_for_key_type(GITypeInfo  *key_param_info)
 /* Converts a JS::Value to a GHashTable key, stuffing it into @pointer_out if
  * possible, otherwise giving the location of an allocated key in @pointer_out.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 value_to_ghashtable_key(JSContext      *cx,
                         JS::HandleValue value,
@@ -480,6 +489,7 @@ value_to_ghashtable_key(JSContext      *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_object_to_g_hash(JSContext   *context,
                      JS::Value    hash_value,
@@ -641,6 +651,7 @@ gjs_array_to_strv(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_string_to_intarray(JSContext       *context,
                        JS::HandleString str,
@@ -683,6 +694,7 @@ gjs_string_to_intarray(JSContext       *context,
     return false;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_gboolean_array(JSContext      *cx,
                             JS::Value       array_value,
@@ -709,6 +721,7 @@ gjs_array_to_gboolean_array(JSContext      *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_intarray(JSContext   *context,
                       JS::Value    array_value,
@@ -770,6 +783,7 @@ gjs_array_to_intarray(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_gtypearray_to_array(JSContext   *context,
                         JS::Value    array_value,
@@ -815,6 +829,7 @@ gjs_gtypearray_to_array(JSContext   *context,
     return false;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_floatarray(JSContext   *context,
                         JS::Value    array_value,
@@ -868,6 +883,7 @@ gjs_array_to_floatarray(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_ptrarray(JSContext   *context,
                       JS::Value    array_value,
@@ -922,6 +938,7 @@ gjs_array_to_ptrarray(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_flat_gvalue_array(JSContext   *context,
                                JS::Value    array_value,
@@ -957,6 +974,7 @@ gjs_array_to_flat_gvalue_array(JSContext   *context,
     return result;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_flat_gvalue_array(JSContext             *context,
                                  gpointer               array,
@@ -997,6 +1015,7 @@ gjs_array_from_flat_gvalue_array(JSContext             *context,
     return result;
 }
 
+GJS_USE
 static bool
 is_gvalue(GIBaseInfo *info,
           GIInfoType  info_type)
@@ -1015,6 +1034,7 @@ is_gvalue(GIBaseInfo *info,
     return false;
 }
 
+GJS_USE
 static bool
 is_gvalue_flat_array(GITypeInfo *param_info,
                      GITypeTag   element_type)
@@ -1037,6 +1057,7 @@ is_gvalue_flat_array(GITypeInfo *param_info,
     return result;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_array(JSContext   *context,
                    JS::Value    array_value,
@@ -1126,6 +1147,7 @@ gjs_array_to_array(JSContext   *context,
     }
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static GArray*
 gjs_g_array_new_for_type(JSContext    *context,
                          unsigned int  length,
@@ -1199,6 +1221,7 @@ gjs_g_array_new_for_type(JSContext    *context,
     return g_array_sized_new(true, false, element_size, length);
 }
 
+GJS_USE
 static gchar *
 get_argument_display_name(const char     *arg_name,
                           GjsArgumentType arg_type)
@@ -1221,6 +1244,7 @@ get_argument_display_name(const char     *arg_name,
     }
 }
 
+GJS_USE
 static const char *
 type_tag_to_human_string(GITypeInfo *type_info)
 {
@@ -1257,6 +1281,7 @@ throw_invalid_argument(JSContext      *context,
     g_free(display_name);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_to_explicit_array_internal(JSContext       *context,
                                      JS::HandleValue  value,
@@ -1328,6 +1353,7 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
     return ret;
 }
 
+GJS_USE
 static bool
 is_gdk_atom(GIBaseInfo *info)
 {
@@ -2220,6 +2246,7 @@ gjs_value_to_explicit_array (JSContext      *context,
                                                 length_p);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_g_list (JSContext             *context,
                        JS::MutableHandleValue value_p,
@@ -2266,6 +2293,7 @@ gjs_array_from_g_list (JSContext             *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_carray_internal (JSContext             *context,
                                 JS::MutableHandleValue value_p,
@@ -2407,6 +2435,7 @@ gjs_array_from_carray_internal (JSContext             *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_fixed_size_array (JSContext             *context,
                                  JS::MutableHandleValue value_p,
@@ -2449,6 +2478,7 @@ gjs_value_from_explicit_array(JSContext             *context,
     return res;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_boxed_array (JSContext             *context,
                             JS::MutableHandleValue value_p,
@@ -2487,6 +2517,7 @@ gjs_array_from_boxed_array (JSContext             *context,
     return gjs_array_from_carray_internal(context, value_p, param_info, length, data);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_array_from_zero_terminated_c_array (JSContext             *context,
                                         JS::MutableHandleValue value_p,
@@ -2593,7 +2624,7 @@ gjs_array_from_zero_terminated_c_array (JSContext             *context,
     return true;
 }
 
-
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_object_from_g_hash (JSContext             *context,
                         JS::MutableHandleValue value_p,
@@ -3100,6 +3131,7 @@ gjs_value_from_g_argument (JSContext             *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_g_arg_release_internal(JSContext  *context,
                                          GITransfer  transfer,
                                          GITypeInfo *type_info,
@@ -3145,6 +3177,7 @@ gjs_ghr_helper(gpointer key, gpointer val, gpointer user_data) {
  */
 #define TRANSFER_IN_NOTHING (GI_TRANSFER_EVERYTHING + 1)
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_g_arg_release_internal(JSContext  *context,
                            GITransfer  transfer,
diff --git a/gi/arg.h b/gi/arg.h
index 06a41b31..76b8fe67 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -28,6 +28,7 @@
 #include <glib.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 #include <girepository.h>
 
@@ -43,11 +44,13 @@ typedef enum {
     GJS_ARGUMENT_ARRAY_ELEMENT
 } GjsArgumentType;
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_to_arg(JSContext      *context,
                       JS::HandleValue value,
                       GIArgInfo      *arg_info,
                       GIArgument     *arg);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_to_explicit_array(JSContext       *context,
                                  JS::HandleValue  value,
                                  GIArgInfo       *arg_info,
@@ -58,6 +61,7 @@ void gjs_g_argument_init_default (JSContext      *context,
                                   GITypeInfo     *type_info,
                                   GArgument      *arg);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_to_g_argument (JSContext      *context,
                               JS::HandleValue value,
                               GITypeInfo     *type_info,
@@ -67,48 +71,58 @@ bool gjs_value_to_g_argument (JSContext      *context,
                               bool            may_be_null,
                               GArgument      *arg);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_from_g_argument(JSContext             *context,
                                JS::MutableHandleValue value_p,
                                GITypeInfo            *type_info,
                                GIArgument            *arg,
                                bool                   copy_structs);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_from_explicit_array(JSContext             *context,
                                    JS::MutableHandleValue value_p,
                                    GITypeInfo            *type_info,
                                    GIArgument            *arg,
                                    int                    length);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_g_argument_release    (JSContext  *context,
                                 GITransfer  transfer,
                                 GITypeInfo *type_info,
                                 GArgument  *arg);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_g_argument_release_out_array (JSContext  *context,
                                        GITransfer  transfer,
                                        GITypeInfo *type_info,
                                        guint       length,
                                        GArgument  *arg);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_g_argument_release_in_array (JSContext  *context,
                                       GITransfer  transfer,
                                       GITypeInfo *type_info,
                                       guint       length,
                                       GArgument  *arg);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_g_argument_release_in_arg (JSContext  *context,
                                     GITransfer  transfer,
                                     GITypeInfo *type_info,
                                     GArgument  *arg);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool _gjs_flags_value_is_valid (JSContext   *context,
                                 GType        gtype,
                                 gint64       value);
 
+GJS_USE
 gint64 _gjs_enum_from_int (GIEnumInfo *enum_info,
                            int         int_value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_array_from_strv(JSContext             *context,
                          JS::MutableHandleValue value_p,
                          const char           **strv);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_array_to_strv (JSContext   *context,
                         JS::Value    array_value,
                         unsigned int length,
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 30851291..421607f6 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -66,8 +66,10 @@ struct Boxed {
                                     the reference to the C gboxed */
 };
 
+GJS_USE
 static bool struct_is_simple(GIStructInfo *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool boxed_set_field_from_value(JSContext      *context,
                                        Boxed          *priv,
                                        GIFieldInfo    *field_info,
@@ -77,6 +79,7 @@ extern struct JSClass gjs_boxed_class;
 
 GJS_DEFINE_PRIV_FROM_JS(Boxed, gjs_boxed_class)
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_define_static_methods(JSContext       *context,
                           JS::HandleObject constructor,
@@ -111,6 +114,7 @@ gjs_define_static_methods(JSContext       *context,
 
 /* The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved. */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_resolve(JSContext       *context,
               JS::HandleObject obj,
@@ -176,6 +180,7 @@ boxed_resolve(JSContext       *context,
 /* Check to see if JS::Value passed in is another Boxed object of the same,
  * and if so, retrieves the Boxed private structure for it.
  */
+GJS_USE
 static bool
 boxed_get_copy_source(JSContext *context,
                       Boxed     *priv,
@@ -216,6 +221,7 @@ boxed_new_direct(Boxed       *priv)
  * to do n O(n) lookups, so put put the fields into a hash table and store it on proto->priv
  * for fast lookup. 
  */
+GJS_JSAPI_RETURN_CONVENTION
 static Boxed::FieldMap* get_field_map(JSContext* cx,
                                       GIStructInfo* struct_info) {
     int n_fields;
@@ -246,6 +252,7 @@ static Boxed::FieldMap* get_field_map(JSContext* cx,
  * properties to set as fieds of the object. We don't require that every field
  * of the object be set.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_init_from_props(JSContext   *context,
                       JSObject    *obj,
@@ -301,6 +308,7 @@ boxed_init_from_props(JSContext   *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_invoke_constructor(JSContext             *context,
                          JS::HandleObject       obj,
@@ -323,6 +331,7 @@ boxed_invoke_constructor(JSContext             *context,
                                    args, args.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_new(JSContext             *context,
           JS::HandleObject       obj, /* "this" for constructor */
@@ -519,6 +528,7 @@ boxed_finalize(JSFreeOp *fop,
     g_slice_free(Boxed, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static GIFieldInfo *
 get_field_info(JSContext *cx,
                Boxed     *priv,
@@ -534,6 +544,7 @@ get_field_info(JSContext *cx,
     return field_info;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 get_nested_interface_object(JSContext             *context,
                             JSObject              *parent_obj,
@@ -592,6 +603,7 @@ get_nested_interface_object(JSContext             *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_field_getter(JSContext *context,
                    unsigned   argc,
@@ -658,6 +670,7 @@ out:
     return success;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 set_nested_interface_object (JSContext      *context,
                              Boxed          *parent_priv,
@@ -709,6 +722,7 @@ set_nested_interface_object (JSContext      *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_set_field_from_value(JSContext      *context,
                            Boxed          *priv,
@@ -776,6 +790,7 @@ out:
     return success;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 boxed_field_setter(JSContext *cx,
                    unsigned   argc,
@@ -810,6 +825,7 @@ out:
     return success;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 define_boxed_class_fields(JSContext       *cx,
                           Boxed           *priv,
@@ -850,6 +866,7 @@ define_boxed_class_fields(JSContext       *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 to_string_func(JSContext *context,
                unsigned   argc,
@@ -914,6 +931,7 @@ JSFunctionSpec gjs_boxed_proto_funcs[] = {
     JS_FN("toString", to_string_func, 0, 0),
     JS_FS_END};
 
+GJS_USE
 static bool
 type_can_be_allocated_directly(GITypeInfo *type_info)
 {
@@ -1006,6 +1024,7 @@ type_can_be_allocated_directly(GITypeInfo *type_info)
  * type that we know how to assign to. If so, then we can allocate and free
  * instances without needing a constructor.
  */
+GJS_USE
 static bool
 struct_is_simple(GIStructInfo *info)
 {
diff --git a/gi/boxed.h b/gi/boxed.h
index cd0fc21d..e323679c 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -28,6 +28,7 @@
 #include <glib.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 #include <girepository.h>
 
@@ -45,12 +46,15 @@ void      gjs_define_boxed_class       (JSContext             *context,
                                         JS::HandleObject       in_object,
                                         GIBoxedInfo           *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 void*     gjs_c_struct_from_boxed      (JSContext             *context,
                                         JS::HandleObject       obj);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_boxed_from_c_struct      (JSContext             *context,
                                         GIStructInfo          *info,
                                         void                  *gboxed,
                                         GjsBoxedCreationFlags  flags);
+GJS_USE
 bool      gjs_typecheck_boxed          (JSContext             *context,
                                         JS::HandleObject       obj,
                                         GIStructInfo          *expected_info,
diff --git a/gi/closure.h b/gi/closure.h
index 0367b581..40f5b0d8 100644
--- a/gi/closure.h
+++ b/gi/closure.h
@@ -28,22 +28,28 @@
 #include <glib-object.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_USE
 GClosure*  gjs_closure_new           (JSContext    *context,
                                       JSObject     *callable,
                                       const char   *description,
                                       bool          root_function);
 
+GJS_USE
 bool gjs_closure_invoke(GClosure                   *closure,
                         JS::HandleObject            this_obj,
                         const JS::HandleValueArray& args,
                         JS::MutableHandleValue      retval,
                         bool                        return_exception);
 
+GJS_USE
 JSContext* gjs_closure_get_context   (GClosure     *closure);
+GJS_USE
 bool       gjs_closure_is_valid      (GClosure     *closure);
+GJS_USE
 JSObject*  gjs_closure_get_callable  (GClosure     *closure);
 
 void       gjs_closure_trace         (GClosure     *closure,
diff --git a/gi/enumeration.cpp b/gi/enumeration.cpp
index 2a1a2f95..6ed0e02a 100644
--- a/gi/enumeration.cpp
+++ b/gi/enumeration.cpp
@@ -36,6 +36,7 @@
 
 #include "enumeration.h"
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_define_enum_value(JSContext       *context,
                       JS::HandleObject in_object,
diff --git a/gi/enumeration.h b/gi/enumeration.h
index 3094f30a..ff804e33 100644
--- a/gi/enumeration.h
+++ b/gi/enumeration.h
@@ -28,19 +28,23 @@
 #include <glib.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 #include <girepository.h>
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_enum_values(JSContext       *context,
                             JS::HandleObject in_object,
                             GIEnumInfo      *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_enum_static_methods(JSContext       *context,
                                     JS::HandleObject constructor,
                                     GIEnumInfo      *enum_info);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_enumeration(JSContext       *context,
                             JS::HandleObject in_object,
                             GIEnumInfo      *info);
diff --git a/gi/foreign.cpp b/gi/foreign.cpp
index 43b3c310..ac4ef624 100644
--- a/gi/foreign.cpp
+++ b/gi/foreign.cpp
@@ -41,6 +41,7 @@ static struct {
 
 static GHashTable* foreign_structs_table = NULL;
 
+GJS_USE
 static GHashTable*
 get_foreign_structs(void)
 {
@@ -54,6 +55,7 @@ get_foreign_structs(void)
     return foreign_structs_table;
 }
 
+GJS_USE
 static bool
 gjs_foreign_load_foreign_module(JSContext *context,
                                 const gchar *gi_namespace)
@@ -99,6 +101,7 @@ void gjs_struct_foreign_register(const char* gi_namespace,
     g_hash_table_insert(get_foreign_structs(), canonical_name, info);
 }
 
+GJS_USE
 static GjsForeignInfo *
 gjs_struct_foreign_lookup(JSContext  *context,
                           GIBaseInfo *interface_info)
diff --git a/gi/foreign.h b/gi/foreign.h
index 4b58e45f..385eedae 100644
--- a/gi/foreign.h
+++ b/gi/foreign.h
@@ -26,8 +26,9 @@
 
 #include <stdbool.h>
 #include <girepository.h>
-#include <gjs/gjs.h>
+
 #include "arg.h"
+#include "gjs/macros.h"
 
 typedef bool (*GjsArgOverrideToGArgumentFunc) (JSContext      *context,
                                                JS::Value       value,
@@ -54,6 +55,7 @@ typedef struct {
 void gjs_struct_foreign_register(const char* gi_namespace,
                                  const char* type_name, GjsForeignInfo* info);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool  gjs_struct_foreign_convert_to_g_argument   (JSContext      *context,
                                                   JS::Value       value,
                                                   GIBaseInfo     *interface_info,
@@ -62,11 +64,13 @@ bool  gjs_struct_foreign_convert_to_g_argument   (JSContext      *context,
                                                   GITransfer      transfer,
                                                   bool            may_be_null,
                                                   GArgument      *arg);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_struct_foreign_convert_from_g_argument(JSContext             *context,
                                                 JS::MutableHandleValue value_p,
                                                 GIBaseInfo            *interface_info,
                                                 GIArgument            *arg);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool  gjs_struct_foreign_release_g_argument      (JSContext      *context,
                                                   GITransfer      transfer,
                                                   GIBaseInfo     *interface_info,
diff --git a/gi/function.cpp b/gi/function.cpp
index ebe74142..82a00d56 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -591,6 +591,7 @@ gjs_callback_trampoline_new(JSContext       *context,
 /* an helper function to retrieve array lengths from a GArgument
    (letting the compiler generate good instructions in case of
    big endian machines) */
+GJS_USE
 static unsigned long
 get_length_from_arg (GArgument *arg, GITypeTag tag)
 {
@@ -613,6 +614,7 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
     g_assert_not_reached();
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_fill_method_instance(JSContext       *context,
                          JS::HandleObject obj,
@@ -735,6 +737,7 @@ gjs_fill_method_instance(JSContext       *context,
 }
 
 /* Intended for error messages. Return value must be freed */
+GJS_USE
 static char *
 format_function_name(Function *function,
                      bool      is_method)
@@ -769,6 +772,7 @@ complete_async_calls(void)
  * you can decide to keep the return values in #GArgument format by
  * providing a @r_value argument.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_invoke_c_function(JSContext                             *context,
                       Function                              *function,
@@ -1385,6 +1389,7 @@ release:
     }
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 function_call(JSContext *context,
               unsigned   js_argc,
@@ -1448,6 +1453,7 @@ function_finalize(JSFreeOp *fop,
     g_slice_free(Function, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 get_num_arguments (JSContext *context,
                    unsigned   argc,
@@ -1479,6 +1485,7 @@ get_num_arguments (JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 function_to_string (JSContext *context,
                     guint      argc,
@@ -1578,6 +1585,7 @@ static JSFunctionSpec gjs_function_proto_funcs[] = {
 
 static JSFunctionSpec *gjs_function_static_funcs = nullptr;
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 init_cached_function_data (JSContext      *context,
                            Function       *function,
@@ -1724,6 +1732,7 @@ init_cached_function_data (JSContext      *context,
     return true;
 }
 
+GJS_USE
 static inline JSObject *
 gjs_builtin_function_get_proto(JSContext *cx)
 {
@@ -1733,6 +1742,7 @@ gjs_builtin_function_get_proto(JSContext *cx)
 
 GJS_DEFINE_PROTO_FUNCS_WITH_PARENT(function, builtin_function)
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 function_new(JSContext      *context,
              GType           gtype,
@@ -1768,6 +1778,7 @@ function_new(JSContext      *context,
     return function;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*
 gjs_define_function(JSContext       *context,
                     JS::HandleObject in_object,
diff --git a/gi/function.h b/gi/function.h
index 9d3283a4..30f473c7 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -28,6 +28,7 @@
 #include <glib.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 #include <girepository.h>
 #include <girffi.h>
@@ -54,6 +55,7 @@ struct GjsCallbackTrampoline {
     GjsParamType *param_types;
 };
 
+GJS_JSAPI_RETURN_CONVENTION
 GjsCallbackTrampoline* gjs_callback_trampoline_new(JSContext       *context,
                                                    JS::HandleValue  function,
                                                    GICallableInfo  *callable_info,
@@ -64,17 +66,20 @@ GjsCallbackTrampoline* gjs_callback_trampoline_new(JSContext       *context,
 void gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline);
 void gjs_callback_trampoline_ref(GjsCallbackTrampoline *trampoline);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_define_function(JSContext       *context,
                               JS::HandleObject in_object,
                               GType            gtype,
                               GICallableInfo  *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_invoke_c_function_uncached(JSContext                  *context,
                                     GIFunctionInfo             *info,
                                     JS::HandleObject            obj,
                                     const JS::HandleValueArray& args,
                                     JS::MutableHandleValue      rval);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_invoke_constructor_from_c(JSContext                  *context,
                                    JS::HandleObject            constructor,
                                    JS::HandleObject            obj,
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 01b949f6..30409140 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -73,6 +73,7 @@ extern struct JSClass gjs_fundamental_instance_class;
 
 GJS_DEFINE_PRIV_FROM_JS(FundamentalInstance, gjs_fundamental_instance_class)
 
+GJS_USE
 static GQuark
 gjs_fundamental_table_quark (void)
 {
@@ -83,6 +84,7 @@ gjs_fundamental_table_quark (void)
     return val;
 }
 
+GJS_USE
 static GHashTable *
 _ensure_mapping_table(GjsContext *context)
 {
@@ -117,6 +119,7 @@ _fundamental_remove_object(void *native_object)
     g_hash_table_remove(table, native_object);
 }
 
+GJS_USE
 static JSObject *
 _fundamental_lookup_object(void *native_object)
 {
@@ -127,18 +130,21 @@ _fundamental_lookup_object(void *native_object)
 
 /**/
 
+GJS_USE
 static inline bool
 fundamental_is_prototype(Fundamental *priv)
 {
     return (priv->prototype == nullptr);
 }
 
+GJS_USE
 static inline bool
 fundamental_is_prototype(FundamentalInstance *priv)
 {
     return (priv->prototype == nullptr);
 }
 
+GJS_USE
 static inline Fundamental *
 proto_priv_from_js(JSContext       *context,
                    JS::HandleObject obj)
@@ -203,6 +209,7 @@ associate_js_instance_to_fundamental(JSContext       *context,
 /**/
 
 /* Find the first constructor */
+GJS_USE
 static GIFunctionInfo *
 find_fundamental_constructor(JSContext          *context,
                              GIObjectInfo       *info,
@@ -236,6 +243,7 @@ find_fundamental_constructor(JSContext          *context,
 
 /**/
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 fundamental_instance_resolve_interface(JSContext       *context,
                                        JS::HandleObject obj,
@@ -279,6 +287,7 @@ fundamental_instance_resolve_interface(JSContext       *context,
  * The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 fundamental_instance_resolve(JSContext       *context,
                              JS::HandleObject obj,
@@ -355,6 +364,7 @@ fundamental_instance_resolve(JSContext       *context,
     return status;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 fundamental_invoke_constructor(FundamentalInstance        *priv,
                                JSContext                  *context,
@@ -468,6 +478,7 @@ fundamental_finalize(JSFreeOp  *fop,
     }
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 to_string_func(JSContext *context,
                unsigned   argc,
@@ -544,6 +555,7 @@ static JSFunctionSpec gjs_fundamental_instance_proto_funcs[] = {
     JS_FN("toString", to_string_func, 0, 0),
     JS_FS_END};
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_lookup_fundamental_prototype(JSContext    *context,
                                  GIObjectInfo *info,
@@ -597,6 +609,7 @@ gjs_lookup_fundamental_prototype(JSContext    *context,
     return prototype;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 gjs_lookup_fundamental_prototype_from_gtype(JSContext *context,
                                             GType      gtype)
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 791bb9b4..fa4427d1 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -28,27 +28,34 @@
 #include <stdbool.h>
 #include <glib.h>
 #include <girepository.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_fundamental_class(JSContext              *context,
                                   JS::HandleObject        in_object,
                                   GIObjectInfo           *info,
                                   JS::MutableHandleObject constructor,
                                   JS::MutableHandleObject prototype);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_object_from_g_fundamental      (JSContext     *context,
                                               GIObjectInfo  *info,
                                               void          *fobj);
 
+GJS_JSAPI_RETURN_CONVENTION
 void     *gjs_g_fundamental_from_object(JSContext       *context,
                                         JS::HandleObject obj);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_fundamental_from_g_value       (JSContext     *context,
                                               const GValue  *value,
                                               GType          gtype);
 
+GJS_USE
 bool      gjs_typecheck_fundamental(JSContext       *context,
                                     JS::HandleObject object,
                                     GType            expected_gtype,
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 5fadd83c..bc2ce6d4 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -141,6 +141,7 @@ error_finalize(JSFreeOp *fop,
     g_slice_free(Error, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 error_get_domain(JSContext *context,
                  unsigned   argc,
@@ -155,6 +156,7 @@ error_get_domain(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 error_get_message(JSContext *context,
                   unsigned   argc,
@@ -174,6 +176,7 @@ error_get_message(JSContext *context,
     return gjs_string_from_utf8(context, priv->gerror->message, args.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 error_get_code(JSContext *context,
                unsigned   argc,
@@ -194,6 +197,7 @@ error_get_code(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 error_to_string(JSContext *context,
                 unsigned   argc,
@@ -238,6 +242,7 @@ error_to_string(JSContext *context,
     return gjs_string_from_utf8(context, descr, rec.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 error_constructor_value_of(JSContext *context,
                            unsigned   argc,
@@ -355,6 +360,7 @@ gjs_define_error_class(JSContext       *context,
     gjs_define_enum_static_methods(context, constructor, priv->info);
 }
 
+GJS_USE
 static GIEnumInfo *
 find_error_domain_info(GQuark domain)
 {
@@ -421,6 +427,7 @@ define_error_properties(JSContext       *cx,
         exc.restore();
 }
 
+GJS_USE
 static JSProtoKey
 proto_key_from_error_enum(int val)
 {
@@ -445,6 +452,7 @@ proto_key_from_error_enum(int val)
     }
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_error_from_js_gerror(JSContext *cx,
                          GError    *gerror)
diff --git a/gi/gerror.h b/gi/gerror.h
index 1df4673b..1ff0a300 100644
--- a/gi/gerror.h
+++ b/gi/gerror.h
@@ -29,21 +29,26 @@
 #include <girepository.h>
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
 void      gjs_define_error_class       (JSContext             *context,
                                         JS::HandleObject       in_object,
                                         GIEnumInfo            *info);
+GJS_JSAPI_RETURN_CONVENTION
 GError*   gjs_gerror_from_error        (JSContext             *context,
                                         JS::HandleObject       obj);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_error_from_gerror        (JSContext             *context,
                                         GError                *gerror,
                                         bool                   add_stack);
+GJS_USE
 bool      gjs_typecheck_gerror         (JSContext             *context,
                                         JS::HandleObject       obj,
                                         bool                   throw_error);
 
+GJS_JSAPI_RETURN_CONVENTION
 GError *gjs_gerror_make_from_error(JSContext       *cx,
                                    JS::HandleObject obj);
 
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index d4b74ae5..8e2d762c 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -34,6 +34,7 @@
 
 static std::unordered_map<GType, AutoParamArray> class_init_properties;
 
+GJS_USE
 static JSContext* current_context(void) {
     GjsContext* gjs = gjs_context_get_current();
     return static_cast<JSContext*>(gjs_context_get_native_context(gjs));
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index 64bd8a81..2a46cfeb 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -35,7 +35,8 @@
 static bool weak_pointer_callback = false;
 static std::set<GType> weak_pointer_list;
 
-static JSObject *gjs_gtype_get_proto(JSContext *) G_GNUC_UNUSED;
+GJS_USE static JSObject* gjs_gtype_get_proto(JSContext* cx) G_GNUC_UNUSED;
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_gtype_define_proto(JSContext *, JS::HandleObject,
                                    JS::MutableHandleObject);
 
@@ -45,6 +46,7 @@ GJS_DEFINE_PROTO_ABSTRACT("GIRepositoryGType", gtype,
 /* priv_from_js adds a "*", so this returns "void *" */
 GJS_DEFINE_PRIV_FROM_JS(void, gjs_gtype_class);
 
+GJS_USE
 static GQuark
 gjs_get_gtype_wrapper_quark(void)
 {
@@ -99,6 +101,7 @@ gjs_gtype_finalize(JSFreeOp *fop,
     g_type_set_qdata(gtype, gjs_get_gtype_wrapper_quark(), NULL);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 to_string_func(JSContext *cx,
                unsigned   argc,
@@ -120,6 +123,7 @@ to_string_func(JSContext *cx,
     return gjs_string_from_utf8(cx, strval, rec.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 get_name_func (JSContext *context,
                unsigned   argc,
diff --git a/gi/gtype.h b/gi/gtype.h
index f9ca4e51..3880b74f 100644
--- a/gi/gtype.h
+++ b/gi/gtype.h
@@ -28,20 +28,27 @@
 #include <stdbool.h>
 #include <glib.h>
 #include <girepository.h>
-#include "gjs/jsapi-util.h"
+
+#include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject * gjs_gtype_create_gtype_wrapper (JSContext *context,
                                            GType      gtype);
 
+/* FIXME: This should be GJS_JSAPI_RETURN_CONVENTION, but isn't */
+GJS_USE
 GType       gjs_gtype_get_actual_gtype(JSContext       *context,
                                        JS::HandleObject object);
 
+GJS_USE
 bool        gjs_typecheck_gtype         (JSContext             *context,
                                          JS::HandleObject       obj,
                                          bool                   throw_error);
 
+GJS_USE
 const char *gjs_get_names_from_gtype_and_gi_info(GType        gtype,
                                                  GIBaseInfo  *info,
                                                  const char **constructor_name);
diff --git a/gi/interface.cpp b/gi/interface.cpp
index e8235c0b..2d4c6bae 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -71,6 +71,7 @@ interface_finalize(JSFreeOp *fop,
     g_slice_free(Interface, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_define_static_methods(JSContext       *context,
                           JS::HandleObject constructor,
@@ -103,6 +104,7 @@ gjs_define_static_methods(JSContext       *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 interface_resolve(JSContext       *context,
                   JS::HandleObject obj,
@@ -147,6 +149,7 @@ interface_resolve(JSContext       *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 interface_has_instance_func(JSContext *cx,
                             unsigned   argc,
diff --git a/gi/interface.h b/gi/interface.h
index c118ed97..d34d7862 100644
--- a/gi/interface.h
+++ b/gi/interface.h
@@ -28,16 +28,20 @@
 #include <stdbool.h>
 #include <glib.h>
 #include <girepository.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_interface_class(JSContext              *context,
                                 JS::HandleObject        in_object,
                                 GIInterfaceInfo        *info,
                                 GType                   gtype,
                                 JS::MutableHandleObject constructor);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_lookup_interface_constructor(JSContext             *context,
                                       GType                  gtype,
                                       JS::MutableHandleValue value_p);
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 9ff190f8..9ddac91c 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -45,6 +45,7 @@ GJS_DEFINE_PRIV_FROM_JS(Ns, gjs_ns_class)
 
 /* The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved. */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 ns_resolve(JSContext       *context,
            JS::HandleObject obj,
@@ -107,6 +108,7 @@ ns_resolve(JSContext       *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 get_name (JSContext *context,
           unsigned   argc,
@@ -170,6 +172,7 @@ static JSFunctionSpec *gjs_ns_static_funcs = nullptr;
 
 GJS_DEFINE_PROTO_FUNCS(ns)
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 ns_new(JSContext    *context,
        const char   *ns_name)
diff --git a/gi/ns.h b/gi/ns.h
index e0a6932f..9035e9d8 100644
--- a/gi/ns.h
+++ b/gi/ns.h
@@ -26,10 +26,13 @@
 
 #include <glib.h>
 #include <girepository.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_create_ns(JSContext    *context,
                         const char   *ns_name);
 
diff --git a/gi/object.cpp b/gi/object.cpp
index 530561d5..4e2acbb9 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -82,6 +82,7 @@ G_DEFINE_QUARK(gjs::custom-type, ObjectBase::custom_type)
 G_DEFINE_QUARK(gjs::custom-property, ObjectBase::custom_property)
 // clang-format on
 
+GJS_USE
 static GQuark
 gjs_object_priv_quark (void)
 {
@@ -402,6 +403,7 @@ ObjectInstance::prop_getter_impl(JSContext             *cx,
     return true;
 }
 
+GJS_USE
 static GjsAutoFieldInfo lookup_field_info(GIObjectInfo* info,
                                           const char* name) {
     int n_fields = g_object_info_get_n_fields(info);
@@ -634,6 +636,7 @@ bool ObjectPrototype::is_vfunc_unchanged(GIVFuncInfo* info) {
     return addr1 == addr2;
 }
 
+GJS_USE
 static GjsAutoVFuncInfo find_vfunc_on_parents(GIObjectInfo* info,
                                               const char* name,
                                               bool* out_defined_by_parent) {
@@ -674,6 +677,7 @@ static void canonicalize_key(const GjsAutoChar& key) {
 }
 
 /* @name must already be canonicalized */
+GJS_USE
 static bool is_ginterface_property_name(GIInterfaceInfo* info,
                                         const char* name) {
     int n_props = g_interface_info_get_n_properties(info);
@@ -772,6 +776,7 @@ bool ObjectPrototype::resolve_no_info(JSContext* cx, JS::HandleObject obj,
     return true;
 }
 
+GJS_USE
 static bool
 is_gobject_property_name(GIObjectInfo *info,
                          const char   *name)
@@ -1793,6 +1798,7 @@ JSObject* gjs_lookup_object_constructor_from_info(JSContext* context,
     return constructor;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_lookup_object_prototype_from_info(JSContext    *context,
                                       GIObjectInfo *info,
@@ -1812,6 +1818,7 @@ gjs_lookup_object_prototype_from_info(JSContext    *context,
     return prototype;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_lookup_object_prototype(JSContext *context,
                             GType      gtype)
@@ -2370,6 +2377,7 @@ ObjectInstance::typecheck_object(JSContext *context,
     return result;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool find_vfunc_info(JSContext* context, GType implementor_gtype,
                             GIBaseInfo* vfunc_info, const char* vfunc_name,
                             void** implementor_vtable_ret,
diff --git a/gi/object.h b/gi/object.h
index 74672d97..babf36d5 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -35,6 +35,7 @@
 #include "gjs/jsapi-util-root.h"
 #include "gjs/jsapi-util.h"
 #include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
 
 #include "js/GCHashTable.h"
 
@@ -46,12 +47,12 @@ class GjsListLink {
     ObjectInstance* m_next;
 
  public:
-    ObjectInstance* prev(void) const { return m_prev; }
-    ObjectInstance* next(void) const { return m_next; }
+    GJS_USE ObjectInstance* prev(void) const { return m_prev; }
+    GJS_USE ObjectInstance* next(void) const { return m_next; }
 
     void prepend(ObjectInstance* this_instance, ObjectInstance* head);
     void unlink(void);
-    size_t size(void) const;
+    GJS_USE size_t size(void) const;
 };
 
 struct AutoGValueVector : public std::vector<GValue> {
@@ -96,31 +97,38 @@ class ObjectBase {
     /* Methods to get an existing ObjectBase */
 
  public:
+    GJS_USE
     static ObjectBase* for_js(JSContext* cx, JS::HandleObject obj);
+    GJS_USE
     static ObjectBase* for_js_nocheck(JSObject* obj);
 
     /* Methods for getting a pointer to the correct subclass. We don't use
      * standard C++ subclasses because that would occupy another 8 bytes in
      * ObjectInstance for a vtable. */
 
+    GJS_USE
     bool is_prototype(void) const { return !m_proto; }
 
     /* The to_instance() and to_prototype() methods assert that this ObjectBase
      * is of the correct subclass. If you don't want an assert, then either
      * check beforehand or use get_prototype(). */
 
+    GJS_USE
     ObjectPrototype* to_prototype(void) {
         g_assert(is_prototype());
         return reinterpret_cast<ObjectPrototype*>(this);
     }
+    GJS_USE
     const ObjectPrototype* to_prototype(void) const {
         g_assert(is_prototype());
         return reinterpret_cast<const ObjectPrototype*>(this);
     }
+    GJS_USE
     ObjectInstance* to_instance(void) {
         g_assert(!is_prototype());
         return reinterpret_cast<ObjectInstance*>(this);
     }
+    GJS_USE
     const ObjectInstance* to_instance(void) const {
         g_assert(!is_prototype());
         return reinterpret_cast<const ObjectInstance*>(this);
@@ -130,9 +138,11 @@ class ObjectBase {
      * returns you the same object cast to the correct type; if you call it on
      * an ObjectInstance, it returns you the ObjectPrototype belonging to the
      * corresponding JS prototype. */
+    GJS_USE
     ObjectPrototype* get_prototype(void) {
         return is_prototype() ? to_prototype() : m_proto;
     }
+    GJS_USE
     const ObjectPrototype* get_prototype(void) const {
         return is_prototype() ? to_prototype() : m_proto;
     }
@@ -141,26 +151,31 @@ class ObjectBase {
 
     /* Both ObjectInstance and ObjectPrototype have GIObjectInfo and GType,
      * but for space reasons we store it only on ObjectPrototype. */
-    GIObjectInfo* info(void) const;
-    GType gtype(void) const;
+    GJS_USE GIObjectInfo* info(void) const;
+    GJS_USE GType gtype(void) const;
 
+    GJS_USE
     const char* ns(void) const {
         return info() ? g_base_info_get_namespace(info()) : "";
     }
+    GJS_USE
     const char* name(void) const {
         return info() ? g_base_info_get_name(info()) : type_name();
     }
+    GJS_USE
     const char* type_name(void) const { return g_type_name(gtype()); }
+    GJS_USE
     bool is_custom_js_class(void) const { return !info(); }
 
  private:
     /* These are used in debug methods only. */
-    const void* gobj_addr(void) const;
-    const void* jsobj_addr(void) const;
+    GJS_USE const void* gobj_addr(void) const;
+    GJS_USE const void* jsobj_addr(void) const;
 
     /* Helper methods */
 
  public:
+    GJS_JSAPI_RETURN_CONVENTION
     bool check_is_instance(JSContext* cx, const char* for_what) const;
 
  protected:
@@ -221,24 +236,34 @@ class ObjectBase {
     /* JS property getters/setters */
 
  public:
+    GJS_JSAPI_RETURN_CONVENTION
     static bool prop_getter(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool field_getter(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool prop_setter(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool field_setter(JSContext* cx, unsigned argc, JS::Value* vp);
 
     /* JS methods */
 
+    GJS_JSAPI_RETURN_CONVENTION
     static bool connect(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool connect_after(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool emit(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool to_string(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool init(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
     static bool hook_up_vfunc(JSContext* cx, unsigned argc, JS::Value* vp);
 
     /* Quarks */
 
-    static GQuark custom_type_quark(void);
-    static GQuark custom_property_quark(void);
+    GJS_USE static GQuark custom_type_quark(void);
+    GJS_USE static GQuark custom_property_quark(void);
 };
 
 class ObjectPrototype : public ObjectBase {
@@ -264,30 +289,41 @@ class ObjectPrototype : public ObjectBase {
 
  public:
     /* Public constructor for instances (uses GSlice allocator) */
+    GJS_USE
     static ObjectPrototype* new_for_js_object(GIObjectInfo* info, GType gtype);
 
+    GJS_USE
     static ObjectPrototype* for_js(JSContext* cx, JS::HandleObject obj) {
         return ObjectBase::for_js(cx, obj)->to_prototype();
     }
+    GJS_USE
     static ObjectPrototype* for_gtype(GType gtype);
+    GJS_USE
     static ObjectPrototype* for_js_prototype(JSContext* cx,
                                              JS::HandleObject obj);
 
     /* Helper methods */
  private:
+    GJS_USE
     bool is_vfunc_unchanged(GIVFuncInfo* info);
+    GJS_JSAPI_RETURN_CONVENTION
     bool lazy_define_gobject_property(JSContext* cx, JS::HandleObject obj,
                                       JS::HandleId id, bool* resolved,
                                       const char* name);
+
     enum ResolveWhat { ConsiderOnlyMethods, ConsiderMethodsAndProperties };
+    GJS_JSAPI_RETURN_CONVENTION
     bool resolve_no_info(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                          bool* resolved, const char* name,
                          ResolveWhat resolve_props);
 
  public:
     void set_type_qdata(void);
+    GJS_JSAPI_RETURN_CONVENTION
     GParamSpec* find_param_spec_from_id(JSContext* cx, JS::HandleString key);
+    GJS_JSAPI_RETURN_CONVENTION
     GIFieldInfo* find_field_info_from_id(JSContext* cx, JS::HandleString key);
+    GJS_JSAPI_RETURN_CONVENTION
     bool props_to_g_parameters(JSContext* cx, const JS::HandleValueArray& args,
                                std::vector<const char*>* names,
                                AutoGValueVector* values);
@@ -305,9 +341,11 @@ class ObjectPrototype : public ObjectBase {
 
     /* JSClass operations */
  private:
+    GJS_JSAPI_RETURN_CONVENTION
     bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                       bool* resolved);
 
+    GJS_JSAPI_RETURN_CONVENTION
     bool new_enumerate_impl(
         JSContext* cx, JS::HandleObject obj,
         JS::AutoIdVector& properties,  // NOLINT(runtime/references)
@@ -316,7 +354,9 @@ class ObjectPrototype : public ObjectBase {
 
     /* JS methods */
  private:
+    GJS_JSAPI_RETURN_CONVENTION
     bool to_string_impl(JSContext* cx, const JS::CallArgs& args);
+    GJS_JSAPI_RETURN_CONVENTION
     bool hook_up_vfunc_impl(JSContext* cx, const JS::CallArgs& args,
                             JS::HandleObject prototype);
 
@@ -355,18 +395,23 @@ class ObjectInstance : public ObjectBase {
 
  public:
     /* Public constructor for instances (uses GSlice allocator) */
+    GJS_USE
     static ObjectInstance* new_for_js_object(JSContext* cx,
                                              JS::HandleObject obj);
 
+    GJS_USE
     static ObjectInstance* for_gobject(GObject* gobj);
 
     /* Accessors */
 
  private:
+    GJS_USE
     bool has_wrapper(void) const { return !!m_wrapper; }
 
  public:
+    GJS_USE
     GObject* gobj(void) const { return m_gobj; }
+    GJS_USE
     JSObject* wrapper(void) const { return m_wrapper; }
 
     /* Methods to manipulate the JS object wrapper */
@@ -375,15 +420,17 @@ class ObjectInstance : public ObjectBase {
     void discard_wrapper(void) { m_wrapper.reset(); }
     void switch_to_rooted(JSContext* cx) { m_wrapper.switch_to_rooted(cx); }
     void switch_to_unrooted(void) { m_wrapper.switch_to_unrooted(); }
+    GJS_USE
     bool update_after_gc(void) { return m_wrapper.update_after_gc(); }
 
  public:
+    GJS_USE
     bool wrapper_is_rooted(void) const { return m_wrapper.rooted(); }
     void release_native_object(void);
     void associate_js_gobject(JSContext* cx, JS::HandleObject obj,
                               GObject* gobj);
     void disassociate_js_gobject(void);
-    bool weak_pointer_was_finalized(void);
+    GJS_USE bool weak_pointer_was_finalized(void);
     void toggle_down(void);
     void toggle_up(void);
 
@@ -396,18 +443,21 @@ class ObjectInstance : public ObjectBase {
 
  public:
     void ensure_uses_toggle_ref(JSContext* cx);
-    bool check_gobject_disposed(const char* for_what) const;
+    GJS_USE bool check_gobject_disposed(const char* for_what) const;
 
     /* Methods to manipulate the linked list of instances */
 
  private:
     static ObjectInstance* wrapped_gobject_list;
+    GJS_USE
     ObjectInstance* next(void) const { return m_instance_link.next(); }
     void link(void);
     void unlink(void);
 
  public:
+    GJS_USE
     GjsListLink* get_link(void) { return &m_instance_link; }
+    GJS_USE
     static size_t num_wrapped_gobjects(void) {
         return wrapped_gobject_list
                    ? wrapped_gobject_list->m_instance_link.size()
@@ -421,6 +471,7 @@ class ObjectInstance : public ObjectBase {
     /* JSClass operations */
 
  private:
+    GJS_JSAPI_RETURN_CONVENTION
     bool add_property_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                            JS::HandleValue value);
     void finalize_impl(JSFreeOp* fop, JSObject* obj);
@@ -428,21 +479,29 @@ class ObjectInstance : public ObjectBase {
     /* JS property getters/setters */
 
  private:
+    GJS_JSAPI_RETURN_CONVENTION
     bool prop_getter_impl(JSContext* cx, JS::HandleObject obj,
                           JS::HandleString name, JS::MutableHandleValue rval);
+    GJS_JSAPI_RETURN_CONVENTION
     bool field_getter_impl(JSContext* cx, JS::HandleObject obj,
                            JS::HandleString name, JS::MutableHandleValue rval);
+    GJS_JSAPI_RETURN_CONVENTION
     bool prop_setter_impl(JSContext* cx, JS::HandleObject obj,
                           JS::HandleString name, JS::HandleValue value);
+    GJS_JSAPI_RETURN_CONVENTION
     bool field_setter_impl(JSContext* cx, JS::HandleObject obj,
                            JS::HandleString name, JS::HandleValue value);
 
     /* JS methods */
 
  private:
+    GJS_JSAPI_RETURN_CONVENTION
     bool connect_impl(JSContext* cx, const JS::CallArgs& args, bool after);
+    GJS_JSAPI_RETURN_CONVENTION
     bool emit_impl(JSContext* cx, const JS::CallArgs& args);
+    GJS_JSAPI_RETURN_CONVENTION
     bool to_string_impl(JSContext* cx, const JS::CallArgs& args);
+    GJS_JSAPI_RETURN_CONVENTION
     bool init_impl(JSContext* cx, const JS::CallArgs& args,
                    JS::MutableHandleObject obj);
 
@@ -451,6 +510,7 @@ class ObjectInstance : public ObjectBase {
     static JS::PersistentRootedSymbol hook_up_vfunc_root;
 
  public:
+    GJS_USE
     bool typecheck_object(JSContext* cx, GType expected_type, bool throw_error);
     static JS::Symbol* hook_up_vfunc_symbol(JSContext* cx);
 
@@ -467,6 +527,7 @@ class ObjectInstance : public ObjectBase {
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_object_class(JSContext              *cx,
                              JS::HandleObject        in_object,
                              GIObjectInfo           *info,
@@ -474,24 +535,30 @@ bool gjs_define_object_class(JSContext              *cx,
                              JS::MutableHandleObject constructor,
                              JS::MutableHandleObject prototype);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_lookup_object_constructor(JSContext             *context,
                                    GType                  gtype,
                                    JS::MutableHandleValue value_p);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_lookup_object_constructor_from_info(JSContext* cx,
                                                   GIObjectInfo* info,
                                                   GType gtype);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_object_from_g_object      (JSContext     *context,
                                          GObject       *gobj);
 
+GJS_JSAPI_RETURN_CONVENTION
 GObject  *gjs_g_object_from_object(JSContext       *context,
                                    JS::HandleObject obj);
 
+GJS_USE
 bool      gjs_typecheck_object(JSContext       *context,
                                JS::HandleObject obj,
                                GType            expected_type,
                                bool             throw_error);
 
+GJS_USE
 bool      gjs_typecheck_is_object(JSContext       *context,
                                   JS::HandleObject obj,
                                   bool             throw_error);
@@ -502,6 +569,7 @@ void gjs_object_shutdown_toggle_queue(void);
 void gjs_object_context_dispose_notify(void    *data,
                                        GObject *where_the_object_was);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_define_static_methods(JSContext       *context,
                                       JS::HandleObject constructor,
                                       GType            gtype,
diff --git a/gi/param.cpp b/gi/param.cpp
index ae998fb8..226bfc69 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -49,6 +49,7 @@ GJS_DEFINE_PRIV_FROM_JS(Param, gjs_param_class)
  * The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 param_resolve(JSContext       *context,
               JS::HandleObject obj,
@@ -156,6 +157,7 @@ static JSFunctionSpec gjs_param_constructor_funcs[] = {
     JS_FS_END
 };
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 gjs_lookup_param_prototype(JSContext    *context)
 {
diff --git a/gi/param.h b/gi/param.h
index f5ed5467..adb4657c 100644
--- a/gi/param.h
+++ b/gi/param.h
@@ -27,19 +27,25 @@
 #include <stdbool.h>
 #include <glib.h>
 #include <girepository.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_param_class(JSContext       *context,
                             JS::HandleObject in_object);
 
+GJS_JSAPI_RETURN_CONVENTION
 GParamSpec *gjs_g_param_from_param (JSContext       *context,
                                     JS::HandleObject obj);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*   gjs_param_from_g_param     (JSContext  *context,
                                         GParamSpec *param);
 
+GJS_USE
 bool        gjs_typecheck_param(JSContext       *context,
                                 JS::HandleObject obj,
                                 GType            expected_type,
diff --git a/gi/private.cpp b/gi/private.cpp
index 64bacbf5..6bdf5691 100644
--- a/gi/private.cpp
+++ b/gi/private.cpp
@@ -41,6 +41,7 @@
  * to client code.
  */
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_override_property(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     JS::UniqueChars name;
@@ -83,6 +84,7 @@ static bool gjs_override_property(JSContext* cx, unsigned argc, JS::Value* vp) {
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool validate_interfaces_and_properties_args(JSContext* cx,
                                                     JS::HandleObject interfaces,
                                                     JS::HandleObject properties,
@@ -118,6 +120,7 @@ static bool validate_interfaces_and_properties_args(JSContext* cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool save_properties_for_class_init(JSContext* cx,
                                            JS::HandleObject properties,
                                            uint32_t n_properties, GType gtype) {
@@ -144,6 +147,7 @@ static bool save_properties_for_class_init(JSContext* cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool get_interface_gtypes(JSContext* cx, JS::HandleObject interfaces,
                                  uint32_t n_interfaces, GType* iface_types) {
     for (uint32_t ix = 0; ix < n_interfaces; ix++) {
@@ -172,6 +176,7 @@ static bool get_interface_gtypes(JSContext* cx, JS::HandleObject interfaces,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_register_interface(JSContext* cx, unsigned argc,
                                    JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
@@ -235,6 +240,7 @@ static inline void gjs_add_interface(GType instance_type,
                                 &interface_vtable);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_register_type(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
 
@@ -315,6 +321,7 @@ static bool gjs_register_type(JSContext* cx, unsigned argc, JS::Value* vp) {
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_signal_new(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
@@ -386,6 +393,7 @@ static bool gjs_signal_new(JSContext* cx, unsigned argc, JS::Value* vp) {
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool hook_up_vfunc_symbol_getter(JSContext* cx, unsigned argc,
                                         JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
diff --git a/gi/private.h b/gi/private.h
index 16e8fee7..9c789f22 100644
--- a/gi/private.h
+++ b/gi/private.h
@@ -25,7 +25,9 @@
 #define GI_PRIVATE_H_
 
 #include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_private_gi_stuff(JSContext* cx, JS::MutableHandleObject module);
 
 #endif  // GI_PRIVATE_H_
diff --git a/gi/proxyutils.h b/gi/proxyutils.h
index e8cf6d26..a2fa0489 100644
--- a/gi/proxyutils.h
+++ b/gi/proxyutils.h
@@ -25,9 +25,11 @@
 #define __GJS_PROXYUTILS_H__
 
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool _gjs_proxy_to_string_func(JSContext             *context,
                                JSObject              *this_obj,
                                const char            *objtype,
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 2a3d110a..6948dfc5 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -54,9 +54,11 @@ extern struct JSClass gjs_repo_class;
 
 GJS_DEFINE_PRIV_FROM_JS(Repo, gjs_repo_class)
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool lookup_override_function(JSContext *, JS::HandleId,
                                      JS::MutableHandleValue);
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool get_version_for_ns(JSContext* context, JS::HandleObject repo_obj,
                                JS::HandleId ns_id, JS::UniqueChars* version) {
     JS::RootedObject versions(context);
@@ -76,6 +78,7 @@ static bool get_version_for_ns(JSContext* context, JS::HandleObject repo_obj,
     return gjs_object_require_property(context, versions, NULL, ns_id, version);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool resolve_namespace_object(JSContext* context,
                                      JS::HandleObject repo_obj,
                                      JS::HandleId ns_id) {
@@ -150,6 +153,7 @@ static bool resolve_namespace_object(JSContext* context,
  * The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 repo_resolve(JSContext       *context,
              JS::HandleObject obj,
@@ -236,6 +240,7 @@ static JSFunctionSpec *gjs_repo_static_funcs = nullptr;
 
 GJS_DEFINE_PROTO_FUNCS(repo)
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 repo_new(JSContext *context)
 {
@@ -294,6 +299,7 @@ gjs_define_repo(JSContext              *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_define_constant(JSContext       *context,
                     JS::HandleObject in_object,
@@ -538,6 +544,7 @@ gjs_lookup_namespace_object(JSContext  *context,
 
 /* Check if an exception's 'name' property is equal to compare_name. Ignores
  * all errors that might arise. Requires request. */
+GJS_USE
 static bool
 error_has_name(JSContext       *cx,
                JS::HandleValue  thrown_value,
@@ -566,6 +573,7 @@ out:
     return retval;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 lookup_override_function(JSContext             *cx,
                          JS::HandleId           ns_name,
diff --git a/gi/repo.h b/gi/repo.h
index b1a89a6f..fbf7357c 100644
--- a/gi/repo.h
+++ b/gi/repo.h
@@ -29,32 +29,42 @@
 
 #include <girepository.h>
 
-#include "gjs/jsapi-wrapper.h"
 #include <util/log.h>
+#include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_repo(JSContext              *cx,
                      JS::MutableHandleObject repo);
 
+GJS_USE
 const char* gjs_info_type_name                  (GIInfoType      type);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*   gjs_lookup_private_namespace        (JSContext      *context);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*   gjs_lookup_namespace_object         (JSContext      *context,
                                                  GIBaseInfo     *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_lookup_namespace_object_by_name(JSContext   *context,
                                               JS::HandleId name);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *  gjs_lookup_generic_constructor      (JSContext      *context,
                                                  GIBaseInfo     *info);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *  gjs_lookup_generic_prototype        (JSContext      *context,
                                                  GIBaseInfo     *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_info(JSContext       *context,
                      JS::HandleObject in_object,
                      GIBaseInfo      *info,
                      bool            *defined);
 
+GJS_USE
 char*       gjs_hyphen_from_camel               (const char     *camel_name);
 
 
diff --git a/gi/toggle.h b/gi/toggle.h
index f03b6ea4..e4dd8f19 100644
--- a/gi/toggle.h
+++ b/gi/toggle.h
@@ -31,6 +31,7 @@
 #include <mutex>
 #include <glib-object.h>
 
+#include "gjs/macros.h"
 #include "util/log.h"
 
 /* Thread-safe queue for enqueueing toggle-up or toggle-down events on GObjects
@@ -64,16 +65,19 @@ private:
         gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "ToggleQueue %s %p", did, what);
     }
 
+    GJS_USE
     std::deque<Item>::iterator find_operation_locked(GObject  *gobj,
                                                      Direction direction);
+    GJS_USE
     bool find_and_erase_operation_locked(GObject *gobj, Direction direction);
 
     static gboolean idle_handle_toggle(void *data);
     static void idle_destroy_notify(void *data);
 
-public:
+ public:
     /* These two functions return a pair DOWN, UP signifying whether toggles
      * are / were queued. is_queued() just checks and does not modify. */
+    GJS_USE
     std::pair<bool, bool> is_queued(GObject *gobj);
     /* Cancels pending toggles and returns whether any were queued. */
     std::pair<bool, bool> cancel(GObject *gobj);
@@ -93,6 +97,7 @@ public:
                  Direction direction,
                  Handler   handler);
 
+    GJS_USE
     static ToggleQueue&
     get_default(void) {
         static ToggleQueue the_singleton;
diff --git a/gi/union.cpp b/gi/union.cpp
index d120ce2a..9d148bdf 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -54,6 +54,7 @@ GJS_DEFINE_PRIV_FROM_JS(Union, gjs_union_class)
  * The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 union_resolve(JSContext       *context,
               JS::HandleObject obj,
@@ -117,6 +118,7 @@ union_resolve(JSContext       *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static void*
 union_new(JSContext       *context,
           JS::HandleObject obj, /* "this" for constructor */
@@ -261,6 +263,7 @@ union_finalize(JSFreeOp *fop,
     g_slice_free(Union, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 to_string_func(JSContext *context,
                unsigned   argc,
diff --git a/gi/union.h b/gi/union.h
index 3960f2df..cf338e7f 100644
--- a/gi/union.h
+++ b/gi/union.h
@@ -27,20 +27,26 @@
 #include <stdbool.h>
 #include <glib.h>
 #include <girepository.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_union_class(JSContext       *context,
                             JS::HandleObject in_object,
                             GIUnionInfo     *info);
 
+GJS_JSAPI_RETURN_CONVENTION
 void     *gjs_c_union_from_union(JSContext       *context,
                                  JS::HandleObject obj);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_union_from_c_union       (JSContext    *context,
                                         GIUnionInfo  *info,
                                         void         *gboxed);
+GJS_JSAPI_RETURN_CONVENTION
 bool      gjs_typecheck_union          (JSContext             *context,
                                         JS::HandleObject       obj,
                                         GIStructInfo          *expected_info,
diff --git a/gi/value.cpp b/gi/value.cpp
index 4db748e3..3467132b 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -43,6 +43,7 @@
 
 #include <girepository.h>
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool gjs_value_from_g_value_internal(JSContext             *context,
                                             JS::MutableHandleValue value_p,
                                             const GValue          *gvalue,
@@ -55,6 +56,7 @@ static bool gjs_value_from_g_value_internal(JSContext             *context,
  * only works for signals on introspected GObjects, not signals on GJS-defined
  * GObjects nor standalone closures. The return value must be unreffed.
  */
+GJS_USE
 static GISignalInfo *
 get_signal_info_if_available(GSignalQuery *signal_query)
 {
@@ -85,6 +87,7 @@ get_signal_info_if_available(GSignalQuery *signal_query)
  * Fill in value_p with a JS array, converted from a C array stored as a pointer
  * in array_value, with its length stored in array_length_value.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_value_from_array_and_length_values(JSContext             *context,
                                        JS::MutableHandleValue value_p,
@@ -318,6 +321,7 @@ gjs_closure_new_marshaled (JSContext    *context,
     return closure;
 }
 
+GJS_USE
 static GType
 gjs_value_guess_g_type(JSContext *context,
                        JS::Value  value)
@@ -358,6 +362,7 @@ throw_expect_type(JSContext      *cx,
     return false;  /* for convenience */
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_value_to_g_value_internal(JSContext      *context,
                               JS::HandleValue value,
@@ -710,6 +715,7 @@ gjs_value_to_g_value_no_copy(JSContext      *context,
     return gjs_value_to_g_value_internal(context, value, gvalue, true);
 }
 
+GJS_USE
 static JS::Value
 convert_int_to_enum (GType  gtype,
                      int    v)
@@ -730,6 +736,7 @@ convert_int_to_enum (GType  gtype,
     return JS::NumberValue(v_double);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_value_from_g_value_internal(JSContext             *context,
                                 JS::MutableHandleValue value_p,
diff --git a/gi/value.h b/gi/value.h
index 1ad411df..af61b8d8 100644
--- a/gi/value.h
+++ b/gi/value.h
@@ -26,24 +26,31 @@
 
 #include <stdbool.h>
 #include <glib-object.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool       gjs_value_to_g_value         (JSContext      *context,
                                          JS::HandleValue value,
                                          GValue         *gvalue);
+GJS_JSAPI_RETURN_CONVENTION
 bool       gjs_value_to_g_value_no_copy (JSContext      *context,
                                          JS::HandleValue value,
                                          GValue         *gvalue);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_value_from_g_value(JSContext             *context,
                             JS::MutableHandleValue value_p,
                             const GValue          *gvalue);
 
+GJS_USE
 GClosure*  gjs_closure_new_marshaled    (JSContext    *context,
                                          JSObject     *callable,
                                          const char   *description);
+GJS_USE
 GClosure*  gjs_closure_new_for_signal   (JSContext    *context,
                                          JSObject     *callable,
                                          const char   *description,
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index 71d3ba3a..2d2466d4 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -46,6 +46,7 @@ static void bytes_unref_arraybuffer(void* contents, void* user_data) {
 }
 
 /* implement toString() with an optional encoding arg */
+GJS_JSAPI_RETURN_CONVENTION
 static bool to_string_impl(JSContext* context, JS::HandleObject byte_array,
                            const char* encoding, JS::MutableHandleValue rval) {
     bool encoding_is_utf8;
@@ -113,6 +114,7 @@ static bool to_string_impl(JSContext* context, JS::HandleObject byte_array,
     }
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool to_string_func(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     JS::UniqueChars encoding;
@@ -128,6 +130,7 @@ static bool to_string_func(JSContext* cx, unsigned argc, JS::Value* vp) {
 /* Workaround to keep existing code compatible. This function is tacked onto
  * any Uint8Array instances created in situations where previously a ByteArray
  * would have been created. It logs a compatibility warning. */
+GJS_JSAPI_RETURN_CONVENTION
 static bool instance_to_string_func(JSContext* cx, unsigned argc,
                                     JS::Value* vp) {
     GJS_GET_THIS(cx, argc, vp, args, this_obj);
@@ -142,6 +145,7 @@ static bool instance_to_string_func(JSContext* cx, unsigned argc,
     return to_string_impl(cx, this_obj, encoding.get(), args.rval());
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 to_gbytes_func(JSContext *context,
                unsigned   argc,
@@ -167,6 +171,7 @@ to_gbytes_func(JSContext *context,
 }
 
 /* fromString() function implementation */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 from_string_func(JSContext *context,
                  unsigned   argc,
@@ -253,6 +258,7 @@ from_string_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 from_gbytes_func(JSContext *context,
                  unsigned   argc,
diff --git a/gjs/byteArray.h b/gjs/byteArray.h
index 2b0626b0..59456ea8 100644
--- a/gjs/byteArray.h
+++ b/gjs/byteArray.h
@@ -26,20 +26,27 @@
 
 #include <stdbool.h>
 #include <glib.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_byte_array_stuff(JSContext              *context,
                                  JS::MutableHandleObject module);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_byte_array_from_data(JSContext* cx, size_t nbytes, void* data);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *    gjs_byte_array_from_byte_array (JSContext  *context,
                                               GByteArray *array);
 
+GJS_USE
 GByteArray* gjs_byte_array_get_byte_array(JS::HandleObject obj);
 
+GJS_USE
 GBytes* gjs_byte_array_get_bytes(JS::HandleObject obj);
 
 G_END_DECLS
diff --git a/gjs/console.cpp b/gjs/console.cpp
index c2c9d524..a110bf31 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -61,6 +61,7 @@ static GOptionEntry entries[] = {
 };
 // clang-format on
 
+GJS_USE
 static char **
 strndupv(int           n,
          char * const *strv)
@@ -75,6 +76,7 @@ strndupv(int           n,
     return retval;
 }
 
+GJS_USE
 static char **
 strcatv(char **strv1,
         char **strv2)
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 49c0cf9e..a5e7be34 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -32,6 +32,7 @@
 
 G_BEGIN_DECLS
 
+GJS_USE
 bool         _gjs_context_destroying                  (GjsContext *js_context);
 
 void         _gjs_context_schedule_gc_if_needed       (GjsContext *js_context);
@@ -41,19 +42,24 @@ void _gjs_context_schedule_gc(GjsContext *js_context);
 void _gjs_context_exit(GjsContext *js_context,
                        uint8_t     exit_code);
 
+GJS_USE
 bool _gjs_context_get_is_owner_thread(GjsContext *js_context);
 
+GJS_USE
 bool _gjs_context_should_exit(GjsContext *js_context,
                               uint8_t    *exit_code_p);
 
 void _gjs_context_set_sweeping(GjsContext *js_context,
                                bool        sweeping);
 
+GJS_USE
 bool _gjs_context_is_sweeping(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool _gjs_context_enqueue_job(GjsContext      *gjs_context,
                               JS::HandleObject job);
 
+GJS_USE
 bool _gjs_context_run_jobs(GjsContext *gjs_context);
 
 void _gjs_context_unregister_unhandled_promise_rejection(GjsContext *gjs_context,
diff --git a/gjs/context.h b/gjs/context.h
index eecc0da8..2b54b6bf 100644
--- a/gjs/context.h
+++ b/gjs/context.h
@@ -46,37 +46,26 @@ typedef struct _GjsContextClass GjsContextClass;
 #define GJS_IS_CONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GJS_TYPE_CONTEXT))
 #define GJS_CONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GJS_TYPE_CONTEXT, GjsContextClass))
 
-GJS_EXPORT
-GType           gjs_context_get_type             (void) G_GNUC_CONST;
-
-GJS_EXPORT
-GjsContext*     gjs_context_new                  (void);
-GJS_EXPORT
-GjsContext*     gjs_context_new_with_search_path (char         **search_path);
-GJS_EXPORT
-bool            gjs_context_eval_file            (GjsContext  *js_context,
-                                                  const char    *filename,
-                                                  int           *exit_status_p,
-                                                  GError       **error);
-GJS_EXPORT
-bool            gjs_context_eval                 (GjsContext  *js_context,
-                                                  const char    *script,
-                                                  gssize         script_len,
-                                                  const char    *filename,
-                                                  int           *exit_status_p,
-                                                  GError       **error);
-GJS_EXPORT
-bool            gjs_context_define_string_array  (GjsContext  *js_context,
-                                                  const char    *array_name,
-                                                  gssize         array_length,
-                                                  const char   **array_values,
-                                                  GError       **error);
-
-GJS_EXPORT
-GList*          gjs_context_get_all              (void);
-
-GJS_EXPORT
-GjsContext     *gjs_context_get_current          (void);
+GJS_EXPORT GJS_USE GType gjs_context_get_type(void) G_GNUC_CONST;
+
+GJS_EXPORT GJS_USE GjsContext* gjs_context_new(void);
+GJS_EXPORT GJS_USE GjsContext* gjs_context_new_with_search_path(
+    char** search_path);
+GJS_EXPORT GJS_USE bool gjs_context_eval_file(GjsContext* js_context,
+                                              const char* filename,
+                                              int* exit_status_p,
+                                              GError** error);
+GJS_EXPORT GJS_USE bool gjs_context_eval(GjsContext* js_context,
+                                         const char* script, gssize script_len,
+                                         const char* filename,
+                                         int* exit_status_p, GError** error);
+GJS_EXPORT GJS_USE bool gjs_context_define_string_array(
+    GjsContext* js_context, const char* array_name, gssize array_length,
+    const char** array_values, GError** error);
+
+GJS_EXPORT GJS_USE GList* gjs_context_get_all(void);
+
+GJS_EXPORT GJS_USE GjsContext* gjs_context_get_current(void);
 GJS_EXPORT
 void            gjs_context_make_current         (GjsContext *js_context);
 
@@ -92,18 +81,15 @@ void            gjs_context_maybe_gc              (GjsContext  *context);
 GJS_EXPORT
 void            gjs_context_gc                    (GjsContext  *context);
 
-GJS_EXPORT
-GjsProfiler *gjs_context_get_profiler(GjsContext *self);
+GJS_EXPORT GJS_USE GjsProfiler* gjs_context_get_profiler(GjsContext* self);
 
-GJS_EXPORT
-bool gjs_profiler_chain_signal(GjsContext *context,
-                               siginfo_t  *info);
+GJS_EXPORT GJS_USE bool gjs_profiler_chain_signal(GjsContext* context,
+                                                  siginfo_t* info);
 
 GJS_EXPORT
 void            gjs_dumpstack                     (void);
 
-GJS_EXPORT
-const char *gjs_get_js_version(void);
+GJS_EXPORT GJS_USE const char* gjs_get_js_version(void);
 
 GJS_EXPORT
 void gjs_context_setup_debugger_console(GjsContext* gjs);
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index 68cf0d3d..b636b864 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -68,6 +68,7 @@ enum {
 
 static GParamSpec *properties[PROP_N] = { NULL, };
 
+GJS_USE
 static char *
 get_file_identifier(GFile *source_file) {
     char *path = g_file_get_path(source_file);
@@ -76,6 +77,7 @@ get_file_identifier(GFile *source_file) {
     return path;
 }
 
+GJS_USE
 static bool
 write_source_file_header(GOutputStream *stream,
                          GFile         *source_file,
@@ -85,6 +87,7 @@ write_source_file_header(GOutputStream *stream,
     return g_output_stream_printf(stream, NULL, NULL, error, "SF:%s\n", path.get());
 }
 
+GJS_USE
 static bool
 copy_source_file_to_coverage_output(GFile   *source_file,
                                     GFile   *destination_file,
@@ -107,6 +110,7 @@ copy_source_file_to_coverage_output(GFile   *source_file,
  * the string with the URI scheme stripped or NULL
  * if the path was not a valid URI
  */
+GJS_USE
 static char *
 strip_uri_scheme(const char *potential_uri)
 {
@@ -142,6 +146,7 @@ strip_uri_scheme(const char *potential_uri)
  * automatically return the full URI path with
  * the URI scheme and leading slash stripped out.
  */
+GJS_USE
 static char *
 find_diverging_child_components(GFile *child,
                                 GFile *parent)
@@ -174,6 +179,7 @@ find_diverging_child_components(GFile *child,
     return stripped_uri;
 }
 
+GJS_USE
 static bool
 filename_has_coverage_prefixes(GjsCoverage *self, const char *filename)
 {
@@ -194,6 +200,7 @@ write_line(GOutputStream *out,
     return g_output_stream_printf(out, nullptr, nullptr, error, "%s\n", line);
 }
 
+GJS_USE
 static GjsAutoUnref<GFile>
 write_statistics_internal(GjsCoverage *coverage,
                           JSContext   *cx,
@@ -323,6 +330,7 @@ coverage_tracer(JSTracer *trc, void *data)
     JS::TraceEdge<JSObject *>(trc, &priv->compartment, "Coverage compartment");
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 bootstrap_coverage(GjsCoverage *coverage)
 {
diff --git a/gjs/coverage.h b/gjs/coverage.h
index 5f62f609..0820d9f1 100644
--- a/gjs/coverage.h
+++ b/gjs/coverage.h
@@ -30,6 +30,7 @@
 #include <gio/gio.h>
 
 #include "context.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
@@ -40,10 +41,9 @@ G_DECLARE_FINAL_TYPE(GjsCoverage, gjs_coverage, GJS, COVERAGE, GObject);
 GJS_EXPORT
 void gjs_coverage_write_statistics(GjsCoverage *self);
 
-GJS_EXPORT
-GjsCoverage * gjs_coverage_new(const char * const *coverage_prefixes,
-                               GjsContext         *coverage_context,
-                               GFile              *output_dir);
+GJS_EXPORT GJS_USE GjsCoverage* gjs_coverage_new(
+    const char* const* coverage_prefixes, GjsContext* coverage_context,
+    GFile* output_dir);
 
 G_END_DECLS
 
diff --git a/gjs/debugger.cpp b/gjs/debugger.cpp
index 5203e911..86f3ad5f 100644
--- a/gjs/debugger.cpp
+++ b/gjs/debugger.cpp
@@ -36,6 +36,7 @@
 #include <stdio.h>
 #endif
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool quit(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     JSAutoRequest ar(cx);
@@ -48,6 +49,7 @@ static bool quit(JSContext* cx, unsigned argc, JS::Value* vp) {
     return false;  // without gjs_throw() == "throw uncatchable exception"
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool do_readline(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     JSAutoRequest ar(cx);
diff --git a/gjs/deprecation.cpp b/gjs/deprecation.cpp
index 82f275a0..5431c435 100644
--- a/gjs/deprecation.cpp
+++ b/gjs/deprecation.cpp
@@ -66,6 +66,7 @@ struct hash<DeprecationEntry> {
 
 static std::unordered_set<DeprecationEntry> logged_messages;
 
+GJS_JSAPI_RETURN_CONVENTION
 static char* get_callsite(JSContext* cx) {
     JS::RootedObject stack_frame(cx);
     if (!JS::CaptureCurrentStack(cx, &stack_frame,
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 1f8ef902..1b9b1de0 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -43,6 +43,7 @@
  * to UTF-8, using the appropriate GLib functions, and converting
  * back if necessary.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_locale_to_upper_case (JSContext *context,
                           JS::HandleString src,
@@ -56,6 +57,7 @@ gjs_locale_to_upper_case (JSContext *context,
     return gjs_string_from_utf8(context, upper_case_utf8, retval);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_locale_to_lower_case (JSContext *context,
                           JS::HandleString src,
@@ -69,6 +71,7 @@ gjs_locale_to_lower_case (JSContext *context,
     return gjs_string_from_utf8(context, lower_case_utf8, retval);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_locale_compare (JSContext *context,
                     JS::HandleString src_1,
@@ -88,6 +91,7 @@ gjs_locale_compare (JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_locale_to_unicode (JSContext  *context,
                        const char *src,
@@ -181,6 +185,7 @@ on_garbage_collect(JSContext *cx,
         gjs_object_clear_toggles();
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 on_enqueue_promise_job(JSContext       *cx,
                        JS::HandleObject callback,
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 7465fd5e..0099fcbc 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -30,6 +30,7 @@
 #include "jsapi-util.h"
 #include "jsapi-wrapper.h"
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 run_bootstrap(JSContext       *cx,
               const char      *bootstrap_script,
@@ -63,6 +64,7 @@ run_bootstrap(JSContext       *cx,
     return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_log(JSContext *cx,
         unsigned   argc,
@@ -98,6 +100,7 @@ gjs_log(JSContext *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_log_error(JSContext *cx,
               unsigned   argc,
@@ -128,6 +131,7 @@ gjs_log_error(JSContext *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_print_parse_args(JSContext    *cx,
                      JS::CallArgs& argv,
@@ -169,6 +173,7 @@ gjs_print_parse_args(JSContext    *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_print(JSContext *context,
           unsigned   argc,
@@ -186,6 +191,7 @@ gjs_print(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_printerr(JSContext *context,
              unsigned   argc,
@@ -230,8 +236,8 @@ class GjsGlobal {
         JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
         JS_FS_END};
 
-public:
-
+ public:
+    GJS_USE
     static JSObject *
     create(JSContext *cx)
     {
@@ -252,6 +258,7 @@ public:
         return global;
     }
 
+    GJS_JSAPI_RETURN_CONVENTION
     static bool
     define_properties(JSContext       *cx,
                       JS::HandleObject global,
diff --git a/gjs/global.h b/gjs/global.h
index 9cd3cbcd..49ea8098 100644
--- a/gjs/global.h
+++ b/gjs/global.h
@@ -26,6 +26,7 @@
 
 #include <glib.h>
 
+#include "gjs/macros.h"
 #include "jsapi-wrapper.h"
 
 G_BEGIN_DECLS
@@ -55,8 +56,10 @@ typedef enum {
     GJS_GLOBAL_SLOT_LAST,
 } GjsGlobalSlot;
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_create_global_object(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_global_properties(JSContext       *cx,
                                   JS::HandleObject global,
                                   const char      *bootstrap_script);
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 894ad135..73aa9b6f 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -60,9 +60,11 @@ extern const JSClass gjs_importer_class;
 
 GJS_DEFINE_PRIV_FROM_JS(Importer, gjs_importer_class)
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *gjs_define_importer(JSContext *, JS::HandleObject,
     const char *, const char * const *, bool);
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 importer_to_string(JSContext *cx,
                    unsigned   argc,
@@ -91,6 +93,7 @@ importer_to_string(JSContext *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 define_meta_properties(JSContext       *context,
                        JS::HandleObject module_obj,
@@ -175,6 +178,7 @@ define_meta_properties(JSContext       *context,
                                  to_string_tag, attrs);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 import_directory(JSContext          *context,
                  JS::HandleObject    obj,
@@ -198,6 +202,7 @@ import_directory(JSContext          *context,
 /* Make the property we set in gjs_module_import() permanent;
  * we do this after the import succesfully completes.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 seal_import(JSContext       *cx,
             JS::HandleObject obj,
@@ -283,6 +288,7 @@ gjs_import_native_module(JSContext       *cx,
            JS_DefineProperty(cx, importer, name, module, GJS_MODULE_PROP_FLAGS);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 import_module_init(JSContext       *context,
                    GFile           *file,
@@ -323,6 +329,8 @@ import_module_init(JSContext       *context,
     return ret;
 }
 
+/* FIXME: this function doesn't handle exceptions properly */
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 load_module_init(JSContext       *context,
                  JS::HandleObject in_object,
@@ -377,6 +385,7 @@ load_module_elements(JSContext        *cx,
 /* If error, returns false. If not found, returns true but does not touch
  * the value at *result. If found, returns true and sets *result = true.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 import_symbol_from_init_js(JSContext       *cx,
                            JS::HandleObject importer,
@@ -410,6 +419,7 @@ import_symbol_from_init_js(JSContext       *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 import_file_on_module(JSContext       *context,
                       JS::HandleObject obj,
@@ -442,6 +452,7 @@ import_file_on_module(JSContext       *context,
     return retval;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool do_import(JSContext* context, JS::HandleObject obj, Importer* priv,
                       JS::HandleId id) {
     JS::RootedObject search_path(context);
@@ -591,6 +602,7 @@ static bool do_import(JSContext* context, JS::HandleObject obj, Importer* priv,
 /* Note that in a for ... in loop, this will be called first on the object,
  * then on its prototype.
  */
+GJS_JSAPI_RETURN_CONVENTION
 static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
                                    JS::AutoIdVector& properties,
                                    bool enumerable_only) {
@@ -697,6 +709,7 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
 
 /* The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved. */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 importer_resolve(JSContext        *context,
                  JS::HandleObject  obj,
@@ -795,6 +808,7 @@ JSFunctionSpec gjs_importer_proto_funcs[] = {
 
 GJS_DEFINE_PROTO_FUNCS(importer)
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 importer_new(JSContext *context,
              bool       is_root)
@@ -825,6 +839,7 @@ importer_new(JSContext *context,
     return importer;
 }
 
+GJS_USE
 static G_CONST_RETURN char * G_CONST_RETURN *
 gjs_get_search_path(void)
 {
@@ -887,6 +902,7 @@ gjs_get_search_path(void)
     return (G_CONST_RETURN char * G_CONST_RETURN *)search_path;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 gjs_create_importer(JSContext          *context,
                     const char         *importer_name,
@@ -920,6 +936,7 @@ gjs_create_importer(JSContext          *context,
     return importer;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_define_importer(JSContext          *context,
                     JS::HandleObject    in_object,
diff --git a/gjs/importer.h b/gjs/importer.h
index cdc81ab5..55baffbb 100644
--- a/gjs/importer.h
+++ b/gjs/importer.h
@@ -26,13 +26,17 @@
 
 #include <stdbool.h>
 #include <glib.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_create_root_importer(JSContext          *cx,
                                    const char * const *search_path);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_import_native_module(JSContext       *cx,
                               JS::HandleObject importer,
                               const char      *name);
diff --git a/gjs/jsapi-class.h b/gjs/jsapi-class.h
index 32f8d315..b952fe1d 100644
--- a/gjs/jsapi-class.h
+++ b/gjs/jsapi-class.h
@@ -31,6 +31,7 @@
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_init_class_dynamic(JSContext              *cx,
                             JS::HandleObject        in_object,
                             JS::HandleObject        parent_proto,
@@ -46,15 +47,18 @@ bool gjs_init_class_dynamic(JSContext              *cx,
                             JS::MutableHandleObject prototype,
                             JS::MutableHandleObject constructor);
 
+GJS_USE
 bool gjs_typecheck_instance(JSContext       *cx,
                             JS::HandleObject obj,
                             const JSClass   *static_clasp,
                             bool             throw_error);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_construct_object_dynamic(JSContext                  *cx,
                                        JS::HandleObject            proto,
                                        const JS::HandleValueArray& args);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_property_dynamic(JSContext       *cx,
                                  JS::HandleObject proto,
                                  const char      *prop_name,
@@ -77,35 +81,23 @@ bool gjs_define_property_dynamic(JSContext       *cx,
  * priv_from_js_with_typecheck: a convenience function to call
  *                              do_base_typecheck and priv_from_js
  */
-#define GJS_DEFINE_PRIV_FROM_JS(type, klass)                            \
-    GJS_ALWAYS_INLINE G_GNUC_UNUSED                                     \
-    static inline bool                                                  \
-    do_base_typecheck(JSContext       *context,                         \
-                      JS::HandleObject object,                          \
-                      bool             throw_error)                     \
-    {                                                                   \
-        return gjs_typecheck_instance(context, object, &klass, throw_error);  \
-    }                                                                   \
-    GJS_ALWAYS_INLINE                                                   \
-    static inline type *                                                \
-    priv_from_js(JSContext       *context,                              \
-                 JS::HandleObject object)                               \
-    {                                                                   \
-        type *priv;                                                     \
-        JS_BeginRequest(context);                                       \
-        priv = (type*) JS_GetInstancePrivate(context, object, &klass, NULL);  \
-        JS_EndRequest(context);                                         \
-        return priv;                                                    \
-    }                                                                   \
-    G_GNUC_UNUSED static bool                                           \
-    priv_from_js_with_typecheck(JSContext       *context,               \
-                                JS::HandleObject object,                \
-                                type           **out)                   \
-    {                                                                   \
-        if (!do_base_typecheck(context, object, false))                 \
-            return false;                                               \
-        *out = priv_from_js(context, object);                           \
-        return true;                                                    \
+#define GJS_DEFINE_PRIV_FROM_JS(type, klass)                                   \
+    GJS_ALWAYS_INLINE GJS_USE G_GNUC_UNUSED static inline bool                 \
+    do_base_typecheck(JSContext* cx, JS::HandleObject obj, bool throw_error) { \
+        return gjs_typecheck_instance(cx, obj, &klass, throw_error);           \
+    }                                                                          \
+    GJS_ALWAYS_INLINE GJS_USE static inline type* priv_from_js(                \
+        JSContext* cx, JS::HandleObject obj) {                                 \
+        JSAutoRequest ar(cx);                                                  \
+        return static_cast<type*>(                                             \
+            JS_GetInstancePrivate(cx, obj, &klass, nullptr));                  \
+    }                                                                          \
+    G_GNUC_UNUSED GJS_USE static bool priv_from_js_with_typecheck(             \
+        JSContext* cx, JS::HandleObject obj, type** out) {                     \
+        if (!do_base_typecheck(cx, obj, false))                                \
+            return false;                                                      \
+        *out = priv_from_js(cx, obj);                                          \
+        return true;                                                           \
     }
 
 /*
@@ -212,91 +204,87 @@ _GJS_DEFINE_DEFINE_PROTO(cname, parent_cname,                    \
 #define GJS_DEFINE_PROTO_FUNCS(cname)  \
 GJS_DEFINE_PROTO_FUNCS_WITH_PARENT(cname, no_parent)
 
-#define _GJS_DEFINE_GET_PROTO(cname)                                         \
-JSObject *                                                                   \
-gjs_##cname##_get_proto(JSContext *cx)                                       \
-{                                                                            \
-    JS::RootedValue v_proto(cx,                                              \
-        gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname));         \
-    g_assert(((void) "gjs_" #cname "_define_proto() must be called before "  \
-              "gjs_" #cname "_get_proto()", !v_proto.isUndefined()));        \
-    g_assert(((void) "Someone stored some weird value in a global slot",     \
-              v_proto.isObject()));                                          \
-    return &v_proto.toObject();                                              \
-}
+#define _GJS_DEFINE_GET_PROTO(cname)                                           \
+    GJS_USE JSObject* gjs_##cname##_get_proto(JSContext* cx) {                 \
+        JS::RootedValue v_proto(                                               \
+            cx, gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname));   \
+        g_assert(((void)"gjs_" #cname "_define_proto() must be called before " \
+                        "gjs_" #cname "_get_proto()",                          \
+                  !v_proto.isUndefined()));                                    \
+        g_assert(((void)"Someone stored some weird value in a global slot",    \
+                  v_proto.isObject()));                                        \
+        return &v_proto.toObject();                                            \
+    }
 
-#define _GJS_DEFINE_DEFINE_PROTO(cname, parent_cname, ctor, gtype)           \
-bool                                                                         \
-gjs_##cname##_define_proto(JSContext              *cx,                       \
-                           JS::HandleObject        module,                   \
-                           JS::MutableHandleObject proto)                    \
-{                                                                            \
-    /* If we've been here more than once, we already have the proto */       \
-    JS::RootedValue v_proto(cx,                                              \
-        gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname));         \
-    if (!v_proto.isUndefined()) {                                            \
-        g_assert(((void) "Someone stored some weird value in a global slot", \
-                  v_proto.isObject()));                                      \
-        proto.set(&v_proto.toObject());                                      \
-        return true;                                                         \
-    }                                                                        \
-                                                                             \
-    /* If module is not given, we are defining a global class */             \
-    JS::RootedObject in_obj(cx, module);                                     \
-    if (!in_obj)                                                             \
-        in_obj = gjs_get_import_global(cx);                                  \
-                                                                             \
-    /* Create the class, prototype, and constructor */                       \
-    JS::RootedObject parent_proto(cx, gjs_##parent_cname##_get_proto(cx));   \
-    proto.set(JS_InitClass(cx, in_obj, parent_proto, &gjs_##cname##_class,   \
-                           ctor, 0, gjs_##cname##_proto_props,               \
-                           gjs_##cname##_proto_funcs, nullptr,               \
-                           gjs_##cname##_static_funcs));                     \
-    if (!proto)                                                              \
-        g_error("Can't init class %s", gjs_##cname##_class.name);            \
-    gjs_set_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname,               \
-                        JS::ObjectValue(*proto));                            \
-                                                                             \
-    /* Look up the constructor */                                            \
-    JS::RootedObject ctor_obj(cx);                                           \
-    JS::RootedId class_name(cx,                                              \
-        gjs_intern_string_to_id(cx, gjs_##cname##_class.name));              \
-    if (!gjs_object_require_property(cx, in_obj, #cname " constructor",      \
-                                     class_name, &ctor_obj))                 \
-        return false;                                                        \
-                                                                             \
-    /* JS_InitClass defines the constructor as a property on the given       \
-     * "global" object. If it's a module and not the real global object,     \
-     * redefine it with different flags so it's enumerable; cairo copies     \
-     * properties from cairoNative, for example */                           \
-    if (module) {                                                            \
-        if (!JS_DefinePropertyById(cx, module, class_name, ctor_obj,         \
-                                   GJS_MODULE_PROP_FLAGS))                   \
-            return false;                                                    \
-    }                                                                        \
-                                                                             \
-    /* Define the GType value as a "$gtype" property on the constructor */   \
-    if (gtype != G_TYPE_NONE) {                                              \
-        JS::RootedObject gtype_obj(cx,                                       \
-            gjs_gtype_create_gtype_wrapper(cx, gtype));                      \
-        if (!gtype_obj || !JS_DefineProperty(cx, ctor_obj, "$gtype",         \
-                                             gtype_obj,  JSPROP_PERMANENT))  \
-            return false;                                                    \
-    }                                                                        \
-    gjs_debug(GJS_DEBUG_CONTEXT, "Initialized class %s prototype %p",        \
-              gjs_##cname##_class.name, proto.get());                        \
-    return true;                                                             \
-}
+#define _GJS_DEFINE_DEFINE_PROTO(cname, parent_cname, ctor, gtype)             \
+    GJS_JSAPI_RETURN_CONVENTION                                                \
+    bool gjs_##cname##_define_proto(JSContext* cx, JS::HandleObject module,    \
+                                    JS::MutableHandleObject proto) {           \
+        /* If we've been here more than once, we already have the proto */     \
+        JS::RootedValue v_proto(                                               \
+            cx, gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname));   \
+        if (!v_proto.isUndefined()) {                                          \
+            g_assert(                                                          \
+                ((void)"Someone stored some weird value in a global slot",     \
+                 v_proto.isObject()));                                         \
+            proto.set(&v_proto.toObject());                                    \
+            return true;                                                       \
+        }                                                                      \
+                                                                               \
+        /* If module is not given, we are defining a global class */           \
+        JS::RootedObject in_obj(cx, module);                                   \
+        if (!in_obj)                                                           \
+            in_obj = gjs_get_import_global(cx);                                \
+                                                                               \
+        /* Create the class, prototype, and constructor */                     \
+        JS::RootedObject parent_proto(cx, gjs_##parent_cname##_get_proto(cx)); \
+        proto.set(JS_InitClass(cx, in_obj, parent_proto, &gjs_##cname##_class, \
+                               ctor, 0, gjs_##cname##_proto_props,             \
+                               gjs_##cname##_proto_funcs, nullptr,             \
+                               gjs_##cname##_static_funcs));                   \
+        if (!proto)                                                            \
+            g_error("Can't init class %s", gjs_##cname##_class.name);          \
+        gjs_set_global_slot(cx, GJS_GLOBAL_SLOT_PROTOTYPE_##cname,             \
+                            JS::ObjectValue(*proto));                          \
+                                                                               \
+        /* Look up the constructor */                                          \
+        JS::RootedObject ctor_obj(cx);                                         \
+        JS::RootedId class_name(                                               \
+            cx, gjs_intern_string_to_id(cx, gjs_##cname##_class.name));        \
+        if (!gjs_object_require_property(cx, in_obj, #cname " constructor",    \
+                                         class_name, &ctor_obj))               \
+            return false;                                                      \
+                                                                               \
+        /* JS_InitClass defines the constructor as a property on the given     \
+         * "global" object. If it's a module and not the real global object,   \
+         * redefine it with different flags so it's enumerable; cairo copies   \
+         * properties from cairoNative, for example */                         \
+        if (module) {                                                          \
+            if (!JS_DefinePropertyById(cx, module, class_name, ctor_obj,       \
+                                       GJS_MODULE_PROP_FLAGS))                 \
+                return false;                                                  \
+        }                                                                      \
+                                                                               \
+        /* Define the GType value as a "$gtype" property on the constructor */ \
+        if (gtype != G_TYPE_NONE) {                                            \
+            JS::RootedObject gtype_obj(                                        \
+                cx, gjs_gtype_create_gtype_wrapper(cx, gtype));                \
+            if (!gtype_obj || !JS_DefineProperty(cx, ctor_obj, "$gtype",       \
+                                                 gtype_obj, JSPROP_PERMANENT)) \
+                return false;                                                  \
+        }                                                                      \
+        gjs_debug(GJS_DEBUG_CONTEXT, "Initialized class %s prototype %p",      \
+                  gjs_##cname##_class.name, proto.get());                      \
+        return true;                                                           \
+    }
 
 /**
  * GJS_NATIVE_CONSTRUCTOR_DECLARE:
  * Prototype a constructor.
  */
-#define GJS_NATIVE_CONSTRUCTOR_DECLARE(name)            \
-static bool                                             \
-gjs_##name##_constructor(JSContext  *context,           \
-                         unsigned    argc,              \
-                         JS::Value  *vp)
+#define GJS_NATIVE_CONSTRUCTOR_DECLARE(name)                          \
+    GJS_JSAPI_RETURN_CONVENTION static bool gjs_##name##_constructor( \
+        JSContext* context, unsigned argc, JS::Value* vp)
 
 /**
  * GJS_NATIVE_CONSTRUCTOR_VARIABLES:
@@ -346,6 +334,7 @@ gjs_##name##_constructor(JSContext  *context,           \
 
 G_END_DECLS
 
+GJS_USE
 JS::Value gjs_dynamic_property_private_slot(JSObject *accessor_obj);
 
 #endif /* GJS_JSAPI_CLASS_H */
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 08e40960..8cbe31b7 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -152,6 +152,7 @@ gjs_init_class_dynamic(JSContext              *context,
     return res;
 }
 
+GJS_USE
 static const char*
 format_dynamic_class_name (const char *name)
 {
@@ -200,6 +201,7 @@ gjs_construct_object_dynamic(JSContext                  *context,
     return JS_New(context, constructor, args);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 define_native_accessor_wrapper(JSContext      *cx,
                                JSNative        call,
diff --git a/gjs/jsapi-util-args.h b/gjs/jsapi-util-args.h
index 377feed7..b7a982d4 100644
--- a/gjs/jsapi-util-args.h
+++ b/gjs/jsapi-util-args.h
@@ -30,11 +30,8 @@
 #include "jsapi-util.h"
 #include "jsapi-wrapper.h"
 
-GJS_ALWAYS_INLINE
-static inline bool
-check_nullable(const char*& fchar,
-               const char*& fmt_string)
-{
+GJS_ALWAYS_INLINE GJS_USE static inline bool check_nullable(
+    const char*& fchar, const char*& fmt_string) {
     if (*fchar != '?')
         return false;
 
@@ -225,18 +222,12 @@ free_if_necessary(JS::MutableHandleObject param_ref)
     param_ref.set(NULL);
 }
 
-template<typename T>
-static bool
-parse_call_args_helper(JSContext          *cx,
-                       const char         *function_name,
-                       const JS::CallArgs& args,
-                       bool                ignore_trailing_args,
-                       const char*&        fmt_required,
-                       const char*&        fmt_optional,
-                       unsigned            param_ix,
-                       const char         *param_name,
-                       T                   param_ref)
-{
+template <typename T>
+GJS_JSAPI_RETURN_CONVENTION static bool parse_call_args_helper(
+    JSContext* cx, const char* function_name, const JS::CallArgs& args,
+    bool ignore_trailing_args, const char*& fmt_required,
+    const char*& fmt_optional, unsigned param_ix, const char* param_name,
+    T param_ref) {
     bool nullable = false;
     const char *fchar = fmt_required;
 
@@ -272,19 +263,12 @@ parse_call_args_helper(JSContext          *cx,
     return true;
 }
 
-template<typename T, typename... Args>
-static bool
-parse_call_args_helper(JSContext          *cx,
-                       const char         *function_name,
-                       const JS::CallArgs& args,
-                       bool                ignore_trailing_args,
-                       const char*&        fmt_required,
-                       const char*&        fmt_optional,
-                       unsigned            param_ix,
-                       const char         *param_name,
-                       T                   param_ref,
-                       Args             ...params)
-{
+template <typename T, typename... Args>
+GJS_JSAPI_RETURN_CONVENTION static bool parse_call_args_helper(
+    JSContext* cx, const char* function_name, const JS::CallArgs& args,
+    bool ignore_trailing_args, const char*& fmt_required,
+    const char*& fmt_optional, unsigned param_ix, const char* param_name,
+    T param_ref, Args... params) {
     bool retval;
 
     if (!parse_call_args_helper(cx, function_name, args, ignore_trailing_args,
@@ -304,13 +288,9 @@ parse_call_args_helper(JSContext          *cx,
 }
 
 /* Empty-args version of the template */
-G_GNUC_UNUSED
-static bool
-gjs_parse_call_args(JSContext          *cx,
-                    const char         *function_name,
-                    const JS::CallArgs& args,
-                    const char         *format)
-{
+G_GNUC_UNUSED GJS_JSAPI_RETURN_CONVENTION static bool gjs_parse_call_args(
+    JSContext* cx, const char* function_name, const JS::CallArgs& args,
+    const char* format) {
     bool ignore_trailing_args = false;
 
     if (*format == '!') {
@@ -368,14 +348,10 @@ gjs_parse_call_args(JSContext          *cx,
  * may be null. For 's' or 'F' a null pointer is returned, for 'o' the handle is
  * set to null.
  */
-template<typename... Args>
-static bool
-gjs_parse_call_args(JSContext          *cx,
-                    const char         *function_name,
-                    const JS::CallArgs& args,
-                    const char         *format,
-                    Args             ...params)
-{
+template <typename... Args>
+GJS_JSAPI_RETURN_CONVENTION static bool gjs_parse_call_args(
+    JSContext* cx, const char* function_name, const JS::CallArgs& args,
+    const char* format, Args... params) {
     const char *fmt_iter, *fmt_required, *fmt_optional;
     unsigned n_required = 0, n_total = 0;
     bool optional_args = false, ignore_trailing_args = false, retval;
diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h
index f3f862c2..299562bd 100644
--- a/gjs/jsapi-util-root.h
+++ b/gjs/jsapi-util-root.h
@@ -66,15 +66,13 @@
  */
 template<typename T>
 struct GjsHeapOperation {
-    static bool update_after_gc(JS::Heap<T> *location);
+    GJS_USE static bool update_after_gc(JS::Heap<T>* location);
     static void expose_to_js(JS::Heap<T>& thing);
 };
 
 template<>
 struct GjsHeapOperation<JSObject *> {
-    static bool
-    update_after_gc(JS::Heap<JSObject *> *location)
-    {
+    GJS_USE static bool update_after_gc(JS::Heap<JSObject*>* location) {
         JS_UpdateWeakPointerAfterGC(location);
         return (location->unbarrieredGet() == nullptr);
     }
@@ -202,9 +200,7 @@ public:
      * GjsMaybeOwned wrapper in place of the GC thing itself due to the implicit
      * cast operator. But if you want to call methods on the GC thing, for
      * example if it's a JS::Value, you have to use get(). */
-    const T
-    get(void) const
-    {
+    GJS_USE const T get(void) const {
         return m_rooted ? m_thing.root->get() : m_thing.heap.get();
     }
     operator const T(void) const { return get(); }
@@ -235,9 +231,7 @@ public:
     /* You can get a Handle<T> if the thing is rooted, so that you can use this
      * wrapper with stack rooting. However, you must not do this if the
      * JSContext can be destroyed while the Handle is live. */
-    JS::Handle<T>
-    handle(void)
-    {
+    GJS_USE JS::Handle<T> handle(void) {
         g_assert(m_rooted);
         return *m_thing.root;
     }
@@ -351,15 +345,13 @@ public:
     /* If not tracing, then you must call this method during GC in order to
      * update the object's location if it was moved, or null it out if it was
      * finalized. If the object was finalized, returns true. */
-    bool
-    update_after_gc(void)
-    {
+    GJS_USE bool update_after_gc(void) {
         debug("update_after_gc()");
         g_assert(!m_rooted);
         return GjsHeapOperation<T>::update_after_gc(&m_thing.heap);
     }
 
-    bool rooted(void) const { return m_rooted; }
+    GJS_USE bool rooted(void) const { return m_rooted; }
 };
 
 #endif /* GJS_JSAPI_UTIL_ROOT_H */
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index 87e2023e..950f7bf3 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -151,13 +151,10 @@ gjs_string_from_filename(JSContext             *context,
 
 /* Converts a JSString's array of Latin-1 chars to an array of a wider integer
  * type, by what the compiler believes is the most efficient method possible */
-template<typename T>
-static bool
-from_latin1(JSContext *cx,
-            JSString  *str,
-            T        **data_p,
-            size_t    *len_p)
-{
+template <typename T>
+GJS_JSAPI_RETURN_CONVENTION static bool from_latin1(JSContext* cx,
+                                                    JSString* str, T** data_p,
+                                                    size_t* len_p) {
     /* No garbage collection should be triggered while we are using the string's
      * chars. Crash if that happens. */
     JS::AutoCheckCannotGC nogc;
@@ -376,6 +373,7 @@ gjs_intern_string_to_id(JSContext  *cx,
     return INTERNED_STRING_TO_JSID(cx, str);
 }
 
+GJS_USE
 static std::string
 gjs_debug_flat_string(JSFlatString *fstr)
 {
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 968a1f3d..7b6d872e 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -349,6 +349,7 @@ gjs_define_string_array(JSContext       *context,
  * are \x escaped.
  *
  */
+GJS_USE
 static char *
 gjs_string_readable(JSContext       *context,
                     JS::HandleString string)
@@ -384,6 +385,7 @@ gjs_string_readable(JSContext       *context,
     return g_string_free(buf, false);
 }
 
+GJS_USE
 static char *
 _gjs_g_utf8_make_valid (const char *name)
 {
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 319a2c69..ee9b73c5 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -30,8 +30,9 @@
 
 #include <glib-object.h>
 
-#include "jsapi-wrapper.h"
 #include "gi/gtype.h"
+#include "gjs/macros.h"
+#include "jsapi-wrapper.h"
 
 #ifdef __GNUC__
 #define GJS_ALWAYS_INLINE __attribute__((always_inline))
@@ -55,10 +56,11 @@ struct GjsAutoPointer : std::unique_ptr<T, decltype(free_func)> {
     operator T*() const { return this->get(); }
     T& operator[](size_t i) const { return static_cast<T*>(*this)[i]; }
 
+    GJS_USE
     T* copy() const { return reinterpret_cast<T*>(ref_func(this->get())); }
 
     template <typename C>
-    C* as() const {
+    GJS_USE C* as() const {
         return const_cast<C*>(reinterpret_cast<const C*>(this->get()));
     }
 };
@@ -92,9 +94,9 @@ struct GjsAutoBaseInfo : GjsAutoPointer<GIBaseInfo, GIBaseInfo,
     GjsAutoBaseInfo(GIBaseInfo* ptr = nullptr)  // NOLINT(runtime/explicit)
         : GjsAutoPointer(ptr) {}
 
-    const char* name() const { return g_base_info_get_name(*this); }
-    const char* ns() const { return g_base_info_get_namespace(*this); }
-    GIInfoType type() const { return g_base_info_get_type(*this); }
+    GJS_USE const char* name() const { return g_base_info_get_name(*this); }
+    GJS_USE const char* ns() const { return g_base_info_get_namespace(*this); }
+    GJS_USE GIInfoType type() const { return g_base_info_get_type(*this); }
 };
 
 // Use GjsAutoInfo, preferably its typedefs below, when you know for sure that
@@ -205,6 +207,7 @@ typedef struct GjsRootedArray GjsRootedArray;
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);          \
     JS::RootedObject to(cx, &args.computeThis(cx).toObject())
 
+GJS_USE
 JSObject*   gjs_get_import_global            (JSContext       *context);
 
 void gjs_throw_constructor_error             (JSContext       *context);
@@ -212,10 +215,12 @@ void gjs_throw_constructor_error             (JSContext       *context);
 void gjs_throw_abstract_constructor_error(JSContext    *context,
                                           JS::CallArgs& args);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*   gjs_build_string_array           (JSContext       *context,
                                               gssize           array_length,
                                               char           **array_values);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *gjs_define_string_array(JSContext       *context,
                                   JS::HandleObject obj,
                                   const char      *array_name,
@@ -241,9 +246,11 @@ bool gjs_log_exception_full(JSContext       *context,
                             JS::HandleValue  exc,
                             JS::HandleString message);
 
+GJS_USE
 char *gjs_value_debug_string(JSContext      *context,
                              JS::HandleValue value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_call_function_value(JSContext                  *context,
                              JS::HandleObject            obj,
                              JS::HandleValue             fval,
@@ -253,43 +260,54 @@ bool gjs_call_function_value(JSContext                  *context,
 void gjs_warning_reporter(JSContext     *cx,
                           JSErrorReport *report);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_to_utf8(JSContext* cx, const JS::Value string_val,
                         JS::UniqueChars* utf8_string_p);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_from_utf8(JSContext             *context,
                           const char            *utf8_string,
                           JS::MutableHandleValue value_p);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_from_utf8_n(JSContext             *cx,
                             const char            *utf8_chars,
                             size_t                 len,
                             JS::MutableHandleValue out);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_to_filename(JSContext       *cx,
                             const JS::Value  string_val,
                             GjsAutoChar     *filename_string);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_from_filename(JSContext             *context,
                               const char            *filename_string,
                               ssize_t                n_bytes,
                               JS::MutableHandleValue value_p);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_get_char16_data(JSContext       *cx,
                                 JS::HandleString str,
                                 char16_t       **data_p,
                                 size_t          *len_p);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_to_ucs4(JSContext       *cx,
                         JS::HandleString value,
                         gunichar       **ucs4_string_p,
                         size_t          *len_p);
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_string_from_ucs4(JSContext             *cx,
                           const gunichar        *ucs4_string,
                           ssize_t                n_chars,
                           JS::MutableHandleValue value_p);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_get_string_id(JSContext* cx, jsid id, JS::UniqueChars* name_p);
+GJS_USE
 jsid        gjs_intern_string_to_id          (JSContext       *context,
                                               const char      *string);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool        gjs_unichar_from_string          (JSContext       *context,
                                               JS::Value        string,
                                               gunichar        *result);
@@ -300,6 +318,7 @@ void gjs_maybe_gc (JSContext *context);
 void gjs_schedule_gc_if_needed(JSContext *cx);
 void gjs_gc_if_needed(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_eval_with_scope(JSContext             *context,
                          JS::HandleObject       object,
                          const char            *script,
@@ -339,6 +358,7 @@ typedef enum {
   GJS_STRING_LAST
 } GjsConstString;
 
+GJS_USE
 const char * gjs_strip_unix_shebang(const char *script,
                                     size_t     *script_len,
                                     int        *new_start_line_number);
@@ -363,6 +383,7 @@ bool gjs_object_has_property(JSContext       *cx,
 
 G_END_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 GjsAutoChar gjs_format_stack_trace(JSContext       *cx,
                                    JS::HandleObject saved_frame);
 
@@ -396,35 +417,41 @@ JS::HandleId gjs_context_get_const_string(JSContext     *cx,
 /* Overloaded functions, must be outside G_DECLS. More types are intended to be
  * added as the opportunity arises. */
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_property(JSContext             *context,
                                  JS::HandleObject       obj,
                                  const char            *obj_description,
                                  JS::HandleId           property_name,
                                  JS::MutableHandleValue value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_property(JSContext       *cx,
                                  JS::HandleObject obj,
                                  const char      *description,
                                  JS::HandleId     property_name,
                                  bool            *value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_property(JSContext       *cx,
                                  JS::HandleObject obj,
                                  const char      *description,
                                  JS::HandleId     property_name,
                                  int32_t         *value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_property(JSContext* cx, JS::HandleObject obj,
                                  const char* description,
                                  JS::HandleId property_name,
                                  JS::UniqueChars* value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_property(JSContext              *cx,
                                  JS::HandleObject        obj,
                                  const char             *description,
                                  JS::HandleId            property_name,
                                  JS::MutableHandleObject value);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_object_require_converted_property(JSContext       *context,
                                            JS::HandleObject obj,
                                            const char      *description,
@@ -433,36 +460,31 @@ bool gjs_object_require_converted_property(JSContext       *context,
 
 /* Here, too, we have wrappers that take a GjsConstString. */
 
-template<typename T>
-bool gjs_object_require_property(JSContext        *cx,
-                                 JS::HandleObject  obj,
-                                 const char       *description,
-                                 GjsConstString    property_name,
-                                 T                 value)
-{
+template <typename T>
+GJS_JSAPI_RETURN_CONVENTION bool gjs_object_require_property(
+    JSContext* cx, JS::HandleObject obj, const char* description,
+    GjsConstString property_name, T value) {
     return gjs_object_require_property(cx, obj, description,
                                        gjs_context_get_const_string(cx, property_name),
                                        value);
 }
 
-template<typename T>
-bool gjs_object_require_converted_property(JSContext       *cx,
-                                           JS::HandleObject obj,
-                                           const char      *description,
-                                           GjsConstString   property_name,
-                                           T                value)
-{
+template <typename T>
+GJS_JSAPI_RETURN_CONVENTION bool gjs_object_require_converted_property(
+    JSContext* cx, JS::HandleObject obj, const char* description,
+    GjsConstString property_name, T value) {
     return gjs_object_require_converted_property(cx, obj, description,
                                                  gjs_context_get_const_string(cx, property_name),
                                                  value);
 }
 
-std::string gjs_debug_string(JSString *str);
-std::string gjs_debug_symbol(JS::Symbol * const sym);
-std::string gjs_debug_object(JSObject *obj);
-std::string gjs_debug_value(JS::Value v);
-std::string gjs_debug_id(jsid id);
+GJS_USE std::string gjs_debug_string(JSString* str);
+GJS_USE std::string gjs_debug_symbol(JS::Symbol* const sym);
+GJS_USE std::string gjs_debug_object(JSObject* obj);
+GJS_USE std::string gjs_debug_value(JS::Value v);
+GJS_USE std::string gjs_debug_id(jsid id);
 
+GJS_USE
 char* gjs_hyphen_to_underscore(const char* str);
 
 #endif  /* __GJS_JSAPI_UTIL_H__ */
diff --git a/gjs/macros.h b/gjs/macros.h
index 05457da6..dae6c430 100644
--- a/gjs/macros.h
+++ b/gjs/macros.h
@@ -36,4 +36,31 @@
 # define GJS_EXPORT
 #endif
 
+/**
+ * GJS_USE:
+ *
+ * Indicates a return value must be used, or the compiler should log a warning.
+ * If it is really okay to ignore the return value, use mozilla::Unused to
+ * bypass this warning.
+ */
+#if defined(__GNUC__) || defined(__clang__)
+#    define GJS_USE __attribute__((warn_unused_result))
+#else
+#    define GJS_USE
+#endif
+
+/**
+ * GJS_JSAPI_RETURN_CONVENTION:
+ *
+ * Same as %GJS_USE, but indicates that a return value of true or non-null means
+ * that no exception must be pending on the passed-in #JSContext. Conversely, a
+ * return value of false or nullptr means that an exception must be pending, or
+ * else an uncatchable exception has been thrown.
+ *
+ * Same as %GJS_USE for now, but in the future this should be able to be used by
+ * static analysis tools to do better consistency checks. It's also intended as
+ * documentation for the programmer.
+ */
+#define GJS_JSAPI_RETURN_CONVENTION GJS_USE
+
 #endif /* GJS_MACROS_H */
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 417091a0..a5330ee7 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -46,6 +46,7 @@ class GjsModule {
 
     /* Private data accessors */
 
+    GJS_USE
     static inline GjsModule *
     priv(JSObject *module)
     {
@@ -53,6 +54,7 @@ class GjsModule {
     }
 
     /* Creates a JS module object. Use instead of the class's constructor */
+    GJS_USE
     static JSObject *
     create(JSContext  *cx,
            const char *name)
@@ -63,6 +65,7 @@ class GjsModule {
     }
 
     /* Defines the empty module as a property on the importer */
+    GJS_JSAPI_RETURN_CONVENTION
     bool
     define_import(JSContext       *cx,
                   JS::HandleObject module,
@@ -80,6 +83,7 @@ class GjsModule {
     }
 
     /* Carries out the actual execution of the module code */
+    GJS_JSAPI_RETURN_CONVENTION
     bool
     evaluate_import(JSContext       *cx,
                     JS::HandleObject module,
@@ -113,6 +117,7 @@ class GjsModule {
     }
 
     /* Loads JS code from a file and imports it */
+    GJS_JSAPI_RETURN_CONVENTION
     bool
     import_file(JSContext       *cx,
                 JS::HandleObject module,
@@ -140,6 +145,7 @@ class GjsModule {
 
     /* JSClass operations */
 
+    GJS_JSAPI_RETURN_CONVENTION
     bool
     resolve_impl(JSContext       *cx,
                  JS::HandleObject module,
@@ -175,6 +181,7 @@ class GjsModule {
             JS_DefinePropertyById(cx, module, id, desc);
     }
 
+    GJS_JSAPI_RETURN_CONVENTION
     static bool
     resolve(JSContext       *cx,
             JS::HandleObject module,
@@ -207,9 +214,9 @@ class GjsModule {
         &GjsModule::class_ops,
     };
 
-public:
-
+ public:
     /* Carries out the import operation */
+    GJS_JSAPI_RETURN_CONVENTION
     static JSObject *
     import(JSContext       *cx,
            JS::HandleObject importer,
diff --git a/gjs/module.h b/gjs/module.h
index 90413917..89e2a331 100644
--- a/gjs/module.h
+++ b/gjs/module.h
@@ -26,10 +26,12 @@
 
 #include <gio/gio.h>
 
+#include "gjs/macros.h"
 #include "jsapi-wrapper.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *
 gjs_module_import(JSContext       *cx,
                   JS::HandleObject importer,
diff --git a/gjs/native.h b/gjs/native.h
index b71364e3..9856671a 100644
--- a/gjs/native.h
+++ b/gjs/native.h
@@ -26,7 +26,9 @@
 
 #include <stdbool.h>
 #include <glib.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
@@ -38,11 +40,13 @@ void   gjs_register_native_module (const char            *module_id,
                                    GjsDefineModuleFunc  func);
 
 /* called by importer.c to to check for already loaded modules */
+GJS_USE
 bool     gjs_is_registered_native_module(JSContext  *context,
                                          JSObject   *parent,
                                          const char *name);
 
 /* called by importer.cpp to load a statically linked native module */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_load_native_module(JSContext              *cx,
                             const char             *name,
                             JS::MutableHandleObject module_out);
diff --git a/gjs/profiler-private.h b/gjs/profiler-private.h
index 98bb7224..20cb9f46 100644
--- a/gjs/profiler-private.h
+++ b/gjs/profiler-private.h
@@ -25,6 +25,7 @@
 #define GJS_PROFILER_PRIVATE_H
 
 #include "context.h"
+#include "gjs/macros.h"
 #include "profiler.h"
 
 G_BEGIN_DECLS
@@ -32,6 +33,7 @@ G_BEGIN_DECLS
 GjsProfiler *_gjs_profiler_new(GjsContext *context);
 void _gjs_profiler_free(GjsProfiler *self);
 
+GJS_USE
 bool _gjs_profiler_is_running(GjsProfiler *self);
 
 void _gjs_profiler_setup_signals(GjsProfiler *self, GjsContext *context);
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index a23c85b7..cc53f5f3 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -123,6 +123,7 @@ static GjsContext *profiling_context;
  * Returns: %TRUE if successful; otherwise %FALSE and the profile
  *   should abort.
  */
+GJS_USE
 static bool
 gjs_profiler_extract_maps(GjsProfiler *self)
 {
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 418126fb..7a3168b9 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -28,19 +28,18 @@
 #include "gjs/jsapi-class.h"
 #include "gjs/jsapi-util-args.h"
 #include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
 
 #include <cairo.h>
 #include <cairo-gobject.h>
 #include "cairo-private.h"
 
-#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(mname) \
-static bool                                         \
-mname##_func(JSContext *context,                    \
-              unsigned   argc,                      \
-              JS::Value *vp)                        \
-{                                                   \
-    GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); \
-    cairo_t *cr = priv ? priv->cr : NULL;
+#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(mname)                        \
+    GJS_JSAPI_RETURN_CONVENTION                                            \
+    static bool mname##_func(JSContext* context, unsigned argc,            \
+                             JS::Value* vp) {                              \
+        GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); \
+        cairo_t* cr = priv ? priv->cr : nullptr;
 
 #define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END                               \
     return gjs_cairo_check_status(context, cairo_status(cr), "context"); \
@@ -238,6 +237,7 @@ typedef struct {
     cairo_t * cr;
 } GjsCairoContext;
 
+GJS_USE
 static JSObject *gjs_cairo_context_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_GTYPE("Context", cairo_context,
@@ -393,7 +393,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC2(translate, cairo_translate, "ff", double, tx, do
 _GJS_CAIRO_CONTEXT_DEFINE_FUNC2FFAFF(userToDevice, cairo_user_to_device, "x", "y")
 _GJS_CAIRO_CONTEXT_DEFINE_FUNC2FFAFF(userToDeviceDistance, cairo_user_to_device_distance, "x", "y")
 
-
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 dispose_func(JSContext *context,
              unsigned   argc,
@@ -409,6 +409,7 @@ dispose_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 appendPath_func(JSContext *context,
                 unsigned   argc,
@@ -434,6 +435,7 @@ appendPath_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 copyPath_func(JSContext *context,
               unsigned   argc,
@@ -451,6 +453,7 @@ copyPath_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 copyPathFlat_func(JSContext *context,
                   unsigned   argc,
@@ -468,6 +471,7 @@ copyPathFlat_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 mask_func(JSContext *context,
           unsigned   argc,
@@ -497,6 +501,7 @@ mask_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 maskSurface_func(JSContext *context,
                  unsigned   argc,
@@ -529,6 +534,7 @@ maskSurface_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 setDash_func(JSContext *context,
              unsigned   argc,
@@ -587,6 +593,7 @@ setDash_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 setSource_func(JSContext *context,
                unsigned   argc,
@@ -617,6 +624,7 @@ setSource_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 setSourceSurface_func(JSContext *context,
                       unsigned   argc,
@@ -650,6 +658,7 @@ setSourceSurface_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 showText_func(JSContext *context,
               unsigned   argc,
@@ -673,6 +682,7 @@ showText_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 selectFontFace_func(JSContext *context,
                     unsigned   argc,
@@ -699,6 +709,7 @@ selectFontFace_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 popGroup_func(JSContext *context,
               unsigned   argc,
@@ -729,6 +740,7 @@ popGroup_func(JSContext *context,
 
     return true;
 }
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getSource_func(JSContext *context,
                unsigned   argc,
@@ -760,6 +772,7 @@ getSource_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getTarget_func(JSContext *context,
                unsigned   argc,
@@ -791,6 +804,7 @@ getTarget_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getGroupTarget_func(JSContext *context,
                     unsigned   argc,
@@ -952,6 +966,7 @@ gjs_cairo_context_get_context(JSContext       *context,
     return priv->cr;
 }
 
+GJS_USE
 static bool
 context_to_g_argument(JSContext      *context,
                       JS::Value       value,
@@ -974,6 +989,7 @@ context_to_g_argument(JSContext      *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 context_from_g_argument(JSContext             *context,
                         JS::MutableHandleValue value_p,
diff --git a/modules/cairo-gradient.cpp b/modules/cairo-gradient.cpp
index d4c45ac6..924f14e9 100644
--- a/modules/cairo-gradient.cpp
+++ b/modules/cairo-gradient.cpp
@@ -46,6 +46,7 @@ JSPropertySpec gjs_cairo_gradient_proto_props[] = {
 
 /* Methods */
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 addColorStopRGB_func(JSContext *context,
                      unsigned   argc,
@@ -73,6 +74,7 @@ addColorStopRGB_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 addColorStopRGBA_func(JSContext *context,
                       unsigned   argc,
diff --git a/modules/cairo-image-surface.cpp b/modules/cairo-image-surface.cpp
index ee88bbd9..a0c89278 100644
--- a/modules/cairo-image-surface.cpp
+++ b/modules/cairo-image-surface.cpp
@@ -29,6 +29,7 @@
 #include <cairo.h>
 #include "cairo-private.h"
 
+GJS_USE
 static JSObject *gjs_cairo_image_surface_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("ImageSurface", cairo_image_surface,
@@ -73,6 +74,7 @@ JSPropertySpec gjs_cairo_image_surface_proto_props[] = {
     JS_PS_END
 };
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 createFromPNG_func(JSContext *context,
                    unsigned   argc,
@@ -106,6 +108,7 @@ createFromPNG_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getFormat_func(JSContext *context,
                unsigned   argc,
@@ -130,6 +133,7 @@ getFormat_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getWidth_func(JSContext *context,
               unsigned   argc,
@@ -154,6 +158,7 @@ getWidth_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getHeight_func(JSContext *context,
                unsigned   argc,
@@ -178,6 +183,7 @@ getHeight_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getStride_func(JSContext *context,
                unsigned   argc,
diff --git a/modules/cairo-linear-gradient.cpp b/modules/cairo-linear-gradient.cpp
index 8d7d44ca..0fb89d19 100644
--- a/modules/cairo-linear-gradient.cpp
+++ b/modules/cairo-linear-gradient.cpp
@@ -28,6 +28,7 @@
 #include <cairo.h>
 #include "cairo-private.h"
 
+GJS_USE
 static JSObject *gjs_cairo_linear_gradient_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("LinearGradient", cairo_linear_gradient,
diff --git a/modules/cairo-module.h b/modules/cairo-module.h
index a839cce5..90a2265f 100644
--- a/modules/cairo-module.h
+++ b/modules/cairo-module.h
@@ -23,6 +23,10 @@
 #ifndef __CAIRO_MODULE_H__
 #define __CAIRO_MODULE_H__
 
+#include "gjs/jsapi-wrapper.h"
+#include "gjs/macros.h"
+
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_js_define_cairo_stuff(JSContext              *context,
                                JS::MutableHandleObject module);
 
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index a62cc437..4567cd4c 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -34,6 +34,7 @@ typedef struct {
     cairo_path_t    *path;
 } GjsCairoPath;
 
+GJS_USE
 static JSObject *gjs_cairo_path_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_ABSTRACT("Path", cairo_path, JSCLASS_BACKGROUND_FINALIZE)
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 39ebf8e5..84d1f1e6 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -60,6 +60,7 @@ JSPropertySpec gjs_cairo_pattern_proto_props[] = {
 
 /* Methods */
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getType_func(JSContext *context,
              unsigned   argc,
diff --git a/modules/cairo-pdf-surface.cpp b/modules/cairo-pdf-surface.cpp
index 1c97d735..46b60a03 100644
--- a/modules/cairo-pdf-surface.cpp
+++ b/modules/cairo-pdf-surface.cpp
@@ -31,6 +31,7 @@
 #if CAIRO_HAS_PDF_SURFACE
 #include <cairo-pdf.h>
 
+GJS_USE
 static JSObject *gjs_cairo_pdf_surface_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("PDFSurface", cairo_pdf_surface,
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index caef1406..552d1101 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -26,40 +26,50 @@
 #include "cairo-module.h"
 #include <cairo.h>
 
+GJS_JSAPI_RETURN_CONVENTION
 bool             gjs_cairo_check_status                 (JSContext       *context,
                                                          cairo_status_t   status,
                                                          const char      *name);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_region_define_proto(JSContext              *cx,
                                    JS::HandleObject        module,
                                    JS::MutableHandleObject proto);
 
 void             gjs_cairo_region_init                  (JSContext       *context);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_context_define_proto(JSContext              *cx,
                                     JS::HandleObject        module,
                                     JS::MutableHandleObject proto);
 
+GJS_USE
 cairo_t *        gjs_cairo_context_get_context          (JSContext       *context,
                                                          JS::HandleObject object);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_context_from_context         (JSContext       *context,
                                                          cairo_t         *cr);
 void             gjs_cairo_context_init                 (JSContext       *context);
 void             gjs_cairo_surface_init                 (JSContext       *context);
 
 /* path */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_path_define_proto(JSContext              *cx,
                                  JS::HandleObject        module,
                                  JS::MutableHandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_path_from_path               (JSContext       *context,
                                                          cairo_path_t    *path);
+GJS_USE
 cairo_path_t *   gjs_cairo_path_get_path                (JSContext       *context,
                                                          JSObject        *path_wrapper);
 
 /* surface */
+GJS_USE
 JSObject *gjs_cairo_surface_get_proto(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_surface_define_proto(JSContext              *cx,
                                     JS::HandleObject        module,
                                     JS::MutableHandleObject proto);
@@ -69,12 +79,15 @@ void             gjs_cairo_surface_construct            (JSContext       *contex
                                                          cairo_surface_t *surface);
 void             gjs_cairo_surface_finalize_surface     (JSFreeOp        *fop,
                                                          JSObject        *object);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_surface_from_surface         (JSContext       *context,
                                                          cairo_surface_t *surface);
+GJS_USE
 cairo_surface_t* gjs_cairo_surface_get_surface          (JSContext       *context,
                                                          JSObject        *object);
 
 /* image surface */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_image_surface_define_proto(JSContext              *cx,
                                           JS::HandleObject        module,
                                           JS::MutableHandleObject proto);
@@ -82,39 +95,48 @@ bool gjs_cairo_image_surface_define_proto(JSContext              *cx,
 void             gjs_cairo_image_surface_init           (JSContext       *context,
                                                          JS::HandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_image_surface_from_surface   (JSContext       *context,
                                                          cairo_surface_t *surface);
 
 /* postscript surface */
 #ifdef CAIRO_HAS_PS_SURFACE
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_ps_surface_define_proto(JSContext              *cx,
                                        JS::HandleObject        module,
                                        JS::MutableHandleObject proto);
 #endif
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_ps_surface_from_surface       (JSContext       *context,
                                                           cairo_surface_t *surface);
 
 /* pdf surface */
 #ifdef CAIRO_HAS_PDF_SURFACE
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_pdf_surface_define_proto(JSContext              *cx,
                                         JS::HandleObject        module,
                                         JS::MutableHandleObject proto);
 #endif
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_pdf_surface_from_surface     (JSContext       *context,
                                                          cairo_surface_t *surface);
 
 /* svg surface */
 #ifdef CAIRO_HAS_SVG_SURFACE
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_svg_surface_define_proto(JSContext              *cx,
                                         JS::HandleObject        module,
                                         JS::MutableHandleObject proto);
 #endif
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_svg_surface_from_surface     (JSContext       *context,
                                                          cairo_surface_t *surface);
 
 /* pattern */
+GJS_USE
 JSObject *gjs_cairo_pattern_get_proto(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_pattern_define_proto(JSContext              *cx,
                                     JS::HandleObject        module,
                                     JS::MutableHandleObject proto);
@@ -124,47 +146,59 @@ void             gjs_cairo_pattern_construct            (JSContext       *contex
                                                          cairo_pattern_t *pattern);
 void             gjs_cairo_pattern_finalize_pattern     (JSFreeOp        *fop,
                                                          JSObject        *object);
+GJS_JSAPI_RETURN_CONVENTION
 JSObject*        gjs_cairo_pattern_from_pattern         (JSContext       *context,
                                                          cairo_pattern_t *pattern);
+GJS_USE
 cairo_pattern_t* gjs_cairo_pattern_get_pattern          (JSContext       *context,
                                                          JSObject        *object);
 
 /* gradient */
+GJS_USE
 JSObject *gjs_cairo_gradient_get_proto(JSContext *cx);
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_gradient_define_proto(JSContext              *cx,
                                      JS::HandleObject        module,
                                      JS::MutableHandleObject proto);
 
 /* linear gradient */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_linear_gradient_define_proto(JSContext              *cx,
                                             JS::HandleObject        module,
                                             JS::MutableHandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_linear_gradient_from_pattern (JSContext       *context,
                                                          cairo_pattern_t *pattern);
 
 /* radial gradient */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_radial_gradient_define_proto(JSContext              *cx,
                                             JS::HandleObject        module,
                                             JS::MutableHandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_radial_gradient_from_pattern (JSContext       *context,
                                                          cairo_pattern_t *pattern);
 
 /* surface pattern */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_surface_pattern_define_proto(JSContext              *cx,
                                             JS::HandleObject        module,
                                             JS::MutableHandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_surface_pattern_from_pattern (JSContext       *context,
                                                          cairo_pattern_t *pattern);
 
 /* solid pattern */
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_cairo_solid_pattern_define_proto(JSContext              *cx,
                                           JS::HandleObject        module,
                                           JS::MutableHandleObject proto);
 
+GJS_JSAPI_RETURN_CONVENTION
 JSObject *       gjs_cairo_solid_pattern_from_pattern   (JSContext       *context,
                                                          cairo_pattern_t *pattern);
 
diff --git a/modules/cairo-ps-surface.cpp b/modules/cairo-ps-surface.cpp
index 833dc8d7..3401052f 100644
--- a/modules/cairo-ps-surface.cpp
+++ b/modules/cairo-ps-surface.cpp
@@ -31,6 +31,7 @@
 #if CAIRO_HAS_PS_SURFACE
 #include <cairo-ps.h>
 
+GJS_USE
 static JSObject *gjs_cairo_ps_surface_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("PSSurface", cairo_ps_surface, cairo_surface,
diff --git a/modules/cairo-radial-gradient.cpp b/modules/cairo-radial-gradient.cpp
index 356c4cf8..7aa2dcb3 100644
--- a/modules/cairo-radial-gradient.cpp
+++ b/modules/cairo-radial-gradient.cpp
@@ -28,6 +28,7 @@
 #include <cairo.h>
 #include "cairo-private.h"
 
+GJS_USE
 static JSObject *gjs_cairo_radial_gradient_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("RadialGradient", cairo_radial_gradient,
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index aaf65154..61c94a6d 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -37,6 +37,7 @@ typedef struct {
     cairo_region_t *region;
 } GjsCairoRegion;
 
+GJS_USE
 static JSObject *gjs_cairo_region_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_GTYPE("Region", cairo_region,
@@ -55,6 +56,7 @@ get_region(JSContext       *context,
         return priv->region;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 fill_rectangle(JSContext             *context,
                JS::HandleObject       obj,
@@ -67,45 +69,40 @@ fill_rectangle(JSContext             *context,
 #define RETURN_STATUS                                           \
     return gjs_cairo_check_status(context, cairo_region_status(this_region), "region");
 
-#define REGION_DEFINE_REGION_FUNC(method)                       \
-    static bool                                                 \
-    method##_func(JSContext *context,                           \
-                  unsigned argc,                                \
-                  JS::Value *vp)                                \
-    {                                                           \
-        PRELUDE;                                                \
-        JS::RootedObject other_obj(context);                    \
-        cairo_region_t *other_region;                           \
-        if (!gjs_parse_call_args(context, #method, argv, "o",   \
-                                 "other_region", &other_obj))   \
-            return false;                                       \
-                                                                \
-        other_region = get_region(context, other_obj);          \
-                                                                \
-        cairo_region_##method(this_region, other_region);       \
-            argv.rval().setUndefined();                         \
-            RETURN_STATUS;                                      \
+#define REGION_DEFINE_REGION_FUNC(method)                                     \
+    GJS_JSAPI_RETURN_CONVENTION                                               \
+    static bool method##_func(JSContext* context, unsigned argc,              \
+                              JS::Value* vp) {                                \
+        PRELUDE;                                                              \
+        JS::RootedObject other_obj(context);                                  \
+        if (!gjs_parse_call_args(context, #method, argv, "o", "other_region", \
+                                 &other_obj))                                 \
+            return false;                                                     \
+                                                                              \
+        cairo_region_t* other_region = get_region(context, other_obj);        \
+                                                                              \
+        cairo_region_##method(this_region, other_region);                     \
+        argv.rval().setUndefined();                                           \
+        RETURN_STATUS;                                                        \
     }
 
-#define REGION_DEFINE_RECT_FUNC(method)                         \
-    static bool                                                 \
-    method##_rectangle_func(JSContext *context,                 \
-                            unsigned argc,                      \
-                            JS::Value *vp)                      \
-    {                                                           \
-        PRELUDE;                                                \
-        JS::RootedObject rect_obj(context);                     \
-        cairo_rectangle_int_t rect;                             \
-        if (!gjs_parse_call_args(context, #method, argv, "o",   \
-                                 "rect", &rect_obj))            \
-            return false;                                       \
-                                                                \
-        if (!fill_rectangle(context, rect_obj, &rect))          \
-            return false;                                       \
-                                                                \
-        cairo_region_##method##_rectangle(this_region, &rect);  \
-            argv.rval().setUndefined();                         \
-            RETURN_STATUS;                                      \
+#define REGION_DEFINE_RECT_FUNC(method)                                    \
+    GJS_JSAPI_RETURN_CONVENTION                                            \
+    static bool method##_rectangle_func(JSContext* context, unsigned argc, \
+                                        JS::Value* vp) {                   \
+        PRELUDE;                                                           \
+        JS::RootedObject rect_obj(context);                                \
+        if (!gjs_parse_call_args(context, #method, argv, "o", "rect",      \
+                                 &rect_obj))                               \
+            return false;                                                  \
+                                                                           \
+        cairo_rectangle_int_t rect;                                        \
+        if (!fill_rectangle(context, rect_obj, &rect))                     \
+            return false;                                                  \
+                                                                           \
+        cairo_region_##method##_rectangle(this_region, &rect);             \
+        argv.rval().setUndefined();                                        \
+        RETURN_STATUS;                                                     \
     }
 
 REGION_DEFINE_REGION_FUNC(union)
@@ -118,6 +115,7 @@ REGION_DEFINE_RECT_FUNC(subtract)
 REGION_DEFINE_RECT_FUNC(intersect)
 REGION_DEFINE_RECT_FUNC(xor)
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 fill_rectangle(JSContext             *context,
                JS::HandleObject       obj,
@@ -148,6 +146,7 @@ fill_rectangle(JSContext             *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 make_rectangle(JSContext *context,
                cairo_rectangle_int_t *rect)
@@ -176,6 +175,7 @@ make_rectangle(JSContext *context,
     return rect_obj;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 num_rectangles_func(JSContext *context,
                     unsigned argc,
@@ -192,6 +192,7 @@ num_rectangles_func(JSContext *context,
     RETURN_STATUS;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 get_rectangle_func(JSContext *context,
                    unsigned argc,
@@ -284,6 +285,7 @@ gjs_cairo_region_finalize(JSFreeOp *fop,
     g_slice_free(GjsCairoRegion, priv);
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static JSObject *
 gjs_cairo_region_from_region(JSContext *context,
                              cairo_region_t *region)
@@ -299,6 +301,7 @@ gjs_cairo_region_from_region(JSContext *context,
     return object;
 }
 
+GJS_USE
 static bool
 region_to_g_argument(JSContext      *context,
                      JS::Value       value,
@@ -321,6 +324,7 @@ region_to_g_argument(JSContext      *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 region_from_g_argument(JSContext             *context,
                        JS::MutableHandleValue value_p,
diff --git a/modules/cairo-solid-pattern.cpp b/modules/cairo-solid-pattern.cpp
index 597040b8..89066687 100644
--- a/modules/cairo-solid-pattern.cpp
+++ b/modules/cairo-solid-pattern.cpp
@@ -28,6 +28,7 @@
 #include <cairo.h>
 #include "cairo-private.h"
 
+GJS_USE
 static JSObject *gjs_cairo_solid_pattern_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_ABSTRACT_WITH_PARENT("SolidPattern", cairo_solid_pattern,
@@ -45,6 +46,7 @@ JSPropertySpec gjs_cairo_solid_pattern_proto_props[] = {
     JS_PS_END
 };
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 createRGB_func(JSContext *context,
                unsigned   argc,
@@ -73,6 +75,7 @@ createRGB_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 createRGBA_func(JSContext *context,
                 unsigned   argc,
diff --git a/modules/cairo-surface-pattern.cpp b/modules/cairo-surface-pattern.cpp
index 44e558b2..48fd2cfe 100644
--- a/modules/cairo-surface-pattern.cpp
+++ b/modules/cairo-surface-pattern.cpp
@@ -28,6 +28,7 @@
 #include <cairo.h>
 #include "cairo-private.h"
 
+GJS_USE
 static JSObject *gjs_cairo_surface_pattern_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("SurfacePattern", cairo_surface_pattern,
@@ -77,7 +78,7 @@ JSPropertySpec gjs_cairo_surface_pattern_proto_props[] = {
     JS_PS_END
 };
 
-
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 setExtend_func(JSContext *context,
                unsigned   argc,
@@ -101,6 +102,7 @@ setExtend_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getExtend_func(JSContext *context,
                unsigned   argc,
@@ -126,6 +128,7 @@ getExtend_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 setFilter_func(JSContext *context,
                unsigned   argc,
@@ -149,6 +152,7 @@ setFilter_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getFilter_func(JSContext *context,
                unsigned   argc,
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index d14e03a8..6b671ba5 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -60,6 +60,7 @@ JSPropertySpec gjs_cairo_surface_proto_props[] = {
 };
 
 /* Methods */
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 writeToPNG_func(JSContext *context,
                 unsigned   argc,
@@ -85,6 +86,7 @@ writeToPNG_func(JSContext *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 getType_func(JSContext *context,
              unsigned   argc,
@@ -243,6 +245,7 @@ gjs_cairo_surface_get_surface(JSContext *context,
     return priv->surface;
 }
 
+GJS_USE
 static bool
 surface_to_g_argument(JSContext      *context,
                       JS::Value       value,
@@ -266,6 +269,7 @@ surface_to_g_argument(JSContext      *context,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 surface_from_g_argument(JSContext             *context,
                         JS::MutableHandleValue value_p,
diff --git a/modules/cairo-svg-surface.cpp b/modules/cairo-svg-surface.cpp
index 52e46458..9dabb07d 100644
--- a/modules/cairo-svg-surface.cpp
+++ b/modules/cairo-svg-surface.cpp
@@ -31,6 +31,7 @@
 #if CAIRO_HAS_SVG_SURFACE
 #include <cairo-svg.h>
 
+GJS_USE
 static JSObject *gjs_cairo_svg_surface_get_proto(JSContext *);
 
 GJS_DEFINE_PROTO_WITH_PARENT("SVGSurface", cairo_svg_surface,
diff --git a/modules/console.cpp b/modules/console.cpp
index cf5350b2..8fae56b2 100644
--- a/modules/console.cpp
+++ b/modules/console.cpp
@@ -237,6 +237,7 @@ public:
 };
 
 #ifdef HAVE_READLINE_READLINE_H
+GJS_USE
 static bool
 gjs_console_readline(JSContext *cx, char **bufp, FILE *file, const char *prompt)
 {
@@ -250,6 +251,7 @@ gjs_console_readline(JSContext *cx, char **bufp, FILE *file, const char *prompt)
     return true;
 }
 #else
+GJS_USE
 static bool
 gjs_console_readline(JSContext *cx, char **bufp, FILE *file, const char *prompt)
 {
@@ -267,6 +269,7 @@ gjs_console_readline(JSContext *cx, char **bufp, FILE *file, const char *prompt)
  * exception. (This is because the exception should be auto-printed around the
  * invocation of this function.)
  */
+GJS_USE
 static bool
 gjs_console_eval_and_print(JSContext  *cx,
                            const char *bytes,
@@ -297,6 +300,7 @@ gjs_console_eval_and_print(JSContext  *cx,
     return true;
 }
 
+GJS_JSAPI_RETURN_CONVENTION
 static bool
 gjs_console_interact(JSContext *context,
                      unsigned   argc,
diff --git a/modules/console.h b/modules/console.h
index ccdf1129..0f1dc8bf 100644
--- a/modules/console.h
+++ b/modules/console.h
@@ -26,10 +26,13 @@
 
 #include <config.h>
 #include <glib.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_define_console_stuff(JSContext              *context,
                               JS::MutableHandleObject module);
 
diff --git a/modules/system.h b/modules/system.h
index e907e84b..1344c128 100644
--- a/modules/system.h
+++ b/modules/system.h
@@ -27,10 +27,13 @@
 
 #include <config.h>
 #include <glib.h>
+
 #include "gjs/jsapi-util.h"
+#include "gjs/macros.h"
 
 G_BEGIN_DECLS
 
+GJS_JSAPI_RETURN_CONVENTION
 bool gjs_js_define_system_stuff(JSContext              *context,
                                 JS::MutableHandleObject module);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]