Prechádzať zdrojové kódy

Mon Oct 1 20:43:57 CEST 2001 Paolo Molaro <[email protected]>

	* icall.c: implemented some of the Reflection internalcalls.
	* image.c, image.h: start writing out the PE/COFF image.
	* metadata.h, metadata.c: implement mono_metadata_encode_value ()
	that does the reverse than decode_blob_size ().
	* object.c: use mono_metadata_encode_value (). Move here
	temporary implementation of mono_string_to_utf8 ().
	* rawbuffer.c: make malloc_map static.

svn path=/trunk/mono/; revision=1045
Paolo Molaro 24 rokov pred
rodič
commit
12800ef10b

+ 11 - 0
mono/metadata/ChangeLog

@@ -1,3 +1,14 @@
+
+Mon Oct 1 20:43:57 CEST 2001 Paolo Molaro <[email protected]>
+
+	* icall.c: implemented some of the Reflection internalcalls.
+	* image.c, image.h: start writing out the PE/COFF image.
+	* metadata.h, metadata.c: implement mono_metadata_encode_value ()
+	that does the reverse than decode_blob_size ().
+	* object.c: use mono_metadata_encode_value (). Move here
+	temporary implementation of mono_string_to_utf8 ().
+	* rawbuffer.c: make malloc_map static.
+
 Fri Sep 28 19:26:30 CEST 2001 Paolo Molaro <[email protected]>
 
 	* metadata.c: fix type comparison for arrays.

+ 76 - 6
mono/metadata/icall.c

@@ -10,6 +10,7 @@
 #include <config.h>
 #include <glib.h>
 #include <stdarg.h>
+#include <string.h>
 
 #include <mono/metadata/object.h>
 #include <mono/metadata/threads.h>
@@ -190,28 +191,96 @@ ves_icall_app_get_cur_domain ()
 	return mono_new_object (klass);
 }
 
+static MonoObject *
+my_mono_new_object (MonoClass *klass, gpointer data)
+{
+	MonoClassField *field;
+	MonoObject *res = mono_new_object (klass);
+	gpointer *slot;
+
+	field = mono_class_get_field_from_name (klass, "_impl");
+	slot = (gpointer*)((char*)res + field->offset);
+	*slot = data;
+	return res;
+}
+
+static gpointer
+object_impl_pointer (MonoObject *obj)
+{
+	MonoClassField *field;
+	gpointer *slot;
+
+	field = mono_class_get_field_from_name (obj->klass, "_impl");
+	slot = (gpointer*)((char*)obj + field->offset);
+	return *slot;
+}
+
+
 static MonoObject *
 ves_icall_app_define_assembly (MonoObject *appdomain, MonoObject *assembly_name, int access)
 {
 	MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "AssemblyBuilder");
+	MonoDynamicAssembly *ass = g_new0 (MonoDynamicAssembly, 1);
+	MonoClassField *field;
+	MonoObject *name;
 
-	return mono_new_object (klass);
+	field = mono_class_get_field_from_name (assembly_name->klass, "name");
+	name = (MonoObject*)((char*)assembly_name + field->offset);
+
+	ass->name = mono_string_to_utf8 (name);
+
+	return my_mono_new_object (klass, ass);
 }
 
-static MonoObject *
-ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
+static gint32
+ves_icall_get_data_chunk (MonoObject *assb, gint32 type, MonoArrayObject *buf)
 {
-	MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
+	MonoDynamicAssembly *ass = object_impl_pointer (assb);
+	int count;
 
-	return mono_new_object (klass);
+	count = mono_image_get_header (ass, buf->vector, buf->bounds->length);
+	if (count != -1)
+		return count;
+	
+	return 0;
 }
 
 static MonoObject *
 ves_icall_define_module (MonoObject *assb, MonoObject *name, MonoObject *fname)
 {
 	MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "ModuleBuilder");
+	MonoModuleBuilder *mb = g_new0 (MonoModuleBuilder, 1);
+	MonoDynamicAssembly *ass = object_impl_pointer (assb);
+	ass->modules = g_list_prepend (ass->modules, mb);
 
