| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- // ***NOTE*** If this code is changed, make corresponding changes in System.ServiceModel.CodeGenerator also
- namespace System.Runtime.Serialization
- {
- using System;
- using System.Collections;
- using System.Diagnostics;
- using System.Globalization;
- using System.Reflection;
- #if !NO_DYNAMIC_CODEGEN
- using System.Reflection.Emit;
- #endif
- using System.Security;
- class CodeGenerator
- {
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo getTypeFromHandle;
- static MethodInfo GetTypeFromHandle
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical getTypeFromHandle field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (getTypeFromHandle == null)
- getTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
- return getTypeFromHandle;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo stringFormat;
- static MethodInfo StringFormat
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical stringFormat field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (stringFormat == null)
- stringFormat = typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object[]) });
- return stringFormat;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo stringConcat2;
- static MethodInfo StringConcat2
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical stringConcat2 field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (stringConcat2 == null)
- stringConcat2 = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) });
- return stringConcat2;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo stringConcat3;
- static MethodInfo StringConcat3
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical stringConcat3 field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (stringConcat3 == null)
- stringConcat3 = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) });
- return stringConcat3;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo objectToString;
- static MethodInfo ObjectToString
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical objectToString field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (objectToString == null)
- objectToString = typeof(object).GetMethod("ToString", new Type[0]);
- return objectToString;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo objectEquals;
- static MethodInfo ObjectEquals
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical objectEquals field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (objectEquals == null)
- objectEquals = Globals.TypeOfObject.GetMethod("Equals", BindingFlags.Public | BindingFlags.Static);
- return objectEquals;
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static MethodInfo arraySetValue;
- static MethodInfo ArraySetValue
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical arraySetValue field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (arraySetValue == null)
- arraySetValue = typeof(Array).GetMethod("SetValue", new Type[] { typeof(object), typeof(int) });
- return arraySetValue;
- }
- }
- Type delegateType;
- #if USE_REFEMIT
- AssemblyBuilder assemblyBuilder;
- ModuleBuilder moduleBuilder;
- TypeBuilder typeBuilder;
- static int typeCounter;
- MethodBuilder methodBuilder;
- #else
- [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- [SecurityCritical]
- static Module serializationModule;
- static Module SerializationModule
- {
- [Fx.Tag.SecurityNote(Critical = "Fetches the critical serializationModule field.",
- Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")]
- [SecuritySafeCritical]
- get
- {
- if (serializationModule == null)
- {
- serializationModule = typeof(CodeGenerator).Module; // could to be replaced by different dll that has SkipVerification set to false
- }
- return serializationModule;
- }
- }
- DynamicMethod dynamicMethod;
- #endif
- ILGenerator ilGen;
- ArrayList argList;
- Stack blockStack;
- Label methodEndLabel;
- LocalBuilder stringFormatArray;
- Hashtable localNames;
- int lineNo = 1;
- enum CodeGenTrace { None, Save, Tron };
- CodeGenTrace codeGenTrace;
- internal CodeGenerator()
- {
- SourceSwitch codeGenSwitch = SerializationTrace.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;
- }
- #if !USE_REFEMIT
- internal void BeginMethod(DynamicMethod dynamicMethod, Type delegateType, string methodName, Type[] argTypes, bool allowPrivateMemberAccess)
- {
- this.dynamicMethod = dynamicMethod;
- this.ilGen = this.dynamicMethod.GetILGenerator();
- this.delegateType = delegateType;
- InitILGeneration(methodName, argTypes);
- }
- #endif
- 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();
- #endif
- InitILGeneration(methodName, argTypes);
- }
- void InitILGeneration(string methodName, Type[] argTypes)
- {
- 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();
- 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, object initialValue)
- {
- LocalBuilder local = DeclareLocal(type, name);
- Load(initialValue);
- Store(local);
- return local;
- }
- 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 Set(LocalBuilder local, object value)
- {
- Load(value);
- Store(local);
- }
- internal object For(LocalBuilder local, object start, object end)
- {
- ForState forState = new ForState(local, DefineLabel(), DefineLabel(), end);
- if (forState.Index != null)
- {
- Load(start);
- Stloc(forState.Index);
- Br(forState.TestLabel);
- }
- MarkLabel(forState.BeginLabel);
- blockStack.Push(forState);
- return forState;
- }
- internal void EndFor()
- {
- object stackTop = blockStack.Pop();
- ForState forState = stackTop as ForState;
- if (forState == null)
- ThrowMismatchException(stackTop);
- if (forState.Index != null)
- {
- Ldloc(forState.Index);
- Ldc(1);
- Add();
- Stloc(forState.Index);
- MarkLabel(forState.TestLabel);
- Ldloc(forState.Index);
- Load(forState.End);
- if (GetVariableType(forState.End).IsArray)
- Ldlen();
- Blt(forState.BeginLabel);
- }
- else
- Br(forState.BeginLabel);
- if (forState.RequiresEndLabel)
- MarkLabel(forState.EndLabel);
- }
- internal void Break(object forState)
- {
- InternalBreakFor(forState, OpCodes.Br);
- }
- internal void IfTrueBreak(object forState)
- {
- InternalBreakFor(forState, OpCodes.Brtrue);
- }
- internal void IfFalseBreak(object forState)
- {
- InternalBreakFor(forState, OpCodes.Brfalse);
- }
- internal void InternalBreakFor(object userForState, OpCode branchInstruction)
- {
- foreach (object block in blockStack)
- {
- ForState forState = block as ForState;
- if (forState != null && (object)forState == userForState)
- {
- if (!forState.RequiresEndLabel)
- {
- forState.EndLabel = DefineLabel();
- forState.RequiresEndLabel = true;
- }
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(branchInstruction + " " + forState.EndLabel.GetHashCode());
- ilGen.Emit(branchInstruction, forState.EndLabel);
- break;
- }
- }
- }
- internal void ForEach(LocalBuilder local, Type elementType, Type enumeratorType,
- LocalBuilder enumerator, MethodInfo getCurrentMethod)
- {
- ForState forState = new ForState(local, DefineLabel(), DefineLabel(), enumerator);
- Br(forState.TestLabel);
- MarkLabel(forState.BeginLabel);
- Call(enumerator, getCurrentMethod);
- ConvertValue(elementType, GetVariableType(local));
- Stloc(local);
- blockStack.Push(forState);
- }
- internal void EndForEach(MethodInfo moveNextMethod)
- {
- object stackTop = blockStack.Pop();
- ForState forState = stackTop as ForState;
- if (forState == null)
- ThrowMismatchException(stackTop);
- MarkLabel(forState.TestLabel);
- object enumerator = forState.End;
- Call(enumerator, moveNextMethod);
- Brtrue(forState.BeginLabel);
- if (forState.RequiresEndLabel)
- MarkLabel(forState.EndLabel);
- }
- internal void IfNotDefaultValue(object value)
- {
- Type type = GetVariableType(value);
- TypeCode typeCode = Type.GetTypeCode(type);
- if ((typeCode == TypeCode.Object && type.IsValueType) ||
- typeCode == TypeCode.DateTime || typeCode == TypeCode.Decimal)
- {
- LoadDefaultValue(type);
- ConvertValue(type, Globals.TypeOfObject);
- Load(value);
- ConvertValue(type, Globals.TypeOfObject);
- Call(ObjectEquals);
- IfNot();
- }
- else
- {
- LoadDefaultValue(type);
- Load(value);
- If(Cmp.NotEqualTo);
- }
- }
- internal void If()
- {
- InternalIf(false);
- }
- internal void IfNot()
- {
- InternalIf(true);
- }
- OpCode GetBranchCode(Cmp cmp)
- {
- switch (cmp)
- {
- case Cmp.LessThan:
- return OpCodes.Bge;
- case Cmp.EqualTo:
- return OpCodes.Bne_Un;
- case Cmp.LessThanOrEqualTo:
- return OpCodes.Bgt;
- case Cmp.GreaterThan:
- return OpCodes.Ble;
- case Cmp.NotEqualTo:
- return OpCodes.Beq;
- default:
- Fx.Assert(cmp == Cmp.GreaterThanOrEqualTo, "Unexpected cmp");
- return OpCodes.Blt;
- }
- }
- Cmp GetCmpInverse(Cmp cmp)
- {
- switch (cmp)
- {
- case Cmp.LessThan:
- return Cmp.GreaterThanOrEqualTo;
- case Cmp.EqualTo:
- return Cmp.NotEqualTo;
- case Cmp.LessThanOrEqualTo:
- return Cmp.GreaterThan;
- case Cmp.GreaterThan:
- return Cmp.LessThanOrEqualTo;
- case Cmp.NotEqualTo:
- return Cmp.EqualTo;
- default:
- Fx.Assert(cmp == Cmp.GreaterThanOrEqualTo, "Unexpected cmp");
- return Cmp.LessThan;
- }
- }
- internal void If(Cmp cmpOp)
- {
- IfState ifState = new IfState();
- ifState.EndIf = DefineLabel();
- ifState.ElseBegin = DefineLabel();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + GetCmpInverse(cmpOp).ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
- ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- internal void If(object value1, Cmp cmpOp, object value2)
- {
- Load(value1);
- Load(value2);
- If(cmpOp);
- }
- internal void Else()
- {
- IfState ifState = PopIfState();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- ifState.ElseBegin = ifState.EndIf;
- blockStack.Push(ifState);
- }
- internal void ElseIf(object value1, Cmp cmpOp, object value2)
- {
- IfState ifState = (IfState)blockStack.Pop();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- Load(value1);
- Load(value2);
- ifState.ElseBegin = DefineLabel();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + GetCmpInverse(cmpOp).ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
- ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- internal void EndIf()
- {
- IfState ifState = PopIfState();
- if (!ifState.ElseBegin.Equals(ifState.EndIf))
- MarkLabel(ifState.ElseBegin);
- MarkLabel(ifState.EndIf);
- }
- internal void VerifyParameterCount(MethodInfo methodInfo, int expectedCount)
- {
- if (methodInfo.GetParameters().Length != expectedCount)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ParameterCountMismatch, methodInfo.Name, methodInfo.GetParameters().Length, expectedCount)));
- }
- internal void Call(object thisObj, MethodInfo methodInfo)
- {
- VerifyParameterCount(methodInfo, 0);
- LoadThis(thisObj, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1)
- {
- VerifyParameterCount(methodInfo, 1);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2)
- {
- VerifyParameterCount(methodInfo, 2);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- LoadParam(param2, 2, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3)
- {
- VerifyParameterCount(methodInfo, 3);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- LoadParam(param2, 2, methodInfo);
- LoadParam(param3, 3, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4)
- {
- VerifyParameterCount(methodInfo, 4);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- LoadParam(param2, 2, methodInfo);
- LoadParam(param3, 3, methodInfo);
- LoadParam(param4, 4, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5)
- {
- VerifyParameterCount(methodInfo, 5);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- LoadParam(param2, 2, methodInfo);
- LoadParam(param3, 3, methodInfo);
- LoadParam(param4, 4, methodInfo);
- LoadParam(param5, 5, methodInfo);
- Call(methodInfo);
- }
- internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5, object param6)
- {
- VerifyParameterCount(methodInfo, 6);
- LoadThis(thisObj, methodInfo);
- LoadParam(param1, 1, methodInfo);
- LoadParam(param2, 2, methodInfo);
- LoadParam(param3, 3, methodInfo);
- LoadParam(param4, 4, methodInfo);
- LoadParam(param5, 5, methodInfo);
- LoadParam(param6, 6, methodInfo);
- Call(methodInfo);
- }
- internal void Call(MethodInfo methodInfo)
- {
- if (methodInfo.IsVirtual && !methodInfo.DeclaringType.IsValueType)
- {
- 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 Call(ConstructorInfo ctor)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Call " + ctor.ToString() + " on type " + ctor.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Call, ctor);
- }
- internal void New(ConstructorInfo constructorInfo)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Newobj " + constructorInfo.ToString() + " on type " + constructorInfo.DeclaringType.ToString());
- ilGen.Emit(OpCodes.Newobj, constructorInfo);
- }
- internal void New(ConstructorInfo constructorInfo, object param1)
- {
- LoadParam(param1, 1, constructorInfo);
- New(constructorInfo);
- }
- internal void InitObj(Type valueType)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Initobj " + valueType);
- ilGen.Emit(OpCodes.Initobj, valueType);
- }
- internal void NewArray(Type elementType, object len)
- {
- Load(len);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Newarr " + elementType);
- ilGen.Emit(OpCodes.Newarr, elementType);
- }
- internal void IgnoreReturnValue()
- {
- Pop();
- }
- 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 arrayType = GetVariableType(obj);
- if (arrayType == Globals.TypeOfArray)
- {
- Call(obj, ArraySetValue, value, arrayIndex);
- }
- else
- {
- Type objType = arrayType.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 Type LoadMember(MemberInfo memberInfo)
- {
- Type memberType = null;
- if (memberInfo.MemberType == MemberTypes.Field)
- {
- FieldInfo fieldInfo = (FieldInfo)memberInfo;
- memberType = fieldInfo.FieldType;
- if (fieldInfo.IsStatic)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldsfld " + fieldInfo + " on type " + fieldInfo.DeclaringType);
- ilGen.Emit(OpCodes.Ldsfld, fieldInfo);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldfld " + fieldInfo + " on type " + fieldInfo.DeclaringType);
- ilGen.Emit(OpCodes.Ldfld, fieldInfo);
- }
- }
- else if (memberInfo.MemberType == MemberTypes.Property)
- {
- PropertyInfo property = memberInfo as PropertyInfo;
- memberType = property.PropertyType;
- if (property != null)
- {
- MethodInfo getMethod = property.GetGetMethod(true);
- if (getMethod == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NoGetMethodForProperty, property.DeclaringType, property)));
- Call(getMethod);
- }
- }
- else if (memberInfo.MemberType == MemberTypes.Method)
- {
- MethodInfo method = (MethodInfo)memberInfo;
- memberType = method.ReturnType;
- Call(method);
- }
- else
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotLoadMemberType, memberInfo.MemberType, memberInfo.DeclaringType, memberInfo.Name)));
- EmitStackTop(memberType);
- return memberType;
- }
- internal void StoreMember(MemberInfo memberInfo)
- {
- if (memberInfo.MemberType == MemberTypes.Field)
- {
- FieldInfo fieldInfo = (FieldInfo)memberInfo;
- if (fieldInfo.IsStatic)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stsfld " + fieldInfo + " on type " + fieldInfo.DeclaringType);
- ilGen.Emit(OpCodes.Stsfld, fieldInfo);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stfld " + fieldInfo + " on type " + fieldInfo.DeclaringType);
- ilGen.Emit(OpCodes.Stfld, fieldInfo);
- }
- }
- else if (memberInfo.MemberType == MemberTypes.Property)
- {
- PropertyInfo property = memberInfo as PropertyInfo;
- if (property != null)
- {
- MethodInfo setMethod = property.GetSetMethod(true);
- if (setMethod == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NoSetMethodForProperty, property.DeclaringType, property)));
- Call(setMethod);
- }
- }
- else if (memberInfo.MemberType == MemberTypes.Method)
- Call((MethodInfo)memberInfo);
- else
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotLoadMemberType, memberInfo.MemberType)));
- }
- internal void LoadDefaultValue(Type type)
- {
- if (type.IsValueType)
- {
- switch (Type.GetTypeCode(type))
- {
- case TypeCode.Boolean:
- Ldc(false);
- break;
- case TypeCode.Char:
- case TypeCode.SByte:
- case TypeCode.Byte:
- case TypeCode.Int16:
- case TypeCode.UInt16:
- case TypeCode.Int32:
- case TypeCode.UInt32:
- Ldc(0);
- break;
- case TypeCode.Int64:
- case TypeCode.UInt64:
- Ldc(0L);
- break;
- case TypeCode.Single:
- Ldc(0.0F);
- break;
- case TypeCode.Double:
- Ldc(0.0);
- break;
- case TypeCode.Decimal:
- case TypeCode.DateTime:
- default:
- LocalBuilder zero = DeclareLocal(type, "zero");
- LoadAddress(zero);
- InitObj(type);
- Load(zero);
- break;
- }
- }
- else
- Load(null);
- }
- 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
- {
- Fx.Assert("Data can only be stored into ArgBuilder or LocalBuilder.");
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CanOnlyStoreIntoArgOrLocGot0, DataContract.GetClrTypeFullName(var.GetType()))));
- }
- }
- internal void Dec(object var)
- {
- Load(var);
- Load(1);
- Subtract();
- Store(var);
- }
- internal void Inc(object var)
- {
- Load(var);
- Load(1);
- Add();
- Store(var);
- }
- 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);
- }
- 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;
- }
- //
- }
- 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 Ceq()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ceq");
- ilGen.Emit(OpCodes.Ceq);
- }
- internal void Bgt(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Bgt " + label.GetHashCode());
- ilGen.Emit(OpCodes.Bgt, label);
- }
- internal void Ble(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ble " + label.GetHashCode());
- ilGen.Emit(OpCodes.Ble, label);
- }
- internal void Throw()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Throw");
- ilGen.Emit(OpCodes.Throw);
- }
- 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:
- Fx.Assert("Char is not a valid schema primitive and should be treated as int in DataContract");
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.CharIsInvalidPrimitive)));
- 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.UInt64:
- Ldc((long)(ulong)o);
- break;
- case TypeCode.Int64:
- Ldc((long)o);
- break;
- case TypeCode.Single:
- Ldc((float)o);
- break;
- case TypeCode.Double:
- Ldc((double)o);
- break;
- case TypeCode.String:
- Ldstr((string)o);
- break;
- case TypeCode.Object:
- case TypeCode.Decimal:
- case TypeCode.DateTime:
- case TypeCode.Empty:
- case TypeCode.DBNull:
- default:
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownConstantType, DataContract.GetClrTypeFullName(valueType))));
- }
- }
- }
- 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 Ldc(long l)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.i8 " + l);
- ilGen.Emit(OpCodes.Ldc_I8, l);
- }
- internal void Ldc(float f)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.r4 " + f);
- ilGen.Emit(OpCodes.Ldc_R4, f);
- }
- internal void Ldc(double d)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.r8 " + d);
- ilGen.Emit(OpCodes.Ldc_R8, d);
- }
- 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 Ldlen()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldlen");
- ilGen.Emit(OpCodes.Ldlen);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Conv.i4");
- ilGen.Emit(OpCodes.Conv_I4);
- }
- OpCode GetLdelemOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Object:
- case TypeCode.DBNull:
- 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;
- }
- }
- 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 System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
- 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);
- }
- OpCode GetStelemOpCode(TypeCode typeCode)
- {
- switch (typeCode)
- {
- case TypeCode.Object:
- case TypeCode.DBNull:
- 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 Stelem(Type arrayElementType)
- {
- if (arrayElementType.IsEnum)
- Stelem(Enum.GetUnderlyingType(arrayElementType));
- else
- {
- OpCode opCode = GetStelemOpCode(Type.GetTypeCode(arrayElementType));
- if (opCode.Equals(OpCodes.Nop))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
- 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 Add()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Add");
- ilGen.Emit(OpCodes.Add);
- }
- internal void Subtract()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Sub");
- ilGen.Emit(OpCodes.Sub);
- }
- internal void And()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("And");
- ilGen.Emit(OpCodes.And);
- }
- internal void Or()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Or");
- ilGen.Emit(OpCodes.Or);
- }
- internal void Not()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Not");
- ilGen.Emit(OpCodes.Not);
- }
- 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 Blt(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Blt " + label.GetHashCode());
- ilGen.Emit(OpCodes.Blt, 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 LoadThis(object thisObj, MethodInfo methodInfo)
- {
- if (thisObj != null && !methodInfo.IsStatic)
- {
- LoadAddress(thisObj);
- ConvertAddress(GetVariableType(thisObj), methodInfo.DeclaringType);
- }
- }
- void LoadParam(object arg, int oneBasedArgIndex, MethodBase methodInfo)
- {
- Load(arg);
- if (arg != null)
- ConvertValue(GetVariableType(arg), methodInfo.GetParameters()[oneBasedArgIndex - 1].ParameterType);
- }
- 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);
- }
- 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;
- }
- }
- 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 System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NoConversionPossibleTo, DataContract.GetClrTypeFullName(target))));
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode);
- }
- }
- else if (source.IsAssignableFrom(target))
- {
- Unbox(target);
- if (!isAddress)
- Ldobj(target);
- }
- else
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
- }
- 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 System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
- }
- 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)
- {
- AssemblyName name = new AssemblyName();
- name.Name = "Microsoft.GeneratedCode."+methodName;
- assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
- moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name, name.Name + ".dll", false);
- }
- #endif
- void ThrowMismatchException(object expected)
- {
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ExpectingEnd, expected.ToString())));
- }
- Hashtable LocalNames
- {
- get
- {
- if (localNames == null)
- localNames = new Hashtable();
- return localNames;
- }
- }
- 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)
- SerializationTrace.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, XmlFormatGeneratorStatics.TraceInstructionMethod);
- }
- }
- internal void EmitStackTop(Type stackTopType)
- {
- if (codeGenTrace != CodeGenTrace.Tron)
- return;
- codeGenTrace = CodeGenTrace.None;
- Dup();
- ToDebuggableString(stackTopType);
- LocalBuilder topValue = DeclareLocal(Globals.TypeOfString, "topValue");
- Store(topValue);
- Load("//value = ");
- Load(topValue);
- Concat2();
- Call(XmlFormatGeneratorStatics.TraceInstructionMethod);
- codeGenTrace = CodeGenTrace.Tron;
- }
- internal void ToString(Type type)
- {
- if (type != Globals.TypeOfString)
- {
- if (type.IsValueType)
- {
- Box(type);
- }
- Call(ObjectToString);
- }
- }
- internal void ToDebuggableString(Type type)
- {
- if (type.IsValueType)
- {
- Box(type);
- Call(ObjectToString);
- }
- else
- {
- Dup();
- Load(null);
- If(Cmp.EqualTo);
- Pop();
- Load("<null>");
- Else();
- if (type.IsArray)
- {
- LocalBuilder arrayVar = DeclareLocal(type, "arrayVar");
- Store(arrayVar);
- Load("{ ");
- LocalBuilder arrayValueString = DeclareLocal(typeof(string), "arrayValueString");
- Store(arrayValueString);
- LocalBuilder i = DeclareLocal(typeof(int), "i");
- For(i, 0, arrayVar);
- Load(arrayValueString);
- LoadArrayElement(arrayVar, i);
- ToDebuggableString(arrayVar.LocalType.GetElementType());
- Load(", ");
- Concat3();
- Store(arrayValueString);
- EndFor();
- Load(arrayValueString);
- Load("}");
- Concat2();
- }
- else
- Call(ObjectToString);
- EndIf();
- }
- }
- internal void Concat2()
- {
- Call(StringConcat2);
- }
- internal void Concat3()
- {
- Call(StringConcat3);
- }
- internal Label[] Switch(int labelCount)
- {
- SwitchState switchState = new SwitchState(DefineLabel(), DefineLabel());
- Label[] caseLabels = new Label[labelCount];
- for (int i = 0; i < caseLabels.Length; i++)
- caseLabels[i] = DefineLabel();
- if (codeGenTrace != CodeGenTrace.None)
- {
- EmitSourceInstruction("switch (");
- foreach (Label l in caseLabels)
- EmitSourceInstruction(" " + l.GetHashCode());
- EmitSourceInstruction(") {");
- }
- ilGen.Emit(OpCodes.Switch, caseLabels);
- Br(switchState.DefaultLabel);
- blockStack.Push(switchState);
- return caseLabels;
- }
- internal void Case(Label caseLabel1, string caseLabelName)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("case " + caseLabelName + "{");
- MarkLabel(caseLabel1);
- }
- internal void EndCase()
- {
- object stackTop = blockStack.Peek();
- SwitchState switchState = stackTop as SwitchState;
- if (switchState == null)
- ThrowMismatchException(stackTop);
- Br(switchState.EndOfSwitchLabel);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("} //end case ");
- }
- internal void DefaultCase()
- {
- object stackTop = blockStack.Peek();
- SwitchState switchState = stackTop as SwitchState;
- if (switchState == null)
- ThrowMismatchException(stackTop);
- MarkLabel(switchState.DefaultLabel);
- switchState.DefaultDefined = true;
- }
- internal void EndSwitch()
- {
- object stackTop = blockStack.Pop();
- SwitchState switchState = stackTop as SwitchState;
- if (switchState == null)
- ThrowMismatchException(stackTop);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("} //end switch");
- if (!switchState.DefaultDefined)
- MarkLabel(switchState.DefaultLabel);
- MarkLabel(switchState.EndOfSwitchLabel);
- }
- internal void CallStringFormat(string msg, params object[] values)
- {
- NewArray(typeof(object), values.Length);
- if (stringFormatArray == null)
- stringFormatArray = DeclareLocal(typeof(object[]), "stringFormatArray");
- Stloc(stringFormatArray);
- for (int i = 0; i < values.Length; i++)
- StoreArrayElement(stringFormatArray, i, values[i]);
- Load(msg);
- Load(stringFormatArray);
- Call(StringFormat);
- }
- static MethodInfo stringLength = typeof(string).GetProperty("Length").GetGetMethod();
- internal void ElseIfIsEmptyString(LocalBuilder strLocal)
- {
- IfState ifState = (IfState)blockStack.Pop();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- Load(strLocal);
- Call(stringLength);
- Load(0);
- ifState.ElseBegin = DefineLabel();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + GetCmpInverse(Cmp.EqualTo).ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
- ilGen.Emit(GetBranchCode(Cmp.EqualTo), ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- internal void IfNotIsEmptyString(LocalBuilder strLocal)
- {
- Load(strLocal);
- Call(stringLength);
- Load(0);
- If(Cmp.NotEqualTo);
- }
- internal void BeginWhileCondition()
- {
- Label startWhile = DefineLabel();
- MarkLabel(startWhile);
- blockStack.Push(startWhile);
- }
- internal void BeginWhileBody(Cmp cmpOp)
- {
- Label startWhile = (Label)blockStack.Pop();
- If(cmpOp);
- blockStack.Push(startWhile);
- }
- internal void EndWhile()
- {
- Label startWhile = (Label)blockStack.Pop();
- Br(startWhile);
- EndIf();
- }
- #if NotUsed
- static MethodInfo stringCompare = typeof(string).GetMethod("Compare", new Type[] { typeof(string), typeof(string) });
- internal void ElseIfString(object s1, Cmp cmpOp, object s2)
- {
- IfState ifState = (IfState)blockStack.Pop();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- Load(s1);
- Load(s2);
- Call(stringCompare);
- Load(0);
- ifState.ElseBegin = DefineLabel();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + GetCmpInverse(cmpOp).ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
- ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- internal void IfString(object s1, Cmp cmpOp, object s2)
- {
- Load(s1);
- Load(s2);
- Call(stringCompare);
- Load(0);
- If(cmpOp);
- }
- static MethodInfo stringEquals = typeof(string).GetMethod("Equals", new Type[]{ typeof(string), typeof(string)});
- static ConstructorInfo permissionSetCtor = typeof(PermissionSet).GetConstructor(new Type[]{ typeof(PermissionState)});
- static MethodInfo permissionSetDemand = typeof(PermissionSet).GetMethod("Demand", new Type[0]);
- internal void AndIf(Cmp cmpOp)
- {
- IfState ifState = (IfState) blockStack.Peek();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + CmpInverse[(int) cmpOp].ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString());
- ilGen.Emit(BranchCode[(int)cmpOp], ifState.ElseBegin);
- }
- internal void AndIf()
- {
- IfState ifState = (IfState) blockStack.Peek();
- Brfalse(ifState.ElseBegin);
- }
- internal void ElseIf(object boolVal)
- {
- InternalElseIf(boolVal, false);
- }
- void InternalElseIf(object boolVal, bool negate)
- {
- IfState ifState = (IfState)blockStack.Pop();
- Br(ifState.EndIf);
- MarkLabel(ifState.ElseBegin);
- Load(boolVal);
- ifState.ElseBegin = DefineLabel();
- if (negate)
- Brtrue(ifState.ElseBegin);
- else
- Brfalse(ifState.ElseBegin);
- blockStack.Push(ifState);
- }
-
- internal void While(object value1, Cmp cmpOp, object value2)
- {
- IfState ifState = new IfState();
- ifState.EndIf = DefineLabel();
- ifState.ElseBegin = DefineLabel();
- ilGen.MarkLabel(ifState.ElseBegin);
- Load(value1);
- Load(value2);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Branch if " + CmpInverse[(int) cmpOp].ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString());
- ilGen.Emit(BranchCode[(int)cmpOp], ifState.EndIf);
- blockStack.Push(ifState);
- }
- internal void EndWhile()
- {
- IfState ifState = PopIfState();
- Br(ifState.ElseBegin);
- MarkLabel(ifState.EndIf);
- }
- internal void ElseIfNot(object boolVal)
- {
- InternalElseIf(boolVal, true);
- }
- }
- internal void Ldc(long l)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.i8 " + l);
- ilGen.Emit(OpCodes.Ldc_I8, l);
- }
- internal void Ldc(float f)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.r4 " + f);
- ilGen.Emit(OpCodes.Ldc_R4, f);
- }
- internal void Ldc(double d)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Ldc.r8 " + d);
- ilGen.Emit(OpCodes.Ldc_R8, d);
- }
- internal void IsInst(Type type)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("IsInst " + DataContract.GetClrTypeFullName(type));
- ilGen.Emit(OpCodes.Isinst, type);
- }
- internal void Clt()
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Clt");
- ilGen.Emit(OpCodes.Clt);
- }
- internal void StringEquals()
- {
- Call(stringEquals);
- }
- internal void StringEquals(object s1, object s2)
- {
- Load(s1);
- ConvertValue(GetVariableType(s1), typeof(string));
- Load(s2);
- ConvertValue(GetVariableType(s2), typeof(string));
- StringEquals();
- }
- internal void Bge(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Bge " + label.GetHashCode());
- ilGen.Emit(OpCodes.Bge, label);
- }
- internal void Beq(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Beq " + label.GetHashCode());
- ilGen.Emit(OpCodes.Beq, label);
- }
- internal void Bne(Label label)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Bne " + label.GetHashCode());
- ilGen.Emit(OpCodes.Bne_Un, label);
- }
- internal void ResizeArray(object arrayVar, object sizeVar)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("ResizeArray() {");
- Label doResize = DefineLabel();
- Load(arrayVar);
- Load(null);
- Beq(doResize);
- Ldlen(arrayVar);
- Load(sizeVar);
- If(Cmp.NotEqualTo);
- MarkLabel(doResize);
- Type arrayType = GetVariableType(arrayVar);
- Type elementType = arrayType.GetElementType();
- LocalBuilder tempArray = DeclareLocal(arrayType, "tempArray");
- NewArray(elementType, sizeVar);
- Store(tempArray);
- CopyArray(arrayVar, tempArray, sizeVar);
- Load(tempArray);
- Store(arrayVar);
- EndIf();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("} // ResizeArray");
- }
- LocalBuilder resizeLen, resizeCounter;
- internal void EnsureArrayCapacity(object arrayVar, object lastElementVar)
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("EnsureArrayCapacity() {");
- Type arrayType = GetVariableType(arrayVar);
- Type elementType = arrayType.GetElementType();
- If(arrayVar, Cmp.EqualTo, null);
- NewArray(elementType, 4);
- Store(arrayVar);
- Else();
- Load(lastElementVar);
- Ldlen(arrayVar);
- If(Cmp.GreaterThanOrEqualTo);
- LocalBuilder tempArray = DeclareLocal(arrayType, "tempArray");
- if (resizeLen == null)
- resizeLen = DeclareLocal(typeof(int), "resizeLen");
- Load(lastElementVar);
- Load(2);
- Mul();
- Store(resizeLen);
- NewArray(elementType, resizeLen);
- Store(tempArray);
- CopyArray(arrayVar, tempArray, arrayVar);
- Load(tempArray);
- Store(arrayVar);
- EndIf();
- EndIf();
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("} // EnsureArrayCapacity");
- }
- internal void CopyArray(object sourceArray, object destArray, object length)
- {
- If(sourceArray, Cmp.NotEqualTo, null);
- if (resizeCounter == null)
- resizeCounter = DeclareLocal(typeof(int), "resizeCounter");
- For(resizeCounter, 0, length);
- Load(destArray);
- Load(resizeCounter);
- LoadArrayElement(sourceArray, resizeCounter);
- Stelem(GetVariableType(destArray).GetElementType());
- EndFor();
- EndIf();
- }
- internal void GotoMethodEnd()
- {
- Br(this.methodEndLabel);
- }
- internal void AndWhile(Cmp cmpOp)
- {
- object startWhile = blockStack.Pop();
- AndIf(cmpOp);
- blockStack.Push(startWhile);
- }
- internal void BeginWhileBody(Cmp cmpOp)
- {
- Label startWhile = (Label) blockStack.Pop();
- If(cmpOp);
- blockStack.Push(startWhile);
- }
- internal void Cne()
- {
- Ceq();
- Load(0);
- Ceq();
- }
- internal void New(ConstructorInfo constructorInfo, object param1, object param2)
- {
- LoadParam(param1, 1, constructorInfo);
- LoadParam(param2, 2, constructorInfo);
- New(constructorInfo);
- }
- //This code is not tested
- internal void Stind(Type type)
- {
- OpCode opCode = StindOpCodes[(int) Type.GetTypeCode(type)];
- if (!opCode.Equals(OpCodes.Nop))
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction(opCode.ToString());
- ilGen.Emit(opCode);
- }
- else
- {
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceInstruction("Stobj " + type);
- ilGen.Emit(OpCodes.Stobj, type);
- }
- }
- //This code is not tested
- internal void StoreOutParam(ArgBuilder arg, object value)
- {
- Type destType = arg.ArgType;
- if (!destType.IsByRef)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.OutParametersMustBeByRefTypeReceived, DataContract.GetClrTypeFullName(destType))));
- destType = destType.GetElementType();
- Type sourceType;
- if (value is ArgBuilder)
- sourceType = ((ArgBuilder) value).ArgType;
- else if (value is LocalBuilder)
- sourceType = ((LocalBuilder) value).LocalType;
- else if (value != null)
- sourceType = value.GetType();
- else
- sourceType = null;
- Load(arg);
- Load(value);
- if (sourceType != null)
- ConvertAddress(sourceType, destType);
- Stind(destType);
- }
- void CheckSecurity(FieldInfo field)
- {
- if (fullTrustDemanded)
- return;
- if (IsProtectedWithSecurity(field))
- DemandFullTrust();
- }
- void CheckSecurity(MethodBase method)
- {
- if (fullTrustDemanded)
- return;
- if (IsProtectedWithSecurity(method))
- DemandFullTrust();
- }
- void CheckSecurity(Type type)
- {
- if (fullTrustDemanded)
- return;
- if (IsProtectedWithSecurity(type))
- DemandFullTrust();
- }
- void CheckSecurity(Assembly assembly)
- {
- if (fullTrustDemanded)
- return;
- if (IsProtectedWithSecurity(assembly))
- DemandFullTrust();
- }
- static bool IsProtectedWithSecurity(FieldInfo field)
- {
- return IsProtectedWithSecurity(field.DeclaringType);
- }
- static bool IsProtectedWithSecurity(Type type)
- {
- return IsProtectedWithSecurity(type.Assembly) || (type.Attributes & TypeAttributes.HasSecurity) != 0;
- }
- static bool IsProtectedWithSecurity(Assembly assembly)
- {
- object[] attrs = assembly.GetCustomAttributes(typeof(AllowPartiallyTrustedCallersAttribute), true);
- bool hasAptca = attrs != null && attrs.Length > 0;
- return !hasAptca;
- }
- void DemandFullTrust()
- {
- fullTrustDemanded = true;
- /*
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("DemandFullTrust() {");
- Ldc(PermissionState.Unrestricted);
- New(permissionSetCtor);
- Call(permissionSetDemand);
- if (codeGenTrace != CodeGenTrace.None)
- EmitSourceComment("}");
- */
- }
- static bool IsProtectedWithSecurity(MethodBase method)
- {
- return false;
- //return (method.Attributes & MethodAttributes.HasSecurity) != 0;
- }
- #endif
- }
- internal class ArgBuilder
- {
- internal int Index;
- internal Type ArgType;
- internal ArgBuilder(int index, Type argType)
- {
- this.Index = index;
- this.ArgType = argType;
- }
- }
- internal class ForState
- {
- LocalBuilder indexVar;
- Label beginLabel;
- Label testLabel;
- Label endLabel;
- bool requiresEndLabel;
- object end;
- internal ForState(LocalBuilder indexVar, Label beginLabel, Label testLabel, object end)
- {
- this.indexVar = indexVar;
- this.beginLabel = beginLabel;
- this.testLabel = testLabel;
- this.end = end;
- }
- internal LocalBuilder Index
- {
- get
- {
- return indexVar;
- }
- }
- internal Label BeginLabel
- {
- get
- {
- return beginLabel;
- }
- }
- internal Label TestLabel
- {
- get
- {
- return testLabel;
- }
- }
- internal Label EndLabel
- {
- get
- {
- return endLabel;
- }
- set
- {
- endLabel = value;
- }
- }
- internal bool RequiresEndLabel
- {
- get
- {
- return requiresEndLabel;
- }
- set
- {
- requiresEndLabel = value;
- }
- }
- internal object End
- {
- get
- {
- return end;
- }
- }
- }
- internal enum Cmp
- {
- LessThan,
- EqualTo,
- LessThanOrEqualTo,
- GreaterThan,
- NotEqualTo,
- GreaterThanOrEqualTo
- }
- 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;
- }
- }
- }
- #if NotUsed
- internal class BitFlagsGenerator
- {
- LocalBuilder[] locals;
- CodeGenerator ilg;
- int bitCount;
- internal BitFlagsGenerator(int bitCount, CodeGenerator ilg, string localName)
- {
- this.ilg = ilg;
- this.bitCount = bitCount;
- int localCount = (bitCount+7)/8;
- locals = new LocalBuilder[localCount];
- for (int i=0;i<locals.Length;i++)
- locals[i] = ilg.DeclareLocal(Globals.TypeOfByte, localName+i, (byte)0);
- }
- internal void Store(int bitIndex, bool value)
- {
- LocalBuilder local = locals[GetByteIndex(bitIndex)];
- byte bitValue = GetBitValue(bitIndex);
- if (value)
- {
- ilg.Load(local);
- ilg.Load(bitValue);
- ilg.Or();
- ilg.Stloc(local);
- }
- else
- {
- ilg.Load(local);
- ilg.Load(bitValue);
- ilg.Not();
- ilg.And();
- ilg.Stloc(local);
- }
- }
- internal void Load(int bitIndex)
- {
- LocalBuilder local = locals[GetByteIndex(bitIndex)];
- byte bitValue = GetBitValue(bitIndex);
- ilg.Load(local);
- ilg.Load(bitValue);
- ilg.And();
- ilg.Load(bitValue);
- ilg.Ceq();
- }
- internal void LoadArray()
- {
- LocalBuilder localArray = ilg.DeclareLocal(Globals.TypeOfByteArray, "localArray");
- ilg.NewArray(Globals.TypeOfByte, locals.Length);
- ilg.Store(localArray);
- for (int i=0;i<locals.Length;i++)
- ilg.StoreArrayElement(localArray, i, locals[i]);
- ilg.Load(localArray);
- }
- internal int GetLocalCount()
- {
- return locals.Length;
- }
- internal int GetBitCount()
- {
- return bitCount;
- }
- internal LocalBuilder GetLocal(int i)
- {
- return locals[i];
- }
- internal static bool IsBitSet(byte[] bytes, int bitIndex)
- {
- int byteIndex = GetByteIndex(bitIndex);
- byte bitValue = GetBitValue(bitIndex);
- return (bytes[byteIndex] & bitValue) == bitValue;
- }
- internal static void SetBit(byte[] bytes, int bitIndex)
- {
- int byteIndex = GetByteIndex(bitIndex);
- byte bitValue = GetBitValue(bitIndex);
- bytes[byteIndex] |= bitValue;
- }
- static int GetByteIndex(int bitIndex)
- {
- return bitIndex >> 3;
- }
- static byte GetBitValue(int bitIndex)
- {
- return (byte)(1 << (bitIndex & 7));
- }
- }
- #endif
- internal class SwitchState
- {
- Label defaultLabel;
- Label endOfSwitchLabel;
- bool defaultDefined;
- internal SwitchState(Label defaultLabel, Label endOfSwitchLabel)
- {
- this.defaultLabel = defaultLabel;
- this.endOfSwitchLabel = endOfSwitchLabel;
- this.defaultDefined = false;
- }
- internal Label DefaultLabel
- {
- get
- {
- return defaultLabel;
- }
- }
- internal Label EndOfSwitchLabel
- {
- get
- {
- return endOfSwitchLabel;
- }
- }
- internal bool DefaultDefined
- {
- get
- {
- return defaultDefined;
- }
- set
- {
- defaultDefined = value;
- }
- }
- }
- }
|