| 2835 | } |
| 2836 | |
| 2837 | static JSObject* gjs_lookup_object_constructor_from_info( |
| 2838 | JSContext* cx, Maybe<const GI::RegisteredTypeInfo> info, GType gtype) { |
| 2839 | g_return_val_if_fail(!info || info->is_object() || info->is_interface(), |
| 2840 | nullptr); |
| 2841 | |
| 2842 | JS::RootedObject in_object{cx}; |
| 2843 | const char* constructor_name; |
| 2844 | if (info) { |
| 2845 | in_object = gjs_lookup_namespace_object(cx, info.value()); |
| 2846 | constructor_name = info->name(); |
| 2847 | } else { |
| 2848 | in_object = gjs_lookup_private_namespace(cx); |
| 2849 | constructor_name = g_type_name(gtype); |
| 2850 | } |
| 2851 | |
| 2852 | if (G_UNLIKELY (!in_object)) |
| 2853 | return nullptr; |
| 2854 | |
| 2855 | bool found; |
| 2856 | if (!JS_HasProperty(cx, in_object, constructor_name, &found)) |
| 2857 | return nullptr; |
| 2858 | |
| 2859 | JS::RootedValue value{cx}; |
| 2860 | if (found && !JS_GetProperty(cx, in_object, constructor_name, &value)) |
| 2861 | return nullptr; |
| 2862 | |
| 2863 | JS::RootedObject constructor{cx}; |
| 2864 | if (value.isUndefined()) { |
| 2865 | // In case we're looking for a private type, and we don't find it, we |
| 2866 | // need to define it first. |
| 2867 | JS::RootedObject ignored{cx}; |
| 2868 | if (!ObjectPrototype::define_class(cx, in_object, Nothing{}, gtype, |
| 2869 | nullptr, 0, &constructor, &ignored)) |
| 2870 | return nullptr; |
| 2871 | } else { |
| 2872 | if (G_UNLIKELY (!value.isObject())) |
| 2873 | return nullptr; |
| 2874 | |
| 2875 | constructor = &value.toObject(); |
| 2876 | } |
| 2877 | |
| 2878 | g_assert(constructor); |
| 2879 | |
| 2880 | return constructor; |
| 2881 | } |
| 2882 | |
| 2883 | GJS_JSAPI_RETURN_CONVENTION |
| 2884 | static JSObject* gjs_lookup_object_prototype_from_info( |
no test coverage detected