private GetTempLocal ( Type type ) : LocalBuilder | ||
type | Type | |
return | LocalBuilder |
void WriteEnumMethod(EnumMapping mapping) { MethodBuilder get_TableName = null; if (mapping.IsFlags) WriteHashtable(mapping, mapping.TypeDesc.Name, out get_TableName); string methodName = (string)MethodNames[mapping]; string fullTypeName = mapping.TypeDesc.CSharpName; List<Type> argTypes = new List<Type>(); List<string> argNames = new List<string>(); Type returnType; Type underlyingType; returnType = mapping.TypeDesc.Type; underlyingType = Enum.GetUnderlyingType(returnType); argTypes.Add(typeof(string)); argNames.Add("s"); ilg = new CodeGenerator(this.typeBuilder); ilg.BeginMethod( returnType, GetMethodBuilder(methodName), argTypes.ToArray(), argNames.ToArray(), CodeGenerator.PrivateMethodAttributes); ConstantMapping[] constants = mapping.Constants; if (mapping.IsFlags) { { MethodInfo XmlSerializationReader_ToEnum = typeof(XmlSerializationReader).GetMethod( "ToEnum", CodeGenerator.StaticBindingFlags, null, new Type[] { typeof(String), typeof(Hashtable), typeof(String) }, null ); ilg.Ldarg("s"); ilg.Ldarg(0); Debug.Assert(get_TableName != null); ilg.Call(get_TableName); ilg.Ldstr(fullTypeName); ilg.Call(XmlSerializationReader_ToEnum); // XmlSerializationReader_ToEnum return long! if (underlyingType != typeof(long)) { ilg.ConvertValue(typeof(long), underlyingType); } ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } } else { List<Label> caseLabels = new List<Label>(); List<object> retValues = new List<object>(); Label defaultLabel = ilg.DefineLabel(); Label endSwitchLabel = ilg.DefineLabel(); // This local is necessary; otherwise, it becomes if/else LocalBuilder localTmp = ilg.GetTempLocal(typeof(string)); ilg.Ldarg("s"); ilg.Stloc(localTmp); ilg.Ldloc(localTmp); ilg.Brfalse(defaultLabel); Hashtable cases = new Hashtable(); for (int i = 0; i < constants.Length; i++) { ConstantMapping c = constants[i]; CodeIdentifier.CheckValidIdentifier(c.Name); if (cases[c.XmlName] == null) { cases[c.XmlName] = c.XmlName; Label caseLabel = ilg.DefineLabel(); ilg.Ldloc(localTmp); ilg.Ldstr(c.XmlName); MethodInfo String_op_Equality = typeof(string).GetMethod( "op_Equality", CodeGenerator.StaticBindingFlags, null, new Type[] { typeof(string), typeof(string) }, null ); ilg.Call(String_op_Equality); ilg.Brtrue(caseLabel); caseLabels.Add(caseLabel); retValues.Add(Enum.ToObject(mapping.TypeDesc.Type, c.Value)); } } ilg.Br(defaultLabel); // Case bodies for (int i = 0; i < caseLabels.Count; i++) { ilg.MarkLabel(caseLabels[i]); ilg.Ldc(retValues[i]); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } MethodInfo XmlSerializationReader_CreateUnknownConstantException = typeof(XmlSerializationReader).GetMethod( "CreateUnknownConstantException", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(string), typeof(Type) }, null ); // Default body ilg.MarkLabel(defaultLabel); ilg.Ldarg(0); ilg.Ldarg("s"); // typeof(..) ilg.Ldc(mapping.TypeDesc.Type); ilg.Call(XmlSerializationReader_CreateUnknownConstantException); ilg.Throw(); // End switch ilg.MarkLabel(endSwitchLabel); } ilg.MarkLabel(ilg.ReturnLabel); ilg.Ldloc(ilg.ReturnLocal); ilg.EndMethod(); }
internal void ILGenForCreateInstance(CodeGenerator ilg, Type type, bool ctorInaccessible, bool cast) { if (!ctorInaccessible) { ConstructorInfo ctor = type.GetConstructor( CodeGenerator.InstanceBindingFlags, Array.Empty<Type>() ); if (ctor != null) ilg.New(ctor); else { Debug.Assert(type.GetTypeInfo().IsValueType); LocalBuilder tmpLoc = ilg.GetTempLocal(type); ilg.Ldloca(tmpLoc); ilg.InitObj(type); ilg.Ldloc(tmpLoc); } return; } ILGenForCreateInstance(ilg, type, cast ? type : null, ctorInaccessible); }