X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fclass%2FIKVM.Reflection%2FEmit%2FILGenerator.cs;h=7fddd7bcdb6f0edbfbeb7083f8a9c01d98db4c18;hb=10eadfdd38d35fbc2906008375984770dcc478bc;hp=8ed9bd8f7efbea0dccf3f7b2867537efb89a917a;hpb=880bea0e62f7b4d97eab34fde65c5121e706ea72;p=mono.git diff --git a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs b/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs index 8ed9bd8f7ef..7fddd7bcdb6 100644 --- a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs +++ b/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2011 Jeroen Frijters + Copyright (C) 2008-2012 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,6 @@ using System.Runtime.InteropServices; using System.Collections.Generic; using System.Diagnostics.SymbolStore; using System.Diagnostics; -using IKVM.Reflection.Metadata; using IKVM.Reflection.Writer; namespace IKVM.Reflection.Emit @@ -116,43 +115,12 @@ namespace IKVM.Reflection.Emit } } - sealed class MarkerType : Type - { - public override Type BaseType - { - get { throw new InvalidOperationException(); } - } - - public override TypeAttributes Attributes - { - get { throw new InvalidOperationException(); } - } - - public override string Name - { - get { throw new InvalidOperationException(); } - } - - public override string FullName - { - get { throw new InvalidOperationException(); } - } - - public override Module Module - { - get { throw new InvalidOperationException(); } - } - } - public sealed class ILGenerator { - private static readonly Type FAULT = new MarkerType(); - private static readonly Type FINALLY = new MarkerType(); - private static readonly Type FILTER = new MarkerType(); private readonly ModuleBuilder moduleBuilder; private readonly ByteBuffer code; - private readonly List locals = new List(); - private List localCustomModifiers; + private readonly SignatureHelper locals; + private int localsCount; private readonly List tokenFixups = new List(); private readonly List labels = new List(); private readonly List labelStackHeight = new List(); @@ -183,7 +151,7 @@ namespace IKVM.Reflection.Emit internal int tryLength; internal int handlerOffset; internal int handlerLength; - internal Type exceptionType; // FINALLY = finally block, FILTER = handler with filter, FAULT = fault block + internal Type exceptionType; // MarkerType.Finally = finally block, MarkerType.Filter = handler with filter, MarkerType.Fault = fault block internal int filterOffset; internal ExceptionBlock(int ordinal) @@ -245,17 +213,13 @@ namespace IKVM.Reflection.Emit { this.code = new ByteBuffer(initialCapacity); this.moduleBuilder = moduleBuilder; + this.locals = SignatureHelper.GetLocalVarSigHelper(moduleBuilder); if (moduleBuilder.symbolWriter != null) { scope = new Scope(null); } } - private bool IsLabelReachable(Label label) - { - return labelStackHeight[label.Index] != -1; - } - // non-standard API public void __DisableExceptionBlockAssistance() { @@ -310,7 +274,7 @@ namespace IKVM.Reflection.Emit UpdateStack(1); if (exceptionType == null) { - if (block.exceptionType != FILTER || block.handlerOffset != 0) + if (block.exceptionType != MarkerType.Filter || block.handlerOffset != 0) { throw new ArgumentNullException("exceptionType"); } @@ -335,7 +299,7 @@ namespace IKVM.Reflection.Emit exceptionStack.Push(block); } block.exceptionType = exceptionType; - if (exceptionType == FILTER) + if (exceptionType == MarkerType.Filter) { block.filterOffset = code.Position; } @@ -359,17 +323,17 @@ namespace IKVM.Reflection.Emit public void BeginExceptFilterBlock() { - BeginCatchBlock(FILTER); + BeginCatchBlock(MarkerType.Filter); } public void BeginFaultBlock() { - BeginFinallyFaultBlock(FAULT); + BeginFinallyFaultBlock(MarkerType.Fault); } public void BeginFinallyBlock() { - BeginFinallyFaultBlock(FINALLY); + BeginFinallyFaultBlock(MarkerType.Finally); } private void BeginFinallyFaultBlock(Type type) @@ -416,7 +380,7 @@ namespace IKVM.Reflection.Emit ExceptionBlock block = exceptionStack.Pop(); if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) { - if (block.filterOffset != 0 || (block.exceptionType != FINALLY && block.exceptionType != FAULT)) + if (block.filterOffset != 0 || (block.exceptionType != MarkerType.Finally && block.exceptionType != MarkerType.Fault)) { Emit(OpCodes.Leave, block.labelEnd); } @@ -452,8 +416,8 @@ namespace IKVM.Reflection.Emit public LocalBuilder DeclareLocal(Type localType, bool pinned) { - LocalBuilder local = new LocalBuilder(localType, locals.Count, pinned); - locals.Add(local); + LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned); + locals.AddArgument(localType, pinned); if (scope != null) { scope.locals.Add(local); @@ -463,22 +427,13 @@ namespace IKVM.Reflection.Emit public LocalBuilder __DeclareLocal(Type localType, bool pinned, CustomModifiers customModifiers) { - if (!customModifiers.IsEmpty) + LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned); + locals.__AddArgument(localType, pinned, customModifiers); + if (scope != null) { - if (localCustomModifiers == null) - { - localCustomModifiers = new List(); - } - // we lazily fill up the list (to sync with the locals list) and we don't need to - // make sure that the list has the same length as the locals list, because - // Signature.WriteLocalVarSig() can tolerate that. - while (localCustomModifiers.Count < locals.Count) - { - localCustomModifiers.Add(new CustomModifiers()); - } - localCustomModifiers.Add(customModifiers); + scope.locals.Add(local); } - return DeclareLocal(localType, pinned); + return local; } public Label DefineLabel() @@ -786,7 +741,7 @@ namespace IKVM.Reflection.Emit public void Emit(OpCode opc, string str) { Emit(opc); - code.Write(0x70000000 | moduleBuilder.UserStrings.Add(str)); + code.Write(moduleBuilder.GetStringConstant(str).Token); } public void Emit(OpCode opc, Type type) @@ -806,7 +761,7 @@ namespace IKVM.Reflection.Emit { Emit(opcode); UpdateStack(opcode, signature.HasThis, signature.ReturnType, signature.ParameterCount); - code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(signature.GetSignature(moduleBuilder)))); + code.Write(moduleBuilder.GetSignatureToken(signature).Token); } public void EmitCall(OpCode opc, MethodInfo method, Type[] optionalParameterTypes) @@ -824,20 +779,7 @@ namespace IKVM.Reflection.Emit { Emit(opc); UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount + optionalParameterTypes.Length); - ByteBuffer sig = new ByteBuffer(16); - method.MethodSignature.WriteMethodRefSig(moduleBuilder, sig, optionalParameterTypes, customModifiers); - MemberRefTable.Record record = new MemberRefTable.Record(); - if (method.Module == moduleBuilder) - { - record.Class = method.MetadataToken; - } - else - { - record.Class = moduleBuilder.GetTypeTokenForMemberRef(method.DeclaringType ?? method.Module.GetModuleType()); - } - record.Name = moduleBuilder.Strings.Add(method.Name); - record.Signature = moduleBuilder.Blobs.Add(sig); - code.Write(0x0A000000 | moduleBuilder.MemberRef.FindOrAddRecord(record)); + code.Write(moduleBuilder.__GetMethodToken(method, optionalParameterTypes, customModifiers).Token); } } @@ -853,12 +795,18 @@ namespace IKVM.Reflection.Emit public void EmitCalli(OpCode opc, CallingConvention callingConvention, Type returnType, Type[] parameterTypes) { - __EmitCalli(opc, moduleBuilder.universe.MakeStandAloneMethodSig(callingConvention, returnType, new CustomModifiers(), parameterTypes, null)); + SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType); + sig.AddArguments(parameterTypes, null, null); + Emit(opc, sig); } public void EmitCalli(OpCode opc, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) { - __EmitCalli(opc, moduleBuilder.universe.MakeStandAloneMethodSig(callingConvention, returnType, new CustomModifiers(), parameterTypes, optionalParameterTypes, null)); + SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType); + sig.AddArguments(parameterTypes, null, null); + sig.AddSentinel(); + sig.AddArguments(optionalParameterTypes, null, null); + Emit(opc, sig); } public void __EmitCalli(OpCode opc, __StandAloneMethodSig sig) @@ -974,7 +922,7 @@ namespace IKVM.Reflection.Emit int localVarSigTok = 0; int rva; - if (locals.Count == 0 && exceptions.Count == 0 && maxStack <= 8 && code.Length < 64 && !fatHeader) + if (localsCount == 0 && exceptions.Count == 0 && maxStack <= 8 && code.Length < 64 && !fatHeader) { rva = WriteTinyHeaderAndCode(bb); } @@ -1062,11 +1010,9 @@ namespace IKVM.Reflection.Emit bb.Align(4); int rva = bb.Position; - if (locals.Count != 0) + if (localsCount != 0) { - ByteBuffer localVarSig = new ByteBuffer(locals.Count + 2); - Signature.WriteLocalVarSig(moduleBuilder, localVarSig, locals, localCustomModifiers); - localVarSigTok = 0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(localVarSig)); + localVarSigTok = moduleBuilder.GetSignatureToken(locals).Token; } const byte CorILMethod_FatFormat = 0x03; @@ -1124,15 +1070,15 @@ namespace IKVM.Reflection.Emit bb.Write((short)(dataSize >> 8)); foreach (ExceptionBlock block in exceptions) { - if (block.exceptionType == FAULT) + if (block.exceptionType == MarkerType.Fault) { bb.Write((int)COR_ILEXCEPTION_CLAUSE_FAULT); } - else if (block.exceptionType == FILTER) + else if (block.exceptionType == MarkerType.Filter) { bb.Write((int)COR_ILEXCEPTION_CLAUSE_FILTER); } - else if (block.exceptionType == FINALLY) + else if (block.exceptionType == MarkerType.Finally) { bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY); } @@ -1144,7 +1090,7 @@ namespace IKVM.Reflection.Emit bb.Write(block.tryLength); bb.Write(block.handlerOffset); bb.Write(block.handlerLength); - if (block.exceptionType != FAULT && block.exceptionType != FILTER && block.exceptionType != FINALLY) + if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) { bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); } @@ -1161,15 +1107,15 @@ namespace IKVM.Reflection.Emit bb.Write((short)0); foreach (ExceptionBlock block in exceptions) { - if (block.exceptionType == FAULT) + if (block.exceptionType == MarkerType.Fault) { bb.Write(COR_ILEXCEPTION_CLAUSE_FAULT); } - else if (block.exceptionType == FILTER) + else if (block.exceptionType == MarkerType.Filter) { bb.Write(COR_ILEXCEPTION_CLAUSE_FILTER); } - else if (block.exceptionType == FINALLY) + else if (block.exceptionType == MarkerType.Finally) { bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY); } @@ -1181,7 +1127,7 @@ namespace IKVM.Reflection.Emit bb.Write((byte)block.tryLength); bb.Write((short)block.handlerOffset); bb.Write((byte)block.handlerLength); - if (block.exceptionType != FAULT && block.exceptionType != FILTER && block.exceptionType != FINALLY) + if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) { bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); }