public void Build(IMethodBuilder builder) { //Dump(); ILGenerator il = builder.GetILGenerator(); Dictionary<BlockLabel, Label> labels = new Dictionary<BlockLabel, Label>(); Dictionary<BlockLocal, LocalBuilder> locals = new Dictionary<BlockLocal, LocalBuilder>(); foreach (IBlockLine line in (IEnumerable<IBlockLine>) lines) { BlockInstruction instruction = line as BlockInstruction; if ((instruction != null) && (instruction.Operation == BlockOperation.MarkLabel)) labels[(BlockLabel) instruction.Parameter] = il.DefineLabel(); } foreach (IBlockLine line in (IEnumerable<IBlockLine>) lines) { if (line is Instruction) { Instruction instruction = line as Instruction; if (instruction.Parameter == null) il.Emit(instruction.Op); else if (instruction.Parameter is int) il.Emit(instruction.Op, (int) instruction.Parameter); else if (instruction.Parameter is string) il.Emit(instruction.Op, (string) instruction.Parameter); else if (instruction.Parameter is Type) il.Emit(instruction.Op, (Type) instruction.Parameter); else if (instruction.Parameter is FieldInfo) il.Emit(instruction.Op, (FieldInfo) instruction.Parameter); else if (instruction.Parameter is MethodInfo) il.Emit(instruction.Op, (MethodInfo) instruction.Parameter); else if (instruction.Parameter is ConstructorInfo) il.Emit(instruction.Op, (ConstructorInfo) instruction.Parameter); else if (instruction.Parameter is BlockLabel) { BlockLabel blockLabel = (BlockLabel) instruction.Parameter; Label label; if (!labels.TryGetValue(blockLabel, out label)) throw new Exception("Label " + blockLabel.Name + " not marked"); il.Emit(instruction.Op, label); } else if (instruction.Parameter is BlockLocal) il.Emit(instruction.Op, locals[(BlockLocal) instruction.Parameter]); else throw new NotImplementedException(instruction.Op.Value + " " + TypeNames.GetName(instruction.Parameter.GetType())); } else if (line is BlockInstruction) { BlockInstruction instruction = line as BlockInstruction; if (instruction.Operation == BlockOperation.Comment) {} else if (instruction.Operation == BlockOperation.MarkLabel) il.MarkLabel(labels[(BlockLabel) instruction.Parameter]); else if (instruction.Operation == BlockOperation.DeclareLocal) { BlockLocal local = (BlockLocal) instruction.Parameter; locals[local] = il.DeclareLocal(local.Type); } else if (instruction.Operation == BlockOperation.BeginScope) il.BeginScope(); else if (instruction.Operation == BlockOperation.EndScope) il.EndScope(); else throw new Exception(); } else throw new Exception(); } }
public void Build(IMethodBuilder builder) { //Dump(); ILGenerator il = builder.GetILGenerator(); Dictionary <BlockLabel, Label> labels = new Dictionary <BlockLabel, Label>(); Dictionary <BlockLocal, LocalBuilder> locals = new Dictionary <BlockLocal, LocalBuilder>(); foreach (IBlockLine line in (IEnumerable <IBlockLine>)lines) { BlockInstruction instruction = line as BlockInstruction; if ((instruction != null) && (instruction.Operation == BlockOperation.MarkLabel)) { labels[(BlockLabel)instruction.Parameter] = il.DefineLabel(); } } foreach (IBlockLine line in (IEnumerable <IBlockLine>)lines) { if (line is Instruction) { Instruction instruction = line as Instruction; if (instruction.Parameter == null) { il.Emit(instruction.Op); } else if (instruction.Parameter is int) { il.Emit(instruction.Op, (int)instruction.Parameter); } else if (instruction.Parameter is string) { il.Emit(instruction.Op, (string)instruction.Parameter); } else if (instruction.Parameter is Type) { il.Emit(instruction.Op, (Type)instruction.Parameter); } else if (instruction.Parameter is FieldInfo) { il.Emit(instruction.Op, (FieldInfo)instruction.Parameter); } else if (instruction.Parameter is MethodInfo) { il.Emit(instruction.Op, (MethodInfo)instruction.Parameter); } else if (instruction.Parameter is ConstructorInfo) { il.Emit(instruction.Op, (ConstructorInfo)instruction.Parameter); } else if (instruction.Parameter is BlockLabel) { BlockLabel blockLabel = (BlockLabel)instruction.Parameter; Label label; if (!labels.TryGetValue(blockLabel, out label)) { throw new Exception("Label " + blockLabel.Name + " not marked"); } il.Emit(instruction.Op, label); } else if (instruction.Parameter is BlockLocal) { il.Emit(instruction.Op, locals[(BlockLocal)instruction.Parameter]); } else { throw new NotImplementedException(instruction.Op.Value + " " + TypeNames.GetName(instruction.Parameter.GetType())); } } else if (line is BlockInstruction) { BlockInstruction instruction = line as BlockInstruction; if (instruction.Operation == BlockOperation.Comment) { } else if (instruction.Operation == BlockOperation.MarkLabel) { il.MarkLabel(labels[(BlockLabel)instruction.Parameter]); } else if (instruction.Operation == BlockOperation.DeclareLocal) { BlockLocal local = (BlockLocal)instruction.Parameter; locals[local] = il.DeclareLocal(local.Type); } else if (instruction.Operation == BlockOperation.BeginScope) { il.BeginScope(); } else if (instruction.Operation == BlockOperation.EndScope) { il.EndScope(); } else { throw new Exception(); } } else { throw new Exception(); } } }