CodeGenerator.cs 87 KB

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