Permalink
Browse files

Tue Feb 19 20:23:11 CET 2002 Paolo Molaro <lupus@ximian.com>

	* icall.c: register the GetCustomAttributes method.
	* object.c, object.h: add mono_string_new_len ().
	* reflection.h, reflection.c: added mono_runtime_invoke(),
	mono_install_runtime_invoke(). Added
	mono_reflection_get_custom_attrs () to load custom attributes and
	create the attribute objects.


Tue Feb 19 20:21:14 CET 2002 Paolo Molaro <lupus@ximian.com>

	* interp.c: implement the runtime_invoke function.

svn path=/trunk/mono/; revision=2514
  • Loading branch information...
1 parent 12baa90 commit 4479530b9e681edfacc6ea4ef839814ef591eb61 @illupus illupus committed Feb 19, 2002
@@ -1,4 +1,8 @@
+Tue Feb 19 20:21:14 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: implement the runtime_invoke function.
+
Mon Feb 18 15:49:20 CET 2002 Paolo Molaro <lupus@ximian.com>
* interp.c: fix alignment code. Make sure to init classes
@@ -807,6 +807,58 @@ verify_method (MonoMethod *m)
#define CHECK_ADD_OVERFLOW64_UN(a,b) \
(guint64)(ULONG_MAX) - (guint64)(b) < (guint64)(a) ? -1 : 0
+static MonoObject*
+interp_mono_runtime_invoke (MonoMethod *method, void *obj, void **params)
+{
+ MonoInvocation frame;
+ MonoObject *retval;
+ MonoMethodSignature *sig = method->signature;
+ int i;
+ void *ret;
+ stackval *args = g_new0 (stackval, sig->param_count);
+
+ /* FIXME: Set frame for execption handling. */
+
+ /* allocate ret object. */
+ if (sig->ret->type == MONO_TYPE_VOID) {
+ retval = NULL;
+ ret = NULL;
+ } else {
+ MonoClass *klass = mono_class_from_mono_type (sig->ret);
+ if (klass->valuetype) {
+ retval = mono_object_new (mono_domain_get (), mono_class_from_mono_type (sig->ret));
+ ret = ((char*)retval) + sizeof (MonoObject);
+ } else {
+ ret = &retval;
+ }
+ }
+ for (i = 0; i < sig->param_count; ++i) {
+ if (sig->params [i]->byref) {
+ args [i].data.p = params [i];
+ continue;
+ }
+ switch (sig->params [i]->type) {
+ case MONO_TYPE_BOOLEAN:
+ args [i].type = VAL_I32;
+ args [i].data.i = *(MonoBoolean*)params [i];
+ args [i].data.vt.klass = NULL;
+ break;
+ case MONO_TYPE_STRING:
+ args [i].type = VAL_OBJ;
+ args [i].data.p = params [i];
+ args [i].data.vt.klass = NULL;
+ break;
+ default:
+ g_error ("type 0x%x not handled in invoke", sig->params [i]->type);
+ }
+ }
+
+ INIT_FRAME(&frame,NULL,obj,args,ret,method);
+ ves_exec_method (&frame);
+ g_free (args);
+ return retval;
+}
+
/*
* Need to optimize ALU ops when natural int == int32
*
@@ -3787,6 +3839,7 @@ main (int argc, char *argv [])
mono_install_runtime_class_init (runtime_class_init);
mono_install_runtime_object_init (runtime_object_init);
mono_install_runtime_exec_main (runtime_exec_main);
+ mono_install_runtime_invoke (interp_mono_runtime_invoke);
mono_install_handler (interp_ex_handler);
@@ -1,3 +1,13 @@
+
+Tue Feb 19 20:23:11 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+ * icall.c: register the GetCustomAttributes method.
+ * object.c, object.h: add mono_string_new_len ().
+ * reflection.h, reflection.c: added mono_runtime_invoke(),
+ mono_install_runtime_invoke(). Added
+ mono_reflection_get_custom_attrs () to load custom attributes and
+ create the attribute objects.
+
2002-02-19 Dick Porter <dick@ximian.com>
* threads-dummy-types.c:
* threads-dummy-types.h:
@@ -1011,6 +1011,7 @@ static gpointer icall_map [] = {
"System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
"System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
"System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
+ "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
/* System.Enum */
@@ -251,6 +251,28 @@ mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
return s;
}
+MonoString*
+mono_string_new_len
+(MonoDomain *domain, const char *text, guint length)
+{
+ GError *error = NULL;
+ MonoString *o = NULL;
+ guint16 *ut;
+ glong items_written;
+
+
+ ut = g_utf8_to_utf16 (text, length, NULL, &items_written, &error);
+
+ if (!error)
+ o = mono_string_new_utf16 (domain, ut, items_written);
+ else
+ g_error_free (error);
+
+ g_free (ut);
+
+ return o;
+}
+
/**
* mono_string_new:
* @text: a pointer to an utf8 string
@@ -131,6 +131,9 @@ mono_string_intern (MonoString *str);
MonoString*
mono_string_new (MonoDomain *domain, const char *text);
+MonoString*
+mono_string_new_len (MonoDomain *domain, const char *text, guint length);
+
char *
mono_string_to_utf8 (MonoString *string_obj);
@@ -12,6 +12,7 @@
#include "mono/metadata/reflection.h"
#include "mono/metadata/tabledefs.h"
#include "mono/metadata/tokentype.h"
+#include "mono/metadata/appdomain.h"
#include <stdio.h>
#include <glib.h>
#include <errno.h>
@@ -1864,3 +1865,204 @@ mono_reflection_parse_type (char *name, MonoTypeNameParse *info) {
return 1;
}
+static MonoObject*
+dummy_runtime_invoke (MonoMethod *method, void *obj, void **params)
+{
+ g_error ("runtime invoke called on uninitialized runtime");
+ return NULL;
+}
+
+MonoInvokeFunc mono_default_runtime_invoke = dummy_runtime_invoke;
+
+void
+mono_install_runtime_invoke (MonoInvokeFunc func) {
+ if (func)
+ mono_default_runtime_invoke = func;
+ else
+ mono_default_runtime_invoke = dummy_runtime_invoke;
+}
+
+MonoObject*
+mono_runtime_invoke (MonoMethod *method, void *obj, void **params)
+{
+ return mono_default_runtime_invoke (method, obj, params);;
+}
+
+static void
+fill_param_data (MonoImage *image, MonoMethodSignature *sig, guint32 blobidx, void **params) {
+ int len, i, slen;
+ const char *p = mono_metadata_blob_heap (image, blobidx);
+
+ len = mono_metadata_decode_value (p, &p);
+ if (len < 2 || read16 (p) != 0x0001) /* Prolog */
+ return;
+
+ for (i = 0; i < sig->param_count; ++i) {
+ if (read16 (p) != 0x0001)
+ g_warning ("no prolog in custom attr");
+ p += 2;
+ switch (sig->params [i]->type) {
+ case MONO_TYPE_BOOLEAN: {
+ MonoBoolean *bval = params [i] = g_malloc (sizeof (MonoBoolean));
+ *bval = *p;
+ ++p;
+ break;
+ }
+ case MONO_TYPE_VALUETYPE:
+#if 0
+ if (sig->params [i]->data.klass->enumtype) {
+ /*
+ * FIXME: we should check the unrelying eum type...
+ */
+ g_string_sprintfa (res, "0x%x", read32 (p));
+ p += 4;
+ } else {
+ g_warning ("generic valutype not handled in custom attr value decoding");
+ }
+#endif
+ g_warning ("generic valutype not handled in custom attr value decoding");
+ break;
+ case MONO_TYPE_STRING: {
+ slen = mono_metadata_decode_value (p, &p);
+ params [i] = mono_string_new_len (mono_domain_get (), p, slen);
+ p += slen;
+ break;
+ }
+ default:
+ g_warning ("Type %02x not handled in custom attr value decoding", sig->params [i]->type);
+ break;
+ }
+ }
+}
+
+static void
+free_param_data (MonoMethodSignature *sig, void **params) {
+ int i;
+ for (i = 0; i < sig->param_count; ++i) {
+ switch (sig->params [i]->type) {
+ case MONO_TYPE_BOOLEAN:
+ g_free (params [i]);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * Find the method index in the metadata methodDef table.
+ */
+static guint32
+find_method_index (MonoMethod *method) {
+ MonoClass *klass = method->klass;
+ int i;
+
+ for (i = 0; i < klass->method.count; ++i) {
+ if (method == klass->methods [i]) {
+ guint32 mlist = mono_metadata_decode_row_col (&klass->image->tables [MONO_TABLE_TYPEDEF], mono_metadata_token_index (klass->type_token) - 1, MONO_TYPEDEF_METHOD_LIST);
+ return mlist + i;
+ }
+ }
+ return 0;
+}
+
+MonoArray*
+mono_reflection_get_custom_attrs (MonoObject *obj)
+{
+ guint32 index, mtoken, i;
+ guint32 cols [MONO_CUSTOM_ATTR_SIZE];
+ MonoClass *klass;
+ MonoImage *image;
+ MonoTableInfo *ca;
+ MonoMethod *method;
+ MonoObject *attr;
+ MonoArray *result;
+ GList *list = NULL;
+ void **params;
+
+ klass = obj->vtable->klass;
+ if (klass == mono_defaults.monotype_class) {
+ MonoReflectionType *rtype = (MonoReflectionType*)obj;
+ klass = mono_class_from_mono_type (rtype->type);
+ index = mono_metadata_token_index (klass->type_token);
+ index <<= CUSTOM_ATTR_BITS;
+ index |= CUSTOM_ATTR_TYPEDEF;
+ image = klass->image;
+ } else if (strcmp ("ParameterInfo", klass->name) == 0) {
+ MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
+ MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
+ guint32 method_index = find_method_index (rmethod->method);
+ guint32 param_list, param_last, param_pos, found;
+
+ image = rmethod->method->klass->image;
+ ca = &image->tables [MONO_TABLE_METHOD];
+
+ param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
+ if (method_index == ca->rows) {
+ ca = &image->tables [MONO_TABLE_PARAM];
+ param_last = ca->rows + 1;
+ } else {
+ param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
+ ca = &image->tables [MONO_TABLE_PARAM];
+ }
+ found = 0;
+ for (i = param_list; i < param_list; ++i) {
+ param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
+ if (param_pos == param->PositionImpl) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return mono_array_new (mono_domain_get (), mono_defaults.object_class, 0);
+ index = i;
+ index <<= CUSTOM_ATTR_BITS;
+ index |= CUSTOM_ATTR_PARAMDEF;
+ } else { /* handle other types here... */
+ g_error ("get custom attrs not yet supported for %s", klass->name);
+ }
+
+ /* at this point image and index are set correctly for searching the custom attr */
+ ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+ /* the table is not sorted */
+ for (i = 0; i < ca->rows; ++i) {
+ mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
+ if (cols [MONO_CUSTOM_ATTR_PARENT] != index)
+ continue;
+ mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
+ switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
+ case CUSTOM_ATTR_TYPE_METHODDEF:
+ mtoken |= MONO_TOKEN_METHOD_DEF;
+ break;
+ case CUSTOM_ATTR_TYPE_MEMBERREF:
+ mtoken |= MONO_TOKEN_MEMBER_REF;
+ break;
+ default:
+ g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
+ break;
+ }
+ method = mono_get_method (image, mtoken, NULL);
+ if (!method)
+ g_error ("Can't find custom attr constructor");
+ mono_class_init (method->klass);
+ /*g_print ("got attr %s\n", method->klass->name);*/
+ params = g_new (void*, method->signature->param_count);
+ fill_param_data (image, method->signature, cols [MONO_CUSTOM_ATTR_VALUE], params);
+ attr = mono_object_new (mono_domain_get (), method->klass);
+ mono_runtime_invoke (method, attr, params);
+ list = g_list_prepend (list, attr);
+ free_param_data (method->signature, params);
+ g_free (params);
+ }
+
+ index = g_list_length (list);
+ result = mono_array_new (mono_domain_get (), mono_defaults.object_class, index);
+ for (i = 0; i < index; ++i) {
+ mono_array_set (result, gpointer, i, list->data);
+ list = list->next;
+ }
+ g_list_free (g_list_first (list));
+
+ return result;
+}
+
@@ -298,5 +298,14 @@ MonoReflectionProperty* mono_property_get_object (MonoDomain *domain, MonoClass
/* note: this one is slightly different: we keep the whole array of params in the cache */
MonoReflectionParameter** mono_param_get_objects (MonoDomain *domain, MonoMethod *method);
+
+typedef MonoObject* (*MonoInvokeFunc) (MonoMethod *method, void *obj, void **params);
+
+extern MonoInvokeFunc mono_default_runtime_invoke;
+
+void mono_install_runtime_invoke (MonoInvokeFunc func);
+MonoObject* mono_runtime_invoke (MonoMethod *method, void *obj, void **params);
+MonoArray* mono_reflection_get_custom_attrs (MonoObject *obj);
+
#endif /* __METADATA_REFLECTION_H__ */
@@ -24,6 +24,7 @@ TESTSRC= \
exception4.cs \
exception5.cs \
exception6.cs \
+ exception7.cs \
struct.cs \
valuetype-gettype.cs \
static-constructor.cs \
@@ -34,6 +35,8 @@ TESTSRC= \
enum2.cs \
property.cs \
enumcast.cs \
+ custom-attr.cs \
+ double-cast.cs \
newobj-valuetype.cs \
arraylist-clone.cs \
setenv.cs \
Oops, something went wrong.

0 comments on commit 4479530

Please sign in to comment.