/WCFWebApi/prototype/Microsoft.ApplicationServer.HttpEnhancements/System/ServiceModel/Dispatcher/CodeGenerator.cs
C# | 1481 lines | 1309 code | 165 blank | 7 comment | 190 complexity | c545bf363a038adeb716b2ea6d8eda46 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, Apache-2.0
- // <copyright>
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
-
- namespace System.ServiceModel.Dispatcher
- {
- using System;
- using Collections;
- using System.Diagnostics;
- using Globalization;
- using Reflection;
- using Reflection.Emit;
- using System.Security;
- using Diagnostics;
- using Microsoft.Server.Common;
- using Microsoft.ApplicationServer.HttpEnhancements;
-
- [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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 = this.GetStelemOpCode(Type.GetTypeCode(arrayElementType));
- if (opCode.Equals(OpCodes.Nop))
- {
- throw Fx.Exception.AsError(
- new InvalidOperationException(SR2.SFxCodeGenArrayTypeIsNotSupported(arrayElementType.FullName)));
- }
- if (this.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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 Fx.Exception.AsError(new InvalidOperationException(SR2.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;
- }
-
- // REVIEW, stefanph: What's the type code for Ldind_I (natural int)?
- }
-
- 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;
- }
- }
- }
- }
-
-