| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767 |
- //------------------------------------------------------------------------------
- // <copyright file="CodeGenerator.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- //------------------------------------------------------------------------------
- using System;
- using System.Reflection;
- using System.Resources;
- using System.Runtime.CompilerServices;
- namespace System.Xml.Serialization {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Globalization;
- using System.Xml;
- using System.Xml.Serialization.Configuration;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.IO;
- using System.Security;
- using System.Security.Permissions;
- using System.Text.RegularExpressions;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- internal class CodeGenerator {
- [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Method does validation only without any user input")]
- internal static bool IsValidLanguageIndependentIdentifier(string ident) { return System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(ident); }
- [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Method does validation only without any user input")]
- internal static void ValidateIdentifiers(System.CodeDom.CodeObject e) { System.CodeDom.Compiler.CodeGenerator.ValidateIdentifiers(e); }
- internal static BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public;
- internal static BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
- internal static BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
- internal static MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;
- internal static MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
- internal static MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig;
- internal static MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig;
- internal static Type[] EmptyTypeArray = new Type[] { };
- internal static string[] EmptyStringArray = new string[] { };
- TypeBuilder typeBuilder;
- MethodBuilder methodBuilder;
- ILGenerator ilGen;
- Dictionary<string, ArgBuilder> argList;
- LocalScope currentScope;
- // Stores a queue of free locals available in the context of the method, keyed by
- // type and name of the local
- Dictionary<Tuple<Type, string>, Queue<LocalBuilder>> freeLocals;
- Stack blockStack;
- Label methodEndLabel;
- internal CodeGenerator(TypeBuilder typeBuilder) {
- System.Diagnostics.Debug.Assert(typeBuilder != null);
- this.typeBuilder = typeBuilder;
- }
- internal static bool IsNullableGenericType(Type type) {
- return type.Name == "Nullable`1";
- }
- internal static void AssertHasInterface(Type type, Type iType) {
- #if DEBUG
- Debug.Assert(iType.IsInterface);
- foreach (Type iFace in type.GetInterfaces()) {
- if (iFace == iType)
- return;
- }
- Debug.Assert(false);
- #endif
- }
- internal void BeginMethod(Type returnType, string methodName, Type[] argTypes, string[] argNames, MethodAttributes methodAttributes) {
- this.methodBuilder = typeBuilder.DefineMethod(methodName, methodAttributes, returnType, argTypes);
- this.ilGen = methodBuilder.GetILGenerator();
- InitILGeneration(argTypes, argNames, (methodBuilder.Attributes & MethodAttributes.Static) == MethodAttributes.Static);
- }
- internal void BeginMethod(Type returnType, MethodBuilderInfo methodBuilderInfo, Type[] argTypes, string[] argNames, MethodAttributes methodAttributes) {
- #if DEBUG
- methodBuilderInfo.Validate(returnType, argTypes, methodAttributes);
- #endif
- this.methodBuilder = methodBuilderInfo.MethodBuilder;
- this.ilGen = methodBuilder.GetILGenerator();
- InitILGeneration(argTypes, argNames, (methodBuilder.Attributes & MethodAttributes.Static) == MethodAttributes.Static);
- }
- void InitILGeneration(Type[] argTypes, string[] argNames, bool isStatic) {
- this.methodEndLabel = ilGen.DefineLabel();
- this.retLabel = ilGen.DefineLabel();
- this.blockStack = new Stack();
- this.whileStack = new Stack();
- this.currentScope = new LocalScope();
- this.freeLocals = new Dictionary<Tuple<Type, string>, Queue<LocalBuilder>>();
- this.argList = new Dictionary<string, ArgBuilder>();
- // this ptr is arg 0 for non static, assuming ref type (not value type)
- if (!isStatic)
- argList.Add("this", new ArgBuilder("this", 0, this.typeBuilder.BaseType));
- for (int i = 0; i < argTypes.Length; i++) {
- ArgBuilder arg = new ArgBuilder(argNames[i], argList.Count, argTypes[i]);
- argList.Add(arg.Name, arg);
- this.methodBuilder.DefineParameter(arg.Index, ParameterAttributes.None, arg.Name);
- }
- }
- internal MethodBuilder EndMethod() {
- MarkLabel(methodEndLabel);
- Ret();
- MethodBuilder retVal = null;
- retVal = methodBuilder;
- methodBuilder = null;
- ilGen = null;
- freeLocals = null;
- blockStack = null;
- whileStack = null;
- argList = null;
- currentScope = null;
- retLocal = null;
- return retVal;
- }
- internal MethodBuilder MethodBuilder {
- get { return this.methodBuilder; }
- }
- internal static Exception NotSupported(string msg) {
- System.Diagnostics.Debug.Assert(false, msg);
- return new NotSupportedException(msg);
- }
- internal ArgBuilder GetArg(string name) {
- System.Diagnostics.Debug.Assert(argList != null && argList.ContainsKey(name));
- return (ArgBuilder)argList[name];
- }
- internal LocalBuilder GetLocal(string name) {
- System.Diagnostics.Debug.Assert(currentScope != null && currentScope.ContainsKey(name));
- return currentScope[name];
- }
- internal LocalBuilder retLocal;
- internal Label retLabel;
- internal LocalBuilder ReturnLocal {
- get {
- if (retLocal == null)
- retLocal = DeclareLocal(this.methodBuilder.ReturnType, "_ret");
- return retLocal;
- }
- }
- internal Label ReturnLabel {
- get { return retLabel; }
- }
- Dictionary<Type, LocalBuilder> TmpLocals = new Dictionary<Type, LocalBuilder>();
- internal LocalBuilder GetTempLocal(Type type) {
- LocalBuilder localTmp;
- if (!TmpLocals.TryGetValue(type, out localTmp)) {
- localTmp = DeclareLocal(type, "_tmp" + TmpLocals.Count);
- TmpLocals.Add(type, localTmp);
- }
- return localTmp;
- }
- 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 object GetVariable(string name) {
- object var;
- if (TryGetVariable(name, out var))
- return var;
- System.Diagnostics.Debug.Assert(false);
- return null;
- }
- internal bool TryGetVariable(string name, out object variable) {
- LocalBuilder loc;
- if (currentScope != null && currentScope.TryGetValue(name, out loc)) {
- variable = loc;
- return true;
- }
- ArgBuilder arg;
- if (argList != null && argList.TryGetValue(name, out arg)) {
- variable = arg;
- return true;
- }
- int val;
- if (Int32.TryParse(name, out val)) {
- variable = val;
- return true;
- }
- variable = null;
- return false;
- }
- #if NotUsed
- internal LocalBuilder DeclareLocal(Type type, string name, object initialValue) {
- LocalBuilder local = DeclareLocal(type, name);
- Load(initialValue);
- Store(local);
- return local;
- }
- #endif
- internal void EnterScope() {
- LocalScope newScope = new LocalScope(this.currentScope);
- this.currentScope = newScope;
- }
- internal void ExitScope()
- {
- Debug.Assert(this.currentScope.parent != null);
- this.currentScope.AddToFreeLocals(freeLocals);
- this.currentScope = this.currentScope.parent;
- }
- private bool TryDequeueLocal(Type type, string name, out LocalBuilder local) {
- // This method can only be called between BeginMethod and EndMethod (i.e.
- // while we are emitting code for a method
- Debug.Assert(freeLocals != null);
- Queue<LocalBuilder> freeLocalQueue;
- Tuple<Type, string> key = new Tuple<Type, string>(type, name);
- if (freeLocals.TryGetValue(key, out freeLocalQueue)) {
- local = freeLocalQueue.Dequeue();
- // If the queue is empty, remove this key from the dictionary
- // of free locals
- if (freeLocalQueue.Count == 0) {
- freeLocals.Remove(key);
- }
- return true;
- }
- local = null;
- return false;
- }
- internal LocalBuilder DeclareLocal(Type type, string name) {
- Debug.Assert(!currentScope.ContainsKey(name));
- LocalBuilder local;
- if (!TryDequeueLocal(type, name, out local)) {
- local = ilGen.DeclareLocal(type, false);
- if (DiagnosticsSwitches.KeepTempFiles.Enabled)
- local.SetLocalSymInfo(name);
- }
- currentScope[name] = local;
- return local;
- }
- internal LocalBuilder DeclareOrGetLocal(Type type, string name) {
- LocalBuilder local;
- if (!currentScope.TryGetValue(name, out local))
- local = DeclareLocal(type, name);
- else
- Debug.Assert(local.LocalType == type);
- return local;
- }
- #if NotUsed
- Dictionary<string, int> parameterMapping = new Dictionary<string, int>();
- internal Dictionary<string, int> ParameterMapping { get { return this.parameterMapping; } }
- internal ParameterBuilder DefineParameter(int index, ParameterAttributes attributes, string name)
- {
- if (this.parameterMapping == null)
- {
- this.parameterMapping = new Dictionary<string, int>();
- }
- this.parameterMapping.Add(name, index);
- return this.methodBuilder.DefineParameter(index, attributes, name);
- }
- internal void Set(LocalBuilder local, object value)
- {
- Load(value);
- Store(local);
- }
- #endif
- 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;
- Debug.Assert(forState != null);
- if (forState.Index != null) {
- Ldloc(forState.Index);
- Ldc(1);
- Add();
- Stloc(forState.Index);
- MarkLabel(forState.TestLabel);
- Ldloc(forState.Index);
- Load(forState.End);
- Type varType = GetVariableType(forState.End);
- if (varType.IsArray) {
- Ldlen();
- }
- else {
- #if DEBUG
- CodeGenerator.AssertHasInterface(varType, typeof(ICollection));
- #endif
- MethodInfo ICollection_get_Count = typeof(ICollection).GetMethod(
- "get_Count",
- CodeGenerator.InstanceBindingFlags,
- null,
- CodeGenerator.EmptyTypeArray,
- null
- );
- Call(ICollection_get_Count);
- }
- Blt(forState.BeginLabel);
- }
- else
- Br(forState.BeginLabel);
- }
- #if NotUsed
- 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;
- }
- 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);
- }
- }
- #endif
- internal void If() {
- InternalIf(false);
- }
- internal void IfNot() {
- InternalIf(true);
- }
- static OpCode[] BranchCodes = new OpCode[] {
- OpCodes.Bge,
- OpCodes.Bne_Un,
- OpCodes.Bgt,
- OpCodes.Ble,
- OpCodes.Beq,
- OpCodes.Blt,
- };
- OpCode GetBranchCode(Cmp cmp) {
- return BranchCodes[(int)cmp];
- }
- #if NotUsed
- 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:
- Debug.Assert(cmp == Cmp.GreaterThanOrEqualTo, "Unexpected cmp");
- return Cmp.LessThan;
- }
- }
- #endif
- internal void If(Cmp cmpOp) {
- IfState ifState = new IfState();
- ifState.EndIf = DefineLabel();
- ifState.ElseBegin = DefineLabel();
- 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);
- }
- #if NotUsed
- 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();
- ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
- blockStack.Push(ifState);
- }
- #endif
- internal void EndIf() {
- IfState ifState = PopIfState();
- if (!ifState.ElseBegin.Equals(ifState.EndIf))
- MarkLabel(ifState.ElseBegin);
- MarkLabel(ifState.EndIf);
- }
- Stack leaveLabels = new Stack();
- internal void BeginExceptionBlock() {
- leaveLabels.Push(DefineLabel());
- ilGen.BeginExceptionBlock();
- }
- internal void BeginCatchBlock(Type exception) {
- ilGen.BeginCatchBlock(exception);
- }
- internal void EndExceptionBlock() {
- ilGen.EndExceptionBlock();
- ilGen.MarkLabel((Label)leaveLabels.Pop());
- }
- internal void Leave() {
- ilGen.Emit(OpCodes.Leave, (Label)leaveLabels.Peek());
- }
- #if NotUsed
- internal void VerifyParameterCount(MethodInfo methodInfo, int expectedCount)
- {
- if (methodInfo.GetParameters().Length != expectedCount)
- throw Utility.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);
- }
- #endif
- internal void Call(MethodInfo methodInfo) {
- Debug.Assert(methodInfo != null);
- if (methodInfo.IsVirtual && !methodInfo.DeclaringType.IsValueType)
- ilGen.Emit(OpCodes.Callvirt, methodInfo);
- else
- ilGen.Emit(OpCodes.Call, methodInfo);
- }
- internal void Call(ConstructorInfo ctor) {
- Debug.Assert(ctor != null);
- ilGen.Emit(OpCodes.Call, ctor);
- }
- internal void New(ConstructorInfo constructorInfo) {
- Debug.Assert(constructorInfo != null);
- ilGen.Emit(OpCodes.Newobj, constructorInfo);
- }
- #if NotUsed
- internal void New(ConstructorInfo constructorInfo, object param1)
- {
- LoadParam(param1, 1, constructorInfo);
- New(constructorInfo);
- }
- #endif
- internal void InitObj(Type valueType) {
- ilGen.Emit(OpCodes.Initobj, valueType);
- }
- internal void NewArray(Type elementType, object len) {
- Load(len);
- ilGen.Emit(OpCodes.Newarr, elementType);
- }
- #if NotUsed
- internal void IgnoreReturnValue()
- {
- Pop();
- }
- #endif
- 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 == typeof(Array)) {
- Load(obj);
- Call(typeof(Array).GetMethod("SetValue", new Type[] { typeof(object), typeof(int) }));
- }
- 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(object obj, MemberInfo memberInfo) {
- if (GetVariableType(obj).IsValueType)
- LoadAddress(obj);
- else
- Load(obj);
- return LoadMember(memberInfo);
- }
- private static MethodInfo GetPropertyMethodFromBaseType(PropertyInfo propertyInfo, bool isGetter) {
- // we only invoke this when the propertyInfo does not have a GET or SET method on it
-
- Type currentType = propertyInfo.DeclaringType.BaseType;
- PropertyInfo currentProperty;
- string propertyName = propertyInfo.Name;
- MethodInfo result = null;
- while (currentType != null) {
- currentProperty = currentType.GetProperty(propertyName);
- if (currentProperty != null) {
- if (isGetter) {
- result = currentProperty.GetGetMethod(true);
- }
- else {
- result = currentProperty.GetSetMethod(true);
- }
- if (result != null) {
- // we found the GetMethod/SetMethod on the type closest to the current declaring type
- break;
- }
- }
- // keep looking at the base type like compiler does
- currentType = currentType.BaseType;
- }
- return result;
- }
- internal Type LoadMember(MemberInfo memberInfo) {
- Type memberType = null;
- if (memberInfo.MemberType == MemberTypes.Field) {
- FieldInfo fieldInfo = (FieldInfo)memberInfo;
- memberType = fieldInfo.FieldType;
- if (fieldInfo.IsStatic) {
- ilGen.Emit(OpCodes.Ldsfld, fieldInfo);
- }
- else {
- ilGen.Emit(OpCodes.Ldfld, fieldInfo);
- }
- }
- else {
- System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
- PropertyInfo property = (PropertyInfo)memberInfo;
- memberType = property.PropertyType;
- if (property != null) {
- MethodInfo getMethod = property.GetGetMethod(true);
- if (getMethod == null)
- {
- getMethod = GetPropertyMethodFromBaseType(property, true);
- }
- System.Diagnostics.Debug.Assert(getMethod != null);
- Call(getMethod);
- }
- }
- return memberType;
- }
- internal Type LoadMemberAddress(MemberInfo memberInfo) {
- Type memberType = null;
- if (memberInfo.MemberType == MemberTypes.Field) {
- FieldInfo fieldInfo = (FieldInfo)memberInfo;
- memberType = fieldInfo.FieldType;
- if (fieldInfo.IsStatic) {
- ilGen.Emit(OpCodes.Ldsflda, fieldInfo);
- }
- else {
- ilGen.Emit(OpCodes.Ldflda, fieldInfo);
- }
- }
- else {
- System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
- PropertyInfo property = (PropertyInfo)memberInfo;
- memberType = property.PropertyType;
- if (property != null) {
- MethodInfo getMethod = property.GetGetMethod(true);
- if (getMethod == null)
- {
- getMethod = GetPropertyMethodFromBaseType(property, true);
- }
- System.Diagnostics.Debug.Assert(getMethod != null);
- Call(getMethod);
- LocalBuilder tmpLoc = GetTempLocal(memberType);
- Stloc(tmpLoc);
- Ldloca(tmpLoc);
- }
- }
- return memberType;
- }
- internal void StoreMember(MemberInfo memberInfo) {
- if (memberInfo.MemberType == MemberTypes.Field) {
- FieldInfo fieldInfo = (FieldInfo)memberInfo;
- if (fieldInfo.IsStatic) {
- ilGen.Emit(OpCodes.Stsfld, fieldInfo);
- }
- else {
- ilGen.Emit(OpCodes.Stfld, fieldInfo);
- }
- }
- else {
- System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
- PropertyInfo property = (PropertyInfo)memberInfo;
- if (property != null) {
- MethodInfo setMethod = property.GetSetMethod(true);
- if (setMethod == null)
- {
- setMethod = GetPropertyMethodFromBaseType(property, false);
- }
- System.Diagnostics.Debug.Assert(setMethod != null);
- Call(setMethod);
- }
- }
- }
- #if NotUsed
- 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);
- }
- #endif
- internal void Load(object obj) {
- if (obj == null)
- ilGen.Emit(OpCodes.Ldnull);
- else if (obj is ArgBuilder)
- Ldarg((ArgBuilder)obj);
- else if (obj is LocalBuilder)
- Ldloc((LocalBuilder)obj);
- else
- Ldc(obj);
- }
- #if NotUsed
- internal void Store(object var)
- {
- if (var is ArgBuilder)
- Starg((ArgBuilder)var);
- else
- {
- System.Diagnostics.Debug.Assert(var is LocalBuilder);
- Stloc((LocalBuilder)var);
- }
- }
- internal void Dec(object var)
- {
- Load(var);
- Load(1);
- Subtract();
- Store(var);
- }
- internal void Inc(object var)
- {
- Load(var);
- Load(1);
- Add();
- Store(var);
- }
- #endif
- 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) {
- ilGen.Emit(OpCodes.Castclass, target);
- }
- internal void Box(Type type) {
- ilGen.Emit(OpCodes.Box, type);
- }
- internal void Unbox(Type type) {
- ilGen.Emit(OpCodes.Unbox, type);
- }
- static OpCode[] LdindOpCodes = new OpCode[] {
- OpCodes.Nop,//Empty = 0,
- OpCodes.Nop,//Object = 1,
- OpCodes.Nop,//DBNull = 2,
- OpCodes.Ldind_I1,//Boolean = 3,
- OpCodes.Ldind_I2,//Char = 4,
- OpCodes.Ldind_I1,//SByte = 5,
- OpCodes.Ldind_U1,//Byte = 6,
- OpCodes.Ldind_I2,//Int16 = 7,
- OpCodes.Ldind_U2,//UInt16 = 8,
- OpCodes.Ldind_I4,//Int32 = 9,
- OpCodes.Ldind_U4,//UInt32 = 10,
- OpCodes.Ldind_I8,//Int64 = 11,
- OpCodes.Ldind_I8,//UInt64 = 12,
- OpCodes.Ldind_R4,//Single = 13,
- OpCodes.Ldind_R8,//Double = 14,
- OpCodes.Nop,//Decimal = 15,
- OpCodes.Nop,//DateTime = 16,
- OpCodes.Nop,//17
- OpCodes.Ldind_Ref,//String = 18,
- };
- OpCode GetLdindOpCode(TypeCode typeCode) {
- return LdindOpCodes[(int)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)) {
- ilGen.Emit(opCode);
- }
- else {
- ilGen.Emit(OpCodes.Ldobj, type);
- }
- }
- internal void Stobj(Type type) {
- ilGen.Emit(OpCodes.Stobj, type);
- }
- internal void Ceq() {
- ilGen.Emit(OpCodes.Ceq);
- }
- internal void Clt() {
- ilGen.Emit(OpCodes.Clt);
- }
- internal void Cne() {
- Ceq();
- Ldc(0);
- Ceq();
- }
- #if NotUsed
- internal void Bgt(Label label)
- {
- ilGen.Emit(OpCodes.Bgt, label);
- }
- #endif
- internal void Ble(Label label) {
- ilGen.Emit(OpCodes.Ble, label);
- }
- internal void Throw() {
- ilGen.Emit(OpCodes.Throw);
- }
- internal void Ldtoken(Type t) {
- ilGen.Emit(OpCodes.Ldtoken, t);
- }
- internal void Ldc(object o) {
- Type valueType = o.GetType();
- if (o is Type) {
- Ldtoken((Type)o);
- Call(typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(RuntimeTypeHandle) }, null));
- }
- else if (valueType.IsEnum) {
- Ldc(((IConvertible)o).ToType(Enum.GetUnderlyingType(valueType), null));
- }
- else {
- switch (Type.GetTypeCode(valueType)) {
- case TypeCode.Boolean:
- Ldc((bool)o);
- break;
- case TypeCode.Char:
- Debug.Assert(false, "Char is not a valid schema primitive and should be treated as int in DataContract");
- throw new NotSupportedException("Char is not a valid schema primitive and should be treated as int in DataContract");
- 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.Decimal:
- ConstructorInfo Decimal_ctor = typeof(Decimal).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- new Type[] { typeof(Int32), typeof(Int32), typeof(Int32), typeof(Boolean), typeof(Byte) },
- null
- );
- int[] bits = Decimal.GetBits((decimal)o);
- Ldc(bits[0]); // digit
- Ldc(bits[1]); // digit
- Ldc(bits[2]); // digit
- Ldc((bits[3] & 0x80000000) == 0x80000000); // sign
- Ldc((Byte)((bits[3] >> 16) & 0xFF)); // decimal location
- New(Decimal_ctor);
- break;
- case TypeCode.DateTime:
- ConstructorInfo DateTime_ctor = typeof(DateTime).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- new Type[] { typeof(Int64) },
- null
- );
- Ldc(((DateTime)o).Ticks); // ticks
- New(DateTime_ctor);
- break;
- case TypeCode.Object:
- case TypeCode.Empty:
- case TypeCode.DBNull:
- default:
- if (valueType == typeof(TimeSpan) && LocalAppContextSwitches.EnableTimeSpanSerialization)
- {
- ConstructorInfo TimeSpan_ctor = typeof(TimeSpan).GetConstructor(
- CodeGenerator.InstanceBindingFlags,
- null,
- new Type[] { typeof(Int64) },
- null
- );
- Ldc(((TimeSpan)o).Ticks); // ticks
- New(TimeSpan_ctor);
- break;
- }
- else
- {
- Debug.Assert(false, "UnknownConstantType");
- throw new NotSupportedException("UnknownConstantType"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownConstantType, DataContract.GetClrTypeFullName(valueType))));
- }
- }
- }
- }
- internal void Ldc(bool boolVar) {
- if (boolVar) {
- ilGen.Emit(OpCodes.Ldc_I4_1);
- }
- else {
- ilGen.Emit(OpCodes.Ldc_I4_0);
- }
- }
- internal void Ldc(int 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) {
- ilGen.Emit(OpCodes.Ldc_I8, l);
- }
- internal void Ldc(float f) {
- ilGen.Emit(OpCodes.Ldc_R4, f);
- }
- internal void Ldc(double d) {
- ilGen.Emit(OpCodes.Ldc_R8, d);
- }
- internal void Ldstr(string strVar) {
- if (strVar == null)
- ilGen.Emit(OpCodes.Ldnull);
- else
- ilGen.Emit(OpCodes.Ldstr, strVar);
- }
- internal void LdlocAddress(LocalBuilder localBuilder) {
- if (localBuilder.LocalType.IsValueType)
- Ldloca(localBuilder);
- else
- Ldloc(localBuilder);
- }
- internal void Ldloc(LocalBuilder localBuilder) {
- ilGen.Emit(OpCodes.Ldloc, localBuilder);
- }
- internal void Ldloc(string name) {
- Debug.Assert(currentScope.ContainsKey(name));
- LocalBuilder local = currentScope[name];
- Ldloc(local);
- }
- internal void Stloc(Type type, string name) {
- LocalBuilder local = null;
- if (!currentScope.TryGetValue(name, out local)) {
- local = DeclareLocal(type, name);
- }
- Debug.Assert(local.LocalType == type);
- Stloc(local);
- }
- internal void Stloc(LocalBuilder local) {
- ilGen.Emit(OpCodes.Stloc, local);
- }
- internal void Ldloc(Type type, string name) {
- Debug.Assert(currentScope.ContainsKey(name));
- LocalBuilder local = currentScope[name];
- Debug.Assert(local.LocalType == type);
- Ldloc(local);
- }
- #if NotUsed
- internal void Ldloc(int 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)
- {
- 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(int slot)
- {
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldloca_S, slot);
- else
- ilGen.Emit(OpCodes.Ldloca, slot);
- }
- #endif
- internal void Ldloca(LocalBuilder localBuilder) {
- ilGen.Emit(OpCodes.Ldloca, localBuilder);
- }
- internal void LdargAddress(ArgBuilder argBuilder) {
- if (argBuilder.ArgType.IsValueType)
- Ldarga(argBuilder);
- else
- Ldarg(argBuilder);
- }
- internal void Ldarg(string arg) {
- Ldarg(GetArg(arg));
- }
- internal void Ldarg(ArgBuilder arg) {
- Ldarg(arg.Index);
- }
- internal void Ldarg(int 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;
- }
- }
- #if NotUsed
- internal void Starg(ArgBuilder arg)
- {
- Starg(arg.Index);
- }
- internal void Starg(int slot)
- {
- if (slot <= 255)
- ilGen.Emit(OpCodes.Starg_S, slot);
- else
- ilGen.Emit(OpCodes.Starg, slot);
- }
- #endif
- internal void Ldarga(ArgBuilder argBuilder) {
- Ldarga(argBuilder.Index);
- }
- internal void Ldarga(int slot) {
- if (slot <= 255)
- ilGen.Emit(OpCodes.Ldarga_S, slot);
- else
- ilGen.Emit(OpCodes.Ldarga, slot);
- }
- internal void Ldlen() {
- ilGen.Emit(OpCodes.Ldlen);
- ilGen.Emit(OpCodes.Conv_I4);
- }
- static OpCode[] LdelemOpCodes = new OpCode[] {
- OpCodes.Nop,//Empty = 0,
- OpCodes.Ldelem_Ref,//Object = 1,
- OpCodes.Ldelem_Ref,//DBNull = 2,
- OpCodes.Ldelem_I1,//Boolean = 3,
- OpCodes.Ldelem_I2,//Char = 4,
- OpCodes.Ldelem_I1,//SByte = 5,
- OpCodes.Ldelem_U1,//Byte = 6,
- OpCodes.Ldelem_I2,//Int16 = 7,
- OpCodes.Ldelem_U2,//UInt16 = 8,
- OpCodes.Ldelem_I4,//Int32 = 9,
- OpCodes.Ldelem_U4,//UInt32 = 10,
- OpCodes.Ldelem_I8,//Int64 = 11,
- OpCodes.Ldelem_I8,//UInt64 = 12,
- OpCodes.Ldelem_R4,//Single = 13,
- OpCodes.Ldelem_R8,//Double = 14,
- OpCodes.Nop,//Decimal = 15,
- OpCodes.Nop,//DateTime = 16,
- OpCodes.Nop,//17
- OpCodes.Ldelem_Ref,//String = 18,
- };
- OpCode GetLdelemOpCode(TypeCode typeCode) {
- return LdelemOpCodes[(int)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));
- Debug.Assert(!opCode.Equals(OpCodes.Nop));
- if (opCode.Equals(OpCodes.Nop))
- throw new InvalidOperationException("ArrayTypeIsNotSupported"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
- ilGen.Emit(opCode);
- }
- }
- internal void Ldelema(Type arrayElementType) {
- OpCode opCode = OpCodes.Ldelema;
- ilGen.Emit(opCode, arrayElementType);
- }
- static OpCode[] StelemOpCodes = new OpCode[] {
- OpCodes.Nop,//Empty = 0,
- OpCodes.Stelem_Ref,//Object = 1,
- OpCodes.Stelem_Ref,//DBNull = 2,
- OpCodes.Stelem_I1,//Boolean = 3,
- OpCodes.Stelem_I2,//Char = 4,
- OpCodes.Stelem_I1,//SByte = 5,
- OpCodes.Stelem_I1,//Byte = 6,
- OpCodes.Stelem_I2,//Int16 = 7,
- OpCodes.Stelem_I2,//UInt16 = 8,
- OpCodes.Stelem_I4,//Int32 = 9,
- OpCodes.Stelem_I4,//UInt32 = 10,
- OpCodes.Stelem_I8,//Int64 = 11,
- OpCodes.Stelem_I8,//UInt64 = 12,
- OpCodes.Stelem_R4,//Single = 13,
- OpCodes.Stelem_R8,//Double = 14,
- OpCodes.Nop,//Decimal = 15,
- OpCodes.Nop,//DateTime = 16,
- OpCodes.Nop,//17
- OpCodes.Stelem_Ref,//String = 18,
- };
- OpCode GetStelemOpCode(TypeCode typeCode) {
- return StelemOpCodes[(int)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 new InvalidOperationException("ArrayTypeIsNotSupported"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
- ilGen.Emit(opCode);
- }
- }
- internal Label DefineLabel() {
- return ilGen.DefineLabel();
- }
- internal void MarkLabel(Label label) {
- ilGen.MarkLabel(label);
- }
- internal void Nop() {
- ilGen.Emit(OpCodes.Nop);
- }
- internal void Add() {
- ilGen.Emit(OpCodes.Add);
- }
- #if NotUsed
- internal void Subtract()
- {
- ilGen.Emit(OpCodes.Sub);
- }
- internal void And()
- {
- ilGen.Emit(OpCodes.And);
- }
- internal void Or()
- {
- ilGen.Emit(OpCodes.Or);
- }
- internal void Not()
- {
- ilGen.Emit(OpCodes.Not);
- }
- #endif
- internal void Ret() {
- ilGen.Emit(OpCodes.Ret);
- }
- internal void Br(Label label) {
- ilGen.Emit(OpCodes.Br, label);
- }
- internal void Br_S(Label label) {
- ilGen.Emit(OpCodes.Br_S, label);
- }
- internal void Blt(Label label) {
- ilGen.Emit(OpCodes.Blt, label);
- }
- internal void Brfalse(Label label) {
- ilGen.Emit(OpCodes.Brfalse, label);
- }
- internal void Brtrue(Label label) {
- ilGen.Emit(OpCodes.Brtrue, label);
- }
- internal void Pop() {
- ilGen.Emit(OpCodes.Pop);
- }
- internal void Dup() {
- ilGen.Emit(OpCodes.Dup);
- }
- #if !SILVERLIGHT // Not in SL
- internal void Ldftn(MethodInfo methodInfo) {
- ilGen.Emit(OpCodes.Ldftn, methodInfo);
- }
- #endif
- #if NotUsed
- 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);
- }
- #endif
- 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);
- }
- static OpCode[] ConvOpCodes = new OpCode[] {
- OpCodes.Nop,//Empty = 0,
- OpCodes.Nop,//Object = 1,
- OpCodes.Nop,//DBNull = 2,
- OpCodes.Conv_I1,//Boolean = 3,
- OpCodes.Conv_I2,//Char = 4,
- OpCodes.Conv_I1,//SByte = 5,
- OpCodes.Conv_U1,//Byte = 6,
- OpCodes.Conv_I2,//Int16 = 7,
- OpCodes.Conv_U2,//UInt16 = 8,
- OpCodes.Conv_I4,//Int32 = 9,
- OpCodes.Conv_U4,//UInt32 = 10,
- OpCodes.Conv_I8,//Int64 = 11,
- OpCodes.Conv_U8,//UInt64 = 12,
- OpCodes.Conv_R4,//Single = 13,
- OpCodes.Conv_R8,//Double = 14,
- OpCodes.Nop,//Decimal = 15,
- OpCodes.Nop,//DateTime = 16,
- OpCodes.Nop,//17
- OpCodes.Nop,//String = 18,
- };
- OpCode GetConvOpCode(TypeCode typeCode) {
- return ConvOpCodes[(int)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_U8;// 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)) {
- //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NoConversionPossibleTo, DataContract.GetClrTypeFullName(target))));
- throw new CodeGeneratorConversionException(source, target, isAddress,"NoConversionPossibleTo");
- }
- else {
- ilGen.Emit(opCode);
- }
- }
- else if (source.IsAssignableFrom(target)) {
- Unbox(target);
- if (!isAddress)
- Ldobj(target);
- }
- else {
- //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
- throw new CodeGeneratorConversionException(source, target, isAddress, "IsNotAssignableFrom");
- }
- }
- 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 {
- //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
- throw new CodeGeneratorConversionException(source, target, isAddress, "IsNotAssignableFrom");
- }
- }
- IfState PopIfState() {
- object stackTop = blockStack.Pop();
- IfState ifState = stackTop as IfState;
- Debug.Assert(ifState != null);
- return ifState;
- }
- static internal AssemblyBuilder CreateAssemblyBuilder(AppDomain appDomain, string name) {
- AssemblyName assemblyName = new AssemblyName();
- assemblyName.Name = name;
- assemblyName.Version = new Version(1, 0, 0, 0);
- if (DiagnosticsSwitches.KeepTempFiles.Enabled)
- return appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, TempFilesLocation);
- else
- return appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
- }
- static string tempFilesLocation = null;
- internal static string TempFilesLocation {
- get {
- if (tempFilesLocation == null) {
- #if CONFIGURATION_DEP
- // Return different XmlSerializerSection from legacy assembly due to its register config handlers
- object section = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath);
- string location = null;
- if (section != null) {
- XmlSerializerSection configSection = section as XmlSerializerSection;
- if (configSection != null) {
- location = configSection.TempFilesLocation;
- }
- }
- #else
- string location = null;
- #endif
- if (location != null) {
- tempFilesLocation = location.Trim();
- }
- else {
- tempFilesLocation = Path.GetTempPath();
- }
- }
- return tempFilesLocation;
- }
- set {
- tempFilesLocation = value;
- }
- }
- static internal ModuleBuilder CreateModuleBuilder(AssemblyBuilder assemblyBuilder, string name) {
- if (DiagnosticsSwitches.KeepTempFiles.Enabled)
- return assemblyBuilder.DefineDynamicModule(name, name + ".dll", true);
- else
- return assemblyBuilder.DefineDynamicModule(name);
- }
- static internal TypeBuilder CreateTypeBuilder(ModuleBuilder moduleBuilder, string name, TypeAttributes attributes, Type parent, Type[] interfaces) {
- // parent is nullable if no base class
- return moduleBuilder.DefineType(TempAssembly.GeneratedAssemblyNamespace + "." + name,
- attributes, parent, interfaces);
- }
- #if NotUsed
- 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)
- Console.WriteLine(String.Format("{0:X4}: {1}", lineNo++, line));
- 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();
- ToString(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.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);
- ToString(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 stringEquals = typeof(string).GetMethod("Equals", new Type[]{ typeof(string), typeof(string)});
- static MethodInfo stringCompare = typeof(string).GetMethod("Compare", 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]);
- #endif
- int initElseIfStack = -1;
- IfState elseIfState;
- internal void InitElseIf() {
- Debug.Assert(initElseIfStack == -1);
- elseIfState = (IfState)blockStack.Pop();
- initElseIfStack = blockStack.Count;
- Br(elseIfState.EndIf);
- MarkLabel(elseIfState.ElseBegin);
- }
- int initIfStack = -1;
- internal void InitIf() {
- Debug.Assert(initIfStack == -1);
- initIfStack = blockStack.Count;
- }
- internal void AndIf(Cmp cmpOp) {
- if (initIfStack == blockStack.Count) {
- initIfStack = -1;
- If(cmpOp);
- return;
- }
- if (initElseIfStack == blockStack.Count) {
- initElseIfStack = -1;
- elseIfState.ElseBegin = DefineLabel();
- ilGen.Emit(GetBranchCode(cmpOp), elseIfState.ElseBegin);
- blockStack.Push(elseIfState);
- return;
- }
- Debug.Assert(initIfStack == -1 && initElseIfStack == -1);
- IfState ifState = (IfState)blockStack.Peek();
- ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
- }
- internal void AndIf() {
- if (initIfStack == blockStack.Count) {
- initIfStack = -1;
- If();
- return;
- }
- if (initElseIfStack == blockStack.Count) {
- initElseIfStack = -1;
- elseIfState.ElseBegin = DefineLabel();
- Brfalse(elseIfState.ElseBegin);
- blockStack.Push(elseIfState);
- return;
- }
- Debug.Assert(initIfStack == -1 && initElseIfStack == -1);
- IfState ifState = (IfState)blockStack.Peek();
- Brfalse(ifState.ElseBegin);
- }
- #if NotUsed
- 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 IfString(object s1, Cmp cmpOp, object s2)
- {
- Load(s1);
- Load(s2);
- Call(stringCompare);
- Load(0);
- If(cmpOp);
- }
- 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 " + CmpInverse[(int) cmpOp].ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
- ilGen.Emit(BranchCode[(int)cmpOp], 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);
- }
- #endif
- internal void IsInst(Type type) {
- ilGen.Emit(OpCodes.Isinst, type);
- }
- #if NotUsed
- 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);
- }
- #endif
- internal void Beq(Label label) {
- ilGen.Emit(OpCodes.Beq, label);
- }
- internal void Bne(Label label) {
- ilGen.Emit(OpCodes.Bne_Un, label);
- }
- #if NotUsed
- 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();
- }
- #endif
- internal void GotoMethodEnd() {
- //limit to only short forward (127 CIL instruction)
- //Br_S(this.methodEndLabel);
- Br(this.methodEndLabel);
- }
- internal class WhileState {
- public Label StartLabel;
- public Label CondLabel;
- public Label EndLabel;
- public WhileState(CodeGenerator ilg) {
- StartLabel = ilg.DefineLabel();
- CondLabel = ilg.DefineLabel();
- EndLabel = ilg.DefineLabel();
- }
- }
- // Usage:
- // WhileBegin()
- // WhileBreak()
- // WhileContinue()
- // WhileBeginCondition()
- // (bool on stack)
- // WhileEndCondition()
- // WhileEnd()
- Stack whileStack;
- internal void WhileBegin() {
- WhileState whileState = new WhileState(this);
- Br(whileState.CondLabel);
- MarkLabel(whileState.StartLabel);
- whileStack.Push(whileState);
- }
- internal void WhileEnd() {
- WhileState whileState = (WhileState)whileStack.Pop();
- MarkLabel(whileState.EndLabel);
- }
- internal void WhileBreak() {
- WhileState whileState = (WhileState)whileStack.Peek();
- Br(whileState.EndLabel);
- }
- internal void WhileContinue() {
- WhileState whileState = (WhileState)whileStack.Peek();
- Br(whileState.CondLabel);
- }
- internal void WhileBeginCondition() {
- WhileState whileState = (WhileState)whileStack.Peek();
- // If there are two MarkLabel ILs consecutively, Labels will converge to one label.
- // This could cause the code to look different. We insert Nop here specifically
- // that the While label stands out.
- Nop();
- MarkLabel(whileState.CondLabel);
- }
- internal void WhileEndCondition() {
- WhileState whileState = (WhileState)whileStack.Peek();
- Brtrue(whileState.StartLabel);
- }
- #if NotUsed
- internal void AndWhile(Cmp cmpOp)
- {
- object startWhile = blockStack.Pop();
- AndIf(cmpOp);
- blockStack.Push(startWhile);
- }
- internal void BeginWhileBody()
- {
- Label startWhile = (Label) blockStack.Pop();
- If();
- blockStack.Push(startWhile);
- }
- internal void BeginWhileBody(Cmp cmpOp)
- {
- Label startWhile = (Label) blockStack.Pop();
- If(cmpOp);
- blockStack.Push(startWhile);
- }
- internal Label BeginWhileCondition()
- {
- Label startWhile = DefineLabel();
- MarkLabel(startWhile);
- blockStack.Push(startWhile);
- return 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 new InvalidOperationException("OutParametersMustBeByRefTypeReceived"); //.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 string Name;
- internal int Index;
- internal Type ArgType;
- internal ArgBuilder(string name, int index, Type argType) {
- this.Name = name;
- this.Index = index;
- this.ArgType = argType;
- }
- }
- internal class ForState {
- LocalBuilder indexVar;
- Label beginLabel;
- Label testLabel;
- 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 object End {
- get {
- return end;
- }
- }
- }
- internal enum Cmp : int {
- LessThan = 0,
- 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;
- }
- }
- }
- internal class LocalScope {
- public readonly LocalScope parent;
- readonly Dictionary<string, LocalBuilder> locals;
- // Root scope
- public LocalScope() {
- this.locals = new Dictionary<string, LocalBuilder>();
- }
- public LocalScope(LocalScope parent) : this() {
- this.parent = parent;
- }
- public void Add(string key, LocalBuilder value) {
- locals.Add(key, value);
- }
- public bool ContainsKey(string key) {
- return locals.ContainsKey(key) || (parent != null && parent.ContainsKey(key));
- }
- public bool TryGetValue(string key, out LocalBuilder value) {
- if (locals.TryGetValue(key, out value)) {
- return true;
- }
- else if (parent != null) {
- return parent.TryGetValue(key, out value);
- }
- else {
- value = null;
- return false;
- }
- }
- public LocalBuilder this[string key] {
- get {
- LocalBuilder value;
- TryGetValue(key, out value);
- return value;
- }
- set {
- locals[key] = value;
- }
- }
- public void AddToFreeLocals(Dictionary<Tuple<Type, string>, Queue<LocalBuilder>> freeLocals) {
- foreach (var item in locals) {
- Tuple<Type, string> key = new Tuple<Type, string>(item.Value.LocalType, item.Key);
- Queue<LocalBuilder> freeLocalQueue;
- if (freeLocals.TryGetValue(key, out freeLocalQueue)) {
- // Add to end of the queue so that it will be re-used in
- // FIFO manner
- freeLocalQueue.Enqueue(item.Value);
- }
- else {
- freeLocalQueue = new Queue<LocalBuilder>();
- freeLocalQueue.Enqueue(item.Value);
- freeLocals.Add(key, freeLocalQueue);
- }
- }
- }
- }
- #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));
- }
- }
- 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;
- }
- }
- }
- #endif
- internal class MethodBuilderInfo {
- public readonly MethodBuilder MethodBuilder;
- public readonly Type[] ParameterTypes;
- public MethodBuilderInfo(MethodBuilder methodBuilder, Type[] parameterTypes) {
- this.MethodBuilder = methodBuilder;
- this.ParameterTypes = parameterTypes;
- }
- public void Validate(Type returnType, Type[] parameterTypes, MethodAttributes attributes) {
- #if DEBUG
- Debug.Assert(this.MethodBuilder.ReturnType == returnType);
- Debug.Assert(this.MethodBuilder.Attributes == attributes);
- Debug.Assert(this.ParameterTypes.Length == parameterTypes.Length);
- for (int i = 0; i < parameterTypes.Length; ++i) {
- Debug.Assert(this.ParameterTypes[i] == parameterTypes[i]);
- }
- #endif
- }
- }
- internal class CodeGeneratorConversionException : Exception {
- private Type sourceType;
- private Type targetType;
- private bool isAddress;
- private string reason;
- public CodeGeneratorConversionException(Type sourceType, Type targetType, bool isAddress, string reason)
- : base() {
- this.sourceType = sourceType;
- this.targetType = targetType;
- this.isAddress = isAddress;
- this.reason = reason;
- }
- }
- }
|