+static MonoClass**
+get_constraints (MonoImage *image, int owner)
+{
+ MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
+ guint32 cols [MONO_GENPARCONSTRAINT_SIZE];
+ guint32 i, token, found;
+ MonoClass *klass, **res;
+ GList *cons = NULL, *tmp;
+
+
+ found = 0;
+ for (i = 0; i < tdef->rows; ++i) {
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENPARCONSTRAINT_SIZE);
+ if (cols [MONO_GENPARCONSTRAINT_GENERICPAR] == owner) {
+ token = mono_metadata_token_from_dor (cols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
+ klass = mono_class_get (image, token);
+ cons = g_list_append (cons, klass);
+ ++found;
+ } else {
+ /* contiguous list finished */
+ if (found)
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ res = g_new0 (MonoClass*, found + 1);
+ for (i = 0, tmp = cons; i < found; ++i, tmp = tmp->next) {
+ res [i] = tmp->data;
+ }
+ g_list_free (cons);
+ return res;
+}
+
+MonoGenericParam *
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num, MonoMethod *method)
+{
+ MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAM];
+ guint32 cols [MONO_GENERICPARAM_SIZE];
+ guint32 i, owner, last_num, n;
+ MonoGenericParam *params;
+
+ if (mono_metadata_token_table (token) == MONO_TABLE_TYPEDEF)
+ owner = MONO_TYPEORMETHOD_TYPE;
+ else if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
+ owner = MONO_TYPEORMETHOD_METHOD;
+ else {
+ g_error ("wrong token %x to load_generics_params", token);
+ }
+ owner |= mono_metadata_token_index (token) << MONO_TYPEORMETHOD_BITS;
+ if (num)
+ *num = 0;
+ if (!tdef->base)
+ return NULL;
+
+ for (i = 0; i < tdef->rows; ++i) {
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+ if (cols [MONO_GENERICPARAM_OWNER] == owner)
+ break;
+ }
+ last_num = 0;
+ if (i >= tdef->rows)
+ return NULL;
+ params = NULL;
+ n = 1;
+ do {
+ params = g_realloc (params, sizeof (MonoGenericParam) * n);
+ params [n - 1].pklass = NULL;
+ params [n - 1].method = method;
+ params [n - 1].flags = cols [MONO_GENERICPARAM_FLAGS];
+ params [n - 1].num = cols [MONO_GENERICPARAM_NUMBER];
+ params [n - 1].name = mono_metadata_string_heap (image, cols [MONO_GENERICPARAM_NAME]);
+ params [n - 1].constraints = get_constraints (image, i + 1);
+ if (++i >= tdef->rows)
+ break;
+ mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
+ n++;
+ } while (cols [MONO_GENERICPARAM_OWNER] == owner);
+
+ if (num)
+ *num = n;
+ return params;
+}
+