hugopl/gi-crystal

Interface casts crashes

hugopl opened this issue · 0 comments

Interface cast was implemented like normal object casts, but they aren't. However this way it works in some circustances.

In current test suit, expanding the C macros we get the GObject implementations:

static inline gboolean TEST_IS_IFACE (gpointer ptr) {
  return {
    GTypeInstance *__inst = (GTypeInstance*) (ptr);
    GType __t = (test_iface_get_type ());
    gboolean __r;
    if (!__inst)
      __r = (0);
    else if (__inst->g_class && __inst->g_class->g_type == __t)
      __r = (!(0));
    else
      __r = g_type_check_instance_is_a (__inst, __t);
    __r;
  };
}

static inline TestIfaceInterface * TEST_IFACE_GET_IFACE (gpointer ptr) {
  return (TestIfaceInterface*) g_type_interface_peek(((GTypeInstance*) ptr)->g_class, test_iface_get_type());
}

While in the bindings this is done as:

# Cast a `GObject::Object` to this type, returns nil if cast can't be made.
def self.cast?(obj : GObject::Object) : self?
  return if LibGObject.g_type_check_instance_is_a(obj, g_type).zero?

  instance = GICrystal.instance_pointer(obj)
  # This should never happen with GC resistant objects
  raise GICrystal::ObjectCollectedError.new if instance.null?

  instance.as(self)
end

i.e. we have only the instance cast implementation 😁