CodeGenerator.cs 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767
  1. //------------------------------------------------------------------------------
  2. // <copyright file="CodeGenerator.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">Microsoft</owner>
  6. //------------------------------------------------------------------------------
  7. using System;
  8. using System.Reflection;
  9. using System.Resources;
  10. using System.Runtime.CompilerServices;
  11. namespace System.Xml.Serialization {
  12. using System;
  13. using System.Collections;
  14. using System.Collections.Generic;
  15. using System.Configuration;
  16. using System.Globalization;
  17. using System.Xml;
  18. using System.Xml.Serialization.Configuration;
  19. using System.Reflection;
  20. using System.Reflection.Emit;
  21. using System.IO;
  22. using System.Security;
  23. using System.Security.Permissions;
  24. using System.Text.RegularExpressions;
  25. using System.Diagnostics;
  26. using System.Diagnostics.CodeAnalysis;
  27. internal class CodeGenerator {
  28. [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Method does validation only without any user input")]
  29. internal static bool IsValidLanguageIndependentIdentifier(string ident) { return System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(ident); }
  30. [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Method does validation only without any user input")]
  31. internal static void ValidateIdentifiers(System.CodeDom.CodeObject e) { System.CodeDom.Compiler.CodeGenerator.ValidateIdentifiers(e); }
  32. internal static BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public;
  33. internal static BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
  34. internal static BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
  35. internal static MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;
  36. internal static MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
  37. internal static MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig;
  38. internal static MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig;
  39. internal static Type[] EmptyTypeArray = new Type[] { };
  40. internal static string[] EmptyStringArray = new string[] { };
  41. TypeBuilder typeBuilder;
  42. MethodBuilder methodBuilder;
  43. ILGenerator ilGen;
  44. Dictionary<string, ArgBuilder> argList;
  45. LocalScope currentScope;
  46. // Stores a queue of free locals available in the context of the method, keyed by
  47. // type and name of the local
  48. Dictionary<Tuple<Type, string>, Queue<LocalBuilder>> freeLocals;
  49. Stack blockStack;
  50. Label methodEndLabel;
  51. internal CodeGenerator(TypeBuilder typeBuilder) {
  52. System.Diagnostics.Debug.Assert(typeBuilder != null);
  53. this.typeBuilder = typeBuilder;
  54. }
  55. internal static bool IsNullableGenericType(Type type) {
  56. return type.Name == "Nullable`1";
  57. }
  58. internal static void AssertHasInterface(Type type, Type iType) {
  59. #if DEBUG
  60. Debug.Assert(iType.IsInterface);
  61. foreach (Type iFace in type.GetInterfaces()) {
  62. if (iFace == iType)
  63. return;
  64. }
  65. Debug.Assert(false);
  66. #endif
  67. }
  68. internal void BeginMethod(Type returnType, string methodName, Type[] argTypes, string[] argNames, MethodAttributes methodAttributes) {
  69. this.methodBuilder = typeBuilder.DefineMethod(methodName, methodAttributes, returnType, argTypes);
  70. this.ilGen = methodBuilder.GetILGenerator();
  71. InitILGeneration(argTypes, argNames, (methodBuilder.Attributes & MethodAttributes.Static) == MethodAttributes.Static);
  72. }
  73. internal void BeginMethod(Type returnType, MethodBuilderInfo methodBuilderInfo, Type[] argTypes, string[] argNames, MethodAttributes methodAttributes) {
  74. #if DEBUG
  75. methodBuilderInfo.Validate(returnType, argTypes, methodAttributes);
  76. #endif
  77. this.methodBuilder = methodBuilderInfo.MethodBuilder;
  78. this.ilGen = methodBuilder.GetILGenerator();
  79. InitILGeneration(argTypes, argNames, (methodBuilder.Attributes & MethodAttributes.Static) == MethodAttributes.Static);
  80. }
  81. void InitILGeneration(Type[] argTypes, string[] argNames, bool isStatic) {
  82. this.methodEndLabel = ilGen.DefineLabel();
  83. this.retLabel = ilGen.DefineLabel();
  84. this.blockStack = new Stack();
  85. this.whileStack = new Stack();
  86. this.currentScope = new LocalScope();
  87. this.freeLocals = new Dictionary<Tuple<Type, string>, Queue<LocalBuilder>>();
  88. this.argList = new Dictionary<string, ArgBuilder>();
  89. // this ptr is arg 0 for non static, assuming ref type (not value type)
  90. if (!isStatic)
  91. argList.Add("this", new ArgBuilder("this", 0, this.typeBuilder.BaseType));
  92. for (int i = 0; i < argTypes.Length; i++) {
  93. ArgBuilder arg = new ArgBuilder(argNames[i], argList.Count, argTypes[i]);
  94. argList.Add(arg.Name, arg);
  95. this.methodBuilder.DefineParameter(arg.Index, ParameterAttributes.None, arg.Name);
  96. }
  97. }
  98. internal MethodBuilder EndMethod() {
  99. MarkLabel(methodEndLabel);
  100. Ret();
  101. MethodBuilder retVal = null;
  102. retVal = methodBuilder;
  103. methodBuilder = null;
  104. ilGen = null;
  105. freeLocals = null;
  106. blockStack = null;
  107. whileStack = null;
  108. argList = null;
  109. currentScope = null;
  110. retLocal = null;
  111. return retVal;
  112. }
  113. internal MethodBuilder MethodBuilder {
  114. get { return this.methodBuilder; }
  115. }
  116. internal static Exception NotSupported(string msg) {
  117. System.Diagnostics.Debug.Assert(false, msg);
  118. return new NotSupportedException(msg);
  119. }
  120. internal ArgBuilder GetArg(string name) {
  121. System.Diagnostics.Debug.Assert(argList != null && argList.ContainsKey(name));
  122. return (ArgBuilder)argList[name];
  123. }
  124. internal LocalBuilder GetLocal(string name) {
  125. System.Diagnostics.Debug.Assert(currentScope != null && currentScope.ContainsKey(name));
  126. return currentScope[name];
  127. }
  128. internal LocalBuilder retLocal;
  129. internal Label retLabel;
  130. internal LocalBuilder ReturnLocal {
  131. get {
  132. if (retLocal == null)
  133. retLocal = DeclareLocal(this.methodBuilder.ReturnType, "_ret");
  134. return retLocal;
  135. }
  136. }
  137. internal Label ReturnLabel {
  138. get { return retLabel; }
  139. }
  140. Dictionary<Type, LocalBuilder> TmpLocals = new Dictionary<Type, LocalBuilder>();
  141. internal LocalBuilder GetTempLocal(Type type) {
  142. LocalBuilder localTmp;
  143. if (!TmpLocals.TryGetValue(type, out localTmp)) {
  144. localTmp = DeclareLocal(type, "_tmp" + TmpLocals.Count);
  145. TmpLocals.Add(type, localTmp);
  146. }
  147. return localTmp;
  148. }
  149. internal Type GetVariableType(object var) {
  150. if (var is ArgBuilder)
  151. return ((ArgBuilder)var).ArgType;
  152. else if (var is LocalBuilder)
  153. return ((LocalBuilder)var).LocalType;
  154. else
  155. return var.GetType();
  156. }
  157. internal object GetVariable(string name) {
  158. object var;
  159. if (TryGetVariable(name, out var))
  160. return var;
  161. System.Diagnostics.Debug.Assert(false);
  162. return null;
  163. }
  164. internal bool TryGetVariable(string name, out object variable) {
  165. LocalBuilder loc;
  166. if (currentScope != null && currentScope.TryGetValue(name, out loc)) {
  167. variable = loc;
  168. return true;
  169. }
  170. ArgBuilder arg;
  171. if (argList != null && argList.TryGetValue(name, out arg)) {
  172. variable = arg;
  173. return true;
  174. }
  175. int val;
  176. if (Int32.TryParse(name, out val)) {
  177. variable = val;
  178. return true;
  179. }
  180. variable = null;
  181. return false;
  182. }
  183. #if NotUsed
  184. internal LocalBuilder DeclareLocal(Type type, string name, object initialValue) {
  185. LocalBuilder local = DeclareLocal(type, name);
  186. Load(initialValue);
  187. Store(local);
  188. return local;
  189. }
  190. #endif
  191. internal void EnterScope() {
  192. LocalScope newScope = new LocalScope(this.currentScope);
  193. this.currentScope = newScope;
  194. }
  195. internal void ExitScope()
  196. {
  197. Debug.Assert(this.currentScope.parent != null);
  198. this.currentScope.AddToFreeLocals(freeLocals);
  199. this.currentScope = this.currentScope.parent;
  200. }
  201. private bool TryDequeueLocal(Type type, string name, out LocalBuilder local) {
  202. // This method can only be called between BeginMethod and EndMethod (i.e.
  203. // while we are emitting code for a method
  204. Debug.Assert(freeLocals != null);
  205. Queue<LocalBuilder> freeLocalQueue;
  206. Tuple<Type, string> key = new Tuple<Type, string>(type, name);
  207. if (freeLocals.TryGetValue(key, out freeLocalQueue)) {
  208. local = freeLocalQueue.Dequeue();
  209. // If the queue is empty, remove this key from the dictionary
  210. // of free locals
  211. if (freeLocalQueue.Count == 0) {
  212. freeLocals.Remove(key);
  213. }
  214. return true;
  215. }
  216. local = null;
  217. return false;
  218. }
  219. internal LocalBuilder DeclareLocal(Type type, string name) {
  220. Debug.Assert(!currentScope.ContainsKey(name));
  221. LocalBuilder local;
  222. if (!TryDequeueLocal(type, name, out local)) {
  223. local = ilGen.DeclareLocal(type, false);
  224. if (DiagnosticsSwitches.KeepTempFiles.Enabled)
  225. local.SetLocalSymInfo(name);
  226. }
  227. currentScope[name] = local;
  228. return local;
  229. }
  230. internal LocalBuilder DeclareOrGetLocal(Type type, string name) {
  231. LocalBuilder local;
  232. if (!currentScope.TryGetValue(name, out local))
  233. local = DeclareLocal(type, name);
  234. else
  235. Debug.Assert(local.LocalType == type);
  236. return local;
  237. }
  238. #if NotUsed
  239. Dictionary<string, int> parameterMapping = new Dictionary<string, int>();
  240. internal Dictionary<string, int> ParameterMapping { get { return this.parameterMapping; } }
  241. internal ParameterBuilder DefineParameter(int index, ParameterAttributes attributes, string name)
  242. {
  243. if (this.parameterMapping == null)
  244. {
  245. this.parameterMapping = new Dictionary<string, int>();
  246. }
  247. this.parameterMapping.Add(name, index);
  248. return this.methodBuilder.DefineParameter(index, attributes, name);
  249. }
  250. internal void Set(LocalBuilder local, object value)
  251. {
  252. Load(value);
  253. Store(local);
  254. }
  255. #endif
  256. internal object For(LocalBuilder local, object start, object end) {
  257. ForState forState = new ForState(local, DefineLabel(), DefineLabel(), end);
  258. if (forState.Index != null) {
  259. Load(start);
  260. Stloc(forState.Index);
  261. Br(forState.TestLabel);
  262. }
  263. MarkLabel(forState.BeginLabel);
  264. blockStack.Push(forState);
  265. return forState;
  266. }
  267. internal void EndFor() {
  268. object stackTop = blockStack.Pop();
  269. ForState forState = stackTop as ForState;
  270. Debug.Assert(forState != null);
  271. if (forState.Index != null) {
  272. Ldloc(forState.Index);
  273. Ldc(1);
  274. Add();
  275. Stloc(forState.Index);
  276. MarkLabel(forState.TestLabel);
  277. Ldloc(forState.Index);
  278. Load(forState.End);
  279. Type varType = GetVariableType(forState.End);
  280. if (varType.IsArray) {
  281. Ldlen();
  282. }
  283. else {
  284. #if DEBUG
  285. CodeGenerator.AssertHasInterface(varType, typeof(ICollection));
  286. #endif
  287. MethodInfo ICollection_get_Count = typeof(ICollection).GetMethod(
  288. "get_Count",
  289. CodeGenerator.InstanceBindingFlags,
  290. null,
  291. CodeGenerator.EmptyTypeArray,
  292. null
  293. );
  294. Call(ICollection_get_Count);
  295. }
  296. Blt(forState.BeginLabel);
  297. }
  298. else
  299. Br(forState.BeginLabel);
  300. }
  301. #if NotUsed
  302. internal void Break(object forState)
  303. {
  304. InternalBreakFor(forState, OpCodes.Br);
  305. }
  306. internal void IfTrueBreak(object forState)
  307. {
  308. InternalBreakFor(forState, OpCodes.Brtrue);
  309. }
  310. internal void IfFalseBreak(object forState)
  311. {
  312. InternalBreakFor(forState, OpCodes.Brfalse);
  313. }
  314. internal void InternalBreakFor(object userForState, OpCode branchInstruction)
  315. {
  316. foreach (object block in blockStack)
  317. {
  318. ForState forState = block as ForState;
  319. if (forState != null && (object)forState == userForState)
  320. {
  321. if (!forState.RequiresEndLabel)
  322. {
  323. forState.EndLabel = DefineLabel();
  324. forState.RequiresEndLabel = true;
  325. }
  326. ilGen.Emit(branchInstruction, forState.EndLabel);
  327. break;
  328. }
  329. }
  330. }
  331. internal void ForEach(LocalBuilder local, Type elementType, Type enumeratorType,
  332. LocalBuilder enumerator, MethodInfo getCurrentMethod)
  333. {
  334. ForState forState = new ForState(local, DefineLabel(), DefineLabel(), enumerator);
  335. Br(forState.TestLabel);
  336. MarkLabel(forState.BeginLabel);
  337. Call(enumerator, getCurrentMethod);
  338. ConvertValue(elementType, GetVariableType(local));
  339. Stloc(local);
  340. blockStack.Push(forState);
  341. }
  342. internal void EndForEach(MethodInfo moveNextMethod)
  343. {
  344. object stackTop = blockStack.Pop();
  345. ForState forState = stackTop as ForState;
  346. if (forState == null)
  347. ThrowMismatchException(stackTop);
  348. MarkLabel(forState.TestLabel);
  349. object enumerator = forState.End;
  350. Call(enumerator, moveNextMethod);
  351. Brtrue(forState.BeginLabel);
  352. if (forState.RequiresEndLabel)
  353. MarkLabel(forState.EndLabel);
  354. }
  355. internal void IfNotDefaultValue(object value)
  356. {
  357. Type type = GetVariableType(value);
  358. TypeCode typeCode = Type.GetTypeCode(type);
  359. if ((typeCode == TypeCode.Object && type.IsValueType) ||
  360. typeCode == TypeCode.DateTime || typeCode == TypeCode.Decimal)
  361. {
  362. LoadDefaultValue(type);
  363. ConvertValue(type, Globals.TypeOfObject);
  364. Load(value);
  365. ConvertValue(type, Globals.TypeOfObject);
  366. Call(ObjectEquals);
  367. IfNot();
  368. }
  369. else
  370. {
  371. LoadDefaultValue(type);
  372. Load(value);
  373. If(Cmp.NotEqualTo);
  374. }
  375. }
  376. #endif
  377. internal void If() {
  378. InternalIf(false);
  379. }
  380. internal void IfNot() {
  381. InternalIf(true);
  382. }
  383. static OpCode[] BranchCodes = new OpCode[] {
  384. OpCodes.Bge,
  385. OpCodes.Bne_Un,
  386. OpCodes.Bgt,
  387. OpCodes.Ble,
  388. OpCodes.Beq,
  389. OpCodes.Blt,
  390. };
  391. OpCode GetBranchCode(Cmp cmp) {
  392. return BranchCodes[(int)cmp];
  393. }
  394. #if NotUsed
  395. Cmp GetCmpInverse(Cmp cmp)
  396. {
  397. switch (cmp) {
  398. case Cmp.LessThan:
  399. return Cmp.GreaterThanOrEqualTo;
  400. case Cmp.EqualTo:
  401. return Cmp.NotEqualTo;
  402. case Cmp.LessThanOrEqualTo:
  403. return Cmp.GreaterThan;
  404. case Cmp.GreaterThan:
  405. return Cmp.LessThanOrEqualTo;
  406. case Cmp.NotEqualTo:
  407. return Cmp.EqualTo;
  408. default:
  409. Debug.Assert(cmp == Cmp.GreaterThanOrEqualTo, "Unexpected cmp");
  410. return Cmp.LessThan;
  411. }
  412. }
  413. #endif
  414. internal void If(Cmp cmpOp) {
  415. IfState ifState = new IfState();
  416. ifState.EndIf = DefineLabel();
  417. ifState.ElseBegin = DefineLabel();
  418. ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
  419. blockStack.Push(ifState);
  420. }
  421. internal void If(object value1, Cmp cmpOp, object value2) {
  422. Load(value1);
  423. Load(value2);
  424. If(cmpOp);
  425. }
  426. internal void Else() {
  427. IfState ifState = PopIfState();
  428. Br(ifState.EndIf);
  429. MarkLabel(ifState.ElseBegin);
  430. ifState.ElseBegin = ifState.EndIf;
  431. blockStack.Push(ifState);
  432. }
  433. #if NotUsed
  434. internal void ElseIf(object value1, Cmp cmpOp, object value2)
  435. {
  436. IfState ifState = (IfState)blockStack.Pop();
  437. Br(ifState.EndIf);
  438. MarkLabel(ifState.ElseBegin);
  439. Load(value1);
  440. Load(value2);
  441. ifState.ElseBegin = DefineLabel();
  442. ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
  443. blockStack.Push(ifState);
  444. }
  445. #endif
  446. internal void EndIf() {
  447. IfState ifState = PopIfState();
  448. if (!ifState.ElseBegin.Equals(ifState.EndIf))
  449. MarkLabel(ifState.ElseBegin);
  450. MarkLabel(ifState.EndIf);
  451. }
  452. Stack leaveLabels = new Stack();
  453. internal void BeginExceptionBlock() {
  454. leaveLabels.Push(DefineLabel());
  455. ilGen.BeginExceptionBlock();
  456. }
  457. internal void BeginCatchBlock(Type exception) {
  458. ilGen.BeginCatchBlock(exception);
  459. }
  460. internal void EndExceptionBlock() {
  461. ilGen.EndExceptionBlock();
  462. ilGen.MarkLabel((Label)leaveLabels.Pop());
  463. }
  464. internal void Leave() {
  465. ilGen.Emit(OpCodes.Leave, (Label)leaveLabels.Peek());
  466. }
  467. #if NotUsed
  468. internal void VerifyParameterCount(MethodInfo methodInfo, int expectedCount)
  469. {
  470. if (methodInfo.GetParameters().Length != expectedCount)
  471. throw Utility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ParameterCountMismatch, methodInfo.Name, methodInfo.GetParameters().Length, expectedCount)));
  472. }
  473. internal void Call(object thisObj, MethodInfo methodInfo)
  474. {
  475. VerifyParameterCount(methodInfo, 0);
  476. LoadThis(thisObj, methodInfo);
  477. Call(methodInfo);
  478. }
  479. internal void Call(object thisObj, MethodInfo methodInfo, object param1)
  480. {
  481. VerifyParameterCount(methodInfo, 1);
  482. LoadThis(thisObj, methodInfo);
  483. LoadParam(param1, 1, methodInfo);
  484. Call(methodInfo);
  485. }
  486. internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2)
  487. {
  488. VerifyParameterCount(methodInfo, 2);
  489. LoadThis(thisObj, methodInfo);
  490. LoadParam(param1, 1, methodInfo);
  491. LoadParam(param2, 2, methodInfo);
  492. Call(methodInfo);
  493. }
  494. internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3)
  495. {
  496. VerifyParameterCount(methodInfo, 3);
  497. LoadThis(thisObj, methodInfo);
  498. LoadParam(param1, 1, methodInfo);
  499. LoadParam(param2, 2, methodInfo);
  500. LoadParam(param3, 3, methodInfo);
  501. Call(methodInfo);
  502. }
  503. internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4)
  504. {
  505. VerifyParameterCount(methodInfo, 4);
  506. LoadThis(thisObj, methodInfo);
  507. LoadParam(param1, 1, methodInfo);
  508. LoadParam(param2, 2, methodInfo);
  509. LoadParam(param3, 3, methodInfo);
  510. LoadParam(param4, 4, methodInfo);
  511. Call(methodInfo);
  512. }
  513. internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5)
  514. {
  515. VerifyParameterCount(methodInfo, 5);
  516. LoadThis(thisObj, methodInfo);
  517. LoadParam(param1, 1, methodInfo);
  518. LoadParam(param2, 2, methodInfo);
  519. LoadParam(param3, 3, methodInfo);
  520. LoadParam(param4, 4, methodInfo);
  521. LoadParam(param5, 5, methodInfo);
  522. Call(methodInfo);
  523. }
  524. internal void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5, object param6)
  525. {
  526. VerifyParameterCount(methodInfo, 6);
  527. LoadThis(thisObj, methodInfo);
  528. LoadParam(param1, 1, methodInfo);
  529. LoadParam(param2, 2, methodInfo);
  530. LoadParam(param3, 3, methodInfo);
  531. LoadParam(param4, 4, methodInfo);
  532. LoadParam(param5, 5, methodInfo);
  533. LoadParam(param6, 6, methodInfo);
  534. Call(methodInfo);
  535. }
  536. #endif
  537. internal void Call(MethodInfo methodInfo) {
  538. Debug.Assert(methodInfo != null);
  539. if (methodInfo.IsVirtual && !methodInfo.DeclaringType.IsValueType)
  540. ilGen.Emit(OpCodes.Callvirt, methodInfo);
  541. else
  542. ilGen.Emit(OpCodes.Call, methodInfo);
  543. }
  544. internal void Call(ConstructorInfo ctor) {
  545. Debug.Assert(ctor != null);
  546. ilGen.Emit(OpCodes.Call, ctor);
  547. }
  548. internal void New(ConstructorInfo constructorInfo) {
  549. Debug.Assert(constructorInfo != null);
  550. ilGen.Emit(OpCodes.Newobj, constructorInfo);
  551. }
  552. #if NotUsed
  553. internal void New(ConstructorInfo constructorInfo, object param1)
  554. {
  555. LoadParam(param1, 1, constructorInfo);
  556. New(constructorInfo);
  557. }
  558. #endif
  559. internal void InitObj(Type valueType) {
  560. ilGen.Emit(OpCodes.Initobj, valueType);
  561. }
  562. internal void NewArray(Type elementType, object len) {
  563. Load(len);
  564. ilGen.Emit(OpCodes.Newarr, elementType);
  565. }
  566. #if NotUsed
  567. internal void IgnoreReturnValue()
  568. {
  569. Pop();
  570. }
  571. #endif
  572. internal void LoadArrayElement(object obj, object arrayIndex) {
  573. Type objType = GetVariableType(obj).GetElementType();
  574. Load(obj);
  575. Load(arrayIndex);
  576. if (IsStruct(objType)) {
  577. Ldelema(objType);
  578. Ldobj(objType);
  579. }
  580. else
  581. Ldelem(objType);
  582. }
  583. internal void StoreArrayElement(object obj, object arrayIndex, object value) {
  584. Type arrayType = GetVariableType(obj);
  585. if (arrayType == typeof(Array)) {
  586. Load(obj);
  587. Call(typeof(Array).GetMethod("SetValue", new Type[] { typeof(object), typeof(int) }));
  588. }
  589. else {
  590. Type objType = arrayType.GetElementType();
  591. Load(obj);
  592. Load(arrayIndex);
  593. if (IsStruct(objType))
  594. Ldelema(objType);
  595. Load(value);
  596. ConvertValue(GetVariableType(value), objType);
  597. if (IsStruct(objType))
  598. Stobj(objType);
  599. else
  600. Stelem(objType);
  601. }
  602. }
  603. static bool IsStruct(Type objType) {
  604. return objType.IsValueType && !objType.IsPrimitive;
  605. }
  606. internal Type LoadMember(object obj, MemberInfo memberInfo) {
  607. if (GetVariableType(obj).IsValueType)
  608. LoadAddress(obj);
  609. else
  610. Load(obj);
  611. return LoadMember(memberInfo);
  612. }
  613. private static MethodInfo GetPropertyMethodFromBaseType(PropertyInfo propertyInfo, bool isGetter) {
  614. // we only invoke this when the propertyInfo does not have a GET or SET method on it
  615. Type currentType = propertyInfo.DeclaringType.BaseType;
  616. PropertyInfo currentProperty;
  617. string propertyName = propertyInfo.Name;
  618. MethodInfo result = null;
  619. while (currentType != null) {
  620. currentProperty = currentType.GetProperty(propertyName);
  621. if (currentProperty != null) {
  622. if (isGetter) {
  623. result = currentProperty.GetGetMethod(true);
  624. }
  625. else {
  626. result = currentProperty.GetSetMethod(true);
  627. }
  628. if (result != null) {
  629. // we found the GetMethod/SetMethod on the type closest to the current declaring type
  630. break;
  631. }
  632. }
  633. // keep looking at the base type like compiler does
  634. currentType = currentType.BaseType;
  635. }
  636. return result;
  637. }
  638. internal Type LoadMember(MemberInfo memberInfo) {
  639. Type memberType = null;
  640. if (memberInfo.MemberType == MemberTypes.Field) {
  641. FieldInfo fieldInfo = (FieldInfo)memberInfo;
  642. memberType = fieldInfo.FieldType;
  643. if (fieldInfo.IsStatic) {
  644. ilGen.Emit(OpCodes.Ldsfld, fieldInfo);
  645. }
  646. else {
  647. ilGen.Emit(OpCodes.Ldfld, fieldInfo);
  648. }
  649. }
  650. else {
  651. System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
  652. PropertyInfo property = (PropertyInfo)memberInfo;
  653. memberType = property.PropertyType;
  654. if (property != null) {
  655. MethodInfo getMethod = property.GetGetMethod(true);
  656. if (getMethod == null)
  657. {
  658. getMethod = GetPropertyMethodFromBaseType(property, true);
  659. }
  660. System.Diagnostics.Debug.Assert(getMethod != null);
  661. Call(getMethod);
  662. }
  663. }
  664. return memberType;
  665. }
  666. internal Type LoadMemberAddress(MemberInfo memberInfo) {
  667. Type memberType = null;
  668. if (memberInfo.MemberType == MemberTypes.Field) {
  669. FieldInfo fieldInfo = (FieldInfo)memberInfo;
  670. memberType = fieldInfo.FieldType;
  671. if (fieldInfo.IsStatic) {
  672. ilGen.Emit(OpCodes.Ldsflda, fieldInfo);
  673. }
  674. else {
  675. ilGen.Emit(OpCodes.Ldflda, fieldInfo);
  676. }
  677. }
  678. else {
  679. System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
  680. PropertyInfo property = (PropertyInfo)memberInfo;
  681. memberType = property.PropertyType;
  682. if (property != null) {
  683. MethodInfo getMethod = property.GetGetMethod(true);
  684. if (getMethod == null)
  685. {
  686. getMethod = GetPropertyMethodFromBaseType(property, true);
  687. }
  688. System.Diagnostics.Debug.Assert(getMethod != null);
  689. Call(getMethod);
  690. LocalBuilder tmpLoc = GetTempLocal(memberType);
  691. Stloc(tmpLoc);
  692. Ldloca(tmpLoc);
  693. }
  694. }
  695. return memberType;
  696. }
  697. internal void StoreMember(MemberInfo memberInfo) {
  698. if (memberInfo.MemberType == MemberTypes.Field) {
  699. FieldInfo fieldInfo = (FieldInfo)memberInfo;
  700. if (fieldInfo.IsStatic) {
  701. ilGen.Emit(OpCodes.Stsfld, fieldInfo);
  702. }
  703. else {
  704. ilGen.Emit(OpCodes.Stfld, fieldInfo);
  705. }
  706. }
  707. else {
  708. System.Diagnostics.Debug.Assert(memberInfo.MemberType == MemberTypes.Property);
  709. PropertyInfo property = (PropertyInfo)memberInfo;
  710. if (property != null) {
  711. MethodInfo setMethod = property.GetSetMethod(true);
  712. if (setMethod == null)
  713. {
  714. setMethod = GetPropertyMethodFromBaseType(property, false);
  715. }
  716. System.Diagnostics.Debug.Assert(setMethod != null);
  717. Call(setMethod);
  718. }
  719. }
  720. }
  721. #if NotUsed
  722. internal void LoadDefaultValue(Type type)
  723. {
  724. if (type.IsValueType)
  725. {
  726. switch (Type.GetTypeCode(type))
  727. {
  728. case TypeCode.Boolean:
  729. Ldc(false);
  730. break;
  731. case TypeCode.Char:
  732. case TypeCode.SByte:
  733. case TypeCode.Byte:
  734. case TypeCode.Int16:
  735. case TypeCode.UInt16:
  736. case TypeCode.Int32:
  737. case TypeCode.UInt32:
  738. Ldc(0);
  739. break;
  740. case TypeCode.Int64:
  741. case TypeCode.UInt64:
  742. Ldc(0L);
  743. break;
  744. case TypeCode.Single:
  745. Ldc(0.0F);
  746. break;
  747. case TypeCode.Double:
  748. Ldc(0.0);
  749. break;
  750. case TypeCode.Decimal:
  751. case TypeCode.DateTime:
  752. default:
  753. LocalBuilder zero = DeclareLocal(type, "zero");
  754. LoadAddress(zero);
  755. InitObj(type);
  756. Load(zero);
  757. break;
  758. }
  759. }
  760. else
  761. Load(null);
  762. }
  763. #endif
  764. internal void Load(object obj) {
  765. if (obj == null)
  766. ilGen.Emit(OpCodes.Ldnull);
  767. else if (obj is ArgBuilder)
  768. Ldarg((ArgBuilder)obj);
  769. else if (obj is LocalBuilder)
  770. Ldloc((LocalBuilder)obj);
  771. else
  772. Ldc(obj);
  773. }
  774. #if NotUsed
  775. internal void Store(object var)
  776. {
  777. if (var is ArgBuilder)
  778. Starg((ArgBuilder)var);
  779. else
  780. {
  781. System.Diagnostics.Debug.Assert(var is LocalBuilder);
  782. Stloc((LocalBuilder)var);
  783. }
  784. }
  785. internal void Dec(object var)
  786. {
  787. Load(var);
  788. Load(1);
  789. Subtract();
  790. Store(var);
  791. }
  792. internal void Inc(object var)
  793. {
  794. Load(var);
  795. Load(1);
  796. Add();
  797. Store(var);
  798. }
  799. #endif
  800. internal void LoadAddress(object obj) {
  801. if (obj is ArgBuilder)
  802. LdargAddress((ArgBuilder)obj);
  803. else if (obj is LocalBuilder)
  804. LdlocAddress((LocalBuilder)obj);
  805. else
  806. Load(obj);
  807. }
  808. internal void ConvertAddress(Type source, Type target) {
  809. InternalConvert(source, target, true);
  810. }
  811. internal void ConvertValue(Type source, Type target) {
  812. InternalConvert(source, target, false);
  813. }
  814. internal void Castclass(Type target) {
  815. ilGen.Emit(OpCodes.Castclass, target);
  816. }
  817. internal void Box(Type type) {
  818. ilGen.Emit(OpCodes.Box, type);
  819. }
  820. internal void Unbox(Type type) {
  821. ilGen.Emit(OpCodes.Unbox, type);
  822. }
  823. static OpCode[] LdindOpCodes = new OpCode[] {
  824. OpCodes.Nop,//Empty = 0,
  825. OpCodes.Nop,//Object = 1,
  826. OpCodes.Nop,//DBNull = 2,
  827. OpCodes.Ldind_I1,//Boolean = 3,
  828. OpCodes.Ldind_I2,//Char = 4,
  829. OpCodes.Ldind_I1,//SByte = 5,
  830. OpCodes.Ldind_U1,//Byte = 6,
  831. OpCodes.Ldind_I2,//Int16 = 7,
  832. OpCodes.Ldind_U2,//UInt16 = 8,
  833. OpCodes.Ldind_I4,//Int32 = 9,
  834. OpCodes.Ldind_U4,//UInt32 = 10,
  835. OpCodes.Ldind_I8,//Int64 = 11,
  836. OpCodes.Ldind_I8,//UInt64 = 12,
  837. OpCodes.Ldind_R4,//Single = 13,
  838. OpCodes.Ldind_R8,//Double = 14,
  839. OpCodes.Nop,//Decimal = 15,
  840. OpCodes.Nop,//DateTime = 16,
  841. OpCodes.Nop,//17
  842. OpCodes.Ldind_Ref,//String = 18,
  843. };
  844. OpCode GetLdindOpCode(TypeCode typeCode) {
  845. return LdindOpCodes[(int)typeCode];
  846. //switch (typeCode)
  847. //{
  848. //case TypeCode.Boolean:
  849. // return OpCodes.Ldind_I1; // TypeCode.Boolean:
  850. //case TypeCode.Char:
  851. // return OpCodes.Ldind_I2; // TypeCode.Char:
  852. //case TypeCode.SByte:
  853. // return OpCodes.Ldind_I1; // TypeCode.SByte:
  854. //case TypeCode.Byte:
  855. // return OpCodes.Ldind_U1; // TypeCode.Byte:
  856. //case TypeCode.Int16:
  857. // return OpCodes.Ldind_I2; // TypeCode.Int16:
  858. //case TypeCode.UInt16:
  859. // return OpCodes.Ldind_U2; // TypeCode.UInt16:
  860. //case TypeCode.Int32:
  861. // return OpCodes.Ldind_I4; // TypeCode.Int32:
  862. //case TypeCode.UInt32:
  863. // return OpCodes.Ldind_U4; // TypeCode.UInt32:
  864. //case TypeCode.Int64:
  865. // return OpCodes.Ldind_I8; // TypeCode.Int64:
  866. //case TypeCode.UInt64:
  867. // return OpCodes.Ldind_I8; // TypeCode.UInt64:
  868. //case TypeCode.Single:
  869. // return OpCodes.Ldind_R4; // TypeCode.Single:
  870. //case TypeCode.Double:
  871. // return OpCodes.Ldind_R8; // TypeCode.Double:
  872. //case TypeCode.String:
  873. // return OpCodes.Ldind_Ref; // TypeCode.String:
  874. //default:
  875. // return OpCodes.Nop;
  876. //}
  877. //
  878. }
  879. internal void Ldobj(Type type) {
  880. OpCode opCode = GetLdindOpCode(Type.GetTypeCode(type));
  881. if (!opCode.Equals(OpCodes.Nop)) {
  882. ilGen.Emit(opCode);
  883. }
  884. else {
  885. ilGen.Emit(OpCodes.Ldobj, type);
  886. }
  887. }
  888. internal void Stobj(Type type) {
  889. ilGen.Emit(OpCodes.Stobj, type);
  890. }
  891. internal void Ceq() {
  892. ilGen.Emit(OpCodes.Ceq);
  893. }
  894. internal void Clt() {
  895. ilGen.Emit(OpCodes.Clt);
  896. }
  897. internal void Cne() {
  898. Ceq();
  899. Ldc(0);
  900. Ceq();
  901. }
  902. #if NotUsed
  903. internal void Bgt(Label label)
  904. {
  905. ilGen.Emit(OpCodes.Bgt, label);
  906. }
  907. #endif
  908. internal void Ble(Label label) {
  909. ilGen.Emit(OpCodes.Ble, label);
  910. }
  911. internal void Throw() {
  912. ilGen.Emit(OpCodes.Throw);
  913. }
  914. internal void Ldtoken(Type t) {
  915. ilGen.Emit(OpCodes.Ldtoken, t);
  916. }
  917. internal void Ldc(object o) {
  918. Type valueType = o.GetType();
  919. if (o is Type) {
  920. Ldtoken((Type)o);
  921. Call(typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(RuntimeTypeHandle) }, null));
  922. }
  923. else if (valueType.IsEnum) {
  924. Ldc(((IConvertible)o).ToType(Enum.GetUnderlyingType(valueType), null));
  925. }
  926. else {
  927. switch (Type.GetTypeCode(valueType)) {
  928. case TypeCode.Boolean:
  929. Ldc((bool)o);
  930. break;
  931. case TypeCode.Char:
  932. Debug.Assert(false, "Char is not a valid schema primitive and should be treated as int in DataContract");
  933. throw new NotSupportedException("Char is not a valid schema primitive and should be treated as int in DataContract");
  934. case TypeCode.SByte:
  935. case TypeCode.Byte:
  936. case TypeCode.Int16:
  937. case TypeCode.UInt16:
  938. Ldc(((IConvertible)o).ToInt32(CultureInfo.InvariantCulture));
  939. break;
  940. case TypeCode.Int32:
  941. Ldc((int)o);
  942. break;
  943. case TypeCode.UInt32:
  944. Ldc((int)(uint)o);
  945. break;
  946. case TypeCode.UInt64:
  947. Ldc((long)(ulong)o);
  948. break;
  949. case TypeCode.Int64:
  950. Ldc((long)o);
  951. break;
  952. case TypeCode.Single:
  953. Ldc((float)o);
  954. break;
  955. case TypeCode.Double:
  956. Ldc((double)o);
  957. break;
  958. case TypeCode.String:
  959. Ldstr((string)o);
  960. break;
  961. case TypeCode.Decimal:
  962. ConstructorInfo Decimal_ctor = typeof(Decimal).GetConstructor(
  963. CodeGenerator.InstanceBindingFlags,
  964. null,
  965. new Type[] { typeof(Int32), typeof(Int32), typeof(Int32), typeof(Boolean), typeof(Byte) },
  966. null
  967. );
  968. int[] bits = Decimal.GetBits((decimal)o);
  969. Ldc(bits[0]); // digit
  970. Ldc(bits[1]); // digit
  971. Ldc(bits[2]); // digit
  972. Ldc((bits[3] & 0x80000000) == 0x80000000); // sign
  973. Ldc((Byte)((bits[3] >> 16) & 0xFF)); // decimal location
  974. New(Decimal_ctor);
  975. break;
  976. case TypeCode.DateTime:
  977. ConstructorInfo DateTime_ctor = typeof(DateTime).GetConstructor(
  978. CodeGenerator.InstanceBindingFlags,
  979. null,
  980. new Type[] { typeof(Int64) },
  981. null
  982. );
  983. Ldc(((DateTime)o).Ticks); // ticks
  984. New(DateTime_ctor);
  985. break;
  986. case TypeCode.Object:
  987. case TypeCode.Empty:
  988. case TypeCode.DBNull:
  989. default:
  990. if (valueType == typeof(TimeSpan) && LocalAppContextSwitches.EnableTimeSpanSerialization)
  991. {
  992. ConstructorInfo TimeSpan_ctor = typeof(TimeSpan).GetConstructor(
  993. CodeGenerator.InstanceBindingFlags,
  994. null,
  995. new Type[] { typeof(Int64) },
  996. null
  997. );
  998. Ldc(((TimeSpan)o).Ticks); // ticks
  999. New(TimeSpan_ctor);
  1000. break;
  1001. }
  1002. else
  1003. {
  1004. Debug.Assert(false, "UnknownConstantType");
  1005. throw new NotSupportedException("UnknownConstantType"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownConstantType, DataContract.GetClrTypeFullName(valueType))));
  1006. }
  1007. }
  1008. }
  1009. }
  1010. internal void Ldc(bool boolVar) {
  1011. if (boolVar) {
  1012. ilGen.Emit(OpCodes.Ldc_I4_1);
  1013. }
  1014. else {
  1015. ilGen.Emit(OpCodes.Ldc_I4_0);
  1016. }
  1017. }
  1018. internal void Ldc(int intVar) {
  1019. switch (intVar) {
  1020. case -1:
  1021. ilGen.Emit(OpCodes.Ldc_I4_M1);
  1022. break;
  1023. case 0:
  1024. ilGen.Emit(OpCodes.Ldc_I4_0);
  1025. break;
  1026. case 1:
  1027. ilGen.Emit(OpCodes.Ldc_I4_1);
  1028. break;
  1029. case 2:
  1030. ilGen.Emit(OpCodes.Ldc_I4_2);
  1031. break;
  1032. case 3:
  1033. ilGen.Emit(OpCodes.Ldc_I4_3);
  1034. break;
  1035. case 4:
  1036. ilGen.Emit(OpCodes.Ldc_I4_4);
  1037. break;
  1038. case 5:
  1039. ilGen.Emit(OpCodes.Ldc_I4_5);
  1040. break;
  1041. case 6:
  1042. ilGen.Emit(OpCodes.Ldc_I4_6);
  1043. break;
  1044. case 7:
  1045. ilGen.Emit(OpCodes.Ldc_I4_7);
  1046. break;
  1047. case 8:
  1048. ilGen.Emit(OpCodes.Ldc_I4_8);
  1049. break;
  1050. default:
  1051. ilGen.Emit(OpCodes.Ldc_I4, intVar);
  1052. break;
  1053. }
  1054. }
  1055. internal void Ldc(long l) {
  1056. ilGen.Emit(OpCodes.Ldc_I8, l);
  1057. }
  1058. internal void Ldc(float f) {
  1059. ilGen.Emit(OpCodes.Ldc_R4, f);
  1060. }
  1061. internal void Ldc(double d) {
  1062. ilGen.Emit(OpCodes.Ldc_R8, d);
  1063. }
  1064. internal void Ldstr(string strVar) {
  1065. if (strVar == null)
  1066. ilGen.Emit(OpCodes.Ldnull);
  1067. else
  1068. ilGen.Emit(OpCodes.Ldstr, strVar);
  1069. }
  1070. internal void LdlocAddress(LocalBuilder localBuilder) {
  1071. if (localBuilder.LocalType.IsValueType)
  1072. Ldloca(localBuilder);
  1073. else
  1074. Ldloc(localBuilder);
  1075. }
  1076. internal void Ldloc(LocalBuilder localBuilder) {
  1077. ilGen.Emit(OpCodes.Ldloc, localBuilder);
  1078. }
  1079. internal void Ldloc(string name) {
  1080. Debug.Assert(currentScope.ContainsKey(name));
  1081. LocalBuilder local = currentScope[name];
  1082. Ldloc(local);
  1083. }
  1084. internal void Stloc(Type type, string name) {
  1085. LocalBuilder local = null;
  1086. if (!currentScope.TryGetValue(name, out local)) {
  1087. local = DeclareLocal(type, name);
  1088. }
  1089. Debug.Assert(local.LocalType == type);
  1090. Stloc(local);
  1091. }
  1092. internal void Stloc(LocalBuilder local) {
  1093. ilGen.Emit(OpCodes.Stloc, local);
  1094. }
  1095. internal void Ldloc(Type type, string name) {
  1096. Debug.Assert(currentScope.ContainsKey(name));
  1097. LocalBuilder local = currentScope[name];
  1098. Debug.Assert(local.LocalType == type);
  1099. Ldloc(local);
  1100. }
  1101. #if NotUsed
  1102. internal void Ldloc(int slot)
  1103. {
  1104. switch (slot)
  1105. {
  1106. case 0:
  1107. ilGen.Emit(OpCodes.Ldloc_0);
  1108. break;
  1109. case 1:
  1110. ilGen.Emit(OpCodes.Ldloc_1);
  1111. break;
  1112. case 2:
  1113. ilGen.Emit(OpCodes.Ldloc_2);
  1114. break;
  1115. case 3:
  1116. ilGen.Emit(OpCodes.Ldloc_3);
  1117. break;
  1118. default:
  1119. if (slot <= 255)
  1120. ilGen.Emit(OpCodes.Ldloc_S, slot);
  1121. else
  1122. ilGen.Emit(OpCodes.Ldloc, slot);
  1123. break;
  1124. }
  1125. }
  1126. internal void Stloc(int slot)
  1127. {
  1128. switch (slot)
  1129. {
  1130. case 0:
  1131. ilGen.Emit(OpCodes.Stloc_0);
  1132. break;
  1133. case 1:
  1134. ilGen.Emit(OpCodes.Stloc_1);
  1135. break;
  1136. case 2:
  1137. ilGen.Emit(OpCodes.Stloc_2);
  1138. break;
  1139. case 3:
  1140. ilGen.Emit(OpCodes.Stloc_3);
  1141. break;
  1142. default:
  1143. if (slot <= 255)
  1144. ilGen.Emit(OpCodes.Stloc_S, slot);
  1145. else
  1146. ilGen.Emit(OpCodes.Stloc, slot);
  1147. break;
  1148. }
  1149. }
  1150. internal void Ldloca(int slot)
  1151. {
  1152. if (slot <= 255)
  1153. ilGen.Emit(OpCodes.Ldloca_S, slot);
  1154. else
  1155. ilGen.Emit(OpCodes.Ldloca, slot);
  1156. }
  1157. #endif
  1158. internal void Ldloca(LocalBuilder localBuilder) {
  1159. ilGen.Emit(OpCodes.Ldloca, localBuilder);
  1160. }
  1161. internal void LdargAddress(ArgBuilder argBuilder) {
  1162. if (argBuilder.ArgType.IsValueType)
  1163. Ldarga(argBuilder);
  1164. else
  1165. Ldarg(argBuilder);
  1166. }
  1167. internal void Ldarg(string arg) {
  1168. Ldarg(GetArg(arg));
  1169. }
  1170. internal void Ldarg(ArgBuilder arg) {
  1171. Ldarg(arg.Index);
  1172. }
  1173. internal void Ldarg(int slot) {
  1174. switch (slot) {
  1175. case 0:
  1176. ilGen.Emit(OpCodes.Ldarg_0);
  1177. break;
  1178. case 1:
  1179. ilGen.Emit(OpCodes.Ldarg_1);
  1180. break;
  1181. case 2:
  1182. ilGen.Emit(OpCodes.Ldarg_2);
  1183. break;
  1184. case 3:
  1185. ilGen.Emit(OpCodes.Ldarg_3);
  1186. break;
  1187. default:
  1188. if (slot <= 255)
  1189. ilGen.Emit(OpCodes.Ldarg_S, slot);
  1190. else
  1191. ilGen.Emit(OpCodes.Ldarg, slot);
  1192. break;
  1193. }
  1194. }
  1195. #if NotUsed
  1196. internal void Starg(ArgBuilder arg)
  1197. {
  1198. Starg(arg.Index);
  1199. }
  1200. internal void Starg(int slot)
  1201. {
  1202. if (slot <= 255)
  1203. ilGen.Emit(OpCodes.Starg_S, slot);
  1204. else
  1205. ilGen.Emit(OpCodes.Starg, slot);
  1206. }
  1207. #endif
  1208. internal void Ldarga(ArgBuilder argBuilder) {
  1209. Ldarga(argBuilder.Index);
  1210. }
  1211. internal void Ldarga(int slot) {
  1212. if (slot <= 255)
  1213. ilGen.Emit(OpCodes.Ldarga_S, slot);
  1214. else
  1215. ilGen.Emit(OpCodes.Ldarga, slot);
  1216. }
  1217. internal void Ldlen() {
  1218. ilGen.Emit(OpCodes.Ldlen);
  1219. ilGen.Emit(OpCodes.Conv_I4);
  1220. }
  1221. static OpCode[] LdelemOpCodes = new OpCode[] {
  1222. OpCodes.Nop,//Empty = 0,
  1223. OpCodes.Ldelem_Ref,//Object = 1,
  1224. OpCodes.Ldelem_Ref,//DBNull = 2,
  1225. OpCodes.Ldelem_I1,//Boolean = 3,
  1226. OpCodes.Ldelem_I2,//Char = 4,
  1227. OpCodes.Ldelem_I1,//SByte = 5,
  1228. OpCodes.Ldelem_U1,//Byte = 6,
  1229. OpCodes.Ldelem_I2,//Int16 = 7,
  1230. OpCodes.Ldelem_U2,//UInt16 = 8,
  1231. OpCodes.Ldelem_I4,//Int32 = 9,
  1232. OpCodes.Ldelem_U4,//UInt32 = 10,
  1233. OpCodes.Ldelem_I8,//Int64 = 11,
  1234. OpCodes.Ldelem_I8,//UInt64 = 12,
  1235. OpCodes.Ldelem_R4,//Single = 13,
  1236. OpCodes.Ldelem_R8,//Double = 14,
  1237. OpCodes.Nop,//Decimal = 15,
  1238. OpCodes.Nop,//DateTime = 16,
  1239. OpCodes.Nop,//17
  1240. OpCodes.Ldelem_Ref,//String = 18,
  1241. };
  1242. OpCode GetLdelemOpCode(TypeCode typeCode) {
  1243. return LdelemOpCodes[(int)typeCode];
  1244. //switch (typeCode)
  1245. //{
  1246. //case TypeCode.Object:
  1247. //case TypeCode.DBNull:
  1248. // return OpCodes.Ldelem_Ref;// TypeCode.Object:
  1249. //case TypeCode.Boolean:
  1250. // return OpCodes.Ldelem_I1;// TypeCode.Boolean:
  1251. //case TypeCode.Char:
  1252. // return OpCodes.Ldelem_I2;// TypeCode.Char:
  1253. //case TypeCode.SByte:
  1254. // return OpCodes.Ldelem_I1;// TypeCode.SByte:
  1255. //case TypeCode.Byte:
  1256. // return OpCodes.Ldelem_U1;// TypeCode.Byte:
  1257. //case TypeCode.Int16:
  1258. // return OpCodes.Ldelem_I2;// TypeCode.Int16:
  1259. //case TypeCode.UInt16:
  1260. // return OpCodes.Ldelem_U2;// TypeCode.UInt16:
  1261. //case TypeCode.Int32:
  1262. // return OpCodes.Ldelem_I4;// TypeCode.Int32:
  1263. //case TypeCode.UInt32:
  1264. // return OpCodes.Ldelem_U4;// TypeCode.UInt32:
  1265. //case TypeCode.Int64:
  1266. // return OpCodes.Ldelem_I8;// TypeCode.Int64:
  1267. //case TypeCode.UInt64:
  1268. // return OpCodes.Ldelem_I8;// TypeCode.UInt64:
  1269. //case TypeCode.Single:
  1270. // return OpCodes.Ldelem_R4;// TypeCode.Single:
  1271. //case TypeCode.Double:
  1272. // return OpCodes.Ldelem_R8;// TypeCode.Double:
  1273. //case TypeCode.String:
  1274. // return OpCodes.Ldelem_Ref;// TypeCode.String:
  1275. //default:
  1276. // return OpCodes.Nop;
  1277. //}
  1278. }
  1279. internal void Ldelem(Type arrayElementType) {
  1280. if (arrayElementType.IsEnum) {
  1281. Ldelem(Enum.GetUnderlyingType(arrayElementType));
  1282. }
  1283. else {
  1284. OpCode opCode = GetLdelemOpCode(Type.GetTypeCode(arrayElementType));
  1285. Debug.Assert(!opCode.Equals(OpCodes.Nop));
  1286. if (opCode.Equals(OpCodes.Nop))
  1287. throw new InvalidOperationException("ArrayTypeIsNotSupported"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
  1288. ilGen.Emit(opCode);
  1289. }
  1290. }
  1291. internal void Ldelema(Type arrayElementType) {
  1292. OpCode opCode = OpCodes.Ldelema;
  1293. ilGen.Emit(opCode, arrayElementType);
  1294. }
  1295. static OpCode[] StelemOpCodes = new OpCode[] {
  1296. OpCodes.Nop,//Empty = 0,
  1297. OpCodes.Stelem_Ref,//Object = 1,
  1298. OpCodes.Stelem_Ref,//DBNull = 2,
  1299. OpCodes.Stelem_I1,//Boolean = 3,
  1300. OpCodes.Stelem_I2,//Char = 4,
  1301. OpCodes.Stelem_I1,//SByte = 5,
  1302. OpCodes.Stelem_I1,//Byte = 6,
  1303. OpCodes.Stelem_I2,//Int16 = 7,
  1304. OpCodes.Stelem_I2,//UInt16 = 8,
  1305. OpCodes.Stelem_I4,//Int32 = 9,
  1306. OpCodes.Stelem_I4,//UInt32 = 10,
  1307. OpCodes.Stelem_I8,//Int64 = 11,
  1308. OpCodes.Stelem_I8,//UInt64 = 12,
  1309. OpCodes.Stelem_R4,//Single = 13,
  1310. OpCodes.Stelem_R8,//Double = 14,
  1311. OpCodes.Nop,//Decimal = 15,
  1312. OpCodes.Nop,//DateTime = 16,
  1313. OpCodes.Nop,//17
  1314. OpCodes.Stelem_Ref,//String = 18,
  1315. };
  1316. OpCode GetStelemOpCode(TypeCode typeCode) {
  1317. return StelemOpCodes[(int)typeCode];
  1318. //switch (typeCode)
  1319. //{
  1320. //case TypeCode.Object:
  1321. //case TypeCode.DBNull:
  1322. // return OpCodes.Stelem_Ref;// TypeCode.Object:
  1323. //case TypeCode.Boolean:
  1324. // return OpCodes.Stelem_I1;// TypeCode.Boolean:
  1325. //case TypeCode.Char:
  1326. // return OpCodes.Stelem_I2;// TypeCode.Char:
  1327. //case TypeCode.SByte:
  1328. // return OpCodes.Stelem_I1;// TypeCode.SByte:
  1329. //case TypeCode.Byte:
  1330. // return OpCodes.Stelem_I1;// TypeCode.Byte:
  1331. //case TypeCode.Int16:
  1332. // return OpCodes.Stelem_I2;// TypeCode.Int16:
  1333. //case TypeCode.UInt16:
  1334. // return OpCodes.Stelem_I2;// TypeCode.UInt16:
  1335. //case TypeCode.Int32:
  1336. // return OpCodes.Stelem_I4;// TypeCode.Int32:
  1337. //case TypeCode.UInt32:
  1338. // return OpCodes.Stelem_I4;// TypeCode.UInt32:
  1339. //case TypeCode.Int64:
  1340. // return OpCodes.Stelem_I8;// TypeCode.Int64:
  1341. //case TypeCode.UInt64:
  1342. // return OpCodes.Stelem_I8;// TypeCode.UInt64:
  1343. //case TypeCode.Single:
  1344. // return OpCodes.Stelem_R4;// TypeCode.Single:
  1345. //case TypeCode.Double:
  1346. // return OpCodes.Stelem_R8;// TypeCode.Double:
  1347. //case TypeCode.String:
  1348. // return OpCodes.Stelem_Ref;// TypeCode.String:
  1349. //default:
  1350. // return OpCodes.Nop;
  1351. //}
  1352. }
  1353. internal void Stelem(Type arrayElementType) {
  1354. if (arrayElementType.IsEnum)
  1355. Stelem(Enum.GetUnderlyingType(arrayElementType));
  1356. else {
  1357. OpCode opCode = GetStelemOpCode(Type.GetTypeCode(arrayElementType));
  1358. if (opCode.Equals(OpCodes.Nop))
  1359. throw new InvalidOperationException("ArrayTypeIsNotSupported"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayTypeIsNotSupported, DataContract.GetClrTypeFullName(arrayElementType))));
  1360. ilGen.Emit(opCode);
  1361. }
  1362. }
  1363. internal Label DefineLabel() {
  1364. return ilGen.DefineLabel();
  1365. }
  1366. internal void MarkLabel(Label label) {
  1367. ilGen.MarkLabel(label);
  1368. }
  1369. internal void Nop() {
  1370. ilGen.Emit(OpCodes.Nop);
  1371. }
  1372. internal void Add() {
  1373. ilGen.Emit(OpCodes.Add);
  1374. }
  1375. #if NotUsed
  1376. internal void Subtract()
  1377. {
  1378. ilGen.Emit(OpCodes.Sub);
  1379. }
  1380. internal void And()
  1381. {
  1382. ilGen.Emit(OpCodes.And);
  1383. }
  1384. internal void Or()
  1385. {
  1386. ilGen.Emit(OpCodes.Or);
  1387. }
  1388. internal void Not()
  1389. {
  1390. ilGen.Emit(OpCodes.Not);
  1391. }
  1392. #endif
  1393. internal void Ret() {
  1394. ilGen.Emit(OpCodes.Ret);
  1395. }
  1396. internal void Br(Label label) {
  1397. ilGen.Emit(OpCodes.Br, label);
  1398. }
  1399. internal void Br_S(Label label) {
  1400. ilGen.Emit(OpCodes.Br_S, label);
  1401. }
  1402. internal void Blt(Label label) {
  1403. ilGen.Emit(OpCodes.Blt, label);
  1404. }
  1405. internal void Brfalse(Label label) {
  1406. ilGen.Emit(OpCodes.Brfalse, label);
  1407. }
  1408. internal void Brtrue(Label label) {
  1409. ilGen.Emit(OpCodes.Brtrue, label);
  1410. }
  1411. internal void Pop() {
  1412. ilGen.Emit(OpCodes.Pop);
  1413. }
  1414. internal void Dup() {
  1415. ilGen.Emit(OpCodes.Dup);
  1416. }
  1417. #if !SILVERLIGHT // Not in SL
  1418. internal void Ldftn(MethodInfo methodInfo) {
  1419. ilGen.Emit(OpCodes.Ldftn, methodInfo);
  1420. }
  1421. #endif
  1422. #if NotUsed
  1423. void LoadThis(object thisObj, MethodInfo methodInfo)
  1424. {
  1425. if (thisObj != null && !methodInfo.IsStatic)
  1426. {
  1427. LoadAddress(thisObj);
  1428. ConvertAddress(GetVariableType(thisObj), methodInfo.DeclaringType);
  1429. }
  1430. }
  1431. void LoadParam(object arg, int oneBasedArgIndex, MethodBase methodInfo)
  1432. {
  1433. Load(arg);
  1434. if (arg != null)
  1435. ConvertValue(GetVariableType(arg), methodInfo.GetParameters()[oneBasedArgIndex - 1].ParameterType);
  1436. }
  1437. #endif
  1438. void InternalIf(bool negate) {
  1439. IfState ifState = new IfState();
  1440. ifState.EndIf = DefineLabel();
  1441. ifState.ElseBegin = DefineLabel();
  1442. if (negate)
  1443. Brtrue(ifState.ElseBegin);
  1444. else
  1445. Brfalse(ifState.ElseBegin);
  1446. blockStack.Push(ifState);
  1447. }
  1448. static OpCode[] ConvOpCodes = new OpCode[] {
  1449. OpCodes.Nop,//Empty = 0,
  1450. OpCodes.Nop,//Object = 1,
  1451. OpCodes.Nop,//DBNull = 2,
  1452. OpCodes.Conv_I1,//Boolean = 3,
  1453. OpCodes.Conv_I2,//Char = 4,
  1454. OpCodes.Conv_I1,//SByte = 5,
  1455. OpCodes.Conv_U1,//Byte = 6,
  1456. OpCodes.Conv_I2,//Int16 = 7,
  1457. OpCodes.Conv_U2,//UInt16 = 8,
  1458. OpCodes.Conv_I4,//Int32 = 9,
  1459. OpCodes.Conv_U4,//UInt32 = 10,
  1460. OpCodes.Conv_I8,//Int64 = 11,
  1461. OpCodes.Conv_U8,//UInt64 = 12,
  1462. OpCodes.Conv_R4,//Single = 13,
  1463. OpCodes.Conv_R8,//Double = 14,
  1464. OpCodes.Nop,//Decimal = 15,
  1465. OpCodes.Nop,//DateTime = 16,
  1466. OpCodes.Nop,//17
  1467. OpCodes.Nop,//String = 18,
  1468. };
  1469. OpCode GetConvOpCode(TypeCode typeCode) {
  1470. return ConvOpCodes[(int)typeCode];
  1471. //switch (typeCode)
  1472. //{
  1473. //case TypeCode.Boolean:
  1474. // return OpCodes.Conv_I1;// TypeCode.Boolean:
  1475. //case TypeCode.Char:
  1476. // return OpCodes.Conv_I2;// TypeCode.Char:
  1477. //case TypeCode.SByte:
  1478. // return OpCodes.Conv_I1;// TypeCode.SByte:
  1479. //case TypeCode.Byte:
  1480. // return OpCodes.Conv_U1;// TypeCode.Byte:
  1481. //case TypeCode.Int16:
  1482. // return OpCodes.Conv_I2;// TypeCode.Int16:
  1483. //case TypeCode.UInt16:
  1484. // return OpCodes.Conv_U2;// TypeCode.UInt16:
  1485. //case TypeCode.Int32:
  1486. // return OpCodes.Conv_I4;// TypeCode.Int32:
  1487. //case TypeCode.UInt32:
  1488. // return OpCodes.Conv_U4;// TypeCode.UInt32:
  1489. //case TypeCode.Int64:
  1490. // return OpCodes.Conv_I8;// TypeCode.Int64:
  1491. //case TypeCode.UInt64:
  1492. // return OpCodes.Conv_U8;// TypeCode.UInt64:
  1493. //case TypeCode.Single:
  1494. // return OpCodes.Conv_R4;// TypeCode.Single:
  1495. //case TypeCode.Double:
  1496. // return OpCodes.Conv_R8;// TypeCode.Double:
  1497. //default:
  1498. // return OpCodes.Nop;
  1499. //}
  1500. }
  1501. void InternalConvert(Type source, Type target, bool isAddress) {
  1502. if (target == source)
  1503. return;
  1504. if (target.IsValueType) {
  1505. if (source.IsValueType) {
  1506. OpCode opCode = GetConvOpCode(Type.GetTypeCode(target));
  1507. if (opCode.Equals(OpCodes.Nop)) {
  1508. //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NoConversionPossibleTo, DataContract.GetClrTypeFullName(target))));
  1509. throw new CodeGeneratorConversionException(source, target, isAddress,"NoConversionPossibleTo");
  1510. }
  1511. else {
  1512. ilGen.Emit(opCode);
  1513. }
  1514. }
  1515. else if (source.IsAssignableFrom(target)) {
  1516. Unbox(target);
  1517. if (!isAddress)
  1518. Ldobj(target);
  1519. }
  1520. else {
  1521. //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
  1522. throw new CodeGeneratorConversionException(source, target, isAddress, "IsNotAssignableFrom");
  1523. }
  1524. }
  1525. else if (target.IsAssignableFrom(source)) {
  1526. if (source.IsValueType) {
  1527. if (isAddress)
  1528. Ldobj(source);
  1529. Box(source);
  1530. }
  1531. }
  1532. else if (source.IsAssignableFrom(target)) {
  1533. //assert(source.IsValueType == false);
  1534. Castclass(target);
  1535. }
  1536. else if (target.IsInterface || source.IsInterface) {
  1537. Castclass(target);
  1538. }
  1539. else {
  1540. //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsNotAssignableFrom, DataContract.GetClrTypeFullName(target), DataContract.GetClrTypeFullName(source))));
  1541. throw new CodeGeneratorConversionException(source, target, isAddress, "IsNotAssignableFrom");
  1542. }
  1543. }
  1544. IfState PopIfState() {
  1545. object stackTop = blockStack.Pop();
  1546. IfState ifState = stackTop as IfState;
  1547. Debug.Assert(ifState != null);
  1548. return ifState;
  1549. }
  1550. static internal AssemblyBuilder CreateAssemblyBuilder(AppDomain appDomain, string name) {
  1551. AssemblyName assemblyName = new AssemblyName();
  1552. assemblyName.Name = name;
  1553. assemblyName.Version = new Version(1, 0, 0, 0);
  1554. if (DiagnosticsSwitches.KeepTempFiles.Enabled)
  1555. return appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, TempFilesLocation);
  1556. else
  1557. return appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
  1558. }
  1559. static string tempFilesLocation = null;
  1560. internal static string TempFilesLocation {
  1561. get {
  1562. if (tempFilesLocation == null) {
  1563. #if CONFIGURATION_DEP
  1564. // Return different XmlSerializerSection from legacy assembly due to its register config handlers
  1565. object section = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath);
  1566. string location = null;
  1567. if (section != null) {
  1568. XmlSerializerSection configSection = section as XmlSerializerSection;
  1569. if (configSection != null) {
  1570. location = configSection.TempFilesLocation;
  1571. }
  1572. }
  1573. #else
  1574. string location = null;
  1575. #endif
  1576. if (location != null) {
  1577. tempFilesLocation = location.Trim();
  1578. }
  1579. else {
  1580. tempFilesLocation = Path.GetTempPath();
  1581. }
  1582. }
  1583. return tempFilesLocation;
  1584. }
  1585. set {
  1586. tempFilesLocation = value;
  1587. }
  1588. }
  1589. static internal ModuleBuilder CreateModuleBuilder(AssemblyBuilder assemblyBuilder, string name) {
  1590. if (DiagnosticsSwitches.KeepTempFiles.Enabled)
  1591. return assemblyBuilder.DefineDynamicModule(name, name + ".dll", true);
  1592. else
  1593. return assemblyBuilder.DefineDynamicModule(name);
  1594. }
  1595. static internal TypeBuilder CreateTypeBuilder(ModuleBuilder moduleBuilder, string name, TypeAttributes attributes, Type parent, Type[] interfaces) {
  1596. // parent is nullable if no base class
  1597. return moduleBuilder.DefineType(TempAssembly.GeneratedAssemblyNamespace + "." + name,
  1598. attributes, parent, interfaces);
  1599. }
  1600. #if NotUsed
  1601. internal void EmitSourceInstruction(string line)
  1602. {
  1603. EmitSourceLine(" " + line);
  1604. }
  1605. internal void EmitSourceLabel(string line)
  1606. {
  1607. EmitSourceLine(line);
  1608. }
  1609. internal void EmitSourceComment(string comment)
  1610. {
  1611. EmitSourceInstruction("// " + comment);
  1612. }
  1613. internal void EmitSourceLine(string line)
  1614. {
  1615. if (codeGenTrace != CodeGenTrace.None)
  1616. Console.WriteLine(String.Format("{0:X4}: {1}", lineNo++, line));
  1617. SerializationTrace.WriteInstruction(lineNo++, line);
  1618. if (ilGen != null && codeGenTrace == CodeGenTrace.Tron)
  1619. {
  1620. ilGen.Emit(OpCodes.Ldstr, string.Format(CultureInfo.InvariantCulture, "{0:00000}: {1}", lineNo-1, line));
  1621. ilGen.Emit(OpCodes.Call, XmlFormatGeneratorStatics.TraceInstructionMethod);
  1622. }
  1623. }
  1624. internal void EmitStackTop(Type stackTopType)
  1625. {
  1626. if (codeGenTrace != CodeGenTrace.Tron)
  1627. return;
  1628. codeGenTrace = CodeGenTrace.None;
  1629. Dup();
  1630. ToString(stackTopType);
  1631. LocalBuilder topValue = DeclareLocal(Globals.TypeOfString, "topValue");
  1632. Store(topValue);
  1633. Load("//value = ");
  1634. Load(topValue);
  1635. Concat2();
  1636. Call(XmlFormatGeneratorStatics.TraceInstructionMethod);
  1637. codeGenTrace = CodeGenTrace.Tron;
  1638. }
  1639. internal void ToString(Type type)
  1640. {
  1641. if (type.IsValueType)
  1642. {
  1643. Box(type);
  1644. Call(ObjectToString);
  1645. }
  1646. else
  1647. {
  1648. Dup();
  1649. Load(null);
  1650. If(Cmp.EqualTo);
  1651. Pop();
  1652. Load("<null>");
  1653. Else();
  1654. if (type.IsArray)
  1655. {
  1656. LocalBuilder arrayVar = DeclareLocal(type, "arrayVar");
  1657. Store(arrayVar);
  1658. Load("{ ");
  1659. LocalBuilder arrayValueString = DeclareLocal(typeof(string), "arrayValueString");
  1660. Store(arrayValueString);
  1661. LocalBuilder i = DeclareLocal(typeof(int), "i");
  1662. For(i, 0, arrayVar);
  1663. Load(arrayValueString);
  1664. LoadArrayElement(arrayVar, i);
  1665. ToString(arrayVar.LocalType.GetElementType());
  1666. Load(", ");
  1667. Concat3();
  1668. Store(arrayValueString);
  1669. EndFor();
  1670. Load(arrayValueString);
  1671. Load("}");
  1672. Concat2();
  1673. }
  1674. else
  1675. Call(ObjectToString);
  1676. EndIf();
  1677. }
  1678. }
  1679. internal void Concat2()
  1680. {
  1681. Call(StringConcat2);
  1682. }
  1683. internal void Concat3()
  1684. {
  1685. Call(StringConcat3);
  1686. }
  1687. internal Label[] Switch(int labelCount)
  1688. {
  1689. SwitchState switchState = new SwitchState(DefineLabel(), DefineLabel());
  1690. Label[] caseLabels = new Label[labelCount];
  1691. for (int i = 0; i < caseLabels.Length; i++)
  1692. caseLabels[i] = DefineLabel();
  1693. if (codeGenTrace != CodeGenTrace.None)
  1694. {
  1695. EmitSourceInstruction("switch (");
  1696. foreach (Label l in caseLabels)
  1697. EmitSourceInstruction(" " + l.GetHashCode());
  1698. EmitSourceInstruction(") {");
  1699. }
  1700. ilGen.Emit(OpCodes.Switch, caseLabels);
  1701. Br(switchState.DefaultLabel);
  1702. blockStack.Push(switchState);
  1703. return caseLabels;
  1704. }
  1705. internal void Case(Label caseLabel1, string caseLabelName)
  1706. {
  1707. if (codeGenTrace != CodeGenTrace.None)
  1708. EmitSourceInstruction("case " + caseLabelName + "{");
  1709. MarkLabel(caseLabel1);
  1710. }
  1711. internal void EndCase()
  1712. {
  1713. object stackTop = blockStack.Peek();
  1714. SwitchState switchState = stackTop as SwitchState;
  1715. if (switchState == null)
  1716. ThrowMismatchException(stackTop);
  1717. Br(switchState.EndOfSwitchLabel);
  1718. if (codeGenTrace != CodeGenTrace.None)
  1719. EmitSourceInstruction("} //end case ");
  1720. }
  1721. internal void DefaultCase()
  1722. {
  1723. object stackTop = blockStack.Peek();
  1724. SwitchState switchState = stackTop as SwitchState;
  1725. if (switchState == null)
  1726. ThrowMismatchException(stackTop);
  1727. MarkLabel(switchState.DefaultLabel);
  1728. switchState.DefaultDefined = true;
  1729. }
  1730. internal void EndSwitch()
  1731. {
  1732. object stackTop = blockStack.Pop();
  1733. SwitchState switchState = stackTop as SwitchState;
  1734. if (switchState == null)
  1735. ThrowMismatchException(stackTop);
  1736. if (codeGenTrace != CodeGenTrace.None)
  1737. EmitSourceInstruction("} //end switch");
  1738. if (!switchState.DefaultDefined)
  1739. MarkLabel(switchState.DefaultLabel);
  1740. MarkLabel(switchState.EndOfSwitchLabel);
  1741. }
  1742. internal void CallStringFormat(string msg, params object[] values)
  1743. {
  1744. NewArray(typeof(object), values.Length);
  1745. if (stringFormatArray == null)
  1746. stringFormatArray = DeclareLocal(typeof(object[]), "stringFormatArray");
  1747. Stloc(stringFormatArray);
  1748. for (int i = 0; i < values.Length; i++)
  1749. StoreArrayElement(stringFormatArray, i, values[i]);
  1750. Load(msg);
  1751. Load(stringFormatArray);
  1752. Call(StringFormat);
  1753. }
  1754. static MethodInfo stringEquals = typeof(string).GetMethod("Equals", new Type[]{ typeof(string), typeof(string)});
  1755. static MethodInfo stringCompare = typeof(string).GetMethod("Compare", new Type[]{ typeof(string), typeof(string)});
  1756. static ConstructorInfo permissionSetCtor = typeof(PermissionSet).GetConstructor(new Type[]{ typeof(PermissionState)});
  1757. static MethodInfo permissionSetDemand = typeof(PermissionSet).GetMethod("Demand", new Type[0]);
  1758. #endif
  1759. int initElseIfStack = -1;
  1760. IfState elseIfState;
  1761. internal void InitElseIf() {
  1762. Debug.Assert(initElseIfStack == -1);
  1763. elseIfState = (IfState)blockStack.Pop();
  1764. initElseIfStack = blockStack.Count;
  1765. Br(elseIfState.EndIf);
  1766. MarkLabel(elseIfState.ElseBegin);
  1767. }
  1768. int initIfStack = -1;
  1769. internal void InitIf() {
  1770. Debug.Assert(initIfStack == -1);
  1771. initIfStack = blockStack.Count;
  1772. }
  1773. internal void AndIf(Cmp cmpOp) {
  1774. if (initIfStack == blockStack.Count) {
  1775. initIfStack = -1;
  1776. If(cmpOp);
  1777. return;
  1778. }
  1779. if (initElseIfStack == blockStack.Count) {
  1780. initElseIfStack = -1;
  1781. elseIfState.ElseBegin = DefineLabel();
  1782. ilGen.Emit(GetBranchCode(cmpOp), elseIfState.ElseBegin);
  1783. blockStack.Push(elseIfState);
  1784. return;
  1785. }
  1786. Debug.Assert(initIfStack == -1 && initElseIfStack == -1);
  1787. IfState ifState = (IfState)blockStack.Peek();
  1788. ilGen.Emit(GetBranchCode(cmpOp), ifState.ElseBegin);
  1789. }
  1790. internal void AndIf() {
  1791. if (initIfStack == blockStack.Count) {
  1792. initIfStack = -1;
  1793. If();
  1794. return;
  1795. }
  1796. if (initElseIfStack == blockStack.Count) {
  1797. initElseIfStack = -1;
  1798. elseIfState.ElseBegin = DefineLabel();
  1799. Brfalse(elseIfState.ElseBegin);
  1800. blockStack.Push(elseIfState);
  1801. return;
  1802. }
  1803. Debug.Assert(initIfStack == -1 && initElseIfStack == -1);
  1804. IfState ifState = (IfState)blockStack.Peek();
  1805. Brfalse(ifState.ElseBegin);
  1806. }
  1807. #if NotUsed
  1808. internal void ElseIf(object boolVal)
  1809. {
  1810. InternalElseIf(boolVal, false);
  1811. }
  1812. void InternalElseIf(object boolVal, bool negate)
  1813. {
  1814. IfState ifState = (IfState)blockStack.Pop();
  1815. Br(ifState.EndIf);
  1816. MarkLabel(ifState.ElseBegin);
  1817. Load(boolVal);
  1818. ifState.ElseBegin = DefineLabel();
  1819. if (negate)
  1820. Brtrue(ifState.ElseBegin);
  1821. else
  1822. Brfalse(ifState.ElseBegin);
  1823. blockStack.Push(ifState);
  1824. }
  1825. internal void IfString(object s1, Cmp cmpOp, object s2)
  1826. {
  1827. Load(s1);
  1828. Load(s2);
  1829. Call(stringCompare);
  1830. Load(0);
  1831. If(cmpOp);
  1832. }
  1833. internal void ElseIfString(object s1, Cmp cmpOp, object s2)
  1834. {
  1835. IfState ifState = (IfState)blockStack.Pop();
  1836. Br(ifState.EndIf);
  1837. MarkLabel(ifState.ElseBegin);
  1838. Load(s1);
  1839. Load(s2);
  1840. Call(stringCompare);
  1841. Load(0);
  1842. ifState.ElseBegin = DefineLabel();
  1843. if (codeGenTrace != CodeGenTrace.None)
  1844. EmitSourceInstruction("Branch if " + CmpInverse[(int) cmpOp].ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString(NumberFormatInfo.InvariantInfo));
  1845. ilGen.Emit(BranchCode[(int)cmpOp], ifState.ElseBegin);
  1846. blockStack.Push(ifState);
  1847. }
  1848. internal void While(object value1, Cmp cmpOp, object value2)
  1849. {
  1850. IfState ifState = new IfState();
  1851. ifState.EndIf = DefineLabel();
  1852. ifState.ElseBegin = DefineLabel();
  1853. ilGen.MarkLabel(ifState.ElseBegin);
  1854. Load(value1);
  1855. Load(value2);
  1856. if (codeGenTrace != CodeGenTrace.None)
  1857. EmitSourceInstruction("Branch if " + CmpInverse[(int) cmpOp].ToString() + " to " + ifState.ElseBegin.GetHashCode().ToString());
  1858. ilGen.Emit(BranchCode[(int)cmpOp], ifState.EndIf);
  1859. blockStack.Push(ifState);
  1860. }
  1861. internal void EndWhile()
  1862. {
  1863. IfState ifState = PopIfState();
  1864. Br(ifState.ElseBegin);
  1865. MarkLabel(ifState.EndIf);
  1866. }
  1867. internal void ElseIfNot(object boolVal)
  1868. {
  1869. InternalElseIf(boolVal, true);
  1870. }
  1871. internal void Ldc(long l)
  1872. {
  1873. if (codeGenTrace != CodeGenTrace.None)
  1874. EmitSourceInstruction("Ldc.i8 " + l);
  1875. ilGen.Emit(OpCodes.Ldc_I8, l);
  1876. }
  1877. internal void Ldc(float f)
  1878. {
  1879. if (codeGenTrace != CodeGenTrace.None)
  1880. EmitSourceInstruction("Ldc.r4 " + f);
  1881. ilGen.Emit(OpCodes.Ldc_R4, f);
  1882. }
  1883. internal void Ldc(double d)
  1884. {
  1885. if (codeGenTrace != CodeGenTrace.None)
  1886. EmitSourceInstruction("Ldc.r8 " + d);
  1887. ilGen.Emit(OpCodes.Ldc_R8, d);
  1888. }
  1889. #endif
  1890. internal void IsInst(Type type) {
  1891. ilGen.Emit(OpCodes.Isinst, type);
  1892. }
  1893. #if NotUsed
  1894. internal void Clt()
  1895. {
  1896. if (codeGenTrace != CodeGenTrace.None)
  1897. EmitSourceInstruction("Clt");
  1898. ilGen.Emit(OpCodes.Clt);
  1899. }
  1900. internal void StringEquals()
  1901. {
  1902. Call(stringEquals);
  1903. }
  1904. internal void StringEquals(object s1, object s2)
  1905. {
  1906. Load(s1);
  1907. ConvertValue(GetVariableType(s1), typeof(string));
  1908. Load(s2);
  1909. ConvertValue(GetVariableType(s2), typeof(string));
  1910. StringEquals();
  1911. }
  1912. internal void Bge(Label label)
  1913. {
  1914. if (codeGenTrace != CodeGenTrace.None)
  1915. EmitSourceInstruction("Bge " + label.GetHashCode());
  1916. ilGen.Emit(OpCodes.Bge, label);
  1917. }
  1918. #endif
  1919. internal void Beq(Label label) {
  1920. ilGen.Emit(OpCodes.Beq, label);
  1921. }
  1922. internal void Bne(Label label) {
  1923. ilGen.Emit(OpCodes.Bne_Un, label);
  1924. }
  1925. #if NotUsed
  1926. internal void ResizeArray(object arrayVar, object sizeVar)
  1927. {
  1928. if (codeGenTrace != CodeGenTrace.None)
  1929. EmitSourceComment("ResizeArray() {");
  1930. Label doResize = DefineLabel();
  1931. Load(arrayVar);
  1932. Load(null);
  1933. Beq(doResize);
  1934. Ldlen(arrayVar);
  1935. Load(sizeVar);
  1936. If(Cmp.NotEqualTo);
  1937. MarkLabel(doResize);
  1938. Type arrayType = GetVariableType(arrayVar);
  1939. Type elementType = arrayType.GetElementType();
  1940. LocalBuilder tempArray = DeclareLocal(arrayType, "tempArray");
  1941. NewArray(elementType, sizeVar);
  1942. Store(tempArray);
  1943. CopyArray(arrayVar, tempArray, sizeVar);
  1944. Load(tempArray);
  1945. Store(arrayVar);
  1946. EndIf();
  1947. if (codeGenTrace != CodeGenTrace.None)
  1948. EmitSourceComment("} // ResizeArray");
  1949. }
  1950. LocalBuilder resizeLen, resizeCounter;
  1951. internal void EnsureArrayCapacity(object arrayVar, object lastElementVar)
  1952. {
  1953. if (codeGenTrace != CodeGenTrace.None)
  1954. EmitSourceComment("EnsureArrayCapacity() {");
  1955. Type arrayType = GetVariableType(arrayVar);
  1956. Type elementType = arrayType.GetElementType();
  1957. If(arrayVar, Cmp.EqualTo, null);
  1958. NewArray(elementType, 4);
  1959. Store(arrayVar);
  1960. Else();
  1961. Load(lastElementVar);
  1962. Ldlen(arrayVar);
  1963. If(Cmp.GreaterThanOrEqualTo);
  1964. LocalBuilder tempArray = DeclareLocal(arrayType, "tempArray");
  1965. if (resizeLen == null)
  1966. resizeLen = DeclareLocal(typeof(int), "resizeLen");
  1967. Load(lastElementVar);
  1968. Load(2);
  1969. Mul();
  1970. Store(resizeLen);
  1971. NewArray(elementType, resizeLen);
  1972. Store(tempArray);
  1973. CopyArray(arrayVar, tempArray, arrayVar);
  1974. Load(tempArray);
  1975. Store(arrayVar);
  1976. EndIf();
  1977. EndIf();
  1978. if (codeGenTrace != CodeGenTrace.None)
  1979. EmitSourceComment("} // EnsureArrayCapacity");
  1980. }
  1981. internal void CopyArray(object sourceArray, object destArray, object length)
  1982. {
  1983. If(sourceArray, Cmp.NotEqualTo, null);
  1984. if (resizeCounter == null)
  1985. resizeCounter = DeclareLocal(typeof(int), "resizeCounter");
  1986. For(resizeCounter, 0, length);
  1987. Load(destArray);
  1988. Load(resizeCounter);
  1989. LoadArrayElement(sourceArray, resizeCounter);
  1990. Stelem(GetVariableType(destArray).GetElementType());
  1991. EndFor();
  1992. EndIf();
  1993. }
  1994. #endif
  1995. internal void GotoMethodEnd() {
  1996. //limit to only short forward (127 CIL instruction)
  1997. //Br_S(this.methodEndLabel);
  1998. Br(this.methodEndLabel);
  1999. }
  2000. internal class WhileState {
  2001. public Label StartLabel;
  2002. public Label CondLabel;
  2003. public Label EndLabel;
  2004. public WhileState(CodeGenerator ilg) {
  2005. StartLabel = ilg.DefineLabel();
  2006. CondLabel = ilg.DefineLabel();
  2007. EndLabel = ilg.DefineLabel();
  2008. }
  2009. }
  2010. // Usage:
  2011. // WhileBegin()
  2012. // WhileBreak()
  2013. // WhileContinue()
  2014. // WhileBeginCondition()
  2015. // (bool on stack)
  2016. // WhileEndCondition()
  2017. // WhileEnd()
  2018. Stack whileStack;
  2019. internal void WhileBegin() {
  2020. WhileState whileState = new WhileState(this);
  2021. Br(whileState.CondLabel);
  2022. MarkLabel(whileState.StartLabel);
  2023. whileStack.Push(whileState);
  2024. }
  2025. internal void WhileEnd() {
  2026. WhileState whileState = (WhileState)whileStack.Pop();
  2027. MarkLabel(whileState.EndLabel);
  2028. }
  2029. internal void WhileBreak() {
  2030. WhileState whileState = (WhileState)whileStack.Peek();
  2031. Br(whileState.EndLabel);
  2032. }
  2033. internal void WhileContinue() {
  2034. WhileState whileState = (WhileState)whileStack.Peek();
  2035. Br(whileState.CondLabel);
  2036. }
  2037. internal void WhileBeginCondition() {
  2038. WhileState whileState = (WhileState)whileStack.Peek();
  2039. // If there are two MarkLabel ILs consecutively, Labels will converge to one label.
  2040. // This could cause the code to look different. We insert Nop here specifically
  2041. // that the While label stands out.
  2042. Nop();
  2043. MarkLabel(whileState.CondLabel);
  2044. }
  2045. internal void WhileEndCondition() {
  2046. WhileState whileState = (WhileState)whileStack.Peek();
  2047. Brtrue(whileState.StartLabel);
  2048. }
  2049. #if NotUsed
  2050. internal void AndWhile(Cmp cmpOp)
  2051. {
  2052. object startWhile = blockStack.Pop();
  2053. AndIf(cmpOp);
  2054. blockStack.Push(startWhile);
  2055. }
  2056. internal void BeginWhileBody()
  2057. {
  2058. Label startWhile = (Label) blockStack.Pop();
  2059. If();
  2060. blockStack.Push(startWhile);
  2061. }
  2062. internal void BeginWhileBody(Cmp cmpOp)
  2063. {
  2064. Label startWhile = (Label) blockStack.Pop();
  2065. If(cmpOp);
  2066. blockStack.Push(startWhile);
  2067. }
  2068. internal Label BeginWhileCondition()
  2069. {
  2070. Label startWhile = DefineLabel();
  2071. MarkLabel(startWhile);
  2072. blockStack.Push(startWhile);
  2073. return startWhile;
  2074. }
  2075. internal void Cne()
  2076. {
  2077. Ceq();
  2078. Load(0);
  2079. Ceq();
  2080. }
  2081. internal void New(ConstructorInfo constructorInfo, object param1, object param2)
  2082. {
  2083. LoadParam(param1, 1, constructorInfo);
  2084. LoadParam(param2, 2, constructorInfo);
  2085. New(constructorInfo);
  2086. }
  2087. //This code is not tested
  2088. internal void Stind(Type type)
  2089. {
  2090. OpCode opCode = StindOpCodes[(int) Type.GetTypeCode(type)];
  2091. if (!opCode.Equals(OpCodes.Nop))
  2092. {
  2093. if (codeGenTrace != CodeGenTrace.None)
  2094. EmitSourceInstruction(opCode.ToString());
  2095. ilGen.Emit(opCode);
  2096. }
  2097. else
  2098. {
  2099. if (codeGenTrace != CodeGenTrace.None)
  2100. EmitSourceInstruction("Stobj " + type);
  2101. ilGen.Emit(OpCodes.Stobj, type);
  2102. }
  2103. }
  2104. //This code is not tested
  2105. internal void StoreOutParam(ArgBuilder arg, object value)
  2106. {
  2107. Type destType = arg.ArgType;
  2108. if (!destType.IsByRef)
  2109. throw new InvalidOperationException("OutParametersMustBeByRefTypeReceived"); //.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.OutParametersMustBeByRefTypeReceived, DataContract.GetClrTypeFullName(destType))));
  2110. destType = destType.GetElementType();
  2111. Type sourceType;
  2112. if (value is ArgBuilder)
  2113. sourceType = ((ArgBuilder) value).ArgType;
  2114. else if (value is LocalBuilder)
  2115. sourceType = ((LocalBuilder) value).LocalType;
  2116. else if (value != null)
  2117. sourceType = value.GetType();
  2118. else
  2119. sourceType = null;
  2120. Load(arg);
  2121. Load(value);
  2122. if (sourceType != null)
  2123. ConvertAddress(sourceType, destType);
  2124. Stind(destType);
  2125. }
  2126. void CheckSecurity(FieldInfo field)
  2127. {
  2128. if (fullTrustDemanded)
  2129. return;
  2130. if (IsProtectedWithSecurity(field))
  2131. DemandFullTrust();
  2132. }
  2133. void CheckSecurity(MethodBase method)
  2134. {
  2135. if (fullTrustDemanded)
  2136. return;
  2137. if (IsProtectedWithSecurity(method))
  2138. DemandFullTrust();
  2139. }
  2140. void CheckSecurity(Type type)
  2141. {
  2142. if (fullTrustDemanded)
  2143. return;
  2144. if (IsProtectedWithSecurity(type))
  2145. DemandFullTrust();
  2146. }
  2147. void CheckSecurity(Assembly assembly)
  2148. {
  2149. if (fullTrustDemanded)
  2150. return;
  2151. if (IsProtectedWithSecurity(assembly))
  2152. DemandFullTrust();
  2153. }
  2154. static bool IsProtectedWithSecurity(FieldInfo field)
  2155. {
  2156. return IsProtectedWithSecurity(field.DeclaringType);
  2157. }
  2158. static bool IsProtectedWithSecurity(Type type)
  2159. {
  2160. return IsProtectedWithSecurity(type.Assembly) || (type.Attributes & TypeAttributes.HasSecurity) != 0;
  2161. }
  2162. static bool IsProtectedWithSecurity(Assembly assembly)
  2163. {
  2164. object[] attrs = assembly.GetCustomAttributes(typeof(AllowPartiallyTrustedCallersAttribute), true);
  2165. bool hasAptca = attrs != null && attrs.Length > 0;
  2166. return !hasAptca;
  2167. }
  2168. void DemandFullTrust()
  2169. {
  2170. fullTrustDemanded = true;
  2171. /*
  2172. if (codeGenTrace != CodeGenTrace.None)
  2173. EmitSourceComment("DemandFullTrust() {");
  2174. Ldc(PermissionState.Unrestricted);
  2175. New(permissionSetCtor);
  2176. Call(permissionSetDemand);
  2177. if (codeGenTrace != CodeGenTrace.None)
  2178. EmitSourceComment("}");
  2179. */
  2180. }
  2181. static bool IsProtectedWithSecurity(MethodBase method)
  2182. {
  2183. return false;
  2184. //return (method.Attributes & MethodAttributes.HasSecurity) != 0;
  2185. }
  2186. #endif
  2187. }
  2188. internal class ArgBuilder {
  2189. internal string Name;
  2190. internal int Index;
  2191. internal Type ArgType;
  2192. internal ArgBuilder(string name, int index, Type argType) {
  2193. this.Name = name;
  2194. this.Index = index;
  2195. this.ArgType = argType;
  2196. }
  2197. }
  2198. internal class ForState {
  2199. LocalBuilder indexVar;
  2200. Label beginLabel;
  2201. Label testLabel;
  2202. object end;
  2203. internal ForState(LocalBuilder indexVar, Label beginLabel, Label testLabel, object end) {
  2204. this.indexVar = indexVar;
  2205. this.beginLabel = beginLabel;
  2206. this.testLabel = testLabel;
  2207. this.end = end;
  2208. }
  2209. internal LocalBuilder Index {
  2210. get {
  2211. return indexVar;
  2212. }
  2213. }
  2214. internal Label BeginLabel {
  2215. get {
  2216. return beginLabel;
  2217. }
  2218. }
  2219. internal Label TestLabel {
  2220. get {
  2221. return testLabel;
  2222. }
  2223. }
  2224. internal object End {
  2225. get {
  2226. return end;
  2227. }
  2228. }
  2229. }
  2230. internal enum Cmp : int {
  2231. LessThan = 0,
  2232. EqualTo,
  2233. LessThanOrEqualTo,
  2234. GreaterThan,
  2235. NotEqualTo,
  2236. GreaterThanOrEqualTo
  2237. }
  2238. internal class IfState {
  2239. Label elseBegin;
  2240. Label endIf;
  2241. internal Label EndIf {
  2242. get {
  2243. return this.endIf;
  2244. }
  2245. set {
  2246. this.endIf = value;
  2247. }
  2248. }
  2249. internal Label ElseBegin {
  2250. get {
  2251. return this.elseBegin;
  2252. }
  2253. set {
  2254. this.elseBegin = value;
  2255. }
  2256. }
  2257. }
  2258. internal class LocalScope {
  2259. public readonly LocalScope parent;
  2260. readonly Dictionary<string, LocalBuilder> locals;
  2261. // Root scope
  2262. public LocalScope() {
  2263. this.locals = new Dictionary<string, LocalBuilder>();
  2264. }
  2265. public LocalScope(LocalScope parent) : this() {
  2266. this.parent = parent;
  2267. }
  2268. public void Add(string key, LocalBuilder value) {
  2269. locals.Add(key, value);
  2270. }
  2271. public bool ContainsKey(string key) {
  2272. return locals.ContainsKey(key) || (parent != null && parent.ContainsKey(key));
  2273. }
  2274. public bool TryGetValue(string key, out LocalBuilder value) {
  2275. if (locals.TryGetValue(key, out value)) {
  2276. return true;
  2277. }
  2278. else if (parent != null) {
  2279. return parent.TryGetValue(key, out value);
  2280. }
  2281. else {
  2282. value = null;
  2283. return false;
  2284. }
  2285. }
  2286. public LocalBuilder this[string key] {
  2287. get {
  2288. LocalBuilder value;
  2289. TryGetValue(key, out value);
  2290. return value;
  2291. }
  2292. set {
  2293. locals[key] = value;
  2294. }
  2295. }
  2296. public void AddToFreeLocals(Dictionary<Tuple<Type, string>, Queue<LocalBuilder>> freeLocals) {
  2297. foreach (var item in locals) {
  2298. Tuple<Type, string> key = new Tuple<Type, string>(item.Value.LocalType, item.Key);
  2299. Queue<LocalBuilder> freeLocalQueue;
  2300. if (freeLocals.TryGetValue(key, out freeLocalQueue)) {
  2301. // Add to end of the queue so that it will be re-used in
  2302. // FIFO manner
  2303. freeLocalQueue.Enqueue(item.Value);
  2304. }
  2305. else {
  2306. freeLocalQueue = new Queue<LocalBuilder>();
  2307. freeLocalQueue.Enqueue(item.Value);
  2308. freeLocals.Add(key, freeLocalQueue);
  2309. }
  2310. }
  2311. }
  2312. }
  2313. #if NotUsed
  2314. internal class BitFlagsGenerator
  2315. {
  2316. LocalBuilder[] locals;
  2317. CodeGenerator ilg;
  2318. int bitCount;
  2319. internal BitFlagsGenerator(int bitCount, CodeGenerator ilg, string localName)
  2320. {
  2321. this.ilg = ilg;
  2322. this.bitCount = bitCount;
  2323. int localCount = (bitCount+7)/8;
  2324. locals = new LocalBuilder[localCount];
  2325. for (int i=0;i<locals.Length;i++)
  2326. locals[i] = ilg.DeclareLocal(Globals.TypeOfByte, localName+i, (byte)0);
  2327. }
  2328. internal void Store(int bitIndex, bool value)
  2329. {
  2330. LocalBuilder local = locals[GetByteIndex(bitIndex)];
  2331. byte bitValue = GetBitValue(bitIndex);
  2332. if (value)
  2333. {
  2334. ilg.Load(local);
  2335. ilg.Load(bitValue);
  2336. ilg.Or();
  2337. ilg.Stloc(local);
  2338. }
  2339. else
  2340. {
  2341. ilg.Load(local);
  2342. ilg.Load(bitValue);
  2343. ilg.Not();
  2344. ilg.And();
  2345. ilg.Stloc(local);
  2346. }
  2347. }
  2348. internal void Load(int bitIndex)
  2349. {
  2350. LocalBuilder local = locals[GetByteIndex(bitIndex)];
  2351. byte bitValue = GetBitValue(bitIndex);
  2352. ilg.Load(local);
  2353. ilg.Load(bitValue);
  2354. ilg.And();
  2355. ilg.Load(bitValue);
  2356. ilg.Ceq();
  2357. }
  2358. internal void LoadArray()
  2359. {
  2360. LocalBuilder localArray = ilg.DeclareLocal(Globals.TypeOfByteArray, "localArray");
  2361. ilg.NewArray(Globals.TypeOfByte, locals.Length);
  2362. ilg.Store(localArray);
  2363. for (int i=0;i<locals.Length;i++)
  2364. ilg.StoreArrayElement(localArray, i, locals[i]);
  2365. ilg.Load(localArray);
  2366. }
  2367. internal int GetLocalCount()
  2368. {
  2369. return locals.Length;
  2370. }
  2371. internal int GetBitCount()
  2372. {
  2373. return bitCount;
  2374. }
  2375. internal LocalBuilder GetLocal(int i)
  2376. {
  2377. return locals[i];
  2378. }
  2379. internal static bool IsBitSet(byte[] bytes, int bitIndex)
  2380. {
  2381. int byteIndex = GetByteIndex(bitIndex);
  2382. byte bitValue = GetBitValue(bitIndex);
  2383. return (bytes[byteIndex] & bitValue) == bitValue;
  2384. }
  2385. internal static void SetBit(byte[] bytes, int bitIndex)
  2386. {
  2387. int byteIndex = GetByteIndex(bitIndex);
  2388. byte bitValue = GetBitValue(bitIndex);
  2389. bytes[byteIndex] |= bitValue;
  2390. }
  2391. static int GetByteIndex(int bitIndex)
  2392. {
  2393. return bitIndex >> 3;
  2394. }
  2395. static byte GetBitValue(int bitIndex)
  2396. {
  2397. return (byte)(1 << (bitIndex & 7));
  2398. }
  2399. }
  2400. internal class SwitchState
  2401. {
  2402. Label defaultLabel;
  2403. Label endOfSwitchLabel;
  2404. bool defaultDefined;
  2405. internal SwitchState(Label defaultLabel, Label endOfSwitchLabel)
  2406. {
  2407. this.defaultLabel = defaultLabel;
  2408. this.endOfSwitchLabel = endOfSwitchLabel;
  2409. this.defaultDefined = false;
  2410. }
  2411. internal Label DefaultLabel
  2412. {
  2413. get
  2414. {
  2415. return defaultLabel;
  2416. }
  2417. }
  2418. internal Label EndOfSwitchLabel
  2419. {
  2420. get
  2421. {
  2422. return endOfSwitchLabel;
  2423. }
  2424. }
  2425. internal bool DefaultDefined
  2426. {
  2427. get
  2428. {
  2429. return defaultDefined;
  2430. }
  2431. set
  2432. {
  2433. defaultDefined = value;
  2434. }
  2435. }
  2436. }
  2437. #endif
  2438. internal class MethodBuilderInfo {
  2439. public readonly MethodBuilder MethodBuilder;
  2440. public readonly Type[] ParameterTypes;
  2441. public MethodBuilderInfo(MethodBuilder methodBuilder, Type[] parameterTypes) {
  2442. this.MethodBuilder = methodBuilder;
  2443. this.ParameterTypes = parameterTypes;
  2444. }
  2445. public void Validate(Type returnType, Type[] parameterTypes, MethodAttributes attributes) {
  2446. #if DEBUG
  2447. Debug.Assert(this.MethodBuilder.ReturnType == returnType);
  2448. Debug.Assert(this.MethodBuilder.Attributes == attributes);
  2449. Debug.Assert(this.ParameterTypes.Length == parameterTypes.Length);
  2450. for (int i = 0; i < parameterTypes.Length; ++i) {
  2451. Debug.Assert(this.ParameterTypes[i] == parameterTypes[i]);
  2452. }
  2453. #endif
  2454. }
  2455. }
  2456. internal class CodeGeneratorConversionException : Exception {
  2457. private Type sourceType;
  2458. private Type targetType;
  2459. private bool isAddress;
  2460. private string reason;
  2461. public CodeGeneratorConversionException(Type sourceType, Type targetType, bool isAddress, string reason)
  2462. : base() {
  2463. this.sourceType = sourceType;
  2464. this.targetType = targetType;
  2465. this.isAddress = isAddress;
  2466. this.reason = reason;
  2467. }
  2468. }
  2469. }