static JSBool boxed_field_setter (JSContext *context, JSObject *obj, jsid id, JSBool strict, jsval *value) { Boxed *priv; GIFieldInfo *field_info; gboolean success = FALSE; priv = priv_from_js(context, obj); if (!priv) return JS_FALSE; field_info = get_field_info(context, priv, id); if (!field_info) return JS_FALSE; if (priv->gboxed == NULL) { /* direct access to proto field */ gjs_throw(context, "Can't set field %s.%s on prototype", g_base_info_get_name ((GIBaseInfo *)priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); goto out; } success = boxed_set_field_from_value (context, priv, field_info, *value); out: g_base_info_unref ((GIBaseInfo *)field_info); return success; }
static GIFieldInfo * get_field_info (JSContext *context, Boxed *priv, jsid id) { int field_index; jsval id_val; if (!JS_IdToValue(context, id, &id_val)) return JS_FALSE; if (!JSVAL_IS_INT (id_val)) { gjs_throw(context, "Field index for %s is not an integer", g_base_info_get_name ((GIBaseInfo *)priv->info)); return NULL; } field_index = JSVAL_TO_INT(id_val); if (field_index < 0 || field_index >= g_struct_info_get_n_fields (priv->info)) { gjs_throw(context, "Bad field index %d for %s", field_index, g_base_info_get_name ((GIBaseInfo *)priv->info)); return NULL; } return g_struct_info_get_field (priv->info, field_index); }
static GjsForeignInfo * gjs_struct_foreign_lookup(JSContext *context, GIBaseInfo *interface_info) { GjsForeignInfo *retval = NULL; GHashTable *hash_table; char *key; key = g_strdup_printf("%s.%s", g_base_info_get_namespace(interface_info), g_base_info_get_name(interface_info)); hash_table = get_foreign_structs(); retval = (GjsForeignInfo*)g_hash_table_lookup(hash_table, key); if (!retval) { if (gjs_foreign_load_foreign_module(context, g_base_info_get_namespace(interface_info))) { retval = (GjsForeignInfo*)g_hash_table_lookup(hash_table, key); } } if (!retval) { gjs_throw(context, "Unable to find module implementing foreign type %s.%s", g_base_info_get_namespace(interface_info), g_base_info_get_name(interface_info)); } g_free(key); return retval; }
JSObject* gjs_boxed_from_c_struct(JSContext *context, GIStructInfo *info, void *gboxed, GjsBoxedCreationFlags flags) { JSObject *obj; JSObject *proto; Boxed *priv; Boxed *proto_priv; if (gboxed == NULL) return NULL; gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_boxed_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); *priv = *proto_priv; g_base_info_ref( (GIBaseInfo*) priv->info); JS_SetPrivate(context, obj, priv); if ((flags & GJS_BOXED_CREATION_NO_COPY) != 0) { /* we need to create a JS Boxed which references the * original C struct, not a copy of it. Used for * G_SIGNAL_TYPE_STATIC_SCOPE */ priv->gboxed = gboxed; priv->not_owning_gboxed = TRUE; } else { if (priv->gtype != G_TYPE_NONE && g_type_is_a (priv->gtype, G_TYPE_BOXED)) { priv->gboxed = g_boxed_copy(priv->gtype, gboxed); } else if (priv->gtype == G_TYPE_VARIANT) { priv->gboxed = g_variant_ref_sink (gboxed); } else if (priv->can_allocate_directly) { boxed_new_direct(priv); memcpy(priv->gboxed, gboxed, g_struct_info_get_size (priv->info)); } else { gjs_throw(context, "Can't create a Javascript object for %s; no way to copy", g_base_info_get_name( (GIBaseInfo*) priv->info)); } } return obj; }
static JSBool get_nested_interface_object (JSContext *context, JSObject *parent_obj, Boxed *parent_priv, GIFieldInfo *field_info, GITypeInfo *type_info, GIBaseInfo *interface_info, jsval *value) { JSObject *obj; JSObject *proto; int offset; Boxed *priv; Boxed *proto_priv; if (!struct_is_simple ((GIStructInfo *)interface_info)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)parent_priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); return JS_FALSE; } proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info); proto_priv = priv_from_js(context, proto); offset = g_field_info_get_offset (field_info); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); if (obj == NULL) return JS_FALSE; GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); JS_SetPrivate(context, obj, priv); priv->info = (GIBoxedInfo*) interface_info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info); priv->can_allocate_directly = proto_priv->can_allocate_directly; /* A structure nested inside a parent object; doesn't have an independent allocation */ priv->gboxed = ((char *)parent_priv->gboxed) + offset; priv->not_owning_gboxed = TRUE; /* We never actually read the reserved slot, but we put the parent object * into it to hold onto the parent object. */ JS_SetReservedSlot(context, obj, 0, OBJECT_TO_JSVAL (parent_obj)); *value = OBJECT_TO_JSVAL(obj); return JS_TRUE; }
/* * Set up prototype and constructor for structs. Same semantics as objects * except * for the type. */ static void seed_gi_importer_handle_struct(JSContextRef ctx, JSObjectRef namespace_ref, GIStructInfo* info, JSValueRef* exception) { JSObjectRef struct_ref; JSObjectRef proto; gint i, n_methods; GIFunctionInfo* finfo; struct_ref = JSObjectMake(ctx, seed_struct_constructor_class, info); g_base_info_ref(info); n_methods = g_struct_info_get_n_methods(info); for (i = 0; i < n_methods; i++) { GIFunctionInfoFlags flags; finfo = g_struct_info_get_method(info, i); flags = g_function_info_get_flags(finfo); if (flags & GI_FUNCTION_IS_CONSTRUCTOR) { JSObjectRef constructor = JSObjectMake(ctx, gobject_named_constructor_class, finfo); const gchar* fname = g_base_info_get_name((GIBaseInfo*) finfo); if (g_strrstr(fname, "new_") == fname) { // To be compatible with gjs, we need to have a method with // new_, too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname += 4; } else if (!g_strcmp0(fname, "new")) { // To be compatible with gjs, we need to have new as function, // too. seed_object_set_property(ctx, struct_ref, fname, constructor); fname = "c_new"; } seed_object_set_property(ctx, struct_ref, fname, constructor); } else if (flags & GI_FUNCTION_IS_METHOD) g_base_info_unref((GIBaseInfo*) finfo); else seed_gobject_define_property_from_function_info(ctx, finfo, struct_ref, FALSE); } proto = seed_struct_prototype(ctx, (GIBaseInfo*) info); seed_object_set_property(ctx, struct_ref, "prototype", proto); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), struct_ref); }
static JSBool error_to_string(JSContext *context, uintN argc, jsval *vp) { jsval v_self; JSObject *self; Error *priv; jsval v_out; gchar *descr; JSBool retval; v_self = JS_THIS(context, vp); if (!JSVAL_IS_OBJECT(v_self)) { /* Lie a bit here... */ gjs_throw(context, "GLib.Error.prototype.toString() called on a non object"); return JS_FALSE; } self = JSVAL_TO_OBJECT(v_self); priv = priv_from_js(context, self); if (priv == NULL) return JS_FALSE; v_out = JSVAL_VOID; retval = JS_FALSE; /* We follow the same pattern as standard JS errors, at the expense of hiding some useful information */ if (priv->gerror == NULL) { descr = g_strdup_printf("%s.%s", g_base_info_get_namespace(priv->info), g_base_info_get_name(priv->info)); if (!gjs_string_from_utf8(context, descr, -1, &v_out)) goto out; } else { descr = g_strdup_printf("%s.%s: %s", g_base_info_get_namespace(priv->info), g_base_info_get_name(priv->info), priv->gerror->message); if (!gjs_string_from_utf8(context, descr, -1, &v_out)) goto out; } JS_SET_RVAL(context, vp, v_out); retval = JS_TRUE; out: g_free(descr); return retval; }
static JSBool define_boxed_class_fields (JSContext *context, Boxed *priv, JSObject *proto) { int n_fields = g_struct_info_get_n_fields (priv->info); int i; /* We identify properties with a 'TinyId': a 8-bit numeric value * that can be retrieved in the property getter/setter. Using it * allows us to avoid a hash-table lookup or linear search. * It does restrict us to a maximum of 256 fields per type. * * We define all fields as read/write so that the user gets an * error message. If we omitted fields or defined them read-only * we'd: * * - Storing a new property for a non-accessible field * - Silently do nothing when writing a read-only field * * Which is pretty confusing if the only reason a field isn't * writable is language binding or memory-management restrictions. * * We just go ahead and define the fields immediately for the * class; doing it lazily in boxed_new_resolve() would be possible * as well if doing it ahead of time caused to much start-up * memory overhead. */ if (n_fields > 256) { gjs_debug(GJS_DEBUG_ERROR, "Only defining the first 256 fields in boxed type '%s'", g_base_info_get_name ((GIBaseInfo *)priv->info)); n_fields = 256; } for (i = 0; i < n_fields; i++) { GIFieldInfo *field = g_struct_info_get_field (priv->info, i); const char *field_name = g_base_info_get_name ((GIBaseInfo *)field); gboolean result; result = JS_DefinePropertyWithTinyId(context, proto, field_name, i, JSVAL_NULL, boxed_field_getter, boxed_field_setter, JSPROP_PERMANENT | JSPROP_SHARED); g_base_info_unref ((GIBaseInfo *)field); if (!result) return JS_FALSE; } return JS_TRUE; }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback; GIArgInfo *arg_info; GIArgument *callback_argument; arg_info = &(metadata->arg_info); callback = find_callback_function(arg_info); if (!callback) { GITypeInfo type_info; GIBaseInfo *interface_info; VALUE rb_type_name; g_arg_info_load_type(arg_info, &type_info); interface_info = g_type_info_get_interface(&type_info); rb_type_name = CSTR2RVAL(g_base_info_get_name(interface_info)); g_base_info_unref(interface_info); rb_raise(rb_eNotImpError, "TODO: <%s>(%s) callback is not supported yet.", RVAL2CSTR(rb_type_name), g_base_info_get_name(arg_info)); } callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); callback_argument->v_pointer = callback; if (metadata->closure_in_arg_index != -1) { RBGICallbackData *callback_data; GIArgument *closure_argument; callback_data = ALLOC(RBGICallbackData); callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); closure_argument->v_pointer = callback_data; } if (metadata->destroy_in_arg_index != -1) { GIArgument *destroy_argument; destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); destroy_argument->v_pointer = destroy_notify; } }
JSBool gjs_typecheck_fundamental(JSContext *context, JSObject *object, GType expected_gtype, JSBool throw_error) { FundamentalInstance *priv; JSBool result; if (!do_base_typecheck(context, object, throw_error)) return JS_FALSE; priv = priv_from_js(context, object); g_assert(priv != NULL); if (priv->gfundamental == NULL) { if (throw_error) { Fundamental *proto_priv = (Fundamental *) priv; gjs_throw(context, "Object is %s.%s.prototype, not an fundamental instance - cannot convert to void*", proto_priv->info ? g_base_info_get_namespace((GIBaseInfo *) proto_priv->info) : "", proto_priv->info ? g_base_info_get_name((GIBaseInfo *) proto_priv->info) : g_type_name(proto_priv->gtype)); } return JS_FALSE; } if (expected_gtype != G_TYPE_NONE) result = g_type_is_a(priv->prototype->gtype, expected_gtype); else result = JS_TRUE; if (!result && throw_error) { if (priv->prototype->info) { gjs_throw_custom(context, "TypeError", "Object is of type %s.%s - cannot convert to %s", g_base_info_get_namespace((GIBaseInfo *) priv->prototype->info), g_base_info_get_name((GIBaseInfo *) priv->prototype->info), g_type_name(expected_gtype)); } else { gjs_throw_custom(context, "TypeError", "Object is of type %s - cannot convert to %s", g_type_name(priv->prototype->gtype), g_type_name(expected_gtype)); } } return result; }
GError* gjs_gerror_from_error(JSContext *context, JSObject *obj) { Error *priv; if (obj == NULL) return NULL; /* If this is a plain GBoxed (i.e. a GError without metadata), delegate marshalling. */ if (gjs_typecheck_boxed (context, obj, NULL, G_TYPE_ERROR, JS_FALSE)) return gjs_c_struct_from_boxed (context, obj); priv = priv_from_js(context, obj); if (priv == NULL) return NULL; if (priv->gerror == NULL) { gjs_throw(context, "Object is %s.%s.prototype, not an object instance - cannot convert to a boxed instance", g_base_info_get_namespace( (GIBaseInfo*) priv->info), g_base_info_get_name( (GIBaseInfo*) priv->info)); return NULL; } return priv->gerror; }
int lgi_type_get_name (lua_State *L, GIBaseInfo *info) { GSList *list = NULL, *i; int n = 1; lua_pushstring (L, g_base_info_get_namespace (info)); if (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK) /* Avoid duplicate name for callbacks. */ info = g_base_info_get_container (info); /* Add names on the whole path, but in reverse order. */ for (; info != NULL; info = g_base_info_get_container (info)) if (!GI_IS_TYPE_INFO (info)) list = g_slist_prepend (list, info); for (i = list; i != NULL; i = g_slist_next (i)) { if (g_base_info_get_type (i->data) != GI_INFO_TYPE_TYPE) { lua_pushstring (L, "."); lua_pushstring (L, g_base_info_get_name (i->data)); n += 2; } } g_slist_free (list); return n; }
/* Find the first constructor */ static GIFunctionInfo * find_fundamental_constructor(JSContext *context, GIObjectInfo *info, jsid *constructor_name) { int i, n_methods; n_methods = g_object_info_get_n_methods(info); for (i = 0; i < n_methods; ++i) { GIFunctionInfo *func_info; GIFunctionInfoFlags flags; func_info = g_object_info_get_method(info, i); flags = g_function_info_get_flags(func_info); if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0) { const char *name; name = g_base_info_get_name((GIBaseInfo *) func_info); *constructor_name = gjs_intern_string_to_id(context, name); return func_info; } g_base_info_unref((GIBaseInfo *) func_info); } return NULL; }
static void fill_metadata_inout_argv(GPtrArray *args_metadata) { guint i; gint inout_argc_arg_index = -1; for (i = 0; i < args_metadata->len; i++) { RBGIArgMetadata *metadata; GIArgInfo *arg_info; const gchar *name; metadata = g_ptr_array_index(args_metadata, i); if (metadata->direction != GI_DIRECTION_INOUT) { continue; } arg_info = &(metadata->arg_info); name = g_base_info_get_name(arg_info); if (strcmp(name, "argc") == 0) { inout_argc_arg_index = i; } else if (strcmp(name, "argv") == 0) { metadata->inout_argv_p = TRUE; metadata->inout_argc_arg_index = inout_argc_arg_index; } } }
void* gjs_g_fundamental_from_object(JSContext *context, JSObject *obj) { FundamentalInstance *priv; if (obj == NULL) return NULL; priv = priv_from_js(context, obj); if (priv == NULL) { gjs_throw(context, "No introspection information for %p", obj); return NULL; } if (priv->gfundamental == NULL) { gjs_throw(context, "Object is %s.%s.prototype, not an object instance - cannot convert to a fundamental instance", g_base_info_get_namespace((GIBaseInfo *) priv->prototype->info), g_base_info_get_name((GIBaseInfo *) priv->prototype->info)); return NULL; } return priv->gfundamental; }
static void store_objects_with_vfuncs (AV *objects_with_vfuncs, GIObjectInfo *info) { if (g_object_info_get_n_vfuncs (info) <= 0) return; av_push (objects_with_vfuncs, newSVpv (g_base_info_get_name (info), 0)); }
static PyObject * _base_info_repr (PyGIBaseInfo *self) { return PYGLIB_PyUnicode_FromFormat ("<%s object (%s) at 0x%p>", Py_TYPE( (PyObject *) self)->tp_name, g_base_info_get_name (self->info), (void *) self); }
/* * 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 gpointer sv_to_callback (GIArgInfo * arg_info, GITypeInfo * type_info, SV * sv, GPerlI11nInvocationInfo * invocation_info) { GIBaseInfo *callback_interface_info; GPerlI11nPerlCallbackInfo *callback_info; GIScopeType scope; /* the destroy notify func is handled by _handle_automatic_arg */ dwarn (" Perl callback at %d (%s)\n", invocation_info->current_pos, g_base_info_get_name (arg_info)); callback_interface_info = g_type_info_get_interface (type_info); callback_info = create_perl_callback_closure (callback_interface_info, sv); callback_info->data_pos = g_arg_info_get_closure (arg_info); callback_info->destroy_pos = g_arg_info_get_destroy (arg_info); callback_info->free_after_use = FALSE; g_base_info_unref (callback_interface_info); dwarn (" Perl callback data at %d, destroy at %d\n", callback_info->data_pos, callback_info->destroy_pos); scope = (!gperl_sv_is_defined (sv)) ? GI_SCOPE_TYPE_CALL : g_arg_info_get_scope (arg_info); switch (scope) { case GI_SCOPE_TYPE_CALL: dwarn (" Perl callback has scope 'call'\n"); free_after_call (invocation_info, (GFunc) release_perl_callback, callback_info); break; case GI_SCOPE_TYPE_NOTIFIED: dwarn (" Perl callback has scope 'notified'\n"); /* This case is already taken care of by the notify * stuff above */ break; case GI_SCOPE_TYPE_ASYNC: dwarn (" Perl callback has scope 'async'\n"); /* FIXME: callback_info->free_after_use = TRUE; */ break; default: ccroak ("unhandled scope type %d encountered", g_arg_info_get_scope (arg_info)); } invocation_info->callback_infos = g_slist_prepend (invocation_info->callback_infos, callback_info); dwarn (" returning Perl closure %p from info %p\n", callback_info->closure, callback_info); return callback_info->closure; }
void gjs_define_error_class(JSContext *context, JSObject *in_object, GIEnumInfo *info) { const char *constructor_name; GIBoxedInfo *glib_error_info; JSObject *prototype, *parent_proto; JSObject *constructor; Error *priv; /* See the comment in gjs_define_boxed_class() for an * explanation of how this all works; Error is pretty much the * same as Boxed (except that we inherit from GLib.Error). */ constructor_name = g_base_info_get_name( (GIBaseInfo*) info); g_irepository_require(NULL, "GLib", "2.0", (GIRepositoryLoadFlags) 0, NULL); glib_error_info = (GIBoxedInfo*) g_irepository_find_by_name(NULL, "GLib", "Error"); parent_proto = gjs_lookup_generic_prototype(context, glib_error_info); g_base_info_unref((GIBaseInfo*)glib_error_info); if (!gjs_init_class_dynamic(context, in_object, parent_proto, g_base_info_get_namespace( (GIBaseInfo*) info), constructor_name, &gjs_error_class, gjs_error_constructor, 1, /* props of prototype */ &gjs_error_proto_props[0], /* funcs of prototype */ &gjs_error_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ &gjs_error_constructor_funcs[0], &prototype, &constructor)) { gjs_log_exception(context); g_error("Can't init class %s", constructor_name); } GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); priv->info = info; g_base_info_ref( (GIBaseInfo*) priv->info); priv->domain = g_quark_from_string (g_enum_info_get_error_domain(priv->info)); JS_SetPrivate(prototype, priv); gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GetClass(prototype), in_object); gjs_define_enum_values(context, constructor, priv->info); gjs_define_enum_static_methods(context, constructor, priv->info); }
static JSBool set_nested_interface_object (JSContext *context, Boxed *parent_priv, GIFieldInfo *field_info, GITypeInfo *type_info, GIBaseInfo *interface_info, jsval value) { JSObject *proto; int offset; Boxed *proto_priv; Boxed *source_priv; if (!struct_is_simple ((GIStructInfo *)interface_info)) { gjs_throw(context, "Writing field %s.%s is not supported", g_base_info_get_name ((GIBaseInfo *)parent_priv->info), g_base_info_get_name ((GIBaseInfo *)field_info)); return JS_FALSE; } proto = gjs_lookup_boxed_prototype(context, (GIBoxedInfo*) interface_info); proto_priv = priv_from_js(context, proto); /* If we can't directly copy from the source object we need * to construct a new temporary object. */ if (!boxed_get_copy_source(context, proto_priv, value, &source_priv)) { JSObject *tmp_object = gjs_construct_object_dynamic(context, proto, 1, &value); if (!tmp_object) return JS_FALSE; source_priv = priv_from_js(context, tmp_object); if (!source_priv) return JS_FALSE; } offset = g_field_info_get_offset (field_info); memcpy(((char *)parent_priv->gboxed) + offset, source_priv->gboxed, g_struct_info_get_size (source_priv->info)); return JS_TRUE; }
void lgi_type_get_repotype (lua_State *L, GType gtype, GIBaseInfo *info) { luaL_checkstack (L, 4, ""); /* Get repo-index table. */ lua_pushlightuserdata (L, &repo_index); lua_rawget (L, LUA_REGISTRYINDEX); /* Prepare gtype, if not given directly. */ if (gtype == G_TYPE_INVALID && info && GI_IS_REGISTERED_TYPE_INFO (info)) { gtype = g_registered_type_info_get_g_type (info); if (gtype == G_TYPE_NONE) gtype = G_TYPE_INVALID; } /* First of all, check direct indexing of repo-index by gtype, should be fastest. */ if (gtype != G_TYPE_INVALID) { lua_pushlightuserdata (L, (gpointer) gtype); lua_rawget (L, -2); } else lua_pushnil (L); if (lua_isnil (L, -1)) { /* Not indexed yet. Try to lookup by name - this works when lazy-loaded repo tables are not loaded yet. */ if (!info && gtype != G_TYPE_INVALID) { info = g_irepository_find_by_gtype (NULL, gtype); lgi_gi_info_new (L, info); } else /* Keep stack balanced as in the previous 'if' branch. */ lua_pushnil (L); if (info) { lua_pushlightuserdata (L, &repo); lua_rawget (L, LUA_REGISTRYINDEX); lua_getfield (L, -1, g_base_info_get_namespace (info)); lua_getfield (L, -1, g_base_info_get_name (info)); lua_replace (L, -5); lua_pop (L, 3); } else lua_pop (L, 1); } lua_replace (L, -2); }
static gboolean seed_gi_importer_is_init(GIFunctionInfo* info) { if (g_strcmp0(g_base_info_get_name((GIBaseInfo*) info), "init")) { return FALSE; } if (g_callable_info_get_n_args((GICallableInfo*) info) != 2) return FALSE; return TRUE; }
static gchar * get_struct_package (GIBaseInfo* info) { const gchar *basename, *package, *name; basename = g_base_info_get_namespace (info); package = get_package_for_basename (basename); if (!package) return NULL; name = g_base_info_get_name (info); return g_strconcat (package, "::", name, NULL); }
static void seed_gi_importer_handle_callback(JSContextRef ctx, JSObjectRef namespace_ref, GICallbackInfo* info, JSValueRef* exception) { JSObjectRef callback_ref = JSObjectMake(ctx, seed_callback_class, info); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), (JSValueRef) callback_ref); }
/* * Handle definition of enums in a namespace. * Each enum class gets an object containing * a value for each member, all in uppercase * i.e. Gtk.WindowType.NORMAL */ static void seed_gi_importer_handle_enum(JSContextRef ctx, JSObjectRef namespace_ref, GIEnumInfo* info, JSValueRef* exception) { JSObjectRef enum_class; guint num_vals, i, j; gsize name_len; gint value; // TODO: investigate what's up with the glong/gint mystery here gchar* name; GIValueInfo* val; enum_class = JSObjectMake(ctx, 0, 0); num_vals = g_enum_info_get_n_values(info); seed_object_set_property(ctx, namespace_ref, g_base_info_get_name((GIBaseInfo*) info), enum_class); for (i = 0; i < num_vals; i++) { val = g_enum_info_get_value((GIEnumInfo*) info, i); value = g_value_info_get_value(val); name = g_strdup(g_base_info_get_name((GIBaseInfo*) val)); name_len = strlen(name); JSValueRef value_ref; value_ref = JSValueMakeNumber(ctx, value); JSValueProtect(ctx, (JSValueRef) value_ref); for (j = 0; j < name_len; j++) { if (name[j] == '-') name[j] = '_'; name[j] = g_ascii_toupper(name[j]); } seed_object_set_property(ctx, enum_class, name, value_ref); g_free(name); g_base_info_unref((GIBaseInfo*) val); } }
static void boxed_new_direct(Boxed *priv) { g_assert(priv->can_allocate_directly); priv->gboxed = g_slice_alloc0(g_struct_info_get_size (priv->info)); priv->allocated_directly = TRUE; gjs_debug_lifecycle(GJS_DEBUG_GBOXED, "JSObject created by directly allocating %s", g_base_info_get_name ((GIBaseInfo *)priv->info)); }
JSObject* gjs_error_from_gerror(JSContext *context, GError *gerror, gboolean add_stack) { JSObject *obj; JSObject *proto; Error *priv; Error *proto_priv; GIEnumInfo *info; if (gerror == NULL) return NULL; info = find_error_domain_info(gerror->domain); if (!info) { /* We don't have error domain metadata */ /* Marshal the error as a plain GError */ GIBaseInfo *glib_boxed; JSObject *retval; glib_boxed = g_irepository_find_by_name(NULL, "GLib", "Error"); retval = gjs_boxed_from_c_struct(context, glib_boxed, gerror, 0); g_base_info_unref(glib_boxed); return retval; } gjs_debug_marshal(GJS_DEBUG_GBOXED, "Wrapping struct %s %p with JSObject", g_base_info_get_name((GIBaseInfo *)info), gboxed); proto = gjs_lookup_error_prototype(context, info); proto_priv = priv_from_js(context, proto); obj = JS_NewObjectWithGivenProto(context, JS_GET_CLASS(context, proto), proto, gjs_get_import_global (context)); GJS_INC_COUNTER(gerror); priv = g_slice_new0(Error); JS_SetPrivate(context, obj, priv); priv->info = info; priv->domain = proto_priv->domain; g_base_info_ref( (GIBaseInfo*) priv->info); priv->gerror = g_error_copy(gerror); if (add_stack) define_error_properties(context, obj); return obj; }
static void prepare_invocation_info (GPerlI11nInvocationInfo *iinfo, GICallableInfo *info) { gint orig_n_args; guint i; dwarn ("invoke: %s\n" " n_args: %d\n", g_base_info_get_name (info), g_callable_info_get_n_args (info)); iinfo->interface = info; iinfo->is_function = GI_IS_FUNCTION_INFO (info); iinfo->is_vfunc = GI_IS_VFUNC_INFO (info); iinfo->is_callback = (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK); iinfo->is_signal = GI_IS_SIGNAL_INFO (info); dwarn (" is_function = %d, is_vfunc = %d, is_callback = %d\n", iinfo->is_function, iinfo->is_vfunc, iinfo->is_callback); orig_n_args = g_callable_info_get_n_args (info); g_assert (orig_n_args >= 0); iinfo->n_args = (guint) orig_n_args; if (iinfo->n_args) { iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args); iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args); iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * iinfo->n_args); } else { iinfo->arg_infos = NULL; iinfo->arg_types = NULL; iinfo->aux_args = NULL; } for (i = 0 ; i < iinfo->n_args ; i++) { iinfo->arg_infos[i] = g_callable_info_get_arg (info, (gint) i); iinfo->arg_types[i] = g_arg_info_get_type (iinfo->arg_infos[i]); } iinfo->return_type_info = g_callable_info_get_return_type (info); iinfo->has_return_value = GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info); iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info); iinfo->return_type_transfer = g_callable_info_get_caller_owns (info); iinfo->callback_infos = NULL; iinfo->array_infos = NULL; iinfo->free_after_call = NULL; }
static JSBool fundamental_invoke_constructor(FundamentalInstance *priv, JSContext *context, JSObject *obj, unsigned argc, jsval *argv, GArgument *rvalue) { jsval js_constructor, js_constructor_func; jsid constructor_const; JSBool ret = JS_FALSE; constructor_const = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR); if (!gjs_object_require_property(context, obj, NULL, constructor_const, &js_constructor) || priv->prototype->constructor_name == JSID_VOID) { gjs_throw (context, "Couldn't find a constructor for type %s.%s", g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info), g_base_info_get_name((GIBaseInfo*) priv->prototype->info)); goto end; } if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(js_constructor), NULL, priv->prototype->constructor_name, &js_constructor_func)) { gjs_throw (context, "Couldn't find a constructor for type %s.%s", g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info), g_base_info_get_name((GIBaseInfo*) priv->prototype->info)); goto end; } ret = gjs_invoke_constructor_from_c(context, JSVAL_TO_OBJECT(js_constructor_func), obj, argc, argv, rvalue); end: return ret; }