-	return mono_new_object (klass);
+	mb->name = mono_string_to_utf8 (name);
+	mb->fname = mono_string_to_utf8 (fname);
+
+	return my_mono_new_object (klass, mb);
+}
+
+static MonoObject *
+ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
+{
+	MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
+	MonoTypeBuilder *tb = g_new0 (MonoTypeBuilder, 1);
+	MonoModuleBuilder *mb = object_impl_pointer (moduleb);
+	char *nspace = mono_string_to_utf8 (name);
+	char *name = strrchr (nspace, '.');
+	
+	if (name) {
+		*name = 0;
+		name++;
+	} else {
+		nspace = "";
+	}
+	
+	tb->name = name;
+	tb->nspace = nspace;
+	tb->attrs = attrs;
+	mb->types = g_list_prepend (mb->types, tb);
+
+	return my_mono_new_object (klass, tb);
 }
 
 static MonoObject *
@@ -261,6 +330,7 @@ static gpointer icall_map [] = {
 	 * AssemblyBuilder
 	 */
 	"System.Reflection.Emit.AssemblyBuilder::defineModule", ves_icall_define_module,
+	"System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk,
 	
 	/*
 	 * TypeBuilder

+ 33 - 0
mono/metadata/image.c

@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <glib.h>
 #include <errno.h>
+#include <time.h>
 #include <string.h>
 #include "image.h"
 #include "cil-coff.h"
@@ -366,6 +367,38 @@ load_class_names (MonoImage *image) {
 	}
 }
 
+int
+mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
+{
+	MonoMSDOSHeader *msdos;
+	MonoDotNetHeader *header;
+
+	if (maxsize < sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader))
+		return -1;
+
+	memset (buffer, 0, sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader));
+
+	msdos = (MonoMSDOSHeader *)buffer;
+	header = (MonoDotNetHeader *)(buffer + sizeof (MonoMSDOSHeader));
+
+	/* FIXME: byteswap as needed */
+	msdos->msdos_header [0] = 'M';
+	msdos->msdos_header [1] = 'Z';
+
+	msdos->pe_offset = sizeof (MonoMSDOSHeader);
+
+	header->coff.coff_machine = 0x14c;
+	header->coff.coff_time = time (NULL);
+	header->coff.coff_opt_header_size = sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4;
+	header->pe.pe_magic = 0x10B;
+	header->pe.pe_major = 6;
+	header->pe.pe_minor = 0;
+
+	/* Write section tables */
+
+	return sizeof (MonoMSDOSHeader) + sizeof (MonoDotNetHeader);
+}
+
 static MonoImage *
 do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
 {

+ 33 - 0
mono/metadata/image.h

@@ -12,6 +12,38 @@ typedef struct {
 	/* Load files here */
 } MonoAssembly;
 
+typedef struct {
+	char *name;
+	char *data;
+	guint32 length;
+	guint32 data_size; /* malloced bytes */
+	guint32 offset;
+} MonoDynamicStream;
+
+typedef struct {
+	char *name;
+	char *fname;
+	GList *types;
+} MonoModuleBuilder;
+
+typedef struct {
+	char *name;
+	char *nspace;
+	int attrs;
+	GList *methods;
+} MonoTypeBuilder;
+
+typedef struct {
+	char *name;
+	MonoAssembly *assembly;
+	GList *modules;
+	MonoDynamicStream strings;
+	MonoDynamicStream us;
+	MonoDynamicStream blob;
+	MonoDynamicStream tables;
+	MonoDynamicStream guid;
+} MonoDynamicAssembly;
+
 typedef struct {
 	guint32  offset;
 	guint32  size;
@@ -104,4 +136,5 @@ int           mono_image_ensure_section     (MonoImage *image,
 int           mono_image_ensure_section_idx (MonoImage *image,
 					     int section);
 	
+int           mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize);
 #endif

+ 22 - 0
mono/metadata/metadata.c

@@ -1883,3 +1883,25 @@ mono_metadata_signature_equal (MonoMethodSignature *sig1, MonoMethodSignature *s
 	return TRUE;
 }
 
+void
+mono_metadata_encode_value (guint32 value, char *buf, char **endbuf)
+{
+	char *p = buf;
+	
+	if (value <= 127)
+		*p++ = 127;
+	else if (value <= 16384) {
+		p [0] = 0x80 | (value >> 8);
+		p [1] = value & 0xff;
+		p += 2;
+	} else {
+		p [0] = (value >> 24) | 0xc0;
+		p [1] = (value >> 16) & 0xff;
+		p [2] = (value >> 8) & 0xff;
+		p [3] = value & 0xff;
+		p += 4;
+	}
+	if (endbuf)
+		*endbuf = p;
+}
+

+ 2 - 0
mono/metadata/metadata.h

@@ -118,6 +118,8 @@ guint32 mono_metadata_decode_value     (const char            *ptr,
 guint32 mono_metadata_decode_blob_size (const char            *ptr,
                                         const char           **rptr);
 
+void mono_metadata_encode_value (guint32 value, char *bug, char **endbuf);
+
 typedef struct {
 	guint32 flags;
 	guint32 try_offset;

+ 29 - 14
mono/metadata/object.c

@@ -302,20 +302,7 @@ mono_string_intern (MonoObject *o)
 	
 	/* Encode the length */
 	p = ins;
-	if (str->length <= 127)
-		*p++ = 127;
-	else if (str->length <= 16384) {
-		p [0] = 0x80 | (str->length >> 8);
-		p [1] = str->length & 0xff;
-		p += 2;
-	} else {
-		guint32 l = str->length;
-		p [0] = (l >> 24) | 0xc0;
-		p [1] = (l >> 16) & 0xff;
-		p [2] = (l >> 8) & 0xff;
-		p [3] = l & 0xff;
-		p += 4;
-	}
+	mono_metadata_encode_value (str->length, p, &p);
 	memcpy (p, str->c_str->vector, str->length * 2);
 	
 	if ((res = g_hash_table_lookup (ldstr_table, str))) {
@@ -348,3 +335,31 @@ mono_ldstr (MonoImage *image, guint32 index)
 	return o;
 }
 
+char *
+mono_string_to_utf8 (MonoObject *o)
+{
+	MonoStringObject *s = (MonoStringObject *)o;
+	char *as, *vector;
+	int i;
+
+	g_assert (o != NULL);
+
+	if (!s->length)
+		return g_strdup ("");
+
+	vector = s->c_str->vector;
+
+	g_assert (vector != NULL);
+
+	as = g_malloc (s->length + 1);
+
+	/* fixme: replace with a real unicode/ansi conversion */
+	for (i = 0; i < s->length; i++) {
+		as [i] = vector [i*2];
+	}
+
+	as [i] = '\0';
+
+	return as;
+}
+

+ 3 - 0
mono/metadata/object.h

@@ -48,6 +48,9 @@ mono_string_intern          (MonoObject *o);
 MonoObject *
 mono_new_string             (const char *text);
 
+char *
+mono_string_to_utf8         (MonoObject *string_obj);
+
 void       
 mono_object_free            (MonoObject *o);
 

+ 2 - 2
mono/metadata/rawbuffer.c

@@ -15,7 +15,7 @@
 
 #define PAGESIZE 8192
 
-GHashTable *malloc_map;
+static GHashTable *malloc_map = NULL;
 
 void *
 mono_raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
@@ -34,7 +34,7 @@ mono_raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
 	end = (base + size + PAGESIZE - 1) & ~(PAGESIZE - 1);
 
 	/*
-	 * Apparently on cygwin the mmpa succedes, but not all the
+	 * Apparently on cygwin the mmap succedes, but not all the
 	 * area is mapped in and we get segfaults later.
 	 */
 #ifdef __CYGWIN__

+ 0 - 1
mono/tests/codegen.cs

@@ -20,7 +20,6 @@ class CGen {
 		abuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save);
 
 		mbuilder = abuilder.DefineDynamicModule (name, name);
-		abuilder.Save(name);
 
 		tbuilder = mbuilder.DefineType ("Test.CodeGen", attrs);
 		Type result = typeof(int);