Skip to content

Commit

Permalink
Tue Feb 19 20:23:11 CET 2002 Paolo Molaro <lupus@ximian.com>
Browse files Browse the repository at this point in the history
	* 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
illupus committed Feb 19, 2002
1 parent 12baa90 commit 4479530
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 2 deletions.
4 changes: 4 additions & 0 deletions mono/interpreter/ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
53 changes: 53 additions & 0 deletions mono/interpreter/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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);

Expand Down
10 changes: 10 additions & 0 deletions mono/metadata/ChangeLog
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
1 change: 1 addition & 0 deletions mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
22 changes: 22 additions & 0 deletions mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions mono/metadata/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
202 changes: 202 additions & 0 deletions mono/metadata/reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
}

9 changes: 9 additions & 0 deletions mono/metadata/reflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

3 changes: 3 additions & 0 deletions mono/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ TESTSRC= \
exception4.cs \
exception5.cs \
exception6.cs \
exception7.cs \
struct.cs \
valuetype-gettype.cs \
static-constructor.cs \
Expand All @@ -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 \
Expand Down
Loading

0 comments on commit 4479530

Please sign in to comment.