+/*
+ * wrap_non_exception_throws:
+ *
+ * Determine whenever M's assembly has a RuntimeCompatibilityAttribute with the
+ * WrapNonExceptionThrows flag set.
+ */
+static gboolean
+wrap_non_exception_throws (MonoMethod *m)
+{
+ MonoAssembly *ass = m->klass->image->assembly;
+ MonoCustomAttrInfo* attrs;
+ static MonoClass *klass;
+ int i;
+ gboolean val = FALSE;
+
+ g_assert (ass);
+ if (ass->wrap_non_exception_throws_inited)
+ return ass->wrap_non_exception_throws;
+
+ klass = mono_class_from_name_cached (mono_defaults.corlib, "System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");
+
+ attrs = mono_custom_attrs_from_assembly (ass);
+ if (attrs) {
+ for (i = 0; i < attrs->num_attrs; ++i) {
+ MonoCustomAttrEntry *attr = &attrs->attrs [i];
+ const gchar *p;
+ int len, num_named, named_type, data_type, name_len;
+ char *name;
+
+ if (!attr->ctor || attr->ctor->klass != klass)
+ continue;
+ /* Decode the RuntimeCompatibilityAttribute. See reflection.c */
+ len = attr->data_size;
+ p = (const char*)attr->data;
+ g_assert (read16 (p) == 0x0001);
+ p += 2;
+ num_named = read16 (p);
+ if (num_named != 1)
+ continue;
+ p += 2;
+ named_type = *p;
+ p ++;
+ data_type = *p;
+ p ++;
+ /* Property */
+ if (named_type != 0x54)
+ continue;
+ name_len = mono_metadata_decode_blob_size (p, &p);
+ name = g_malloc (name_len + 1);
+ memcpy (name, p, name_len);
+ name [name_len] = 0;
+ p += name_len;
+ g_assert (!strcmp (name, "WrapNonExceptionThrows"));
+ g_free (name);
+ /* The value is a BOOLEAN */
+ val = *p;
+ }
+ }
+
+ ass->wrap_non_exception_throws = val;
+ mono_memory_barrier ();
+ ass->wrap_non_exception_throws_inited = TRUE;
+
+ return val;
+}
+