static JSBool gjs_define_static_methods(JSContext *context, JSObject *constructor, GType gtype, GIStructInfo *boxed_info) { int i; int n_methods; n_methods = g_struct_info_get_n_methods(boxed_info); for (i = 0; i < n_methods; i++) { GIFunctionInfo *meth_info; GIFunctionInfoFlags flags; meth_info = g_struct_info_get_method (boxed_info, i); flags = g_function_info_get_flags (meth_info); /* Anything that isn't a method we put on the prototype of the * constructor. This includes <constructor> introspection * methods, as well as the forthcoming "static methods" * support. We may want to change this to use * GI_FUNCTION_IS_CONSTRUCTOR and GI_FUNCTION_IS_STATIC or the * like in the near future. */ if (!(flags & GI_FUNCTION_IS_METHOD)) { gjs_define_function(context, constructor, gtype, (GICallableInfo *)meth_info); } g_base_info_unref((GIBaseInfo*) meth_info); } return JS_TRUE; }
/* * The *resolved out parameter, on success, should be false to indicate that id * was not resolved; and true if id was resolved. */ static bool param_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, bool *resolved) { GIObjectInfo *info = NULL; GIFunctionInfo *method_info; Param *priv; bool ret = false; priv = priv_from_js(context, obj); if (priv != NULL) { /* instance, not prototype */ *resolved = false; return true; } GjsAutoJSChar name; if (!gjs_get_string_id(context, id, &name)) { *resolved = false; return true; /* not resolved, but no error */ } info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM); method_info = g_object_info_find_method(info, name); if (method_info == NULL) { *resolved = false; ret = true; goto out; } #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { gjs_debug(GJS_DEBUG_GOBJECT, "Defining method %s in prototype for GObject.ParamSpec", g_base_info_get_name( (GIBaseInfo*) method_info)); if (gjs_define_function(context, obj, G_TYPE_PARAM, method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); goto out; } *resolved = true; /* we defined the prop in obj */ } g_base_info_unref( (GIBaseInfo*) method_info); ret = true; out: if (info != NULL) g_base_info_unref( (GIBaseInfo*)info); return ret; }
static JSBool fundamental_instance_new_resolve_interface(JSContext *context, JS::HandleObject obj, JS::MutableHandleObject objp, Fundamental *proto_priv, char *name) { GIFunctionInfo *method_info; JSBool ret; GType *interfaces; guint n_interfaces; guint i; ret = JS_TRUE; interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { GIBaseInfo *base_info; GIInterfaceInfo *iface_info; base_info = g_irepository_find_by_gtype(g_irepository_get_default(), interfaces[i]); if (base_info == NULL) continue; /* An interface GType ought to have interface introspection info */ g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE); iface_info = (GIInterfaceInfo *) base_info; method_info = g_interface_info_find_method(iface_info, name); g_base_info_unref(base_info); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, proto_priv->gtype, (GICallableInfo *) method_info)) { objp.set(obj); } else { ret = JS_FALSE; } } g_base_info_unref((GIBaseInfo *) method_info); } } g_free(interfaces); return ret; }
static bool interface_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp) { Interface *priv; char *name; bool ret = false; GIFunctionInfo *method_info; if (!gjs_get_string_id(context, id, &name)) return true; priv = priv_from_js(context, obj); if (priv == NULL) goto out; /* If we have no GIRepository information then this interface was defined * from within GJS. In that case, it has no properties that need to be * resolved from within C code, as interfaces cannot inherit. */ if (priv->info == NULL) { ret = true; goto out; } method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, priv->gtype, (GICallableInfo*)method_info) == NULL) { g_base_info_unref((GIBaseInfo*)method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo*)method_info); } ret = true; out: g_free (name); return ret; }
static JSBool interface_new_resolve(JSContext *context, JSObject *obj, jsid id, unsigned flags, JSObject **objp) { Interface *priv; char *name; JSBool ret = JS_FALSE; GIFunctionInfo *method_info; *objp = NULL; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; priv = priv_from_js(context, obj); if (priv == NULL) goto out; method_info = g_interface_info_find_method((GIInterfaceInfo*) priv->info, name); if (method_info != NULL) { if (gjs_define_function(context, obj, priv->gtype, (GICallableInfo*)method_info) == NULL) { g_base_info_unref((GIBaseInfo*)method_info); goto out; } *objp = obj; g_base_info_unref((GIBaseInfo*)method_info); } ret = JS_TRUE; out: g_free (name); return ret; }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or fundamental prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool fundamental_instance_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { FundamentalInstance *priv; char *name; JSBool ret = JS_FALSE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GFUNDAMENTAL, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) goto out; /* wrong class */ if (priv->prototype == NULL) { /* We are the prototype, so look for methods and other class properties */ Fundamental *proto_priv = (Fundamental *) priv; GIFunctionInfo *method_info; method_info = g_object_info_find_method((GIStructInfo*) proto_priv->info, name); if (method_info != NULL) { const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo *) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name((GIBaseInfo *) method_info); /* we do not define deprecated methods in the prototype */ if (g_base_info_is_deprecated((GIBaseInfo *) method_info)) { gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Ignoring definition of deprecated method %s in prototype %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); g_base_info_unref((GIBaseInfo *) method_info); ret = JS_TRUE; goto out; } gjs_debug(GJS_DEBUG_GFUNDAMENTAL, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace((GIBaseInfo *) proto_priv->info), g_base_info_get_name((GIBaseInfo *) proto_priv->info)); if (gjs_define_function(context, obj, proto_priv->gtype, method_info) == NULL) { g_base_info_unref((GIBaseInfo *) method_info); goto out; } objp.set(obj); } g_base_info_unref((GIBaseInfo *) method_info); } ret = fundamental_instance_new_resolve_interface(context, obj, objp, proto_priv, name); } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } ret = JS_TRUE; out: g_free(name); return ret; }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or boxed prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool boxed_new_resolve(JSContext *context, JSObject *obj, jsid id, unsigned flags, JSObject **objp) { Boxed *priv; char *name; JSBool ret = JS_FALSE; *objp = NULL; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, obj, priv); if (priv == NULL) goto out; /* wrong class */ if (priv->gboxed == NULL) { /* We are the prototype, so look for methods and other class properties */ GIFunctionInfo *method_info; method_info = g_struct_info_find_method((GIStructInfo*) priv->info, name); if (method_info != NULL) { JSObject *boxed_proto; const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif method_name = g_base_info_get_name( (GIBaseInfo*) method_info); gjs_debug(GJS_DEBUG_GBOXED, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace( (GIBaseInfo*) priv->info), g_base_info_get_name( (GIBaseInfo*) priv->info)); boxed_proto = obj; if (gjs_define_function(context, boxed_proto, priv->gtype, (GICallableInfo *)method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); goto out; } *objp = boxed_proto; /* we defined the prop in object_proto */ g_base_info_unref( (GIBaseInfo*) method_info); } } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } ret = JS_TRUE; out: g_free(name); return ret; }
/* * Like JSResolveOp, but flags provide contextual information as follows: * * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence * JSRESOLVE_DECLARING var, const, or boxed prolog declaration opcode * JSRESOLVE_CLASSNAME class name used when constructing * * The *objp out parameter, on success, should be null to indicate that id * was not resolved; and non-null, referring to obj or one of its prototypes, * if id was resolved. */ static JSBool union_new_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, unsigned flags, JS::MutableHandleObject objp) { Union *priv; char *name; JSBool ret = JS_TRUE; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not resolved, but no error */ priv = priv_from_js(context, obj); gjs_debug_jsprop(GJS_DEBUG_GBOXED, "Resolve prop '%s' hook obj %p priv %p", name, *obj, priv); if (priv == NULL) { ret = JS_FALSE; /* wrong class */ goto out; } if (priv->gboxed == NULL) { /* We are the prototype, so look for methods and other class properties */ GIFunctionInfo *method_info; method_info = g_union_info_find_method((GIUnionInfo*) priv->info, name); if (method_info != NULL) { JSObject *union_proto; const char *method_name; #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { method_name = g_base_info_get_name( (GIBaseInfo*) method_info); gjs_debug(GJS_DEBUG_GBOXED, "Defining method %s in prototype for %s.%s", method_name, g_base_info_get_namespace( (GIBaseInfo*) priv->info), g_base_info_get_name( (GIBaseInfo*) priv->info)); union_proto = obj; if (gjs_define_function(context, union_proto, g_registered_type_info_get_g_type(priv->info), method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); ret = JS_FALSE; goto out; } objp.set(union_proto); /* we defined the prop in object_proto */ } g_base_info_unref( (GIBaseInfo*) method_info); } } else { /* We are an instance, not a prototype, so look for * per-instance props that we want to define on the * JSObject. Generally we do not want to cache these in JS, we * want to always pull them from the C object, or JS would not * see any changes made from C. So we use the get/set prop * hooks, not this resolve hook. */ } out: g_free(name); return ret; }