| 141 | } |
| 142 | |
| 143 | static GObject* gjs_object_constructor( |
| 144 | GType type, unsigned n_construct_properties, |
| 145 | GObjectConstructParam* construct_properties) { |
| 146 | JSContext* cx = current_js_context(); |
| 147 | GjsContextPrivate* gjs = GjsContextPrivate::from_cx(cx); |
| 148 | |
| 149 | if (!gjs->object_init_list().empty()) { |
| 150 | GType parent_type = g_type_parent(type); |
| 151 | |
| 152 | /* The object is being constructed from JS: simply chain up to the first |
| 153 | * non-gjs constructor |
| 154 | */ |
| 155 | while (G_OBJECT_CLASS(g_type_class_peek(parent_type))->constructor == |
| 156 | gjs_object_constructor) |
| 157 | parent_type = g_type_parent(parent_type); |
| 158 | |
| 159 | return G_OBJECT_CLASS(g_type_class_peek(parent_type)) |
| 160 | ->constructor(type, n_construct_properties, construct_properties); |
| 161 | } |
| 162 | |
| 163 | /* The object is being constructed from native code (e.g. GtkBuilder): |
| 164 | * Construct the JS object from the constructor, then use the GObject that |
| 165 | * was associated in gjs_object_custom_init() |
| 166 | */ |
| 167 | Gjs::AutoMainRealm ar{gjs}; |
| 168 | |
| 169 | JS::RootedValue constructor{cx}; |
| 170 | if (!gjs_lookup_object_constructor(cx, type, &constructor)) |
| 171 | return nullptr; |
| 172 | |
| 173 | JS::RootedObject object(cx); |
| 174 | if (n_construct_properties) { |
| 175 | JS::RootedObject props_hash(cx, JS_NewPlainObject(cx)); |
| 176 | |
| 177 | for (unsigned i = 0; i < n_construct_properties; i++) |
| 178 | if (!jsobj_set_gproperty(cx, props_hash, |
| 179 | construct_properties[i].value, |
| 180 | construct_properties[i].pspec)) |
| 181 | return nullptr; |
| 182 | |
| 183 | JS::RootedValueArray<1> args(cx); |
| 184 | args[0].set(JS::ObjectValue(*props_hash)); |
| 185 | |
| 186 | if (!JS::Construct(cx, constructor, args, &object)) |
| 187 | return nullptr; |
| 188 | } else if (!JS::Construct(cx, constructor, JS::HandleValueArray::empty(), |
| 189 | &object)) { |
| 190 | return nullptr; |
| 191 | } |
| 192 | |
| 193 | auto* priv = ObjectBase::for_js_nocheck(object); |
| 194 | /* Should have been set in init_impl() and pushed into object_init_list, |
| 195 | * then popped from object_init_list in gjs_object_custom_init() */ |
| 196 | g_assert(priv); |
| 197 | /* We only hold a toggle ref at this point, add back a ref that the native |
| 198 | * code can own. |
| 199 | */ |
| 200 | return G_OBJECT(g_object_ref(priv->to_instance()->ptr())); |
nothing calls this directly
no test coverage detected