| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- // ***NOTE*** If this code is changed, make corresponding changes in System.Runtime.Serialization.CodeGenerator also
- namespace System.ServiceModel.Dispatcher
- {
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.Globalization;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Runtime;
- using System.Security;
- using System.ServiceModel.Diagnostics;
- [Fx.Tag.SecurityNote(Critical = "Generates IL into an ILGenerator that was created under an Assert."
- + "Generated IL must be correct and must not subvert the type system.")]
- #pragma warning disable 618 // have not moved to the v4 security model yet
- [SecurityCritical(SecurityCriticalScope.Everything)]
- #pragma warning restore 618
- internal class CodeGenerator
- {
- static MethodInfo getTypeFromHandle;
- static MethodInfo stringConcat2;
- static MethodInfo objectToString;
- static MethodInfo boxPointer;
- static MethodInfo unboxPointer;
- #if USE_REFEMIT
- AssemblyBuilder assemblyBuilder;
- ModuleBuilder moduleBuilder;
- TypeBuilder typeBuilder;
- static int typeCounter;
- MethodBuilder methodBuilder;
- #else
- static Module SerializationModule = typeof(CodeGenerator).Module; // Can be replaced by different assembly with SkipVerification set to false
- DynamicMethod dynamicMethod;
- #if DEBUG
- bool allowPrivateMemberAccess;
- #endif
- #endif
- Type delegateType;
- ILGenerator ilGen;
- ArrayList argList;
- Stack blockStack;
- Label methodEndLabel;
- Hashtable localNames;
- int lineNo = 1;
- enum CodeGenTrace { None, Save, Tron };
- CodeGenTrace codeGenTrace;
- internal CodeGenerator()
- {
- SourceSwitch codeGenSwitch = OperationInvokerTrace.CodeGenerationSwitch;
- if ((codeGenSwitch.Level & SourceLevels.Verbose) == SourceLevels.Verbose)
- codeGenTrace = CodeGenTrace.Tron;
- else if ((codeGenSwitch.Level & SourceLevels.Information) == SourceLevels.Information)
- codeGenTrace = CodeGenTrace.Save;
- else
- codeGenTrace = CodeGenTrace.None;
- }
- static MethodInfo GetTypeFromHandle
- {
- get
- {
- if (getTypeFromHandle == null)
- getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
- return getTypeFromHandle;
- }
- }
- static MethodInfo StringConcat2
- {
- get
- {
- if (stringConcat2 == null)
- stringConcat2 = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });
- return stringConcat2;
- }
- }
- static MethodInfo ObjectToString
- {
- get
- {
- if (objectToString == null)
- objectToString = typeof(object).GetMethod("ToString", new Type[0]);
- return objectToString;
- }
- }
- static MethodInfo BoxPointer
- {
- get
- {
- if (boxPointer == null)
- boxPointer = typeof(Pointer).GetMethod("Box");
- return boxPointer;
- }
- }
- static MethodInfo UnboxPointer
- {
- get
- {
- if (unboxPointer == null)
- unboxPointer = typeof(Pointer).GetMethod("Unbox");
- return unboxPointer;
- }
- }
- internal void BeginMethod(string methodName, Type delegateType, bool allowPrivateMemberAccess)
- {
- MethodInfo signature = delegateType.GetMethod("Invoke");
- ParameterInfo[] parameters = signature.GetParameters();
- Type[] paramTypes = new Type[parameters.Length];
- for (int i = 0; i < parameters.Length; i++)
- paramTypes[i] = parameters[i].ParameterType;
- BeginMethod(signature.ReturnType, methodName, paramTypes, allowPrivateMemberAccess);
- this.delegateType = delegateType;
- }
- void BeginMethod(Type returnType, string methodName, Type[] argTypes, bool allowPrivateMemberAccess)
- {
- #if USE_REFEMIT
- string typeName = "Type" + (typeCounter++);
- InitAssemblyBuilder(typeName + "." + methodName);
- this.typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
- this.methodBuilder = typeBuilder.DefineMethod(methodName, MethodAttributes.Public|MethodAttributes.Static, returnType, argTypes);
- this.ilGen = this.methodBuilder.GetILGenerator();
- #else
- this.dynamicMethod = new DynamicMethod(methodName, returnType, argTypes, SerializationModule, allowPrivateMemberAccess);
- this.ilGen = this.dynamicMethod.GetILGenerator();
- #if DEBUG
- this.allowPrivateMemberAccess = allowPrivateMemberAccess;
- #endif
- #endif
- this.methodEndLabel = ilGen.DefineLabel();
- this.blockStack = new Stack();
- this.argList = new ArrayList();
- for (int i = 0; i < argTypes.Length; i++)
- argList.Add(new ArgBuilder(i, argTypes[i]));
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceLabel("Begin method " + methodName + " {");
- }
- internal Delegate EndMethod()
- {
- MarkLabel(methodEndLabel);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceLabel("} End method");
- Ret();
- Delegate retVal = null;
- #if USE_REFEMIT
- Type type = typeBuilder.CreateType();
- if (codeGenTrace != CodeGenTrace.None)
- assemblyBuilder.Save(assemblyBuilder.GetName().Name+".dll");
- MethodInfo method = type.GetMethod(methodBuilder.Name);
- retVal = Delegate.CreateDelegate(delegateType, method);
- methodBuilder = null;
- #else
- retVal = dynamicMethod.CreateDelegate(delegateType);
- dynamicMethod = null;
- #endif
- delegateType = null;
- ilGen = null;
- blockStack = null;
- argList = null;
- return retVal;
- }
- internal MethodInfo CurrentMethod
- {
- get
- {
- #if USE_REFEMIT
- return methodBuilder;
- #else
- return dynamicMethod;
- #endif
- }
- }
- internal ArgBuilder GetArg(int index)
- {
- return (ArgBuilder)argList[index];
- }
- internal Type GetVariableType(object var)
- {
- if (var is ArgBuilder)
- return ((ArgBuilder)var).ArgType;
- else if (var is LocalBuilder)
- return ((LocalBuilder)var).LocalType;
- else
- return var.GetType();
- }
- internal LocalBuilder DeclareLocal(Type type, string name)
- {
- return DeclareLocal(type, name, false);
- }
- internal LocalBuilder DeclareLocal(Type type, string name, bool isPinned)
- {
- LocalBuilder local = ilGen.DeclareLocal(type, isPinned);
- if (codeGenTrace != CodeGenTrace.None)
- {
- LocalNames[local] = name;
- EmitSourceComment("Declare local '" + name + "' of type " + type);
- }
- return local;
- }
- internal void If()
- {
- InternalIf(false);
- }
- internal void IfNot()
- {
- InternalIf(true);
- }
- internal void Else()
- {
- IfState ifState = PopIfState();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- ifState.ElseBegin = ifState.EndIf;
- blockStack.Push(ifState);
- }
- internal void EndIf()
- {
- IfState ifState = PopIfState();
- if (!ifState.ElseBegin.Equals(ifState.EndIf))
- MarkLabel(ifState.ElseBegin);
- MarkLabel(ifState.EndIf);
- }
- internal void Call(MethodInfo methodInfo)
- {
- if (methodInfo.IsVirtual)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Callvirt " + methodInfo.ToString() + " on type " + methodInfo.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Callvirt, methodInfo);
- }
- else if (methodInfo.IsStatic)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Static Call " + methodInfo.ToString() + " on type " + methodInfo.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Call, methodInfo);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Call " + methodInfo.ToString() + " on type " + methodInfo.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Call, methodInfo);
- }
- }
- internal void New(ConstructorInfo constructor)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Newobj " + constructor.ToString() + " on type " + constructor.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Newobj, constructor);
- }
- internal void InitObj(Type valueType)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Initobj " + valueType);
- ilGen.Emit(OpCodes.Initobj, valueType);
- }
- internal void LoadArrayElement(object obj, object arrayIndex)
- {
- Type objType = GetVariableType(obj).GetElementType();
- Load(obj);
- Load(arrayIndex);
- if (IsStruct(objType))
- {
- Ldelema(objType);
- Ldobj(objType);
- }
- else
- Ldelem(objType);
- }
- internal void StoreArrayElement(object obj, object arrayIndex, object value)
- {
- Type objType = GetVariableType(obj).GetElementType();
- Load(obj);
- Load(arrayIndex);
- if (IsStruct(objType))
- Ldelema(objType);
- Load(value);
- ConvertValue(GetVariableType(value), objType);
- if (IsStruct(objType))
- Stobj(objType);
- else
- Stelem(objType);
- }
- static bool IsStruct(Type objType)
- {
- return objType.IsValueType && !objType.IsPrimitive;
- }
- internal void Load(object obj)
- {
- if (obj == null)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldnull");
- ilGen.Emit(OpCodes.Ldnull);
- }
- else if (obj is ArgBuilder)
- Ldarg((ArgBuilder)obj);
- else if (obj is LocalBuilder)
- Ldloc((LocalBuilder)obj);
- else
- Ldc(obj);
- }
- internal void Store(object var)
- {
- if (var is ArgBuilder)
- Starg((ArgBuilder)var);
- else if (var is LocalBuilder)
- Stloc((LocalBuilder)var);
- else
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenCanOnlyStoreIntoArgOrLocGot0, var.GetType().FullName)));
- }
- internal void LoadAddress(object obj)
- {
- if (obj is ArgBuilder)
- LdargAddress((ArgBuilder)obj);
- else if (obj is LocalBuilder)
- LdlocAddress((LocalBuilder)obj);
- else
- Load(obj);
- }
- internal void ConvertAddress(Type source, Type target)
- {
- InternalConvert(source, target, true);
- }
- internal void ConvertValue(Type source, Type target)
- {
- InternalConvert(source, target, false);
- }
- internal void Castclass(Type target)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Castclass " + target);
- ilGen.Emit(OpCodes.Castclass, target);
- }
- internal void Box(Type type)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Box " + type);
- ilGen.Emit(OpCodes.Box, type);
- }
- internal void Unbox(Type type)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Unbox " + type);
- ilGen.Emit(OpCodes.Unbox, type);
- }
- internal void Ldobj(Type type)
- {
- OpCode opCode = GetLdindOpCode(Type.GetTypeCode(type));
- if (!opCode.Equals(OpCodes.Nop))
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldobj " + type);
- ilGen.Emit(OpCodes.Ldobj, type);
- }
- }
- internal void Stobj(Type type)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stobj " + type);
- ilGen.Emit(OpCodes.Stobj, type);
- }
- internal void Ldtoken(Type t)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldtoken " + t);
- ilGen.Emit(OpCodes.Ldtoken, t);
- }
- internal void Ldc(object o)
- {
- Type valueType = o.GetType();
- if (o is Type)
- {
- Ldtoken((Type)o);
- Call(GetTypeFromHandle);
- }
- else if (valueType.IsEnum)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("Ldc " + o.GetType() + "." + o);
- Ldc(((IConvertible)o).ToType(Enum.GetUnderlyingType(valueType), null));
- }
- else
- {
- switch (Type.GetTypeCode(valueType))
- {
- case TypeCode.Boolean:
- Ldc((bool)o);
- break;
- case TypeCode.Char:
- Ldc((int)(char)o);
- break;
- case TypeCode.SByte:
- case TypeCode.Byte:
- case TypeCode.Int16:
- case TypeCode.UInt16:
- Ldc(((IConvertible)o).ToInt32(CultureInfo.InvariantCulture));
- break;
- case TypeCode.Int32:
- Ldc((int)o);
- break;
- case TypeCode.UInt32:
- Ldc((int)(uint)o);
- break;
- case TypeCode.String:
- Ldstr((string)o);
- break;
- case TypeCode.UInt64:
- case TypeCode.Int64:
- case TypeCode.Single:
- case TypeCode.Double:
- case TypeCode.Object:
- case TypeCode.Decimal:
- case TypeCode.DateTime:
- case TypeCode.Empty:
- case TypeCode.DBNull:
- default:
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenUnknownConstantType, valueType.FullName)));
- }
- }
- }
- internal void Ldc(bool boolVar)
- {
- if (boolVar)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.i4 1");
- ilGen.Emit(OpCodes.Ldc_I4_1);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.i4 0");
- ilGen.Emit(OpCodes.Ldc_I4_0);
- }
- }
- internal void Ldc(int intVar)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.i4 " + intVar);
- switch (intVar)
- {
- case -1:
- ilGen.Emit(OpCodes.Ldc_I4_M1);
- break;
- case 0:
- ilGen.Emit(OpCodes.Ldc_I4_0);
- break;
- case 1:
- ilGen.Emit(OpCodes.Ldc_I4_1);
- break;
- case 2:
- ilGen.Emit(OpCodes.Ldc_I4_2);
- break;
- case 3:
- ilGen.Emit(OpCodes.Ldc_I4_3);
- break;
- case 4:
- ilGen.Emit(OpCodes.Ldc_I4_4);
- break;
- case 5:
- ilGen.Emit(OpCodes.Ldc_I4_5);
- break;
- case 6:
- ilGen.Emit(OpCodes.Ldc_I4_6);
- break;
- case 7:
- ilGen.Emit(OpCodes.Ldc_I4_7);
- break;
- case 8:
- ilGen.Emit(OpCodes.Ldc_I4_8);
- break;
- default:
- ilGen.Emit(OpCodes.Ldc_I4, intVar);
- break;
- }
- }
- internal void Ldstr(string strVar)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldstr " + strVar);
- ilGen.Emit(OpCodes.Ldstr, strVar);
- }
- internal void LdlocAddress(LocalBuilder localBuilder)
- {
- if (localBuilder.LocalType.IsValueType)
- Ldloca(localBuilder);
- else
- Ldloc(localBuilder);
- }
- internal void Ldloc(LocalBuilder localBuilder)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldloc " + LocalNames[localBuilder]);
- ilGen.Emit(OpCodes.Ldloc, localBuilder);
- EmitStackTop(localBuilder.LocalType);
- }
- internal void Stloc(LocalBuilder local)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stloc " + LocalNames[local]);
- EmitStackTop(local.LocalType);
- ilGen.Emit(OpCodes.Stloc, local);
- }
- internal void Ldloc(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldloc " + slot);
- switch (slot)
- {
- case 0:
- ilGen.Emit(OpCodes.Ldloc_0);
- break;
- case 1:
- ilGen.Emit(OpCodes.Ldloc_1);
- break;
- case 2:
- ilGen.Emit(OpCodes.Ldloc_2);
- break;
- case 3:
- ilGen.Emit(OpCodes.Ldloc_3);
- break;
- default:
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldloc_S, slot);
- else
- ilGen.Emit(OpCodes.Ldloc, slot);
- break;
- }
- }
- internal void Stloc(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stloc " + slot);
- switch (slot)
- {
- case 0:
- ilGen.Emit(OpCodes.Stloc_0);
- break;
- case 1:
- ilGen.Emit(OpCodes.Stloc_1);
- break;
- case 2:
- ilGen.Emit(OpCodes.Stloc_2);
- break;
- case 3:
- ilGen.Emit(OpCodes.Stloc_3);
- break;
- default:
- if (slot <= 255)
- ilGen.Emit(OpCodes.Stloc_S, slot);
- else
- ilGen.Emit(OpCodes.Stloc, slot);
- break;
- }
- }
- internal void Ldloca(LocalBuilder localBuilder)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldloca " + LocalNames[localBuilder]);
- ilGen.Emit(OpCodes.Ldloca, localBuilder);
- EmitStackTop(localBuilder.LocalType);
- }
- internal void Ldloca(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldloca " + slot);
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldloca_S, slot);
- else
- ilGen.Emit(OpCodes.Ldloca, slot);
- }
- internal void LdargAddress(ArgBuilder argBuilder)
- {
- if (argBuilder.ArgType.IsValueType)
- Ldarga(argBuilder);
- else
- Ldarg(argBuilder);
- }
- internal void Ldarg(ArgBuilder arg)
- {
- Ldarg(arg.Index);
- }
- internal void Starg(ArgBuilder arg)
- {
- Starg(arg.Index);
- }
- internal void Ldarg(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldarg " + slot);
- switch (slot)
- {
- case 0:
- ilGen.Emit(OpCodes.Ldarg_0);
- break;
- case 1:
- ilGen.Emit(OpCodes.Ldarg_1);
- break;
- case 2:
- ilGen.Emit(OpCodes.Ldarg_2);
- break;
- case 3:
- ilGen.Emit(OpCodes.Ldarg_3);
- break;
- default:
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldarg_S, slot);
- else
- ilGen.Emit(OpCodes.Ldarg, slot);
- break;
- }
- }
- internal void Starg(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Starg " + slot);
- if (slot <= 255)
- ilGen.Emit(OpCodes.Starg_S, slot);
- else
- ilGen.Emit(OpCodes.Starg, slot);
- }
- internal void Ldarga(ArgBuilder argBuilder)
- {
- Ldarga(argBuilder.Index);
- }
- internal void Ldarga(int slot)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldarga " + slot);
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldarga_S, slot);
- else
- ilGen.Emit(OpCodes.Ldarga, slot);
- }
- internal void Ldelem(Type arrayElementType)
- {
- if (arrayElementType.IsEnum)
- {
- Ldelem(Enum.GetUnderlyingType(arrayElementType));
- }
- else
- {
- OpCode opCode = GetLdelemOpCode(Type.GetTypeCode(arrayElementType));
- if (opCode.Equals(OpCodes.Nop))
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenArrayTypeIsNotSupported, arrayElementType.FullName)));
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode);
- EmitStackTop(arrayElementType);
- }
- }
- internal void Ldelema(Type arrayElementType)
- {
- OpCode opCode = OpCodes.Ldelema;
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode, arrayElementType);
- EmitStackTop(arrayElementType);
- }
- internal void Stelem(Type arrayElementType)
- {
- if (arrayElementType.IsEnum)
- Stelem(Enum.GetUnderlyingType(arrayElementType));
- else
- {
- OpCode opCode = GetStelemOpCode(Type.GetTypeCode(arrayElementType));
- if (opCode.Equals(OpCodes.Nop))
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenArrayTypeIsNotSupported, arrayElementType.FullName)));
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- EmitStackTop(arrayElementType);
- ilGen.Emit(opCode);
- }
- }
- internal Label DefineLabel()
- {
- return ilGen.DefineLabel();
- }
- internal void MarkLabel(Label label)
- {
- ilGen.MarkLabel(label);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceLabel(label.GetHashCode() + ":");
- }
- internal void Ret()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ret");
- ilGen.Emit(OpCodes.Ret);
- }
- internal void Br(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Br " + label.GetHashCode());
- ilGen.Emit(OpCodes.Br, label);
- }
- internal void Brfalse(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Brfalse " + label.GetHashCode());
- ilGen.Emit(OpCodes.Brfalse, label);
- }
- internal void Brtrue(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Brtrue " + label.GetHashCode());
- ilGen.Emit(OpCodes.Brtrue, label);
- }
- internal void Pop()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Pop");
- ilGen.Emit(OpCodes.Pop);
- }
- internal void Dup()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Dup");
- ilGen.Emit(OpCodes.Dup);
- }
- void InternalIf(bool negate)
- {
- IfState ifState = new IfState();
- ifState.EndIf = DefineLabel();
- ifState.ElseBegin = DefineLabel();
- if (negate)
- Brtrue(ifState.ElseBegin);
- else
- Brfalse(ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- void InternalConvert(Type source, Type target, bool isAddress)
- {
- if (target == source)
- return;
- if (target.IsValueType)
- {
- if (source.IsValueType)
- {
- OpCode opCode = GetConvOpCode(Type.GetTypeCode(target));
- if (opCode.Equals(OpCodes.Nop))
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenNoConversionPossibleTo, target.FullName)));
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode);
- }
- }
- else if (source.IsAssignableFrom(target))
- {
- Unbox(target);
- if (!isAddress)
- Ldobj(target);
- }
- else
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenIsNotAssignableFrom, target.FullName, source.FullName)));
- }
- else if (target.IsPointer)
- {
- Call(UnboxPointer);
- }
- else if (source.IsPointer)
- {
- Load(source);
- Call(BoxPointer);
- }
- else if (target.IsAssignableFrom(source))
- {
- if (source.IsValueType)
- {
- if (isAddress)
- Ldobj(source);
- Box(source);
- }
- }
- else if (source.IsAssignableFrom(target))
- {
- //assert(source.IsValueType == false);
- Castclass(target);
- }
- else if (target.IsInterface || source.IsInterface)
- {
- Castclass(target);
- }
- else
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenIsNotAssignableFrom, target.FullName, source.FullName)));
- }
- IfState PopIfState()
- {
- object stackTop = blockStack.Pop();
- IfState ifState = stackTop as IfState;
- if (ifState == null)
- ThrowMismatchException(stackTop);
- return ifState;
- }
- #if USE_REFEMIT
- void InitAssemblyBuilder(string methodName)
- {
- //if (assemblyBuilder == null) {
- AssemblyName name = new AssemblyName();
- name.Name = "Microsoft.GeneratedCode."+methodName;
- bool saveAssembly = false;
- if (codeGenTrace != CodeGenTrace.None)
- saveAssembly = true;
- if (saveAssembly)
- {
- assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
- moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name, name.Name + ".dll", false);
- }
- else
- {
- assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
- moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name, false);
- }
- //}
- }
- #endif
- void ThrowMismatchException(object expected)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCodeGenExpectingEnd, expected.ToString())));
- }
- Hashtable LocalNames
- {
- get
- {
- if (localNames == null)
- localNames = new Hashtable();
- return localNames;
- }
- }
- OpCode GetConvOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Boolean:
- return OpCodes.Conv_I1; // TypeCode.Boolean:
- case TypeCode.Char:
- return OpCodes.Conv_I2; // TypeCode.Char:
- case TypeCode.SByte:
- return OpCodes.Conv_I1; // TypeCode.SByte:
- case TypeCode.Byte:
- return OpCodes.Conv_U1; // TypeCode.Byte:
- case TypeCode.Int16:
- return OpCodes.Conv_I2; // TypeCode.Int16:
- case TypeCode.UInt16:
- return OpCodes.Conv_U2; // TypeCode.UInt16:
- case TypeCode.Int32:
- return OpCodes.Conv_I4; // TypeCode.Int32:
- case TypeCode.UInt32:
- return OpCodes.Conv_U4; // TypeCode.UInt32:
- case TypeCode.Int64:
- return OpCodes.Conv_I8; // TypeCode.Int64:
- case TypeCode.UInt64:
- return OpCodes.Conv_I8; // TypeCode.UInt64:
- case TypeCode.Single:
- return OpCodes.Conv_R4; // TypeCode.Single:
- case TypeCode.Double:
- return OpCodes.Conv_R8; // TypeCode.Double:
- default:
- return OpCodes.Nop;
- }
- }
- OpCode GetLdindOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Boolean:
- return OpCodes.Ldind_I1; // TypeCode.Boolean:
- case TypeCode.Char:
- return OpCodes.Ldind_I2; // TypeCode.Char:
- case TypeCode.SByte:
- return OpCodes.Ldind_I1; // TypeCode.SByte:
- case TypeCode.Byte:
- return OpCodes.Ldind_U1; // TypeCode.Byte:
- case TypeCode.Int16:
- return OpCodes.Ldind_I2; // TypeCode.Int16:
- case TypeCode.UInt16:
- return OpCodes.Ldind_U2; // TypeCode.UInt16:
- case TypeCode.Int32:
- return OpCodes.Ldind_I4; // TypeCode.Int32:
- case TypeCode.UInt32:
- return OpCodes.Ldind_U4; // TypeCode.UInt32:
- case TypeCode.Int64:
- return OpCodes.Ldind_I8; // TypeCode.Int64:
- case TypeCode.UInt64:
- return OpCodes.Ldind_I8; // TypeCode.UInt64:
- case TypeCode.Single:
- return OpCodes.Ldind_R4; // TypeCode.Single:
- case TypeCode.Double:
- return OpCodes.Ldind_R8; // TypeCode.Double:
- case TypeCode.String:
- return OpCodes.Ldind_Ref; // TypeCode.String:
- default:
- return OpCodes.Nop;
- }
- //
- }
- OpCode GetLdelemOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Object:
- return OpCodes.Ldelem_Ref; // TypeCode.Object:
- case TypeCode.Boolean:
- return OpCodes.Ldelem_I1; // TypeCode.Boolean:
- case TypeCode.Char:
- return OpCodes.Ldelem_I2; // TypeCode.Char:
- case TypeCode.SByte:
- return OpCodes.Ldelem_I1; // TypeCode.SByte:
- case TypeCode.Byte:
- return OpCodes.Ldelem_U1; // TypeCode.Byte:
- case TypeCode.Int16:
- return OpCodes.Ldelem_I2; // TypeCode.Int16:
- case TypeCode.UInt16:
- return OpCodes.Ldelem_U2; // TypeCode.UInt16:
- case TypeCode.Int32:
- return OpCodes.Ldelem_I4; // TypeCode.Int32:
- case TypeCode.UInt32:
- return OpCodes.Ldelem_U4; // TypeCode.UInt32:
- case TypeCode.Int64:
- return OpCodes.Ldelem_I8; // TypeCode.Int64:
- case TypeCode.UInt64:
- return OpCodes.Ldelem_I8; // TypeCode.UInt64:
- case TypeCode.Single:
- return OpCodes.Ldelem_R4; // TypeCode.Single:
- case TypeCode.Double:
- return OpCodes.Ldelem_R8; // TypeCode.Double:
- case TypeCode.String:
- return OpCodes.Ldelem_Ref; // TypeCode.String:
- default:
- return OpCodes.Nop;
- }
- }
- OpCode GetStelemOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Object:
- return OpCodes.Stelem_Ref; // TypeCode.Object:
- case TypeCode.Boolean:
- return OpCodes.Stelem_I1; // TypeCode.Boolean:
- case TypeCode.Char:
- return OpCodes.Stelem_I2; // TypeCode.Char:
- case TypeCode.SByte:
- return OpCodes.Stelem_I1; // TypeCode.SByte:
- case TypeCode.Byte:
- return OpCodes.Stelem_I1; // TypeCode.Byte:
- case TypeCode.Int16:
- return OpCodes.Stelem_I2; // TypeCode.Int16:
- case TypeCode.UInt16:
- return OpCodes.Stelem_I2; // TypeCode.UInt16:
- case TypeCode.Int32:
- return OpCodes.Stelem_I4; // TypeCode.Int32:
- case TypeCode.UInt32:
- return OpCodes.Stelem_I4; // TypeCode.UInt32:
- case TypeCode.Int64:
- return OpCodes.Stelem_I8; // TypeCode.Int64:
- case TypeCode.UInt64:
- return OpCodes.Stelem_I8; // TypeCode.UInt64:
- case TypeCode.Single:
- return OpCodes.Stelem_R4; // TypeCode.Single:
- case TypeCode.Double:
- return OpCodes.Stelem_R8; // TypeCode.Double:
- case TypeCode.String:
- return OpCodes.Stelem_Ref; // TypeCode.String:
- default:
- return OpCodes.Nop;
- }
- }
- internal void EmitSourceInstruction(string line)
- {
- EmitSourceLine(" " + line);
- }
- internal void EmitSourceLabel(string line)
- {
- EmitSourceLine(line);
- }
- internal void EmitSourceComment(string comment)
- {
- EmitSourceInstruction("// " + comment);
- }
- internal void EmitSourceLine(string line)
- {
- if (codeGenTrace != CodeGenTrace.None)
- OperationInvokerTrace.WriteInstruction(lineNo++, line);
- if (ilGen != null && codeGenTrace == CodeGenTrace.Tron)
- {
- ilGen.Emit(OpCodes.Ldstr, string.Format(CultureInfo.InvariantCulture, "{0:00000}: {1}", lineNo - 1, line));
- ilGen.Emit(OpCodes.Call, OperationInvokerTrace.TraceInstructionMethod);
- }
- }
- internal void EmitStackTop(Type stackTopType)
- {
- if (codeGenTrace != CodeGenTrace.Tron)
- return;
- codeGenTrace = CodeGenTrace.None;
- Dup();
- ToString(stackTopType);
- LocalBuilder topValue = DeclareLocal(typeof(string), "topValue");
- Store(topValue);
- Load("//value = ");
- Load(topValue);
- Concat2();
- Call(OperationInvokerTrace.TraceInstructionMethod);
- codeGenTrace = CodeGenTrace.Tron;
- }
- internal void ToString(Type type)
- {
- if (type.IsValueType)
- {
- Box(type);
- Call(ObjectToString);
- }
- else
- {
- Dup();
- IfNot();
- Pop();
- Load("<null>");
- Else();
- Call(ObjectToString);
- EndIf();
- }
- }
- internal void Concat2()
- {
- Call(StringConcat2);
- }
- internal void LoadZeroValueIntoLocal(Type type, LocalBuilder local)
- {
- if (type.IsValueType)
- {
- switch (Type.GetTypeCode(type))
- {
- case TypeCode.Boolean:
- case TypeCode.Char:
- case TypeCode.SByte:
- case TypeCode.Byte:
- case TypeCode.Int16:
- case TypeCode.UInt16:
- case TypeCode.Int32:
- case TypeCode.UInt32:
- ilGen.Emit(OpCodes.Ldc_I4_0);
- Store(local);
- break;
- case TypeCode.Int64:
- case TypeCode.UInt64:
- ilGen.Emit(OpCodes.Ldc_I4_0);
- ilGen.Emit(OpCodes.Conv_I8);
- Store(local);
- break;
- case TypeCode.Single:
- ilGen.Emit(OpCodes.Ldc_R4, 0.0F);
- Store(local);
- break;
- case TypeCode.Double:
- ilGen.Emit(OpCodes.Ldc_R8, 0.0);
- Store(local);
- break;
- case TypeCode.Decimal:
- case TypeCode.DateTime:
- default:
- LoadAddress(local);
- InitObj(type);
- break;
- }
- }
- else
- {
- Load(null);
- Store(local);
- }
- }
- }
- internal class ArgBuilder
- {
- internal int Index;
- internal Type ArgType;
- internal ArgBuilder(int index, Type argType)
- {
- this.Index = index;
- this.ArgType = argType;
- }
- }
- internal class IfState
- {
- Label elseBegin;
- Label endIf;
- internal Label EndIf
- {
- get
- {
- return this.endIf;
- }
- set
- {
- this.endIf = value;
- }
- }
- internal Label ElseBegin
- {
- get
- {
- return this.elseBegin;
- }
- set
- {
- this.elseBegin = value;
- }
- }
- }
- }
|