+2003-04-17 Jackson Harper <jackson@latitudegeo.com>
+
+ * TypeRef.cs: Rewrite - Typerefs are now resolved after parsing.
+ * TypeManager.cs: Rewrite - Just a simple table for looking up
+ typedefs
+ * ExternTable.cs: Create ClassRef's instead of Classes
+ * Location.cs: Make compile
+ * CodeGen.cs: Use new tree system
+
2003-04-17 Jackson Harper <jackson@latitudegeo.com>
* ExternTypeRef.cs: New file - Represents a reference to a type in
private PEFile pefile;\r
\r
private string current_namespace;\r
- private ClassDef current_class;\r
- private Stack class_name_stack;\r
- private MethodDef current_method;\r
- private CILInstructions code_buffer;\r
+ private TypeDef current_typedef;\r
+ private Stack typedef_stack;\r
\r
- private ClassTable class_table;\r
+ private TypeManager type_manager;\r
private ExternTable extern_table;\r
+ private ArrayList global_field_list;\r
\r
public CodeGen (string output_file, bool is_dll, bool is_assembly)\r
{\r
pefile = new PEFile (output_file, is_dll, is_assembly);\r
- class_table = new ClassTable (pefile);\r
+ type_manager = new TypeManager (this);\r
extern_table = new ExternTable (pefile);\r
- class_name_stack = new Stack ();\r
+ typedef_stack = new Stack ();\r
+ global_field_list = new ArrayList ();\r
}\r
\r
public PEFile PEFile {\r
set { current_namespace = value; }\r
}\r
\r
- public ClassDef CurrentClass {\r
- get { return current_class; }\r
- set { current_class = value; }\r
- }\r
-\r
- public MethodDef CurrentMethod {\r
- get { return current_method; }\r
- set { current_method = value; }\r
- }\r
-\r
- public CILInstructions CodeBuffer {\r
- get { return code_buffer; }\r
- }\r
-\r
- public ClassTable ClassTable {\r
- get { return class_table; }\r
+ public TypeDef CurrentTypeDef {\r
+ get { return current_typedef; }\r
+ set { current_typedef = value; }\r
}\r
\r
public ExternTable ExternTable {\r
get { return extern_table; }\r
}\r
\r
- public void AddClass (TypeAttr at, string name, Location location)\r
- {\r
- if (class_name_stack.Count > 0)\r
- name = (string) class_name_stack.Peek () + '/' + name;\r
-\r
- current_class = class_table.AddDefinition (current_namespace, name, at, location);\r
- class_name_stack.Push (name);\r
+ public TypeManager TypeManager {\r
+ get { return type_manager; }\r
}\r
\r
- public void AddClass (TypeAttr at, string name, Class parent, Location location)\r
+ public void BeginTypeDef (TypeAttr attr, string name, IClassRef parent,\r
+ ArrayList impl_list, Location location)\r
{\r
- if (class_name_stack.Count > 0)\r
- name = (string) class_name_stack.Peek () + '/' + name;\r
+ if (typedef_stack.Count > 0)\r
+ name = (string) typedef_stack.Peek () + '/' + name;\r
\r
- current_class = class_table.AddDefinition (current_namespace, name,\r
- at, parent, location);\r
- class_name_stack.Push (name);\r
- }\r
+ TypeDef typedef = type_manager[name];\r
\r
- public void CompleteClass ()\r
- {\r
- class_name_stack.Pop ();\r
- current_class = null;\r
- }\r
+ if (typedef != null) {\r
+ // Class head is allready defined, we are just reopening the class\r
+ current_typedef = typedef;\r
+ typedef_stack.Push (current_typedef);\r
+ return;\r
+ }\r
\r
- public void AddMethod (MethAttr method_attr, ImplAttr impl_attr, CallConv call_conv, string name,\r
- TypeRef return_type, Param[] param_list, TypeRef[] param_type_list, Location location)\r
- {\r
- MethodTable method_table = class_table.GetMethodTable (current_class.Name, location);\r
- current_method = method_table.AddDefinition (method_attr, impl_attr, call_conv, name,\r
- return_type, param_list, param_type_list, location);\r
- code_buffer = current_method.CreateCodeBuffer ();\r
+ typedef = new TypeDef (attr, current_namespace,\r
+ name, parent, impl_list, location);\r
+\r
+ type_manager[typedef.FullName] = typedef;\r
+ current_typedef = typedef;\r
+ typedef_stack.Push (typedef);\r
}\r
\r
- public Method GetMethodRef (TypeRef type, string name, TypeRef return_type,\r
- Param[] param_list, TypeRef[] param_type_list, Location location)\r
+ public void AddFieldDef (FieldDef fielddef)\r
{\r
- MethodTable method_table = class_table.GetMethodTable (type.FullName, location);\r
-\r
- return method_table.GetReference (name, return_type, param_list, param_type_list, location);\r
+ if (current_typedef != null) {\r
+ current_typedef.AddFieldDef (fielddef);\r
+ } else {\r
+ global_field_list.Add (fielddef);\r
+ }\r
}\r
\r
- public FieldDef AddField (FieldAttr attr, string name, TypeRef type, Location location)\r
+ public void EndTypeDef ()\r
{\r
- FieldTable field_table = class_table.GetFieldTable (current_class.Name, location);\r
-\r
- return field_table.AddDefinition (attr, name, type, location);\r
+ typedef_stack.Pop ();\r
+ current_typedef = null;\r
}\r
\r
- public Field GetFieldRef (TypeRef parent, TypeRef type, string name, Location location)\r
+ public void Write ()\r
{\r
- FieldTable field_table = class_table.GetFieldTable (type.FullName, location);\r
+ type_manager.DefineAll ();\r
\r
- return field_table.GetReference (type, name, location);\r
+ foreach (FieldDef fielddef in global_field_list) {\r
+ fielddef.Define (this);\r
+ }\r
+\r
+ pefile.WritePEFile ();\r
}\r
+\r
}\r
\r
}\r
AssemblyRef = pefile.AddExternAssembly (name);
}
- public PEAPI.Class GetType (string name_space, string name)
+ public PEAPI.ClassRef GetType (string name_space, string name)
{
string full_name = String.Format ("{0}.{1}",
name_space, name);
- PEAPI.Class klass = type_table[full_name] as PEAPI.Class;
+ PEAPI.ClassRef klass = type_table[full_name] as PEAPI.ClassRef;
if (klass != null)
return klass;
- klass = AssemblyRef.AddClass (name_space, name);
+ klass = (PEAPI.ClassRef) AssemblyRef.AddClass (name_space, name);
type_table[full_name] = klass;
return klass;
assembly_table[name] = new ExternAssembly (pefile, name, asmb_name);
}
- public PEAPI.Class GetClass (string asmb_name, string name_space, string name)
+ public PEAPI.ClassRef GetClass (string asmb_name, string name_space, string name)
{
ExternAssembly ext_asmb;
ext_asmb = assembly_table[asmb_name] as ExternAssembly;
return ext_asmb.GetType (name_space, name);
}
- public PEAPI.Class GetClass (string asmb_name, string full_name)
+ public PEAPI.ClassRef GetClass (string asmb_name, string full_name)
{
ExternAssembly ext_asmb;
ext_asmb = assembly_table[asmb_name] as ExternAssembly;
string name_space, name;
- ClassTable.GetNameAndNamespace (full_name, out name_space, out name);
+ GetNameAndNamespace (full_name, out name_space, out name);
return ext_asmb.GetType (name_space, name);
}
+ public static void GetNameAndNamespace (string full_name,
+ out string name_space, out string name) {
+
+ int last_dot = full_name.LastIndexOf ('.');
+
+ if (last_dot < 0) {
+ name_space = String.Empty;
+ name = full_name;
+ return;
+ }
+
+ name_space = full_name.Substring (0, last_dot);
+ name = full_name.Substring (last_dot + 1);
+ }
+
}
}
namespace Mono.ILASM {
- /// TODO: This class will eventually store il file location info,
- /// like line and col
- public class Location ()
- {
+ /// TODO: This class will eventually store il file location info,
+ /// like line and col
+ public class Location
+ {
- }
+ }
}
//
using System;
-using System.Reflection;
using System.Collections;
namespace Mono.ILASM {
- public class TypeManager {
+ public class TypeManager {
- private Hashtable type_table;
+ private Hashtable type_table;
+ private CodeGen code_gen;
- public TypeManager ()
- {
+ public TypeManager (CodeGen code_gen)
+ {
+ this.code_gen = code_gen;
+ type_table = new Hashtable ();
+ Hashtable t = type_table;
+ }
- type_table = new Hashtable ();
- Hashtable t = type_table;
+ public TypeDef this[string full_name] {
+ get {
+ return (TypeDef) type_table[full_name];
+ }
+ set {
+ type_table[full_name] = value;
+ }
+ }
- // Add the default types
- t ["object"] = Type.GetType ("System.Object");
- t ["string"] = Type.GetType ("System.String");
- t ["char"] = Type.GetType ("System.Char");
- t ["void"] = Type.GetType ("System.Void");
- t ["bool"] = Type.GetType ("System.Boolean");
- t ["int8"] = Type.GetType ("System.Byte");
- t ["int16"] = Type.GetType ("System.Int16");
- t ["int32"] = Type.GetType ("System.Int32");
- t ["int64"] = Type.GetType ("System.Int64");
- t ["float32"] = Type.GetType ("System.Single");
- t ["float64"] = Type.GetType ("System.Double");
- t ["uint8"] = Type.GetType ("System.SByte");
- t ["uint16"] = Type.GetType ("System.UInt16");
- t ["uint32"] = Type.GetType ("System.UInt32");
- t ["uint64"] = Type.GetType ("System.UInt64");
- }
+ public PEAPI.Type GetPeapiType (string full_name)
+ {
+ TypeDef type_def = (TypeDef) type_table[full_name];
- public Type this [string type_name] {
- get {
- Type return_type = (Type)type_table[type_name];
-
- if (return_type == null) {
- return_type = LoadType (type_name);
- type_table[type_name] = return_type;
- }
- return return_type;
- }
- set {
- type_table[type_name] = value;
- }
- }
+ if (type_def == null)
+ return null;
- /// TODO: Use AssemblyStore, and load types in the same assembly
- private Type LoadType (string type_name) {
- string assembly_name;
- string real_name;
- Assembly assembly;
- int bracket_start, bracket_end;
+ type_def.Define (code_gen);
- bracket_start = type_name.IndexOf ('[');
- bracket_end = type_name.IndexOf (']');
-
- if ((bracket_start == -1) || (bracket_end == -1))
- return null;
+ return type_def.PeapiType;
+ }
- assembly_name = type_name.Substring (bracket_start+1, bracket_end-1);
- real_name = type_name.Substring (bracket_end+1);
+ public void DefineAll ()
+ {
+ foreach (TypeDef typedef in type_table.Values) {
+ typedef.Define (code_gen);
+ }
+ }
- assembly = Assembly.LoadWithPartialName (assembly_name);
- return assembly.GetType (real_name);
-
- }
+ }
- }
-
}
// (C) 2003 Jackson Harper, All rights reserved
//
-using PEAPI;
using System;
-
+using System.Collections;
namespace Mono.ILASM {
- public class TypeRef {
+ /// <summary>
+ /// Reference to a type in the module being compiled.
+ /// </summary>
+ public class TypeRef : IClassRef {
+
+ private enum ConversionMethod {
+ MakeArray,
+ MakeBoundArray,
+ MakeManagedPointer,
+ MakeUnmanagedPointer,
+ MakeCustomModified
+ }
+
+ private Location location;
+ private string full_name;
+ private PEAPI.Type resolved_type;
+ private ArrayList conversion_list;
+ private bool is_pinned;
+
+ private bool is_resolved;
+
+ public TypeRef (string full_name, Location location)
+ {
+ this.full_name = full_name;
+ this.location = location;
+ is_pinned = false;
+ conversion_list = new ArrayList ();
+ is_resolved = false;
+ }
+
+ public string FullName {
+ get { return full_name; }
+ }
+
+ public bool IsPinned {
+ get { return is_pinned; }
+ }
+
+ public PEAPI.Type PeapiType {
+ get { return resolved_type; }
+ }
- public readonly PEAPI.Type Type;
- public readonly string FullName;
+ public PEAPI.Class PeapiClass {
+ get { return resolved_type as PEAPI.Class; }
+ }
+
+ public bool IsResolved {
+ get { return is_resolved; }
+ }
- public bool Pinned;
+ public void MakeArray ()
+ {
+ conversion_list.Add (ConversionMethod.MakeArray);
+ }
+
+ public void MakeBoundArray (ArrayList bounds)
+ {
+ conversion_list.Add (ConversionMethod.MakeBoundArray);
+ conversion_list.Add (bounds);
+ }
- public TypeRef (PEAPI.Type type, string full_name)
+ public void MakeManagedPointer ()
{
- Type = type;
- FullName = full_name;
- Pinned = false;
+ conversion_list.Add (ConversionMethod.MakeManagedPointer);
+ }
+
+ public void MakeUnmanagedPointer ()
+ {
+ conversion_list.Add (ConversionMethod.MakeUnmanagedPointer);
+ }
+
+ public void MakeCustomModified (PEAPI.CustomModifier modifier)
+ {
+ conversion_list.Add (ConversionMethod.MakeCustomModified);
+ conversion_list.Add (modifier);
+ }
+
+ public void MakePinned ()
+ {
+ is_pinned = true;
+ }
+
+ public void Resolve (CodeGen code_gen)
+ {
+ if (is_resolved)
+ return;
+
+ PEAPI.Type base_type;
+ PeapiTypeRef peapi_type;
+ int count = conversion_list.Count;
+
+ base_type = code_gen.TypeManager.GetPeapiType (full_name);
+
+ /// TODO: Proper error message
+ if (base_type == null) {
+ Console.WriteLine ("Type not defined: {0} {1}", full_name, location);
+ return;
+ }
+
+ peapi_type = new PeapiTypeRef (base_type, full_name);
+
+ for (int i=0; i<count; i++) {
+ switch ((ConversionMethod) conversion_list[i]) {
+ case ConversionMethod.MakeArray:
+ peapi_type.MakeArray ();
+ break;
+ case ConversionMethod.MakeBoundArray:
+ peapi_type.MakeBoundArray ((ArrayList) conversion_list[++i]);
+ break;
+ case ConversionMethod.MakeManagedPointer:
+ peapi_type.MakeManagedPointer ();
+ break;
+ case ConversionMethod.MakeUnmanagedPointer:
+ peapi_type.MakeUnmanagedPointer ();
+ break;
+ case ConversionMethod.MakeCustomModified:
+ peapi_type.MakeCustomModified ((PEAPI.CustomModifier) conversion_list[++i]);
+ break;
+ }
+ }
+
+ resolved_type = peapi_type.PeapiType;
+
+ is_resolved = true;
}
public override string ToString ()
}
-
-