singrdk/base/Windows/csic/emit/emit.cs

956 lines
39 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
public class emit {
public MessageWriter msg;
protected TextWriter w;
public BuiltinTypes T;
protected Hashtable map;
public ModuleBuilder module;
public emit(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder module) {
this.w = w;
this.msg = msg;
this.map = map;
this.module = module;
}
static void init(BuiltinTypes T, Hashtable map) {
map.Add(T.Bool, System.Type.GetType("System.Boolean"));
map.Add(T.Byte, System.Type.GetType("System.Byte"));
map.Add(T.Char, System.Type.GetType("System.Char"));
map.Add(T.Decimal, System.Type.GetType("System.Decimal"));
map.Add(T.Double, System.Type.GetType("System.Double"));
map.Add(T.Float, System.Type.GetType("System.Single"));
map.Add(T.Int, System.Type.GetType("System.Int32"));
map.Add(T.Long, System.Type.GetType("System.Int64"));
map.Add(T.Object, System.Type.GetType("System.Object"));
map.Add(T.SByte, System.Type.GetType("System.SByte"));
map.Add(T.Short, System.Type.GetType("System.Int16"));
map.Add(T.String, System.Type.GetType("System.String"));
map.Add(T.UInt, System.Type.GetType("System.UInt32"));
map.Add(T.ULong, System.Type.GetType("System.UInt64"));
map.Add(T.UShort, System.Type.GetType("System.UInt16"));
map.Add(T.Void, System.Type.GetType("System.Void"));
}
public static object visit(object ast, TextWriter w, string[] args, MessageWriter msg) {
if (msg.Count == 0) {
Hashtable map = new Hashtable();
init(((compilation)ast).global.Types, map);
emit1 pass1 = new emit1(w, msg, map);
AssemblyBuilder asm = pass1.compilation((compilation)ast);
(new emit2(w, msg, map, pass1.module)).compilation((compilation)ast);
(new emit3(w, msg, map, pass1.module)).compilation((compilation)ast);
return asm;
}
return ast;
}
public FieldAttributes GetFieldAttributes(stringList modifiers) {
FieldAttributes attr = 0;
foreach (string mod in modifiers)
switch (mod) {
case "private": attr |= FieldAttributes.Private; break;
case "public": attr |= FieldAttributes.Public; break;
case "protected":
if (modifiers.Contains("internal"))
attr |= FieldAttributes.FamORAssem;
else
attr |= FieldAttributes.Family;
break;
case "internal":
if (modifiers.Contains("protected"))
attr |= FieldAttributes.FamORAssem;
else
attr |= FieldAttributes.Assembly;
break;
case "static": attr |= FieldAttributes.Static; break;
}
return attr;
}
public MethodAttributes GetMethodAttributes(stringList modifiers) {
MethodAttributes attr = 0;
foreach (string mod in modifiers)
switch (mod) {
case "private": attr |= MethodAttributes.Private; break;
case "public": attr |= MethodAttributes.Public; break;
case "protected":
if (modifiers.Contains("internal"))
attr |= MethodAttributes.FamORAssem;
else
attr |= MethodAttributes.Family;
break;
case "internal":
if (modifiers.Contains("protected"))
attr |= MethodAttributes.FamORAssem;
else
attr |= MethodAttributes.Assembly;
break;
case "static": attr |= MethodAttributes.Static; break;
case "override":
case "virtual": attr |= MethodAttributes.Virtual; break;
case "new": attr |= MethodAttributes.NewSlot; break;
case "abstract": attr |= MethodAttributes.Abstract; break;
case "sealed": attr |= MethodAttributes.Final; break;
}
return attr;
}
public TypeAttributes GetTypeAttributes(Type t) {
TypeAttributes attr = 0;
foreach (string mod in t.Modifiers)
switch (mod) {
case "private":
attr |= t.IsNested ? TypeAttributes.NestedPrivate : TypeAttributes.NotPublic; break;
case "public":
attr |= t.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public; break;
case "protected":
if (t.IsNested)
attr |= t.Modifiers.Contains("internal") ? TypeAttributes.NestedFamORAssem : TypeAttributes.NestedFamily;
break;
case "internal":
if (t.IsNested)
attr |= t.Modifiers.Contains("protected") ? TypeAttributes.NestedFamORAssem : TypeAttributes.NestedAssembly;
break;
case "sealed": attr |= TypeAttributes.Sealed; break;
case "abstract": attr |= TypeAttributes.Abstract; break;
}
return attr;
}
static System.Type GetTypeFromAssembly(Type ty, string assembly) {
Assembly asm = Assembly.LoadFrom(assembly); // may throw
System.Type type = asm.GetType(ty.RealName);
Debug.Assert(type != null);
return type;
}
public FieldInfo this[Field f] {
get {
FieldInfo info = (FieldInfo)map[f];
if (info == null) {
Type ty = f.GetType();
System.Type type = this[ty];
BindingFlags flags = 0;
flags |= f.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
flags |= f.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
info = type.GetField(f.Name, flags);
if (info != null)
map.Add(f, info);
}
Debug.Assert(info != null);
return info;
}
}
public ConstructorInfo this[Constructor m] {
get {
ConstructorInfo info = (ConstructorInfo)map[m];
if (info == null) {
Type ty = m.GetType();
System.Type type = this[ty];
BindingFlags flags = m.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
System.Type[] args = new System.Type[m.ArgCount];
for (int i = 0; i < m.ArgCount; i++)
args[i] = this[m[i].Type];
info = type.GetConstructor(flags|BindingFlags.Instance, null, args, null);
if (info != null)
map.Add(m, info);
}
Debug.Assert(info != null);
return info;
}
}
public MethodInfo this[Method m] {
get {
MethodInfo info = (MethodInfo)map[m];
if (info == null) {
Type ty = m.GetType();
System.Type type = this[ty];
BindingFlags flags = 0;
flags |= m.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
flags |= m.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic;
System.Type[] args = new System.Type[m.ArgCount];
for (int i = 0; i < m.ArgCount; i++)
args[i] = this[m[i].Type];
info = type.GetMethod(m.Name, flags, null, args, null);
if (info != null)
map.Add(m, info);
}
Debug.Assert(info != null);
return info;
}
}
public System.Type this[PointerType ty] {
get {
System.Type type, etype = this[ty.elementType];
if (ty.elementType.module != null)
type = GetTypeFromAssembly(ty, ty.elementType.module);
else
type = module.GetType(etype.FullName + "&");
Debug.Assert(type != null);
return type;
}
}
public System.Type this[ArrayType ty] {
get {
System.Type type, etype = this[ty.elementType];
if (ty.elementType.module != null)
type = GetTypeFromAssembly(ty, ty.elementType.module);
else
type = module.GetType(string.Format("{0}[{1}]", etype.FullName, "".PadRight(ty.rank - 1, ',')));
Debug.Assert(type != null);
return type;
}
}
public System.Type this[Type ty] {
get {
if (ty is ArrayType)
return this[(ArrayType)ty];
else if (ty is PointerType)
return this[(PointerType)ty];
System.Type type = (System.Type)map[ty];
if (type != null)
return type;
if (ty.module != null)
return GetTypeFromAssembly(ty, ty.module);
type = System.Type.GetType(ty.RealName);
if (type == null)
type = module.GetType(ty.RealName);
if (type != null)
map.Add(ty, type);
if (type == null)
System.Console.WriteLine(ty.RealName);
Debug.Assert(type != null);
return type;
}
}
public virtual System.Type type(type ast) {
return this[ast.sym];
}
}
public class emit1: emit {
public emit1(TextWriter w, MessageWriter msg, Hashtable map) : base(w, msg, map, null) {}
public virtual void class_declaration(class_declaration ast, ModuleBuilder m) {
if (ast.parent is type_declaration) {
TypeBuilder t = ((type_declaration)ast.parent).builder;
ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Class);
} else
ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Class);
map.Add(ast.sym, ast.type);
foreach (declaration x in ast.body)
declaration(x, m);
}
public virtual AssemblyBuilder compilation(compilation ast) {
T = ast.global.Types;
AssemblyName name = new AssemblyName();
if (ast.inputs.Count > 0 && ast.inputs[0].begin.file != null
&& ast.inputs[0].begin.file != "<stream>")
name.Name = Path.GetFileNameWithoutExtension(ast.inputs[0].begin.file);
else
name.Name = Guid.NewGuid().ToString();
AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
string oname = name.Name;
foreach (string s in ast.args)
if (s[0] == '/' || s[0] == '-') {
string arg = s.Substring(1);
if (arg.StartsWith("out:"))
oname = arg.Substring(4);
}
foreach (compilation_unit x in ast.inputs)
compilation_unit(x, asm, oname);
return asm;
}
public virtual void compilation_unit(compilation_unit ast, AssemblyBuilder asm, string name) {
module = asm.DefineDynamicModule(asm.GetName().Name, name, true);
foreach (declaration x in ast.declarations)
declaration(x, module);
}
public virtual void declaration(declaration ast, ModuleBuilder m) {
if (ast is class_declaration) class_declaration((class_declaration)ast, m);
else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast, m);
else if (ast is enum_declaration) enum_declaration((enum_declaration)ast, m);
else if (ast is interface_declaration) interface_declaration((interface_declaration)ast, m);
else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast, m);
else if (ast is struct_declaration) struct_declaration((struct_declaration)ast, m);
}
public virtual void delegate_declaration(delegate_declaration ast, ModuleBuilder m) {
if (ast.parent is type_declaration) {
TypeBuilder t = ((type_declaration)ast.parent).builder;
ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym));
} else
ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym));
map.Add(ast.sym, ast.type);
}
public virtual void enum_declaration(enum_declaration ast, ModuleBuilder m) {
ast.type = m.DefineEnum(ast.sym.FullName, GetTypeAttributes(ast.sym), System.Type.GetType("System.Int32"));
map.Add(ast.sym, ast.type);
}
public virtual void interface_declaration(interface_declaration ast, ModuleBuilder m) {
if (ast.parent is type_declaration) {
TypeBuilder t = ((type_declaration)ast.parent).builder;
ast.type = t.DefineNestedType(ast.sym.FullName,
GetTypeAttributes(ast.sym)|TypeAttributes.Interface|TypeAttributes.Abstract);
} else
ast.type = m.DefineType(ast.sym.FullName,
GetTypeAttributes(ast.sym)|TypeAttributes.Interface|TypeAttributes.Abstract);
map.Add(ast.sym, ast.type);
foreach (declaration x in ast.body)
declaration(x, m);
}
public virtual void namespace_body(namespace_body ast, ModuleBuilder m) {
foreach (declaration x in ast.declarations)
declaration(x, m);
}
public virtual void namespace_declaration(namespace_declaration ast, ModuleBuilder m) {
namespace_body(ast.nb, m);
}
public virtual void struct_declaration(struct_declaration ast, ModuleBuilder m) {
if (ast.parent is type_declaration) {
TypeBuilder t = ((type_declaration)ast.parent).builder;
ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym));
} else
ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym));
map.Add(ast.sym, ast.type);
foreach (declaration x in ast.body)
declaration(x, m);
}
}
public class emit2: emit {
public emit2(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder mod) : base(w, msg, map, mod) {}
public virtual void binary_declarator(binary_declarator ast, TypeBuilder t) {
}
public virtual void class_declaration(class_declaration ast) {
TypeBuilder t = ast.builder;
t.SetParent(this[ast.sym.baseClass]);
foreach (Type x in ast.sym.interfaces)
t.AddInterfaceImplementation(this[x]);
foreach (declaration x in ast.body)
declaration(x, t);
}
public virtual void compilation(compilation ast) {
T = ast.global.Types;
foreach (compilation_unit x in ast.inputs)
compilation_unit(x);
}
public virtual void compilation_unit(compilation_unit ast) {
foreach (declaration x in ast.declarations)
declaration(x);
}
public virtual void constant_declaration(constant_declaration ast, TypeBuilder t) {
foreach (const_declarator x in ast.decls) {
FieldBuilder f = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers));
f.SetConstant(x.sym.value);
map.Add(x.sym, f);
x.builder = f;
}
}
public virtual void constructor_declaration(constructor_declaration ast, TypeBuilder t) {
System.Type[] args = new System.Type[ast.sym.ArgCount];
for (int i = 0; i < ast.sym.ArgCount; i++)
args[i]= this[ast.sym[i].Type];
ConstructorBuilder m = t.DefineConstructor(GetMethodAttributes(ast.sym.Modifiers), CallingConventions.Standard, args);
for (int i = 0; i < ast.sym.ArgCount; i++) {
Formal f = ast.sym[i];
m.DefineParameter(i + 1, f.modifier != null && f.modifier.str == "out" ? ParameterAttributes.Out : 0, f.Name);
f.ordinal = ast.sym.IsInstance ? i + 1 : i;
}
map.Add(ast.sym, m);
ast.builder = m;
}
public virtual void declaration(declaration ast, TypeBuilder t) {
if (ast is class_declaration) class_declaration((class_declaration)ast);
else if (ast is constant_declaration) constant_declaration((constant_declaration)ast, t);
else if (ast is constructor_declaration) constructor_declaration((constructor_declaration)ast, t);
else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast);
else if (ast is destructor_declaration) destructor_declaration((destructor_declaration)ast, t);
else if (ast is enum_declaration) enum_declaration((enum_declaration)ast);
else if (ast is event_declaration1) event_declaration1((event_declaration1)ast, t);
else if (ast is event_declaration2) event_declaration2((event_declaration2)ast, t);
else if (ast is field_declaration) field_declaration((field_declaration)ast, t);
else if (ast is indexer_declaration) indexer_declaration((indexer_declaration)ast, t);
else if (ast is interface_declaration) interface_declaration((interface_declaration)ast);
else if (ast is interface_event_declaration) interface_event_declaration((interface_event_declaration)ast, t);
else if (ast is interface_indexer_declaration) interface_indexer_declaration((interface_indexer_declaration)ast, t);
else if (ast is interface_method_declaration) interface_method_declaration((interface_method_declaration)ast, t);
else if (ast is interface_property_declaration) interface_property_declaration((interface_property_declaration)ast, t);
else if (ast is method_declaration) method_declaration((method_declaration)ast, t);
else if (ast is operator_declaration) operator_declaration((operator_declaration)ast, t);
else if (ast is property_declaration) property_declaration((property_declaration)ast, t);
else if (ast is struct_declaration) struct_declaration((struct_declaration)ast);
else throw new ArgumentException();
}
public virtual void declaration(declaration ast) {
if (ast is class_declaration) class_declaration((class_declaration)ast);
else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast);
else if (ast is enum_declaration) enum_declaration((enum_declaration)ast);
else if (ast is interface_declaration) interface_declaration((interface_declaration)ast);
else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast);
else if (ast is struct_declaration) struct_declaration((struct_declaration)ast);
else throw new ArgumentException();
}
public virtual MethodBuilder DefineMethod(TypeBuilder t, Method m) {
return DefineMethod(t, m, GetMethodAttributes(m.Modifiers));
}
public virtual MethodBuilder DefineMethod(TypeBuilder t, Method m, MethodAttributes attr) {
System.Type[] args;
if (m.Name == "set_Item") {
args = new System.Type[m.ArgCount + 1];
args[m.ArgCount] = this[((Formal)m.locals["value"]).Type];
} else
args = new System.Type[m.ArgCount];
int i;
for (i = 0; i < m.ArgCount; i++) {
Formal f = m[i];
if (f.modifier != null)
args[i] = this[new ManagedPointerType(f.Type)];
else
args[i] = this[f.Type];
}
MethodBuilder mb = t.DefineMethod(m.Name, attr, this[m.Type], args);
for (i = 0; i < m.ArgCount; i++) {
Formal f = m[i];
mb.DefineParameter(i + 1, f.modifier != null && f.modifier.str == "out" ? ParameterAttributes.Out : 0, f.Name);
f.ordinal = m.IsInstance ? i + 1 : i;
}
if (m.Name == "set_Item") {
Formal f = (Formal)m.locals["value"];
f.ordinal = m.IsInstance ? i + 1 : i;
mb.DefineParameter(f.ordinal, 0, f.Name);
}
if (m.interfaceMethod != null)
t.DefineMethodOverride(mb, this[m.interfaceMethod]);
return mb;
}
public virtual void delegate_declaration(delegate_declaration ast) {
TypeBuilder t = ast.builder;
t.SetParent(this[ast.sym.baseClass]);
foreach (Symbol s in ast.sym)
if (s is Constructor) {
Constructor m = (Constructor)s;
System.Type[] args = new System.Type[m.ArgCount];
for (int i = 0; i < m.ArgCount; i++)
args[i]= this[m[i].Type];
ConstructorBuilder mb = t.DefineConstructor(GetMethodAttributes(m.Modifiers), CallingConventions.Standard, args);
for (int i = 0; i < m.ArgCount; i++) {
Formal f = m[i];
mb.DefineParameter(i + 1, 0, f.Name);
f.ordinal = m.IsInstance ? i + 1 : i;
}
map.Add(m, mb);
} else if (s is Method) {
MethodBuilder mb = DefineMethod(t, (Method)s, GetMethodAttributes(s.Modifiers));
map.Add(s, mb);
}
}
public virtual void destructor_declaration(destructor_declaration ast, TypeBuilder t) {
ast.builder = t.DefineMethod(ast.sym.Name,
MethodAttributes.Private|MethodAttributes.Final|MethodAttributes.SpecialName,
this[T.Void], new System.Type[0]);
}
public virtual void enum_declaration(enum_declaration ast) {
EnumBuilder t = (EnumBuilder)ast.type;
foreach (enum_member_declaration x in ast.body)
x.builder = t.DefineLiteral(x.sym.Name, x.sym.value);
if (ast.sym.enclosingType == null)
map[ast.sym] = t.CreateType();
}
public virtual void event_declaration1(event_declaration1 ast, TypeBuilder t) {
foreach (event_declarator x in ast.decls) {
x.builder = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers));
map.Add(x.sym, x.builder);
x.event_builder = t.DefineEvent(x.sym.Name, EventAttributes.None, type(ast.ty));
x.add_builder = DefineMethod(t, x.sym.Add);
map.Add(x.sym.Add, x.add_builder);
x.remove_builder = DefineMethod(t, x.sym.Remove);
map.Add(x.sym.Remove, x.remove_builder);
}
}
public virtual void event_declaration2(event_declaration2 ast, TypeBuilder t) {
EventBuilder e = t.DefineEvent(ast.sym.Name, EventAttributes.None, type(ast.ty));
foreach (event_accessor x in ast.accessors) {
x.builder = DefineMethod(t, x.sym);
map.Add(x.sym, x.builder);
}
ast.builder = e;
}
public virtual void explicit_declarator(explicit_declarator ast, TypeBuilder t) {
}
public virtual void field_declaration(field_declaration ast, TypeBuilder t) {
foreach (field_declarator x in ast.decls) {
FieldBuilder f = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers));
map.Add(x.sym, f);
x.builder = f;
}
}
public virtual System.Type[] formals(formals ast) {
System.Type[] args = new System.Type[ast.fixeds.Count + (ast.param != null ? 1 : 0)];
int i = 0;
foreach (fixed_parameter p in ast.fixeds)
args[i++] = type(p.ty);
if (ast.param != null)
args[i] = type(((params_parameter)ast.param).ty); // fix
return args;
}
public virtual void implicit_declarator(implicit_declarator ast, TypeBuilder t) {
}
public virtual void indexer_declaration(indexer_declaration ast, TypeBuilder t) {
PropertyBuilder p = t.DefineProperty("Item", PropertyAttributes.None, type(ast.i.ty), formals(ast.i.f));
foreach (accessor_declaration x in ast.accessors) {
x.builder = DefineMethod(t, x.sym);
map.Add(x.sym, x.builder);
}
ast.builder = p;
}
public virtual void interface_declaration(interface_declaration ast) {
TypeBuilder t = ast.builder;
if (ast.sym.baseClass != null)
t.SetParent(this[ast.sym.baseClass]);
foreach (Type x in ast.sym.interfaces)
t.AddInterfaceImplementation(this[x]);
foreach (declaration x in ast.body)
declaration(x, t);
}
public virtual void interface_event_declaration(interface_event_declaration ast, TypeBuilder t) {
ast.builder = t.DefineEvent(ast.sym.Name, EventAttributes.None, type(ast.ty));
map[ast.sym.Add] = DefineMethod(t, ast.sym.Add);
map[ast.sym.Remove] = DefineMethod(t, ast.sym.Remove);
}
public virtual void interface_indexer_declaration(interface_indexer_declaration ast, TypeBuilder t) {
PropertyBuilder p = t.DefineProperty("Item", PropertyAttributes.None, type(ast.ty), formals(ast.f));
foreach (accessor_declaration x in ast.accessors) {
x.builder = DefineMethod(t, x.sym);
map.Add(x.sym, x.builder);
}
ast.builder = p;
}
public virtual void interface_method_declaration(interface_method_declaration ast, TypeBuilder t) {
ast.builder = DefineMethod(t, ast.sym);
map.Add(ast.sym, ast.builder);
}
public virtual void interface_property_declaration(interface_property_declaration ast, TypeBuilder t) {
PropertyBuilder p = t.DefineProperty(ast.sym.Name, PropertyAttributes.None, type(ast.ty), new System.Type[0]);
foreach (accessor_declaration x in ast.accessors) {
x.builder = DefineMethod(t, x.sym);
map.Add(x.sym, x.builder);
}
}
public virtual void method_declaration(method_declaration ast, TypeBuilder t) {
ast.builder = DefineMethod(t, ast.sym);
map.Add(ast.sym, ast.builder);
}
public virtual void namespace_declaration(namespace_declaration ast) {
foreach (declaration x in ast.nb.declarations)
declaration(x);
}
public virtual void operator_declaration(operator_declaration ast, TypeBuilder t) {
}
public virtual void operator_declarator(operator_declarator ast, TypeBuilder t) {
if (ast is binary_declarator) binary_declarator((binary_declarator)ast, t);
else if (ast is explicit_declarator) explicit_declarator((explicit_declarator)ast, t);
else if (ast is implicit_declarator) implicit_declarator((implicit_declarator)ast, t);
else if (ast is unary_declarator) unary_declarator((unary_declarator)ast, t);
else throw new ArgumentException();
}
public virtual void property_declaration(property_declaration ast, TypeBuilder t) {
PropertyBuilder p = t.DefineProperty(ast.sym.Name, PropertyAttributes.None, type(ast.ty), new System.Type[0]);
foreach (accessor_declaration x in ast.decls) {
x.builder = DefineMethod(t, x.sym);
map.Add(x.sym, x.builder);
}
ast.builder = p;
}
public virtual void struct_declaration(struct_declaration ast) {
TypeBuilder t = ast.builder;
t.SetParent(this[ast.sym.baseClass]);
foreach (Type x in ast.sym.interfaces)
t.AddInterfaceImplementation(this[x]);
foreach (declaration x in ast.body)
declaration(x, t);
}
public virtual void unary_declarator(unary_declarator ast, TypeBuilder t) {
}
}
public class emit3: emit {
public emit3(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder mod) : base(w, msg, map, mod) {}
public class ILState: gen {
ILGenerator ILgen;
emit map;
ArrayList labels = new ArrayList();
ArrayList locals = new ArrayList();
public ILState(ILGenerator ILgen, emit map) : base(map.T, map.msg) {
this.ILgen = ILgen;
this.map = map;
labels.Add(null);
locals.Add(null);
}
System.Type[] arrayMethodArgs(int rank, params System.Type[] prefix) {
System.Type[] args = new System.Type[rank+prefix.Length];
Array.Copy(prefix, args, prefix.Length);
for (int i = 0; i < rank; i++)
args[i+prefix.Length] = typeof (int);
return args;
}
override public object BeginTry() {
return ILgen.BeginExceptionBlock();
}
override public object BeginFinally(object handle) {
ILgen.BeginFinallyBlock();
return handle;
}
override public void block_statement(block_statement ast) {
ILgen.BeginScope();
foreach (statement x in ast.stmts)
statement(x);
ILgen.EndScope();
}
override public void catch_clause(Type ty, Local sym, statement block, object handle) {
ILgen.BeginCatchBlock(map[ty]);
base.catch_clause(ty, sym, block, handle);
}
override public void defLabel(int lab) {
ILgen.MarkLabel(getLabel(lab));
}
void Emit(OpCode op, ConstructorInfo x) { ILgen.Emit(op, x); }
void Emit(OpCode op, LocalBuilder x) { ILgen.Emit(op, x); }
void Emit(OpCode op, MethodInfo x) { ILgen.Emit(op, x); }
void Emit(OpCode op, System.Reflection.Emit.Label x) { ILgen.Emit(op, x); }
void Emit(OpCode op, System.Type x) { ILgen.Emit(op, x); }
override public void Emit(OpCode op) { ILgen.Emit(op); }
override public void Emit(OpCode op, double x) { ILgen.Emit(op, x); }
override public void Emit(OpCode op, float x) { ILgen.Emit(op, x); }
override public void Emit(OpCode op, Constructor x) { Emit(op, map[x]); }
override public void Emit(OpCode op, Field x) { ILgen.Emit(op, map[x]); }
override public void Emit(OpCode op, int x) { ILgen.Emit(op, x); }
override public void Emit(OpCode op, Formal x) { ILgen.Emit(op, (short)x.ordinal); }
override public void Emit(OpCode op, Local x) { ILgen.Emit(op, getLocal(x.ordinal)); }
override public void Emit(OpCode op, Method x) { Emit(op, map[x]); }
override public void Emit(OpCode op, string x) { ILgen.Emit(op, x); }
override public void Emit(OpCode op, Type x) { Emit(op, map[x]); }
override public void EmitCreateArray(ArrayType ty, Type ety, int rank) {
ILgen.Emit(OpCodes.Newobj, GetArrayMethodToken(ty, ".ctor", null));
}
override public void EmitLoad(int index) {
Emit(OpCodes.Ldloc, getLocal(index));
}
override public void EmitLoadAddress(int index) {
Emit(OpCodes.Ldloca, getLocal(index));
}
override public void EmitLoadElement(ArrayType ty, Type ety, int rank) {
Emit(OpCodes.Call, GetArrayMethodToken(ty, "Get", map[ety]));
}
override public void EmitLoadElementAddress(ArrayType ty, Type ety, int rank) {
System.Type rettype = map[new ManagedPointerType(ety)];
ILgen.Emit(OpCodes.Call, GetArrayMethodToken(ty, "Address", rettype));
}
override public void EmitStore(int index) {
Emit(OpCodes.Stloc, getLocal(index));
}
override public void EmitStoreElement(ArrayType ty, Type ety, int rank) {
ILgen.Emit(OpCodes.Call, GetArrayMethodToken(ty, "Set", null, arrayMethodArgs(rank, map[ety])));
}
override public void EmitSwitch(int[] caselabels) {
System.Reflection.Emit.Label[] labels = new System.Reflection.Emit.Label[caselabels.Length];
for (int i = 0; i < labels.Length; i++)
labels[i] = getLabel(caselabels[i]);
ILgen.Emit(OpCodes.Switch, labels);
}
override public void EndTry(object handle) {
ILgen.EndExceptionBlock();
}
override public int genLabel(int n) {
for (int i = 0; i < n; i++)
labels.Add(ILgen.DefineLabel());
return base.genLabel(n);
}
int GetArrayMethodToken(ArrayType ty, string name, System.Type rettype) {
return GetArrayMethodToken(ty, name, rettype, arrayMethodArgs(ty.rank));
}
int GetArrayMethodToken(ArrayType ty, string name, System.Type rettype, System.Type[] args) {
System.Type t = map[ty];
MethodToken m = map.module.GetArrayMethodToken(t, name,
CallingConventions.Standard|CallingConventions.HasThis, rettype, args);
return m.Token;
}
System.Reflection.Emit.Label getLabel(int lab) {
Debug.Assert(labels[lab] != null);
return (System.Reflection.Emit.Label)labels[lab];
}
LocalBuilder getLocal(int var) {
return (LocalBuilder)locals[var];
}
override public void gotoLabel(OpCode inst, int lab) {
Emit(inst, getLabel(lab));
}
override public int newLocal(Type ty) {
locals.Add(ILgen.DeclareLocal(map[ty]));
return locals.Count - 1;
}
override public int newLocal(Local v) {
int var = base.newLocal(v);
getLocal(var).SetLocalSymInfo(v.Name);
return var;
}
}
public virtual void attribute(attribute ast) {
if (ast.arguments != null)
attribute_arguments(ast.arguments);
type(ast.name);
}
public virtual void attribute_arguments(attribute_arguments ast) {
foreach (named_argument x in ast.namedargs)
named_argument(x);
}
public virtual void attribute_section(attribute_section ast) {
foreach (attribute x in ast.attributes)
attribute(x);
}
public virtual void attribute_sections(attribute_sectionList attributes) {
foreach (attribute_section x in attributes)
attribute_section(x);
}
public virtual void binary_declarator(binary_declarator ast, TypeBuilder t) {
}
public virtual void class_declaration(class_declaration ast) {
attribute_sections(ast.attrs);
declarations(ast.sym, ast.body, ast.builder);
}
public virtual void compilation(compilation ast) {
T = ast.global.Types;
foreach (compilation_unit x in ast.inputs)
compilation_unit(x);
}
public virtual void compilation_unit(compilation_unit ast) {
attribute_sections(ast.attributes);
foreach (declaration x in ast.declarations)
declaration(x);
}
public virtual void constant_declaration(constant_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
}
public virtual void constructor_declaration(constructor_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
ConstructorBuilder m = ast.builder;
if (ast.block != null || ast.decl.init != null) {
declarationList body;
if (ast.parent is class_declaration)
body = ((class_declaration)ast.parent).body;
else
body = ((struct_declaration)ast.parent).body;
ILState g = new ILState(m.GetILGenerator(), this);
if (ast.decl.init != null)
constructor_initializer(ast.decl.init, g, body);
if (ast.sym.IsStatic)
foreach (declaration d in body)
if (d is field_declaration)
field_declaration((field_declaration)d, g, true);
if (ast.block != null)
g.statement(ast.block, ast.sym);
else
g.Emit(OpCodes.Ret);
}
}
public virtual void constructor_initializer(constructor_initializer ast, ILState g, declarationList body) {
if (ast is base_initializer) {
foreach (declaration d in body)
if (d is field_declaration)
field_declaration((field_declaration)d, g, false);
g.base_initializer((base_initializer)ast);
} else if (ast is this_initializer) g.this_initializer((this_initializer)ast);
else throw new ArgumentException();
}
public virtual void declaration(declaration ast, TypeBuilder t) {
if (ast is class_declaration) class_declaration((class_declaration)ast);
else if (ast is constant_declaration) constant_declaration((constant_declaration)ast, t);
else if (ast is constructor_declaration) constructor_declaration((constructor_declaration)ast, t);
else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast);
else if (ast is destructor_declaration) destructor_declaration((destructor_declaration)ast, t);
else if (ast is enum_declaration) enum_declaration((enum_declaration)ast);
else if (ast is event_declaration1) event_declaration1((event_declaration1)ast, t);
else if (ast is event_declaration2) event_declaration2((event_declaration2)ast, t);
else if (ast is field_declaration) return;
else if (ast is indexer_declaration) indexer_declaration((indexer_declaration)ast, t);
else if (ast is interface_declaration) interface_declaration((interface_declaration)ast);
else if (ast is interface_event_declaration) interface_event_declaration((interface_event_declaration)ast, t);
else if (ast is interface_indexer_declaration) interface_indexer_declaration((interface_indexer_declaration)ast, t);
else if (ast is interface_method_declaration) interface_method_declaration((interface_method_declaration)ast, t);
else if (ast is interface_property_declaration) interface_property_declaration((interface_property_declaration)ast, t);
else if (ast is method_declaration) method_declaration((method_declaration)ast, t);
else if (ast is operator_declaration) operator_declaration((operator_declaration)ast, t);
else if (ast is property_declaration) property_declaration((property_declaration)ast, t);
else if (ast is struct_declaration) struct_declaration((struct_declaration)ast);
else throw new ArgumentException();
}
public virtual void declaration(declaration ast) {
if (ast is class_declaration) class_declaration((class_declaration)ast);
else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast);
else if (ast is enum_declaration) enum_declaration((enum_declaration)ast);
else if (ast is interface_declaration) interface_declaration((interface_declaration)ast);
else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast);
else if (ast is struct_declaration) struct_declaration((struct_declaration)ast);
else throw new ArgumentException();
}
public virtual void declarations(Type ty, declarationList decls, TypeBuilder t) {
foreach (declaration x in decls)
declaration(x, t);
if (ty.enclosingType == null)
map[ty] = t.CreateType();
foreach (declaration x in decls)
if (x is type_declaration) {
type_declaration d = (type_declaration)x;
map[d.typ] = d.builder.CreateType();
}
}
public virtual void delegate_declaration(delegate_declaration ast) {
attribute_sections(ast.attrs);
TypeBuilder t = ast.builder;
foreach (Symbol s in ast.sym)
if (s is Constructor) {
ConstructorBuilder m = (ConstructorBuilder)this[(Constructor)s];
m.SetImplementationFlags(MethodImplAttributes.Runtime);
} else if (s is Method) {
MethodBuilder m = (MethodBuilder)this[(Method)s];
m.SetImplementationFlags(MethodImplAttributes.Runtime);
m.CreateMethodBody(new Byte[]{}, 0);
}
if (ast.sym.enclosingType == null)
map[ast.sym] = t.CreateType();
}
public virtual void destructor_declaration(destructor_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
if (ast.block != null)
EmitMethodBody(ast.sym, ast.block, ast.builder);
}
public virtual void EmitMethodBody(Method m, statement body, MethodBuilder mb) {
EmitMethodBody(m, body, new ILState(mb.GetILGenerator(), this));
}
public virtual void EmitMethodBody(Method m, statement body, ILState g) {
g.statement(body, m);
}
public virtual void enum_declaration(enum_declaration ast) {
attribute_sections(ast.attrs);
}
public virtual void event_declaration1(event_declaration1 ast, TypeBuilder t) {
attribute_sections(ast.attrs);
foreach (event_declarator x in ast.decls) {
ILState g = new ILState(x.add_builder.GetILGenerator(), this);
g.EmitDefaultAccessor(x.sym, x.sym.Add);
g = new ILState(x.remove_builder.GetILGenerator(), this);
g.EmitDefaultAccessor(x.sym, x.sym.Remove);
x.event_builder.SetAddOnMethod(x.add_builder);
x.event_builder.SetRemoveOnMethod(x.remove_builder);
}
}
public virtual void event_declaration2(event_declaration2 ast, TypeBuilder t) {
attribute_sections(ast.attrs);
EventBuilder e = ast.builder;
foreach (event_accessor x in ast.accessors) {
attribute_sections(x.attrs);
MethodBuilder m = x.builder;
EmitMethodBody(x.sym, x.block, m);
if (x.id.str == "add")
e.SetAddOnMethod(m);
else
e.SetRemoveOnMethod(m);
}
}
public virtual void explicit_declarator(explicit_declarator ast, TypeBuilder t) {
}
public virtual void field_declaration(field_declaration ast, ILState g, bool doStatic) {
attribute_sections(ast.attrs);
foreach (field_declarator x in ast.decls)
if (x.init != null)
if (doStatic && x.sym.IsStatic) {
g.variable_initializer(x.init);
g.Emit(OpCodes.Stsfld, x.sym);
} else if (!doStatic && !x.sym.IsStatic) {
g.this_access();
g.variable_initializer(x.init);
g.Emit(OpCodes.Stfld, x.sym);
}
}
public virtual void implicit_declarator(implicit_declarator ast, TypeBuilder t) {
}
public virtual void indexer_declaration(indexer_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
PropertyBuilder p = ast.builder;
foreach (accessor_declaration x in ast.accessors) {
MethodBuilder m = x.builder;
if (x.body != null)
EmitMethodBody(x.sym, x.body, m);
if (x.id.str == "get")
p.SetGetMethod(m);
else
p.SetSetMethod(m);
}
}
public virtual void interface_declaration(interface_declaration ast) {
attribute_sections(ast.attrs);
declarations(ast.sym, ast.body, ast.builder);
}
public virtual void interface_event_declaration(interface_event_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
}
public virtual void interface_indexer_declaration(interface_indexer_declaration ast, TypeBuilder t) {
msg.Error("Interface indexers not yet implemented");
}
public virtual void interface_method_declaration(interface_method_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
}
public virtual void interface_property_declaration(interface_property_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
foreach (accessor_declaration x in ast.accessors)
attribute_sections(x.attrs);
}
public virtual void method_declaration(method_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
if (ast.body != null)
EmitMethodBody(ast.sym, ast.body, ast.builder);
if (ast.sym.Name == "Main" && ast.sym.IsStatic && ast.sym.IsPublic)
((AssemblyBuilder)t.Assembly).SetEntryPoint(ast.builder, PEFileKinds.ConsoleApplication);
}
public virtual void named_argument(named_argument ast) {
//expression(ast.expr, null);
// InputElement ast.id
}
public virtual void namespace_declaration(namespace_declaration ast) {
foreach (declaration x in ast.nb.declarations)
declaration(x);
}
public virtual void operator_declaration(operator_declaration ast, TypeBuilder t) {
msg.Error("Operator declarations not yet implemented");
}
public virtual void operator_declarator(operator_declarator ast, TypeBuilder t) {
if (ast is binary_declarator) binary_declarator((binary_declarator)ast, t);
else if (ast is explicit_declarator) explicit_declarator((explicit_declarator)ast, t);
else if (ast is implicit_declarator) implicit_declarator((implicit_declarator)ast, t);
else if (ast is unary_declarator) unary_declarator((unary_declarator)ast, t);
else throw new ArgumentException();
}
public virtual void property_declaration(property_declaration ast, TypeBuilder t) {
attribute_sections(ast.attrs);
PropertyBuilder p = ast.builder;
foreach (accessor_declaration x in ast.decls) {
attribute_sections(x.attrs);
MethodBuilder m = x.builder;
if (x.body != null)
EmitMethodBody(x.sym, x.body, m);
if (x.id.str == "get")
p.SetGetMethod(m);
else
p.SetSetMethod(m);
}
}
public virtual void struct_declaration(struct_declaration ast) {
attribute_sections(ast.attrs);
declarations(ast.sym, ast.body, ast.builder);
}
public virtual void unary_declarator(unary_declarator ast, TypeBuilder t) {
}
}