/* * Get a property from an intrinsic class modifier object. Look up the * property in my own modifier, and recursively in my superclass modifiers. */ int CVmObjClass::get_prop_from_mod(VMG_ vm_prop_id_t prop, vm_val_t *val, vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc) { vm_obj_id_t sc; vm_obj_id_t mod_obj; /* if we have a modifier object, look it up in the modifier */ if ((mod_obj = get_mod_obj()) != VM_INVALID_OBJ && vm_objp(vmg_ mod_obj)->get_prop(vmg_ prop, val, mod_obj, source_obj, argc)) { /* got it - return it from the modifier */ return TRUE; } /* * it's not in our modifier(s); check with any intrinsic superclass * modifiers */ if (get_superclass_count(vmg_ self) != 0 && (sc = get_superclass(vmg_ self, 0)) != VM_INVALID_OBJ) { /* we have a superclass - check it recursively */ return ((CVmObjClass *)vm_objp(vmg_ sc)) ->get_prop_from_mod(vmg_ prop, val, sc, source_obj, argc); } /* * we didn't find it, and we have no superclass, so there's nowhere * else to look - return failure */ return FALSE; }
/* * Find the intrinsic class which the given modifier object modifies. This * can only be used with a modifier that modifies me or one of my * superclasses. */ vm_obj_id_t CVmObjClass::find_mod_src_obj(VMG_ vm_obj_id_t self, vm_obj_id_t mod_obj) { vm_obj_id_t my_mod_obj; vm_obj_id_t sc; /* * Is this one of my modifier objects? It is if it's my most * specialized modifier object (i.e., get_mod_obj()), or if my most * specialized modifier object descends from the given object. */ my_mod_obj = get_mod_obj(); if (my_mod_obj != VM_INVALID_OBJ && (mod_obj == my_mod_obj || vm_objp(vmg_ my_mod_obj)->is_instance_of(vmg_ mod_obj))) { /* it's one of mine, so I'm the intrinsic class mod_obj modifies */ return self; } /* * It's not one of mine, so check my superclasses recursively. If we * have no direct superclass, we've failed to find the object. */ if (get_superclass_count(vmg_ self) == 0 || (sc = get_superclass(vmg_ self, 0)) == VM_INVALID_OBJ) return VM_INVALID_OBJ; /* ask the superclass to find the modifier */ return ((CVmObjClass *)vm_objp(vmg_ sc)) ->find_mod_src_obj(vmg_ sc, mod_obj); }
static const RGObjClassInfo * rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent, gboolean create_class) { GType fundamental_type; RGObjClassInfo* cinfo; RGObjClassInfoDynamic* cinfod; void* gclass = NULL; VALUE c; if (gtype == G_TYPE_INVALID) return NULL; cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype)); if (cinfo) return cinfo; if (!create_class) return NULL; c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo); cinfo->gtype = gtype; cinfo->mark = NULL; cinfo->free = NULL; cinfo->flags = 0; fundamental_type = G_TYPE_FUNDAMENTAL(gtype); switch (fundamental_type) { case G_TYPE_POINTER: case G_TYPE_BOXED: case G_TYPE_PARAM: case G_TYPE_OBJECT: case G_TYPE_ENUM: case G_TYPE_FLAGS: if (NIL_P(parent)) parent = get_superclass(gtype); cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); break; case G_TYPE_INTERFACE: cinfo->klass = rb_module_new(); break; default: if (NIL_P(parent)) parent = get_superclass(gtype); if (NIL_P(parent)) { fprintf(stderr, "%s: %s's fundamental type %s isn't supported\n", "rbgobj_lookup_class_by_gtype", g_type_name(gtype), g_type_name(fundamental_type)); return NULL; } cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); } cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list, g_type_name(gtype)); if (cinfod) { cinfo->mark = cinfod->mark; cinfo->free = cinfod->free; rb_define_const(cinfod->module, cinfod->name, cinfo->klass); } rb_hash_aset(klass_to_cinfo, cinfo->klass, c); g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo); if (G_TYPE_IS_CLASSED(gtype)) gclass = g_type_class_ref(gtype); if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype)) rbgobj_define_action_methods(cinfo->klass); if (G_TYPE_IS_INSTANTIATABLE(gtype)) { GType* interfaces = NULL; guint n_interfaces = 0; guint i; interfaces = g_type_interfaces(gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { const RGObjClassInfo *iface_cinfo; iface_cinfo = rbgobj_lookup_class_by_gtype_without_lock(interfaces[i], Qnil, TRUE); rb_include_module(cinfo->klass, iface_cinfo->klass); } g_free(interfaces); } if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) { switch (fundamental_type) { case G_TYPE_OBJECT: rbgobj_init_object_class(cinfo->klass); break; case G_TYPE_ENUM: rbgobj_init_enum_class(cinfo->klass); break; case G_TYPE_FLAGS: rbgobj_init_flags_class(cinfo->klass); break; case G_TYPE_INTERFACE: rbgobj_init_interface(cinfo->klass); break; default: rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass); break; } } if (gclass) g_type_class_unref(gclass); return cinfo; }