diff options
| author | Jeffrey C. Ollie <jeff@ocjtech.us> | 2025-08-16 00:29:26 -0500 |
|---|---|---|
| committer | Mitchell Hashimoto <m@mitchellh.com> | 2025-08-18 09:20:40 -0700 |
| commit | dd072d2e01635003da49541489434ddf07b20523 (patch) | |
| tree | 1f849c9d026e22865ee8b2f74db8a42acdc44c6d | |
| parent | f147a89b6839bc6c31d79befbf391375e51b50f9 (diff) | |
gtk-ng: add some initial notes on memory layout of GObjects
| -rw-r--r-- | src/apprt/gtk-ng/class.zig | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/apprt/gtk-ng/class.zig b/src/apprt/gtk-ng/class.zig index ee29954cb..b3ea70a37 100644 --- a/src/apprt/gtk-ng/class.zig +++ b/src/apprt/gtk-ng/class.zig @@ -53,13 +53,49 @@ pub fn Common( } }).private else {}; - /// Get the class structure for the object. + /// Get the class for the object. /// - /// This seems ugly and unsafe to me but this is what GObject is doing - /// under the hood. + /// This _seems_ ugly and unsafe but this is what GObject is doing + /// under the hood when it wants to access the class instance: /// /// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.h#L555-571 /// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.h#L2673 + /// + /// This works because when you create a new object in GObject, the pointer + /// that you get back wasn't allocated using your original type struct. + /// Instead you get the following block of data: + /// + /// + /// ┌─────────────────┐ + /// │ │ + /// │ │ + /// │ Private │ + /// │ │ + /// │ │ + /// │ │ + /// │ │ + /// ┌───►├─────────────────┤ + /// *object────┘ │ │ + /// │ TypeInstance │ + /// │ │ ┌───►┌────────────────┐ + /// │ │ │ │ │ + /// │ │ │ │ Class │ + /// │ *g_class ────┼───┘ │ │ + /// │ │ │ │ + /// └─────────────────┘ │ │ + /// │ │ + /// │ │ + /// └────────────────┘ + /// + /// First is a block of data that holds the instance's private data. That private + /// data is accessed by taking the instance pointer and subtracting the size of the + /// private data to get a pointer to the data. + /// + /// Next is an instance of a TypeInstance, whose purpose is to hold a pointer + /// to the class instance. + /// + /// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.c#L1792-1912 + /// pub fn getClass(self: *Self) ?*Self.Class { const type_instance: *gobject.TypeInstance = @ptrCast(self); return @ptrCast(type_instance.f_g_class orelse return null); |
