AssemblyWriter.cs 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317
  1. //
  2. // Author:
  3. // Jb Evain (jbevain@gmail.com)
  4. //
  5. // Copyright (c) 2008 - 2015 Jb Evain
  6. // Copyright (c) 2008 - 2011 Novell, Inc.
  7. //
  8. // Licensed under the MIT/X11 license.
  9. //
  10. using System;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. using System.IO.Compression;
  14. using System.Text;
  15. using Mono;
  16. using Mono.Collections.Generic;
  17. using Mono.Cecil.Cil;
  18. using Mono.Cecil.Metadata;
  19. using Mono.Cecil.PE;
  20. using RVA = System.UInt32;
  21. using RID = System.UInt32;
  22. using CodedRID = System.UInt32;
  23. using StringIndex = System.UInt32;
  24. using BlobIndex = System.UInt32;
  25. using GuidIndex = System.UInt32;
  26. namespace Mono.Cecil {
  27. #if !READ_ONLY
  28. using ModuleRow = Row<StringIndex, GuidIndex>;
  29. using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
  30. using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
  31. using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
  32. using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
  33. using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
  34. using InterfaceImplRow = Row<uint, CodedRID>;
  35. using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
  36. using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
  37. using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
  38. using FieldMarshalRow = Row<CodedRID, BlobIndex>;
  39. using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
  40. using ClassLayoutRow = Row<ushort, uint, RID>;
  41. using FieldLayoutRow = Row<uint, RID>;
  42. using EventMapRow = Row<RID, RID>;
  43. using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
  44. using PropertyMapRow = Row<RID, RID>;
  45. using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
  46. using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
  47. using MethodImplRow = Row<RID, CodedRID, CodedRID>;
  48. using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
  49. using FieldRVARow = Row<RVA, RID>;
  50. using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
  51. using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
  52. using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
  53. using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
  54. using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
  55. using NestedClassRow = Row<RID, RID>;
  56. using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
  57. using MethodSpecRow = Row<CodedRID, BlobIndex>;
  58. using GenericParamConstraintRow = Row<RID, CodedRID>;
  59. using DocumentRow = Row<BlobIndex, GuidIndex, BlobIndex, GuidIndex>;
  60. using MethodDebugInformationRow = Row<RID, BlobIndex>;
  61. using LocalScopeRow = Row<RID, RID, RID, RID, uint, uint>;
  62. using LocalVariableRow = Row<VariableAttributes, ushort, StringIndex>;
  63. using LocalConstantRow = Row<StringIndex, BlobIndex>;
  64. using ImportScopeRow = Row<RID, BlobIndex>;
  65. using StateMachineMethodRow = Row<RID, RID>;
  66. using CustomDebugInformationRow = Row<CodedRID, GuidIndex, BlobIndex>;
  67. static class ModuleWriter {
  68. public static void WriteModule (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
  69. {
  70. using (stream)
  71. Write (module, stream, parameters);
  72. }
  73. static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
  74. {
  75. if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
  76. throw new NotSupportedException ("Writing mixed-mode assemblies is not supported");
  77. if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) {
  78. var immediate_reader = new ImmediateModuleReader (module.Image);
  79. immediate_reader.ReadModule (module, resolve_attributes: false);
  80. immediate_reader.ReadSymbols (module);
  81. }
  82. module.MetadataSystem.Clear ();
  83. if (module.symbol_reader != null)
  84. module.symbol_reader.Dispose ();
  85. var name = module.assembly != null ? module.assembly.Name : null;
  86. var fq_name = stream.value.GetFileName ();
  87. var timestamp = parameters.Timestamp ?? module.timestamp;
  88. var symbol_writer_provider = parameters.SymbolWriterProvider;
  89. if (symbol_writer_provider == null && parameters.WriteSymbols)
  90. symbol_writer_provider = new DefaultSymbolWriterProvider ();
  91. #if !NET_CORE
  92. if (parameters.StrongNameKeyPair != null && name != null) {
  93. name.PublicKey = parameters.StrongNameKeyPair.PublicKey;
  94. module.Attributes |= ModuleAttributes.StrongNameSigned;
  95. }
  96. #endif
  97. using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) {
  98. var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider, symbol_writer);
  99. BuildMetadata (module, metadata);
  100. var writer = ImageWriter.CreateWriter (module, metadata, stream);
  101. stream.value.SetLength (0);
  102. writer.WriteImage ();
  103. #if !NET_CORE
  104. if (parameters.StrongNameKeyPair != null)
  105. CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair);
  106. #endif
  107. }
  108. }
  109. static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
  110. {
  111. if (!module.HasImage) {
  112. metadata.BuildMetadata ();
  113. return;
  114. }
  115. module.Read (metadata, (builder, _) => {
  116. builder.BuildMetadata ();
  117. return builder;
  118. });
  119. }
  120. static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters)
  121. {
  122. if (symbol_writer_provider == null)
  123. return null;
  124. if (parameters.SymbolStream != null)
  125. return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream);
  126. return symbol_writer_provider.GetSymbolWriter (module, fq_name);
  127. }
  128. }
  129. abstract class MetadataTable {
  130. public abstract int Length { get; }
  131. public bool IsLarge {
  132. get { return Length > ushort.MaxValue; }
  133. }
  134. public abstract void Write (TableHeapBuffer buffer);
  135. public abstract void Sort ();
  136. }
  137. abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
  138. internal TRow row;
  139. public sealed override int Length {
  140. get { return 1; }
  141. }
  142. public sealed override void Sort ()
  143. {
  144. }
  145. }
  146. abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
  147. internal TRow [] rows = new TRow [2];
  148. internal int length;
  149. public sealed override int Length {
  150. get { return length; }
  151. }
  152. public int AddRow (TRow row)
  153. {
  154. if (rows.Length == length)
  155. Grow ();
  156. rows [length++] = row;
  157. return length;
  158. }
  159. void Grow ()
  160. {
  161. var rows = new TRow [this.rows.Length * 2];
  162. Array.Copy (this.rows, rows, this.rows.Length);
  163. this.rows = rows;
  164. }
  165. public override void Sort ()
  166. {
  167. }
  168. }
  169. abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
  170. public sealed override void Sort ()
  171. {
  172. Array.Sort (rows, 0, length, this);
  173. }
  174. protected int Compare (uint x, uint y)
  175. {
  176. return x == y ? 0 : x > y ? 1 : -1;
  177. }
  178. public abstract int Compare (TRow x, TRow y);
  179. }
  180. sealed class ModuleTable : OneRowTable<ModuleRow> {
  181. public override void Write (TableHeapBuffer buffer)
  182. {
  183. buffer.WriteUInt16 (0); // Generation
  184. buffer.WriteString (row.Col1); // Name
  185. buffer.WriteGuid (row.Col2); // Mvid
  186. buffer.WriteUInt16 (0); // EncId
  187. buffer.WriteUInt16 (0); // EncBaseId
  188. }
  189. }
  190. sealed class TypeRefTable : MetadataTable<TypeRefRow> {
  191. public override void Write (TableHeapBuffer buffer)
  192. {
  193. for (int i = 0; i < length; i++) {
  194. buffer.WriteCodedRID (
  195. rows [i].Col1, CodedIndex.ResolutionScope); // Scope
  196. buffer.WriteString (rows [i].Col2); // Name
  197. buffer.WriteString (rows [i].Col3); // Namespace
  198. }
  199. }
  200. }
  201. sealed class TypeDefTable : MetadataTable<TypeDefRow> {
  202. public override void Write (TableHeapBuffer buffer)
  203. {
  204. for (int i = 0; i < length; i++) {
  205. buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
  206. buffer.WriteString (rows [i].Col2); // Name
  207. buffer.WriteString (rows [i].Col3); // Namespace
  208. buffer.WriteCodedRID (
  209. rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
  210. buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
  211. buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
  212. }
  213. }
  214. }
  215. sealed class FieldTable : MetadataTable<FieldRow> {
  216. public override void Write (TableHeapBuffer buffer)
  217. {
  218. for (int i = 0; i < length; i++) {
  219. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
  220. buffer.WriteString (rows [i].Col2); // Name
  221. buffer.WriteBlob (rows [i].Col3); // Signature
  222. }
  223. }
  224. }
  225. sealed class MethodTable : MetadataTable<MethodRow> {
  226. public override void Write (TableHeapBuffer buffer)
  227. {
  228. for (int i = 0; i < length; i++) {
  229. buffer.WriteUInt32 (rows [i].Col1); // RVA
  230. buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
  231. buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
  232. buffer.WriteString (rows [i].Col4); // Name
  233. buffer.WriteBlob (rows [i].Col5); // Signature
  234. buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
  235. }
  236. }
  237. }
  238. sealed class ParamTable : MetadataTable<ParamRow> {
  239. public override void Write (TableHeapBuffer buffer)
  240. {
  241. for (int i = 0; i < length; i++) {
  242. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
  243. buffer.WriteUInt16 (rows [i].Col2); // Sequence
  244. buffer.WriteString (rows [i].Col3); // Name
  245. }
  246. }
  247. }
  248. sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
  249. public override void Write (TableHeapBuffer buffer)
  250. {
  251. for (int i = 0; i < length; i++) {
  252. buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
  253. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
  254. }
  255. }
  256. /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
  257. {
  258. return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
  259. }*/
  260. }
  261. sealed class MemberRefTable : MetadataTable<MemberRefRow> {
  262. public override void Write (TableHeapBuffer buffer)
  263. {
  264. for (int i = 0; i < length; i++) {
  265. buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
  266. buffer.WriteString (rows [i].Col2);
  267. buffer.WriteBlob (rows [i].Col3);
  268. }
  269. }
  270. }
  271. sealed class ConstantTable : SortedTable<ConstantRow> {
  272. public override void Write (TableHeapBuffer buffer)
  273. {
  274. for (int i = 0; i < length; i++) {
  275. buffer.WriteUInt16 ((ushort) rows [i].Col1);
  276. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
  277. buffer.WriteBlob (rows [i].Col3);
  278. }
  279. }
  280. public override int Compare (ConstantRow x, ConstantRow y)
  281. {
  282. return Compare (x.Col2, y.Col2);
  283. }
  284. }
  285. sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
  286. public override void Write (TableHeapBuffer buffer)
  287. {
  288. for (int i = 0; i < length; i++) {
  289. buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
  290. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
  291. buffer.WriteBlob (rows [i].Col3);
  292. }
  293. }
  294. public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
  295. {
  296. return Compare (x.Col1, y.Col1);
  297. }
  298. }
  299. sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
  300. public override void Write (TableHeapBuffer buffer)
  301. {
  302. for (int i = 0; i < length; i++) {
  303. buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
  304. buffer.WriteBlob (rows [i].Col2);
  305. }
  306. }
  307. public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
  308. {
  309. return Compare (x.Col1, y.Col1);
  310. }
  311. }
  312. sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
  313. public override void Write (TableHeapBuffer buffer)
  314. {
  315. for (int i = 0; i < length; i++) {
  316. buffer.WriteUInt16 ((ushort) rows [i].Col1);
  317. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
  318. buffer.WriteBlob (rows [i].Col3);
  319. }
  320. }
  321. public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
  322. {
  323. return Compare (x.Col2, y.Col2);
  324. }
  325. }
  326. sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
  327. public override void Write (TableHeapBuffer buffer)
  328. {
  329. for (int i = 0; i < length; i++) {
  330. buffer.WriteUInt16 (rows [i].Col1); // PackingSize
  331. buffer.WriteUInt32 (rows [i].Col2); // ClassSize
  332. buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
  333. }
  334. }
  335. public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
  336. {
  337. return Compare (x.Col3, y.Col3);
  338. }
  339. }
  340. sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
  341. public override void Write (TableHeapBuffer buffer)
  342. {
  343. for (int i = 0; i < length; i++) {
  344. buffer.WriteUInt32 (rows [i].Col1); // Offset
  345. buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
  346. }
  347. }
  348. public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
  349. {
  350. return Compare (x.Col2, y.Col2);
  351. }
  352. }
  353. sealed class StandAloneSigTable : MetadataTable<uint> {
  354. public override void Write (TableHeapBuffer buffer)
  355. {
  356. for (int i = 0; i < length; i++)
  357. buffer.WriteBlob (rows [i]);
  358. }
  359. }
  360. sealed class EventMapTable : MetadataTable<EventMapRow> {
  361. public override void Write (TableHeapBuffer buffer)
  362. {
  363. for (int i = 0; i < length; i++) {
  364. buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
  365. buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
  366. }
  367. }
  368. }
  369. sealed class EventTable : MetadataTable<EventRow> {
  370. public override void Write (TableHeapBuffer buffer)
  371. {
  372. for (int i = 0; i < length; i++) {
  373. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
  374. buffer.WriteString (rows [i].Col2); // Name
  375. buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
  376. }
  377. }
  378. }
  379. sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
  380. public override void Write (TableHeapBuffer buffer)
  381. {
  382. for (int i = 0; i < length; i++) {
  383. buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
  384. buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
  385. }
  386. }
  387. }
  388. sealed class PropertyTable : MetadataTable<PropertyRow> {
  389. public override void Write (TableHeapBuffer buffer)
  390. {
  391. for (int i = 0; i < length; i++) {
  392. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
  393. buffer.WriteString (rows [i].Col2); // Name
  394. buffer.WriteBlob (rows [i].Col3); // Type
  395. }
  396. }
  397. }
  398. sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
  399. public override void Write (TableHeapBuffer buffer)
  400. {
  401. for (int i = 0; i < length; i++) {
  402. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
  403. buffer.WriteRID (rows [i].Col2, Table.Method); // Method
  404. buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
  405. }
  406. }
  407. public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
  408. {
  409. return Compare (x.Col3, y.Col3);
  410. }
  411. }
  412. sealed class MethodImplTable : MetadataTable<MethodImplRow> {
  413. public override void Write (TableHeapBuffer buffer)
  414. {
  415. for (int i = 0; i < length; i++) {
  416. buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
  417. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
  418. buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
  419. }
  420. }
  421. }
  422. sealed class ModuleRefTable : MetadataTable<uint> {
  423. public override void Write (TableHeapBuffer buffer)
  424. {
  425. for (int i = 0; i < length; i++)
  426. buffer.WriteString (rows [i]); // Name
  427. }
  428. }
  429. sealed class TypeSpecTable : MetadataTable<uint> {
  430. public override void Write (TableHeapBuffer buffer)
  431. {
  432. for (int i = 0; i < length; i++)
  433. buffer.WriteBlob (rows [i]); // Signature
  434. }
  435. }
  436. sealed class ImplMapTable : SortedTable<ImplMapRow> {
  437. public override void Write (TableHeapBuffer buffer)
  438. {
  439. for (int i = 0; i < length; i++) {
  440. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
  441. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
  442. buffer.WriteString (rows [i].Col3); // ImportName
  443. buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
  444. }
  445. }
  446. public override int Compare (ImplMapRow x, ImplMapRow y)
  447. {
  448. return Compare (x.Col2, y.Col2);
  449. }
  450. }
  451. sealed class FieldRVATable : SortedTable<FieldRVARow> {
  452. internal int position;
  453. public override void Write (TableHeapBuffer buffer)
  454. {
  455. position = buffer.position;
  456. for (int i = 0; i < length; i++) {
  457. buffer.WriteUInt32 (rows [i].Col1); // RVA
  458. buffer.WriteRID (rows [i].Col2, Table.Field); // Field
  459. }
  460. }
  461. public override int Compare (FieldRVARow x, FieldRVARow y)
  462. {
  463. return Compare (x.Col2, y.Col2);
  464. }
  465. }
  466. sealed class AssemblyTable : OneRowTable<AssemblyRow> {
  467. public override void Write (TableHeapBuffer buffer)
  468. {
  469. buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
  470. buffer.WriteUInt16 (row.Col2); // MajorVersion
  471. buffer.WriteUInt16 (row.Col3); // MinorVersion
  472. buffer.WriteUInt16 (row.Col4); // Build
  473. buffer.WriteUInt16 (row.Col5); // Revision
  474. buffer.WriteUInt32 ((uint) row.Col6); // Flags
  475. buffer.WriteBlob (row.Col7); // PublicKey
  476. buffer.WriteString (row.Col8); // Name
  477. buffer.WriteString (row.Col9); // Culture
  478. }
  479. }
  480. sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
  481. public override void Write (TableHeapBuffer buffer)
  482. {
  483. for (int i = 0; i < length; i++) {
  484. buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
  485. buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
  486. buffer.WriteUInt16 (rows [i].Col3); // Build
  487. buffer.WriteUInt16 (rows [i].Col4); // Revision
  488. buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
  489. buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
  490. buffer.WriteString (rows [i].Col7); // Name
  491. buffer.WriteString (rows [i].Col8); // Culture
  492. buffer.WriteBlob (rows [i].Col9); // Hash
  493. }
  494. }
  495. }
  496. sealed class FileTable : MetadataTable<FileRow> {
  497. public override void Write (TableHeapBuffer buffer)
  498. {
  499. for (int i = 0; i < length; i++) {
  500. buffer.WriteUInt32 ((uint) rows [i].Col1);
  501. buffer.WriteString (rows [i].Col2);
  502. buffer.WriteBlob (rows [i].Col3);
  503. }
  504. }
  505. }
  506. sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
  507. public override void Write (TableHeapBuffer buffer)
  508. {
  509. for (int i = 0; i < length; i++) {
  510. buffer.WriteUInt32 ((uint) rows [i].Col1);
  511. buffer.WriteUInt32 (rows [i].Col2);
  512. buffer.WriteString (rows [i].Col3);
  513. buffer.WriteString (rows [i].Col4);
  514. buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
  515. }
  516. }
  517. }
  518. sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
  519. public override void Write (TableHeapBuffer buffer)
  520. {
  521. for (int i = 0; i < length; i++) {
  522. buffer.WriteUInt32 (rows [i].Col1);
  523. buffer.WriteUInt32 ((uint) rows [i].Col2);
  524. buffer.WriteString (rows [i].Col3);
  525. buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
  526. }
  527. }
  528. }
  529. sealed class NestedClassTable : SortedTable<NestedClassRow> {
  530. public override void Write (TableHeapBuffer buffer)
  531. {
  532. for (int i = 0; i < length; i++) {
  533. buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
  534. buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
  535. }
  536. }
  537. public override int Compare (NestedClassRow x, NestedClassRow y)
  538. {
  539. return Compare (x.Col1, y.Col1);
  540. }
  541. }
  542. sealed class GenericParamTable : MetadataTable<GenericParamRow> {
  543. public override void Write (TableHeapBuffer buffer)
  544. {
  545. for (int i = 0; i < length; i++) {
  546. buffer.WriteUInt16 (rows [i].Col1); // Number
  547. buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
  548. buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
  549. buffer.WriteString (rows [i].Col4); // Name
  550. }
  551. }
  552. }
  553. sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
  554. public override void Write (TableHeapBuffer buffer)
  555. {
  556. for (int i = 0; i < length; i++) {
  557. buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
  558. buffer.WriteBlob (rows [i].Col2); // Instantiation
  559. }
  560. }
  561. }
  562. sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
  563. public override void Write (TableHeapBuffer buffer)
  564. {
  565. for (int i = 0; i < length; i++) {
  566. buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
  567. buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
  568. }
  569. }
  570. }
  571. sealed class DocumentTable : MetadataTable<DocumentRow> {
  572. public override void Write (TableHeapBuffer buffer)
  573. {
  574. for (int i = 0; i < length; i++) {
  575. buffer.WriteBlob (rows [i].Col1); // Name
  576. buffer.WriteGuid (rows [i].Col2); // HashAlgorithm
  577. buffer.WriteBlob (rows [i].Col3); // Hash
  578. buffer.WriteGuid (rows [i].Col4); // Language
  579. }
  580. }
  581. }
  582. sealed class MethodDebugInformationTable : MetadataTable<MethodDebugInformationRow> {
  583. public override void Write (TableHeapBuffer buffer)
  584. {
  585. for (int i = 0; i < length; i++) {
  586. buffer.WriteRID (rows [i].Col1, Table.Document); // Document
  587. buffer.WriteBlob (rows [i].Col2); // SequencePoints
  588. }
  589. }
  590. }
  591. sealed class LocalScopeTable : MetadataTable<LocalScopeRow> {
  592. public override void Write (TableHeapBuffer buffer)
  593. {
  594. for (int i = 0; i < length; i++) {
  595. buffer.WriteRID (rows [i].Col1, Table.Method); // Method
  596. buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope
  597. buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList
  598. buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList
  599. buffer.WriteUInt32 (rows [i].Col5); // StartOffset
  600. buffer.WriteUInt32 (rows [i].Col6); // Length
  601. }
  602. }
  603. }
  604. sealed class LocalVariableTable : MetadataTable<LocalVariableRow> {
  605. public override void Write (TableHeapBuffer buffer)
  606. {
  607. for (int i = 0; i < length; i++) {
  608. buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
  609. buffer.WriteUInt16 (rows [i].Col2); // Index
  610. buffer.WriteString (rows [i].Col3); // Name
  611. }
  612. }
  613. }
  614. sealed class LocalConstantTable : MetadataTable<LocalConstantRow> {
  615. public override void Write (TableHeapBuffer buffer)
  616. {
  617. for (int i = 0; i < length; i++) {
  618. buffer.WriteString (rows [i].Col1); // Name
  619. buffer.WriteBlob (rows [i].Col2); // Signature
  620. }
  621. }
  622. }
  623. sealed class ImportScopeTable : MetadataTable<ImportScopeRow> {
  624. public override void Write (TableHeapBuffer buffer)
  625. {
  626. for (int i = 0; i < length; i++) {
  627. buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent
  628. buffer.WriteBlob (rows [i].Col2); // Imports
  629. }
  630. }
  631. }
  632. sealed class StateMachineMethodTable : MetadataTable<StateMachineMethodRow> {
  633. public override void Write (TableHeapBuffer buffer)
  634. {
  635. for (int i = 0; i < length; i++) {
  636. buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod
  637. buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod
  638. }
  639. }
  640. }
  641. sealed class CustomDebugInformationTable : SortedTable<CustomDebugInformationRow> {
  642. public override void Write (TableHeapBuffer buffer)
  643. {
  644. for (int i = 0; i < length; i++) {
  645. buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent
  646. buffer.WriteGuid (rows [i].Col2); // Kind
  647. buffer.WriteBlob (rows [i].Col3); // Value
  648. }
  649. }
  650. public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y)
  651. {
  652. return Compare(x.Col1, y.Col1);
  653. }
  654. }
  655. sealed class MetadataBuilder {
  656. readonly internal ModuleDefinition module;
  657. readonly internal ISymbolWriterProvider symbol_writer_provider;
  658. readonly internal ISymbolWriter symbol_writer;
  659. readonly internal TextMap text_map;
  660. readonly internal string fq_name;
  661. readonly internal uint timestamp;
  662. readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
  663. readonly Dictionary<uint, MetadataToken> type_spec_map;
  664. readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
  665. readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
  666. readonly Collection<GenericParameter> generic_parameters;
  667. readonly internal CodeWriter code;
  668. readonly internal DataBuffer data;
  669. readonly internal ResourceBuffer resources;
  670. readonly internal StringHeapBuffer string_heap;
  671. readonly internal GuidHeapBuffer guid_heap;
  672. readonly internal UserStringHeapBuffer user_string_heap;
  673. readonly internal BlobHeapBuffer blob_heap;
  674. readonly internal TableHeapBuffer table_heap;
  675. readonly internal PdbHeapBuffer pdb_heap;
  676. internal MetadataToken entry_point;
  677. internal RID type_rid = 1;
  678. internal RID field_rid = 1;
  679. internal RID method_rid = 1;
  680. internal RID param_rid = 1;
  681. internal RID property_rid = 1;
  682. internal RID event_rid = 1;
  683. internal RID local_variable_rid = 1;
  684. internal RID local_constant_rid = 1;
  685. readonly TypeRefTable type_ref_table;
  686. readonly TypeDefTable type_def_table;
  687. readonly FieldTable field_table;
  688. readonly MethodTable method_table;
  689. readonly ParamTable param_table;
  690. readonly InterfaceImplTable iface_impl_table;
  691. readonly MemberRefTable member_ref_table;
  692. readonly ConstantTable constant_table;
  693. readonly CustomAttributeTable custom_attribute_table;
  694. readonly DeclSecurityTable declsec_table;
  695. readonly StandAloneSigTable standalone_sig_table;
  696. readonly EventMapTable event_map_table;
  697. readonly EventTable event_table;
  698. readonly PropertyMapTable property_map_table;
  699. readonly PropertyTable property_table;
  700. readonly TypeSpecTable typespec_table;
  701. readonly MethodSpecTable method_spec_table;
  702. readonly bool portable_pdb;
  703. internal MetadataBuilder metadata_builder;
  704. readonly DocumentTable document_table;
  705. readonly MethodDebugInformationTable method_debug_information_table;
  706. readonly LocalScopeTable local_scope_table;
  707. readonly LocalVariableTable local_variable_table;
  708. readonly LocalConstantTable local_constant_table;
  709. readonly ImportScopeTable import_scope_table;
  710. readonly StateMachineMethodTable state_machine_method_table;
  711. readonly CustomDebugInformationTable custom_debug_information_table;
  712. readonly Dictionary<ImportScopeRow, MetadataToken> import_scope_map;
  713. readonly Dictionary<string, MetadataToken> document_map;
  714. public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer)
  715. {
  716. this.module = module;
  717. this.text_map = CreateTextMap ();
  718. this.fq_name = fq_name;
  719. this.timestamp = timestamp;
  720. this.symbol_writer_provider = symbol_writer_provider;
  721. if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) {
  722. symbol_writer = new PortablePdbWriter (this, module);
  723. }
  724. this.symbol_writer = symbol_writer;
  725. var pdb_writer = symbol_writer as IMetadataSymbolWriter;
  726. if (pdb_writer != null) {
  727. portable_pdb = true;
  728. pdb_writer.SetMetadata (this);
  729. }
  730. this.code = new CodeWriter (this);
  731. this.data = new DataBuffer ();
  732. this.resources = new ResourceBuffer ();
  733. this.string_heap = new StringHeapBuffer ();
  734. this.guid_heap = new GuidHeapBuffer ();
  735. this.user_string_heap = new UserStringHeapBuffer ();
  736. this.blob_heap = new BlobHeapBuffer ();
  737. this.table_heap = new TableHeapBuffer (module, this);
  738. this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
  739. this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
  740. this.field_table = GetTable<FieldTable> (Table.Field);
  741. this.method_table = GetTable<MethodTable> (Table.Method);
  742. this.param_table = GetTable<ParamTable> (Table.Param);
  743. this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
  744. this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
  745. this.constant_table = GetTable<ConstantTable> (Table.Constant);
  746. this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
  747. this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
  748. this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
  749. this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
  750. this.event_table = GetTable<EventTable> (Table.Event);
  751. this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
  752. this.property_table = GetTable<PropertyTable> (Table.Property);
  753. this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
  754. this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
  755. var row_equality_comparer = new RowEqualityComparer ();
  756. type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
  757. type_spec_map = new Dictionary<uint, MetadataToken> ();
  758. member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
  759. method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
  760. generic_parameters = new Collection<GenericParameter> ();
  761. if (!portable_pdb)
  762. return;
  763. this.document_table = GetTable<DocumentTable> (Table.Document);
  764. this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
  765. this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
  766. this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
  767. this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
  768. this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
  769. this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
  770. this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
  771. this.document_map = new Dictionary<string, MetadataToken> (StringComparer.Ordinal);
  772. this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
  773. }
  774. public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider)
  775. {
  776. this.module = module;
  777. this.text_map = new TextMap ();
  778. this.symbol_writer_provider = writer_provider;
  779. this.portable_pdb = true;
  780. this.string_heap = new StringHeapBuffer ();
  781. this.guid_heap = new GuidHeapBuffer ();
  782. this.user_string_heap = new UserStringHeapBuffer ();
  783. this.blob_heap = new BlobHeapBuffer ();
  784. this.table_heap = new TableHeapBuffer (module, this);
  785. this.pdb_heap = new PdbHeapBuffer();
  786. this.document_table = GetTable<DocumentTable> (Table.Document);
  787. this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
  788. this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
  789. this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
  790. this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
  791. this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
  792. this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
  793. this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
  794. var row_equality_comparer = new RowEqualityComparer ();
  795. this.document_map = new Dictionary<string, MetadataToken> ();
  796. this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
  797. }
  798. TextMap CreateTextMap ()
  799. {
  800. var map = new TextMap ();
  801. map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0);
  802. map.AddMap (TextSegment.CLIHeader, 0x48, 8);
  803. return map;
  804. }
  805. TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
  806. {
  807. return table_heap.GetTable<TTable> (table);
  808. }
  809. uint GetStringIndex (string @string)
  810. {
  811. if (string.IsNullOrEmpty (@string))
  812. return 0;
  813. return string_heap.GetStringIndex (@string);
  814. }
  815. uint GetGuidIndex (Guid guid)
  816. {
  817. return guid_heap.GetGuidIndex (guid);
  818. }
  819. uint GetBlobIndex (ByteBuffer blob)
  820. {
  821. if (blob.length == 0)
  822. return 0;
  823. return blob_heap.GetBlobIndex (blob);
  824. }
  825. uint GetBlobIndex (byte [] blob)
  826. {
  827. if (blob.IsNullOrEmpty ())
  828. return 0;
  829. return GetBlobIndex (new ByteBuffer (blob));
  830. }
  831. public void BuildMetadata ()
  832. {
  833. BuildModule ();
  834. table_heap.string_offsets = string_heap.WriteStrings ();
  835. table_heap.ComputeTableInformations ();
  836. table_heap.WriteTableHeap ();
  837. }
  838. void BuildModule ()
  839. {
  840. var table = GetTable<ModuleTable> (Table.Module);
  841. table.row.Col1 = GetStringIndex (module.Name);
  842. table.row.Col2 = GetGuidIndex (module.Mvid);
  843. var assembly = module.Assembly;
  844. if (assembly != null)
  845. BuildAssembly ();
  846. if (module.HasAssemblyReferences)
  847. AddAssemblyReferences ();
  848. if (module.HasModuleReferences)
  849. AddModuleReferences ();
  850. if (module.HasResources)
  851. AddResources ();
  852. if (module.HasExportedTypes)
  853. AddExportedTypes ();
  854. BuildTypes ();
  855. if (assembly != null) {
  856. if (assembly.HasCustomAttributes)
  857. AddCustomAttributes (assembly);
  858. if (assembly.HasSecurityDeclarations)
  859. AddSecurityDeclarations (assembly);
  860. }
  861. if (module.HasCustomAttributes)
  862. AddCustomAttributes (module);
  863. if (module.EntryPoint != null)
  864. entry_point = LookupToken (module.EntryPoint);
  865. var pdb_writer = symbol_writer as IMetadataSymbolWriter;
  866. if (pdb_writer != null)
  867. pdb_writer.WriteModule ();
  868. }
  869. void BuildAssembly ()
  870. {
  871. var assembly = module.Assembly;
  872. var name = assembly.Name;
  873. var table = GetTable<AssemblyTable> (Table.Assembly);
  874. table.row = new AssemblyRow (
  875. name.HashAlgorithm,
  876. (ushort) name.Version.Major,
  877. (ushort) name.Version.Minor,
  878. (ushort) name.Version.Build,
  879. (ushort) name.Version.Revision,
  880. name.Attributes,
  881. GetBlobIndex (name.PublicKey),
  882. GetStringIndex (name.Name),
  883. GetStringIndex (name.Culture));
  884. if (assembly.Modules.Count > 1)
  885. BuildModules ();
  886. }
  887. void BuildModules ()
  888. {
  889. var modules = this.module.Assembly.Modules;
  890. var table = GetTable<FileTable> (Table.File);
  891. for (int i = 0; i < modules.Count; i++) {
  892. var module = modules [i];
  893. if (module.IsMain)
  894. continue;
  895. #if NET_CORE
  896. throw new NotSupportedException ();
  897. #else
  898. var parameters = new WriterParameters {
  899. SymbolWriterProvider = symbol_writer_provider,
  900. };
  901. var file_name = GetModuleFileName (module.Name);
  902. module.Write (file_name, parameters);
  903. var hash = CryptoService.ComputeHash (file_name);
  904. table.AddRow (new FileRow (
  905. FileAttributes.ContainsMetaData,
  906. GetStringIndex (module.Name),
  907. GetBlobIndex (hash)));
  908. #endif
  909. }
  910. }
  911. #if !NET_CORE
  912. string GetModuleFileName (string name)
  913. {
  914. if (string.IsNullOrEmpty (name))
  915. throw new NotSupportedException ();
  916. var path = Path.GetDirectoryName (fq_name);
  917. return Path.Combine (path, name);
  918. }
  919. #endif
  920. void AddAssemblyReferences ()
  921. {
  922. var references = module.AssemblyReferences;
  923. var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
  924. if (module.IsWindowsMetadata ())
  925. module.Projections.RemoveVirtualReferences (references);
  926. for (int i = 0; i < references.Count; i++) {
  927. var reference = references [i];
  928. var key_or_token = reference.PublicKey.IsNullOrEmpty ()
  929. ? reference.PublicKeyToken
  930. : reference.PublicKey;
  931. var version = reference.Version;
  932. var rid = table.AddRow (new AssemblyRefRow (
  933. (ushort) version.Major,
  934. (ushort) version.Minor,
  935. (ushort) version.Build,
  936. (ushort) version.Revision,
  937. reference.Attributes,
  938. GetBlobIndex (key_or_token),
  939. GetStringIndex (reference.Name),
  940. GetStringIndex (reference.Culture),
  941. GetBlobIndex (reference.Hash)));
  942. reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
  943. }
  944. if (module.IsWindowsMetadata ())
  945. module.Projections.AddVirtualReferences (references);
  946. }
  947. void AddModuleReferences ()
  948. {
  949. var references = module.ModuleReferences;
  950. var table = GetTable<ModuleRefTable> (Table.ModuleRef);
  951. for (int i = 0; i < references.Count; i++) {
  952. var reference = references [i];
  953. reference.token = new MetadataToken (
  954. TokenType.ModuleRef,
  955. table.AddRow (GetStringIndex (reference.Name)));
  956. }
  957. }
  958. void AddResources ()
  959. {
  960. var resources = module.Resources;
  961. var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
  962. for (int i = 0; i < resources.Count; i++) {
  963. var resource = resources [i];
  964. var row = new ManifestResourceRow (
  965. 0,
  966. resource.Attributes,
  967. GetStringIndex (resource.Name),
  968. 0);
  969. switch (resource.ResourceType) {
  970. case ResourceType.Embedded:
  971. row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
  972. break;
  973. case ResourceType.Linked:
  974. row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
  975. new MetadataToken (
  976. TokenType.File,
  977. AddLinkedResource ((LinkedResource) resource)));
  978. break;
  979. case ResourceType.AssemblyLinked:
  980. row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
  981. ((AssemblyLinkedResource) resource).Assembly.MetadataToken);
  982. break;
  983. default:
  984. throw new NotSupportedException ();
  985. }
  986. table.AddRow (row);
  987. }
  988. }
  989. uint AddLinkedResource (LinkedResource resource)
  990. {
  991. var table = GetTable<FileTable> (Table.File);
  992. var hash = resource.Hash;
  993. #if !NET_CORE
  994. if (hash.IsNullOrEmpty ())
  995. hash = CryptoService.ComputeHash (resource.File);
  996. #endif
  997. return (uint) table.AddRow (new FileRow (
  998. FileAttributes.ContainsNoMetaData,
  999. GetStringIndex (resource.File),
  1000. GetBlobIndex (hash)));
  1001. }
  1002. uint AddEmbeddedResource (EmbeddedResource resource)
  1003. {
  1004. return resources.AddResource (resource.GetResourceData ());
  1005. }
  1006. void AddExportedTypes ()
  1007. {
  1008. var exported_types = module.ExportedTypes;
  1009. var table = GetTable<ExportedTypeTable> (Table.ExportedType);
  1010. for (int i = 0; i < exported_types.Count; i++) {
  1011. var exported_type = exported_types [i];
  1012. var rid = table.AddRow (new ExportedTypeRow (
  1013. exported_type.Attributes,
  1014. (uint) exported_type.Identifier,
  1015. GetStringIndex (exported_type.Name),
  1016. GetStringIndex (exported_type.Namespace),
  1017. MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
  1018. exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
  1019. }
  1020. }
  1021. MetadataToken GetExportedTypeScope (ExportedType exported_type)
  1022. {
  1023. if (exported_type.DeclaringType != null)
  1024. return exported_type.DeclaringType.MetadataToken;
  1025. var scope = exported_type.Scope;
  1026. switch (scope.MetadataToken.TokenType) {
  1027. case TokenType.AssemblyRef:
  1028. return scope.MetadataToken;
  1029. case TokenType.ModuleRef:
  1030. var file_table = GetTable<FileTable> (Table.File);
  1031. for (int i = 0; i < file_table.length; i++)
  1032. if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
  1033. return new MetadataToken (TokenType.File, i + 1);
  1034. break;
  1035. }
  1036. throw new NotSupportedException ();
  1037. }
  1038. void BuildTypes ()
  1039. {
  1040. if (!module.HasTypes)
  1041. return;
  1042. AttachTokens ();
  1043. AddTypes ();
  1044. AddGenericParameters ();
  1045. }
  1046. void AttachTokens ()
  1047. {
  1048. var types = module.Types;
  1049. for (int i = 0; i < types.Count; i++)
  1050. AttachTypeToken (types [i]);
  1051. }
  1052. void AttachTypeToken (TypeDefinition type)
  1053. {
  1054. type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
  1055. type.fields_range.Start = field_rid;
  1056. type.methods_range.Start = method_rid;
  1057. if (type.HasFields)
  1058. AttachFieldsToken (type);
  1059. if (type.HasMethods)
  1060. AttachMethodsToken (type);
  1061. if (type.HasNestedTypes)
  1062. AttachNestedTypesToken (type);
  1063. }
  1064. void AttachNestedTypesToken (TypeDefinition type)
  1065. {
  1066. var nested_types = type.NestedTypes;
  1067. for (int i = 0; i < nested_types.Count; i++)
  1068. AttachTypeToken (nested_types [i]);
  1069. }
  1070. void AttachFieldsToken (TypeDefinition type)
  1071. {
  1072. var fields = type.Fields;
  1073. type.fields_range.Length = (uint) fields.Count;
  1074. for (int i = 0; i < fields.Count; i++)
  1075. fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
  1076. }
  1077. void AttachMethodsToken (TypeDefinition type)
  1078. {
  1079. var methods = type.Methods;
  1080. type.methods_range.Length = (uint) methods.Count;
  1081. for (int i = 0; i < methods.Count; i++)
  1082. methods [i].token = new MetadataToken (TokenType.Method, method_rid++);
  1083. }
  1084. MetadataToken GetTypeToken (TypeReference type)
  1085. {
  1086. if (type == null)
  1087. return MetadataToken.Zero;
  1088. if (type.IsDefinition)
  1089. return type.token;
  1090. if (type.IsTypeSpecification ())
  1091. return GetTypeSpecToken (type);
  1092. return GetTypeRefToken (type);
  1093. }
  1094. MetadataToken GetTypeSpecToken (TypeReference type)
  1095. {
  1096. var row = GetBlobIndex (GetTypeSpecSignature (type));
  1097. MetadataToken token;
  1098. if (type_spec_map.TryGetValue (row, out token))
  1099. return token;
  1100. return AddTypeSpecification (type, row);
  1101. }
  1102. MetadataToken AddTypeSpecification (TypeReference type, uint row)
  1103. {
  1104. type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
  1105. var token = type.token;
  1106. type_spec_map.Add (row, token);
  1107. return token;
  1108. }
  1109. MetadataToken GetTypeRefToken (TypeReference type)
  1110. {
  1111. var projection = WindowsRuntimeProjections.RemoveProjection (type);
  1112. var row = CreateTypeRefRow (type);
  1113. MetadataToken token;
  1114. if (!type_ref_map.TryGetValue (row, out token))
  1115. token = AddTypeReference (type, row);
  1116. WindowsRuntimeProjections.ApplyProjection (type, projection);
  1117. return token;
  1118. }
  1119. TypeRefRow CreateTypeRefRow (TypeReference type)
  1120. {
  1121. var scope_token = GetScopeToken (type);
  1122. return new TypeRefRow (
  1123. MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
  1124. GetStringIndex (type.Name),
  1125. GetStringIndex (type.Namespace));
  1126. }
  1127. MetadataToken GetScopeToken (TypeReference type)
  1128. {
  1129. if (type.IsNested)
  1130. return GetTypeRefToken (type.DeclaringType);
  1131. var scope = type.Scope;
  1132. if (scope == null)
  1133. return MetadataToken.Zero;
  1134. return scope.MetadataToken;
  1135. }
  1136. static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
  1137. {
  1138. return MakeCodedRID (provider.MetadataToken, index);
  1139. }
  1140. static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
  1141. {
  1142. return index.CompressMetadataToken (token);
  1143. }
  1144. MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
  1145. {
  1146. type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
  1147. var token = type.token;
  1148. type_ref_map.Add (row, token);
  1149. return token;
  1150. }
  1151. void AddTypes ()
  1152. {
  1153. var types = module.Types;
  1154. for (int i = 0; i < types.Count; i++)
  1155. AddType (types [i]);
  1156. }
  1157. void AddType (TypeDefinition type)
  1158. {
  1159. var treatment = WindowsRuntimeProjections.RemoveProjection (type);
  1160. type_def_table.AddRow (new TypeDefRow (
  1161. type.Attributes,
  1162. GetStringIndex (type.Name),
  1163. GetStringIndex (type.Namespace),
  1164. MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
  1165. type.fields_range.Start,
  1166. type.methods_range.Start));
  1167. if (type.HasGenericParameters)
  1168. AddGenericParameters (type);
  1169. if (type.HasInterfaces)
  1170. AddInterfaces (type);
  1171. AddLayoutInfo (type);
  1172. if (type.HasFields)
  1173. AddFields (type);
  1174. if (type.HasMethods)
  1175. AddMethods (type);
  1176. if (type.HasProperties)
  1177. AddProperties (type);
  1178. if (type.HasEvents)
  1179. AddEvents (type);
  1180. if (type.HasCustomAttributes)
  1181. AddCustomAttributes (type);
  1182. if (type.HasSecurityDeclarations)
  1183. AddSecurityDeclarations (type);
  1184. if (type.HasNestedTypes)
  1185. AddNestedTypes (type);
  1186. WindowsRuntimeProjections.ApplyProjection (type, treatment);
  1187. }
  1188. void AddGenericParameters (IGenericParameterProvider owner)
  1189. {
  1190. var parameters = owner.GenericParameters;
  1191. for (int i = 0; i < parameters.Count; i++)
  1192. generic_parameters.Add (parameters [i]);
  1193. }
  1194. sealed class GenericParameterComparer : IComparer<GenericParameter> {
  1195. public int Compare (GenericParameter a, GenericParameter b)
  1196. {
  1197. var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
  1198. var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
  1199. if (a_owner == b_owner) {
  1200. var a_pos = a.Position;
  1201. var b_pos = b.Position;
  1202. return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
  1203. }
  1204. return a_owner > b_owner ? 1 : -1;
  1205. }
  1206. }
  1207. void AddGenericParameters ()
  1208. {
  1209. var items = this.generic_parameters.items;
  1210. var size = this.generic_parameters.size;
  1211. Array.Sort (items, 0, size, new GenericParameterComparer ());
  1212. var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
  1213. var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
  1214. for (int i = 0; i < size; i++) {
  1215. var generic_parameter = items [i];
  1216. var rid = generic_param_table.AddRow (new GenericParamRow (
  1217. (ushort) generic_parameter.Position,
  1218. generic_parameter.Attributes,
  1219. MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
  1220. GetStringIndex (generic_parameter.Name)));
  1221. generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
  1222. if (generic_parameter.HasConstraints)
  1223. AddConstraints (generic_parameter, generic_param_constraint_table);
  1224. if (generic_parameter.HasCustomAttributes)
  1225. AddCustomAttributes (generic_parameter);
  1226. }
  1227. }
  1228. void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
  1229. {
  1230. var constraints = generic_parameter.Constraints;
  1231. var rid = generic_parameter.token.RID;
  1232. for (int i = 0; i < constraints.Count; i++)
  1233. table.AddRow (new GenericParamConstraintRow (
  1234. rid,
  1235. MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef)));
  1236. }
  1237. void AddInterfaces (TypeDefinition type)
  1238. {
  1239. var interfaces = type.Interfaces;
  1240. var type_rid = type.token.RID;
  1241. for (int i = 0; i < interfaces.Count; i++) {
  1242. var iface_impl = interfaces [i];
  1243. var rid = iface_impl_table.AddRow (new InterfaceImplRow (
  1244. type_rid,
  1245. MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef)));
  1246. iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid);
  1247. if (iface_impl.HasCustomAttributes)
  1248. AddCustomAttributes (iface_impl);
  1249. }
  1250. }
  1251. void AddLayoutInfo (TypeDefinition type)
  1252. {
  1253. if (type.HasLayoutInfo) {
  1254. var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
  1255. table.AddRow (new ClassLayoutRow (
  1256. (ushort) type.PackingSize,
  1257. (uint) type.ClassSize,
  1258. type.token.RID));
  1259. return;
  1260. }
  1261. if (type.IsValueType && HasNoInstanceField (type)) {
  1262. var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
  1263. table.AddRow (new ClassLayoutRow (0, 1, type.token.RID));
  1264. }
  1265. }
  1266. static bool HasNoInstanceField (TypeDefinition type)
  1267. {
  1268. if (!type.HasFields)
  1269. return true;
  1270. var fields = type.Fields;
  1271. for (int i = 0; i < fields.Count; i++)
  1272. if (!fields [i].IsStatic)
  1273. return false;
  1274. return true;
  1275. }
  1276. void AddNestedTypes (TypeDefinition type)
  1277. {
  1278. var nested_types = type.NestedTypes;
  1279. var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
  1280. for (int i = 0; i < nested_types.Count; i++) {
  1281. var nested = nested_types [i];
  1282. AddType (nested);
  1283. nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
  1284. }
  1285. }
  1286. void AddFields (TypeDefinition type)
  1287. {
  1288. var fields = type.Fields;
  1289. for (int i = 0; i < fields.Count; i++)
  1290. AddField (fields [i]);
  1291. }
  1292. void AddField (FieldDefinition field)
  1293. {
  1294. var projection = WindowsRuntimeProjections.RemoveProjection (field);
  1295. field_table.AddRow (new FieldRow (
  1296. field.Attributes,
  1297. GetStringIndex (field.Name),
  1298. GetBlobIndex (GetFieldSignature (field))));
  1299. if (!field.InitialValue.IsNullOrEmpty ())
  1300. AddFieldRVA (field);
  1301. if (field.HasLayoutInfo)
  1302. AddFieldLayout (field);
  1303. if (field.HasCustomAttributes)
  1304. AddCustomAttributes (field);
  1305. if (field.HasConstant)
  1306. AddConstant (field, field.FieldType);
  1307. if (field.HasMarshalInfo)
  1308. AddMarshalInfo (field);
  1309. WindowsRuntimeProjections.ApplyProjection (field, projection);
  1310. }
  1311. void AddFieldRVA (FieldDefinition field)
  1312. {
  1313. var table = GetTable<FieldRVATable> (Table.FieldRVA);
  1314. table.AddRow (new FieldRVARow (
  1315. data.AddData (field.InitialValue),
  1316. field.token.RID));
  1317. }
  1318. void AddFieldLayout (FieldDefinition field)
  1319. {
  1320. var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
  1321. table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
  1322. }
  1323. void AddMethods (TypeDefinition type)
  1324. {
  1325. var methods = type.Methods;
  1326. for (int i = 0; i < methods.Count; i++)
  1327. AddMethod (methods [i]);
  1328. }
  1329. void AddMethod (MethodDefinition method)
  1330. {
  1331. var projection = WindowsRuntimeProjections.RemoveProjection (method);
  1332. method_table.AddRow (new MethodRow (
  1333. method.HasBody ? code.WriteMethodBody (method) : 0,
  1334. method.ImplAttributes,
  1335. method.Attributes,
  1336. GetStringIndex (method.Name),
  1337. GetBlobIndex (GetMethodSignature (method)),
  1338. param_rid));
  1339. AddParameters (method);
  1340. if (method.HasGenericParameters)
  1341. AddGenericParameters (method);
  1342. if (method.IsPInvokeImpl)
  1343. AddPInvokeInfo (method);
  1344. if (method.HasCustomAttributes)
  1345. AddCustomAttributes (method);
  1346. if (method.HasSecurityDeclarations)
  1347. AddSecurityDeclarations (method);
  1348. if (method.HasOverrides)
  1349. AddOverrides (method);
  1350. WindowsRuntimeProjections.ApplyProjection (method, projection);
  1351. }
  1352. void AddParameters (MethodDefinition method)
  1353. {
  1354. var return_parameter = method.MethodReturnType.parameter;
  1355. if (return_parameter != null && RequiresParameterRow (return_parameter))
  1356. AddParameter (0, return_parameter, param_table);
  1357. if (!method.HasParameters)
  1358. return;
  1359. var parameters = method.Parameters;
  1360. for (int i = 0; i < parameters.Count; i++) {
  1361. var parameter = parameters [i];
  1362. if (!RequiresParameterRow (parameter))
  1363. continue;
  1364. AddParameter ((ushort) (i + 1), parameter, param_table);
  1365. }
  1366. }
  1367. void AddPInvokeInfo (MethodDefinition method)
  1368. {
  1369. var pinvoke = method.PInvokeInfo;
  1370. if (pinvoke == null)
  1371. return;
  1372. var table = GetTable<ImplMapTable> (Table.ImplMap);
  1373. table.AddRow (new ImplMapRow (
  1374. pinvoke.Attributes,
  1375. MakeCodedRID (method, CodedIndex.MemberForwarded),
  1376. GetStringIndex (pinvoke.EntryPoint),
  1377. pinvoke.Module.MetadataToken.RID));
  1378. }
  1379. void AddOverrides (MethodDefinition method)
  1380. {
  1381. var overrides = method.Overrides;
  1382. var table = GetTable<MethodImplTable> (Table.MethodImpl);
  1383. for (int i = 0; i < overrides.Count; i++) {
  1384. table.AddRow (new MethodImplRow (
  1385. method.DeclaringType.token.RID,
  1386. MakeCodedRID (method, CodedIndex.MethodDefOrRef),
  1387. MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef)));
  1388. }
  1389. }
  1390. static bool RequiresParameterRow (ParameterDefinition parameter)
  1391. {
  1392. return !string.IsNullOrEmpty (parameter.Name)
  1393. || parameter.Attributes != ParameterAttributes.None
  1394. || parameter.HasMarshalInfo
  1395. || parameter.HasConstant
  1396. || parameter.HasCustomAttributes;
  1397. }
  1398. void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table)
  1399. {
  1400. table.AddRow (new ParamRow (
  1401. parameter.Attributes,
  1402. sequence,
  1403. GetStringIndex (parameter.Name)));
  1404. parameter.token = new MetadataToken (TokenType.Param, param_rid++);
  1405. if (parameter.HasCustomAttributes)
  1406. AddCustomAttributes (parameter);
  1407. if (parameter.HasConstant)
  1408. AddConstant (parameter, parameter.ParameterType);
  1409. if (parameter.HasMarshalInfo)
  1410. AddMarshalInfo (parameter);
  1411. }
  1412. void AddMarshalInfo (IMarshalInfoProvider owner)
  1413. {
  1414. var table = GetTable<FieldMarshalTable> (Table.FieldMarshal);
  1415. table.AddRow (new FieldMarshalRow (
  1416. MakeCodedRID (owner, CodedIndex.HasFieldMarshal),
  1417. GetBlobIndex (GetMarshalInfoSignature (owner))));
  1418. }
  1419. void AddProperties (TypeDefinition type)
  1420. {
  1421. var properties = type.Properties;
  1422. property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid));
  1423. for (int i = 0; i < properties.Count; i++)
  1424. AddProperty (properties [i]);
  1425. }
  1426. void AddProperty (PropertyDefinition property)
  1427. {
  1428. property_table.AddRow (new PropertyRow (
  1429. property.Attributes,
  1430. GetStringIndex (property.Name),
  1431. GetBlobIndex (GetPropertySignature (property))));
  1432. property.token = new MetadataToken (TokenType.Property, property_rid++);
  1433. var method = property.GetMethod;
  1434. if (method != null)
  1435. AddSemantic (MethodSemanticsAttributes.Getter, property, method);
  1436. method = property.SetMethod;
  1437. if (method != null)
  1438. AddSemantic (MethodSemanticsAttributes.Setter, property, method);
  1439. if (property.HasOtherMethods)
  1440. AddOtherSemantic (property, property.OtherMethods);
  1441. if (property.HasCustomAttributes)
  1442. AddCustomAttributes (property);
  1443. if (property.HasConstant)
  1444. AddConstant (property, property.PropertyType);
  1445. }
  1446. void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
  1447. {
  1448. for (int i = 0; i < others.Count; i++)
  1449. AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]);
  1450. }
  1451. void AddEvents (TypeDefinition type)
  1452. {
  1453. var events = type.Events;
  1454. event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid));
  1455. for (int i = 0; i < events.Count; i++)
  1456. AddEvent (events [i]);
  1457. }
  1458. void AddEvent (EventDefinition @event)
  1459. {
  1460. event_table.AddRow (new EventRow (
  1461. @event.Attributes,
  1462. GetStringIndex (@event.Name),
  1463. MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef)));
  1464. @event.token = new MetadataToken (TokenType.Event, event_rid++);
  1465. var method = @event.AddMethod;
  1466. if (method != null)
  1467. AddSemantic (MethodSemanticsAttributes.AddOn, @event, method);
  1468. method = @event.InvokeMethod;
  1469. if (method != null)
  1470. AddSemantic (MethodSemanticsAttributes.Fire, @event, method);
  1471. method = @event.RemoveMethod;
  1472. if (method != null)
  1473. AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method);
  1474. if (@event.HasOtherMethods)
  1475. AddOtherSemantic (@event, @event.OtherMethods);
  1476. if (@event.HasCustomAttributes)
  1477. AddCustomAttributes (@event);
  1478. }
  1479. void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method)
  1480. {
  1481. method.SemanticsAttributes = semantics;
  1482. var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics);
  1483. table.AddRow (new MethodSemanticsRow (
  1484. semantics,
  1485. method.token.RID,
  1486. MakeCodedRID (provider, CodedIndex.HasSemantics)));
  1487. }
  1488. void AddConstant (IConstantProvider owner, TypeReference type)
  1489. {
  1490. var constant = owner.Constant;
  1491. var etype = GetConstantType (type, constant);
  1492. constant_table.AddRow (new ConstantRow (
  1493. etype,
  1494. MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
  1495. GetBlobIndex (GetConstantSignature (etype, constant))));
  1496. }
  1497. static ElementType GetConstantType (TypeReference constant_type, object constant)
  1498. {
  1499. if (constant == null)
  1500. return ElementType.Class;
  1501. var etype = constant_type.etype;
  1502. switch (etype) {
  1503. case ElementType.None:
  1504. var type = constant_type.CheckedResolve ();
  1505. if (type.IsEnum)
  1506. return GetConstantType (type.GetEnumUnderlyingType (), constant);
  1507. return ElementType.Class;
  1508. case ElementType.String:
  1509. return ElementType.String;
  1510. case ElementType.Object:
  1511. return GetConstantType (constant.GetType ());
  1512. case ElementType.Array:
  1513. case ElementType.SzArray:
  1514. case ElementType.MVar:
  1515. case ElementType.Var:
  1516. return ElementType.Class;
  1517. case ElementType.GenericInst:
  1518. var generic_instance = (GenericInstanceType) constant_type;
  1519. if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1"))
  1520. return GetConstantType (generic_instance.GenericArguments [0], constant);
  1521. return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
  1522. case ElementType.CModOpt:
  1523. case ElementType.CModReqD:
  1524. case ElementType.ByRef:
  1525. case ElementType.Sentinel:
  1526. return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
  1527. case ElementType.Boolean:
  1528. case ElementType.Char:
  1529. case ElementType.I:
  1530. case ElementType.I1:
  1531. case ElementType.I2:
  1532. case ElementType.I4:
  1533. case ElementType.I8:
  1534. case ElementType.U:
  1535. case ElementType.U1:
  1536. case ElementType.U2:
  1537. case ElementType.U4:
  1538. case ElementType.U8:
  1539. case ElementType.R4:
  1540. case ElementType.R8:
  1541. return GetConstantType (constant.GetType ());
  1542. default:
  1543. return etype;
  1544. }
  1545. }
  1546. static ElementType GetConstantType (Type type)
  1547. {
  1548. switch (type.GetTypeCode ()) {
  1549. case TypeCode.Boolean:
  1550. return ElementType.Boolean;
  1551. case TypeCode.Byte:
  1552. return ElementType.U1;
  1553. case TypeCode.SByte:
  1554. return ElementType.I1;
  1555. case TypeCode.Char:
  1556. return ElementType.Char;
  1557. case TypeCode.Int16:
  1558. return ElementType.I2;
  1559. case TypeCode.UInt16:
  1560. return ElementType.U2;
  1561. case TypeCode.Int32:
  1562. return ElementType.I4;
  1563. case TypeCode.UInt32:
  1564. return ElementType.U4;
  1565. case TypeCode.Int64:
  1566. return ElementType.I8;
  1567. case TypeCode.UInt64:
  1568. return ElementType.U8;
  1569. case TypeCode.Single:
  1570. return ElementType.R4;
  1571. case TypeCode.Double:
  1572. return ElementType.R8;
  1573. case TypeCode.String:
  1574. return ElementType.String;
  1575. default:
  1576. throw new NotSupportedException (type.FullName);
  1577. }
  1578. }
  1579. void AddCustomAttributes (ICustomAttributeProvider owner)
  1580. {
  1581. var custom_attributes = owner.CustomAttributes;
  1582. for (int i = 0; i < custom_attributes.Count; i++) {
  1583. var attribute = custom_attributes [i];
  1584. var projection = WindowsRuntimeProjections.RemoveProjection (attribute);
  1585. custom_attribute_table.AddRow (new CustomAttributeRow (
  1586. MakeCodedRID (owner, CodedIndex.HasCustomAttribute),
  1587. MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType),
  1588. GetBlobIndex (GetCustomAttributeSignature (attribute))));
  1589. WindowsRuntimeProjections.ApplyProjection (attribute, projection);
  1590. }
  1591. }
  1592. void AddSecurityDeclarations (ISecurityDeclarationProvider owner)
  1593. {
  1594. var declarations = owner.SecurityDeclarations;
  1595. for (int i = 0; i < declarations.Count; i++) {
  1596. var declaration = declarations [i];
  1597. declsec_table.AddRow (new DeclSecurityRow (
  1598. declaration.Action,
  1599. MakeCodedRID (owner, CodedIndex.HasDeclSecurity),
  1600. GetBlobIndex (GetSecurityDeclarationSignature (declaration))));
  1601. }
  1602. }
  1603. MetadataToken GetMemberRefToken (MemberReference member)
  1604. {
  1605. var projection = WindowsRuntimeProjections.RemoveProjection (member);
  1606. var row = CreateMemberRefRow (member);
  1607. MetadataToken token;
  1608. if (!member_ref_map.TryGetValue (row, out token))
  1609. token = AddMemberReference (member, row);
  1610. WindowsRuntimeProjections.ApplyProjection (member, projection);
  1611. return token;
  1612. }
  1613. MemberRefRow CreateMemberRefRow (MemberReference member)
  1614. {
  1615. return new MemberRefRow (
  1616. MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent),
  1617. GetStringIndex (member.Name),
  1618. GetBlobIndex (GetMemberRefSignature (member)));
  1619. }
  1620. MetadataToken AddMemberReference (MemberReference member, MemberRefRow row)
  1621. {
  1622. member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row));
  1623. var token = member.token;
  1624. member_ref_map.Add (row, token);
  1625. return token;
  1626. }
  1627. MetadataToken GetMethodSpecToken (MethodSpecification method_spec)
  1628. {
  1629. var row = CreateMethodSpecRow (method_spec);
  1630. MetadataToken token;
  1631. if (method_spec_map.TryGetValue (row, out token))
  1632. return token;
  1633. AddMethodSpecification (method_spec, row);
  1634. return method_spec.token;
  1635. }
  1636. void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row)
  1637. {
  1638. method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row));
  1639. method_spec_map.Add (row, method_spec.token);
  1640. }
  1641. MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec)
  1642. {
  1643. return new MethodSpecRow (
  1644. MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef),
  1645. GetBlobIndex (GetMethodSpecSignature (method_spec)));
  1646. }
  1647. SignatureWriter CreateSignatureWriter ()
  1648. {
  1649. return new SignatureWriter (this);
  1650. }
  1651. SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec)
  1652. {
  1653. if (!method_spec.IsGenericInstance)
  1654. throw new NotSupportedException ();
  1655. var generic_instance = (GenericInstanceMethod) method_spec;
  1656. var signature = CreateSignatureWriter ();
  1657. signature.WriteByte (0x0a);
  1658. signature.WriteGenericInstanceSignature (generic_instance);
  1659. return signature;
  1660. }
  1661. public uint AddStandAloneSignature (uint signature)
  1662. {
  1663. return (uint) standalone_sig_table.AddRow (signature);
  1664. }
  1665. public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables)
  1666. {
  1667. return GetBlobIndex (GetVariablesSignature (variables));
  1668. }
  1669. public uint GetCallSiteBlobIndex (CallSite call_site)
  1670. {
  1671. return GetBlobIndex (GetMethodSignature (call_site));
  1672. }
  1673. public uint GetConstantTypeBlobIndex (TypeReference constant_type)
  1674. {
  1675. return GetBlobIndex (GetConstantTypeSignature (constant_type));
  1676. }
  1677. SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables)
  1678. {
  1679. var signature = CreateSignatureWriter ();
  1680. signature.WriteByte (0x7);
  1681. signature.WriteCompressedUInt32 ((uint) variables.Count);
  1682. for (int i = 0; i < variables.Count; i++)
  1683. signature.WriteTypeSignature (variables [i].VariableType);
  1684. return signature;
  1685. }
  1686. SignatureWriter GetConstantTypeSignature (TypeReference constant_type)
  1687. {
  1688. var signature = CreateSignatureWriter ();
  1689. signature.WriteByte (0x6);
  1690. signature.WriteTypeSignature (constant_type);
  1691. return signature;
  1692. }
  1693. SignatureWriter GetFieldSignature (FieldReference field)
  1694. {
  1695. var signature = CreateSignatureWriter ();
  1696. signature.WriteByte (0x6);
  1697. signature.WriteTypeSignature (field.FieldType);
  1698. return signature;
  1699. }
  1700. SignatureWriter GetMethodSignature (IMethodSignature method)
  1701. {
  1702. var signature = CreateSignatureWriter ();
  1703. signature.WriteMethodSignature (method);
  1704. return signature;
  1705. }
  1706. SignatureWriter GetMemberRefSignature (MemberReference member)
  1707. {
  1708. var field = member as FieldReference;
  1709. if (field != null)
  1710. return GetFieldSignature (field);
  1711. var method = member as MethodReference;
  1712. if (method != null)
  1713. return GetMethodSignature (method);
  1714. throw new NotSupportedException ();
  1715. }
  1716. SignatureWriter GetPropertySignature (PropertyDefinition property)
  1717. {
  1718. var signature = CreateSignatureWriter ();
  1719. byte calling_convention = 0x8;
  1720. if (property.HasThis)
  1721. calling_convention |= 0x20;
  1722. uint param_count = 0;
  1723. Collection<ParameterDefinition> parameters = null;
  1724. if (property.HasParameters) {
  1725. parameters = property.Parameters;
  1726. param_count = (uint) parameters.Count;
  1727. }
  1728. signature.WriteByte (calling_convention);
  1729. signature.WriteCompressedUInt32 (param_count);
  1730. signature.WriteTypeSignature (property.PropertyType);
  1731. if (param_count == 0)
  1732. return signature;
  1733. for (int i = 0; i < param_count; i++)
  1734. signature.WriteTypeSignature (parameters [i].ParameterType);
  1735. return signature;
  1736. }
  1737. SignatureWriter GetTypeSpecSignature (TypeReference type)
  1738. {
  1739. var signature = CreateSignatureWriter ();
  1740. signature.WriteTypeSignature (type);
  1741. return signature;
  1742. }
  1743. SignatureWriter GetConstantSignature (ElementType type, object value)
  1744. {
  1745. var signature = CreateSignatureWriter ();
  1746. switch (type) {
  1747. case ElementType.Array:
  1748. case ElementType.SzArray:
  1749. case ElementType.Class:
  1750. case ElementType.Object:
  1751. case ElementType.None:
  1752. case ElementType.Var:
  1753. case ElementType.MVar:
  1754. signature.WriteInt32 (0);
  1755. break;
  1756. case ElementType.String:
  1757. signature.WriteConstantString ((string) value);
  1758. break;
  1759. default:
  1760. signature.WriteConstantPrimitive (value);
  1761. break;
  1762. }
  1763. return signature;
  1764. }
  1765. SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute)
  1766. {
  1767. var signature = CreateSignatureWriter ();
  1768. if (!attribute.resolved) {
  1769. signature.WriteBytes (attribute.GetBlob ());
  1770. return signature;
  1771. }
  1772. signature.WriteUInt16 (0x0001);
  1773. signature.WriteCustomAttributeConstructorArguments (attribute);
  1774. signature.WriteCustomAttributeNamedArguments (attribute);
  1775. return signature;
  1776. }
  1777. SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration)
  1778. {
  1779. var signature = CreateSignatureWriter ();
  1780. if (!declaration.resolved)
  1781. signature.WriteBytes (declaration.GetBlob ());
  1782. else if (module.Runtime < TargetRuntime.Net_2_0)
  1783. signature.WriteXmlSecurityDeclaration (declaration);
  1784. else
  1785. signature.WriteSecurityDeclaration (declaration);
  1786. return signature;
  1787. }
  1788. SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner)
  1789. {
  1790. var signature = CreateSignatureWriter ();
  1791. signature.WriteMarshalInfo (owner.MarshalInfo);
  1792. return signature;
  1793. }
  1794. static Exception CreateForeignMemberException (MemberReference member)
  1795. {
  1796. return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member));
  1797. }
  1798. public MetadataToken LookupToken (IMetadataTokenProvider provider)
  1799. {
  1800. if (provider == null)
  1801. throw new ArgumentNullException ();
  1802. if (metadata_builder != null)
  1803. return metadata_builder.LookupToken (provider);
  1804. var member = provider as MemberReference;
  1805. if (member == null || member.Module != module)
  1806. throw CreateForeignMemberException (member);
  1807. var token = provider.MetadataToken;
  1808. switch (token.TokenType) {
  1809. case TokenType.TypeDef:
  1810. case TokenType.Method:
  1811. case TokenType.Field:
  1812. case TokenType.Event:
  1813. case TokenType.Property:
  1814. return token;
  1815. case TokenType.TypeRef:
  1816. case TokenType.TypeSpec:
  1817. case TokenType.GenericParam:
  1818. return GetTypeToken ((TypeReference) provider);
  1819. case TokenType.MethodSpec:
  1820. return GetMethodSpecToken ((MethodSpecification) provider);
  1821. case TokenType.MemberRef:
  1822. return GetMemberRefToken (member);
  1823. default:
  1824. throw new NotSupportedException ();
  1825. }
  1826. }
  1827. public void AddMethodDebugInformation (MethodDebugInformation method_info)
  1828. {
  1829. if (method_info.HasSequencePoints)
  1830. AddSequencePoints (method_info);
  1831. if (method_info.Scope != null)
  1832. AddLocalScope (method_info, method_info.Scope);
  1833. if (method_info.StateMachineKickOffMethod != null)
  1834. AddStateMachineMethod (method_info);
  1835. AddCustomDebugInformations (method_info.Method);
  1836. }
  1837. void AddStateMachineMethod (MethodDebugInformation method_info)
  1838. {
  1839. state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID));
  1840. }
  1841. void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope)
  1842. {
  1843. var rid = local_scope_table.AddRow (new LocalScopeRow (
  1844. method_info.Method.MetadataToken.RID,
  1845. scope.import != null ? AddImportScope (scope.import) : 0,
  1846. local_variable_rid,
  1847. local_constant_rid,
  1848. (uint) scope.Start.Offset,
  1849. (uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset)));
  1850. scope.token = new MetadataToken (TokenType.LocalScope, rid);
  1851. AddCustomDebugInformations (scope);
  1852. if (scope.HasVariables)
  1853. AddLocalVariables (scope);
  1854. if (scope.HasConstants)
  1855. AddLocalConstants (scope);
  1856. for (int i = 0; i < scope.Scopes.Count; i++)
  1857. AddLocalScope (method_info, scope.Scopes [i]);
  1858. }
  1859. void AddLocalVariables (ScopeDebugInformation scope)
  1860. {
  1861. for (int i = 0; i < scope.Variables.Count; i++) {
  1862. var variable = scope.Variables [i];
  1863. local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name)));
  1864. variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid);
  1865. local_variable_rid++;
  1866. AddCustomDebugInformations (variable);
  1867. }
  1868. }
  1869. void AddLocalConstants (ScopeDebugInformation scope)
  1870. {
  1871. for (int i = 0; i < scope.Constants.Count; i++) {
  1872. var constant = scope.Constants [i];
  1873. local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant))));
  1874. constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid);
  1875. local_constant_rid++;
  1876. }
  1877. }
  1878. SignatureWriter GetConstantSignature (ConstantDebugInformation constant)
  1879. {
  1880. var type = constant.ConstantType;
  1881. var signature = CreateSignatureWriter ();
  1882. signature.WriteTypeSignature (type);
  1883. if (type.IsTypeOf ("System", "Decimal")) {
  1884. var bits = decimal.GetBits ((decimal) constant.Value);
  1885. var low = (uint) bits [0];
  1886. var mid = (uint) bits [1];
  1887. var high = (uint) bits [2];
  1888. var scale = (byte) (bits [3] >> 16);
  1889. var negative = (bits [3] & 0x80000000) != 0;
  1890. signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00)));
  1891. signature.WriteUInt32 (low);
  1892. signature.WriteUInt32 (mid);
  1893. signature.WriteUInt32 (high);
  1894. return signature;
  1895. }
  1896. if (type.IsTypeOf ("System", "DateTime")) {
  1897. var date = (DateTime) constant.Value;
  1898. signature.WriteInt64 (date.Ticks);
  1899. return signature;
  1900. }
  1901. signature.WriteBytes (GetConstantSignature (type.etype, constant.Value));
  1902. return signature;
  1903. }
  1904. public void AddCustomDebugInformations (ICustomDebugInformationProvider provider)
  1905. {
  1906. if (!provider.HasCustomDebugInformations)
  1907. return;
  1908. var custom_infos = provider.CustomDebugInformations;
  1909. for (int i = 0; i < custom_infos.Count; i++) {
  1910. var custom_info = custom_infos [i];
  1911. switch (custom_info.Kind) {
  1912. case CustomDebugInformationKind.Binary:
  1913. var binary_info = (BinaryCustomDebugInformation) custom_info;
  1914. AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data));
  1915. break;
  1916. case CustomDebugInformationKind.AsyncMethodBody:
  1917. AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info);
  1918. break;
  1919. case CustomDebugInformationKind.StateMachineScope:
  1920. AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info);
  1921. break;
  1922. case CustomDebugInformationKind.EmbeddedSource:
  1923. AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info);
  1924. break;
  1925. case CustomDebugInformationKind.SourceLink:
  1926. AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) custom_info);
  1927. break;
  1928. default:
  1929. throw new NotImplementedException ();
  1930. }
  1931. }
  1932. }
  1933. void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope)
  1934. {
  1935. var method_info = ((MethodDefinition) provider).DebugInformation;
  1936. var signature = CreateSignatureWriter ();
  1937. var scopes = state_machine_scope.Scopes;
  1938. for (int i = 0; i < scopes.Count; i++) {
  1939. var scope = scopes [i];
  1940. signature.WriteUInt32 ((uint) scope.Start.Offset);
  1941. var end_offset = scope.End.IsEndOfMethod
  1942. ? method_info.code_size
  1943. : scope.End.Offset;
  1944. signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset));
  1945. }
  1946. AddCustomDebugInformation (provider, state_machine_scope, signature);
  1947. }
  1948. void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method)
  1949. {
  1950. var signature = CreateSignatureWriter ();
  1951. signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1);
  1952. if (!async_method.yields.IsNullOrEmpty ()) {
  1953. for (int i = 0; i < async_method.yields.Count; i++) {
  1954. signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
  1955. signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
  1956. signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
  1957. }
  1958. }
  1959. AddCustomDebugInformation (provider, async_method, signature);
  1960. }
  1961. void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source)
  1962. {
  1963. var signature = CreateSignatureWriter ();
  1964. var content = embedded_source.content ?? Empty<byte>.Array;
  1965. if (embedded_source.compress) {
  1966. signature.WriteInt32 (content.Length);
  1967. var decompressed_stream = new MemoryStream (content);
  1968. var content_stream = new MemoryStream ();
  1969. using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true))
  1970. decompressed_stream.CopyTo (compress_stream);
  1971. signature.WriteBytes (content_stream.ToArray ());
  1972. } else {
  1973. signature.WriteInt32 (0);
  1974. signature.WriteBytes (content);
  1975. }
  1976. AddCustomDebugInformation (provider, embedded_source, signature);
  1977. }
  1978. void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link)
  1979. {
  1980. var signature = CreateSignatureWriter ();
  1981. signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content));
  1982. AddCustomDebugInformation (provider, source_link, signature);
  1983. }
  1984. void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature)
  1985. {
  1986. AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature));
  1987. }
  1988. void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index)
  1989. {
  1990. var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow (
  1991. MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation),
  1992. GetGuidIndex (custom_info.Identifier),
  1993. blob_index));
  1994. custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid);
  1995. }
  1996. uint AddImportScope (ImportDebugInformation import)
  1997. {
  1998. uint parent = 0;
  1999. if (import.Parent != null)
  2000. parent = AddImportScope (import.Parent);
  2001. uint targets_index = 0;
  2002. if (import.HasTargets) {
  2003. var signature = CreateSignatureWriter ();
  2004. for (int i = 0; i < import.Targets.Count; i++)
  2005. AddImportTarget (import.Targets [i], signature);
  2006. targets_index = GetBlobIndex (signature);
  2007. }
  2008. var row = new ImportScopeRow (parent, targets_index);
  2009. MetadataToken import_token;
  2010. if (import_scope_map.TryGetValue (row, out import_token))
  2011. return import_token.RID;
  2012. import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row));
  2013. import_scope_map.Add (row, import_token);
  2014. return import_token.RID;
  2015. }
  2016. void AddImportTarget (ImportTarget target, SignatureWriter signature)
  2017. {
  2018. signature.WriteCompressedUInt32 ((uint)target.kind);
  2019. switch (target.kind) {
  2020. case ImportTargetKind.ImportNamespace:
  2021. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
  2022. break;
  2023. case ImportTargetKind.ImportNamespaceInAssembly:
  2024. signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
  2025. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
  2026. break;
  2027. case ImportTargetKind.ImportType:
  2028. signature.WriteTypeToken (target.type);
  2029. break;
  2030. case ImportTargetKind.ImportXmlNamespaceWithAlias:
  2031. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2032. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
  2033. break;
  2034. case ImportTargetKind.ImportAlias:
  2035. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2036. break;
  2037. case ImportTargetKind.DefineAssemblyAlias:
  2038. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2039. signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
  2040. break;
  2041. case ImportTargetKind.DefineNamespaceAlias:
  2042. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2043. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
  2044. break;
  2045. case ImportTargetKind.DefineNamespaceInAssemblyAlias:
  2046. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2047. signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
  2048. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
  2049. break;
  2050. case ImportTargetKind.DefineTypeAlias:
  2051. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
  2052. signature.WriteTypeToken (target.type);
  2053. break;
  2054. }
  2055. }
  2056. uint GetUTF8StringBlobIndex (string s)
  2057. {
  2058. return GetBlobIndex (Encoding.UTF8.GetBytes (s));
  2059. }
  2060. public MetadataToken GetDocumentToken (Document document)
  2061. {
  2062. MetadataToken token;
  2063. if (document_map.TryGetValue (document.Url, out token))
  2064. return token;
  2065. token = new MetadataToken (TokenType.Document, document_table.AddRow (
  2066. new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)),
  2067. GetGuidIndex (document.HashAlgorithm.ToGuid ()),
  2068. GetBlobIndex (document.Hash),
  2069. GetGuidIndex (document.Language.ToGuid ()))));
  2070. document.token = token;
  2071. AddCustomDebugInformations (document);
  2072. document_map.Add (document.Url, token);
  2073. return token;
  2074. }
  2075. SignatureWriter GetDocumentNameSignature (Document document)
  2076. {
  2077. var name = document.Url;
  2078. var signature = CreateSignatureWriter ();
  2079. char separator;
  2080. if (!TryGetDocumentNameSeparator (name, out separator)) {
  2081. signature.WriteByte (0);
  2082. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name));
  2083. return signature;
  2084. }
  2085. signature.WriteByte ((byte) separator);
  2086. var parts = name.Split (new [] { separator });
  2087. for (int i = 0; i < parts.Length; i++) {
  2088. if (parts [i] == String.Empty)
  2089. signature.WriteCompressedUInt32 (0);
  2090. else
  2091. signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i]));
  2092. }
  2093. return signature;
  2094. }
  2095. static bool TryGetDocumentNameSeparator (string path, out char separator)
  2096. {
  2097. const char unix = '/';
  2098. const char win = '\\';
  2099. const char zero = (char) 0;
  2100. separator = zero;
  2101. if (string.IsNullOrEmpty (path))
  2102. return false;
  2103. int unix_count = 0;
  2104. int win_count = 0;
  2105. for (int i = 0; i < path.Length; i++) {
  2106. if (path [i] == unix)
  2107. unix_count++;
  2108. else if (path [i] == win)
  2109. win_count++;
  2110. }
  2111. if (unix_count == 0 && win_count == 0)
  2112. return false;
  2113. if (unix_count >= win_count) {
  2114. separator = unix;
  2115. return true;
  2116. }
  2117. separator = win;
  2118. return true;
  2119. }
  2120. void AddSequencePoints (MethodDebugInformation info)
  2121. {
  2122. var rid = info.Method.MetadataToken.RID;
  2123. Document document;
  2124. if (info.TryGetUniqueDocument (out document))
  2125. method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID;
  2126. var signature = CreateSignatureWriter ();
  2127. signature.WriteSequencePoints (info);
  2128. method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature);
  2129. }
  2130. }
  2131. sealed class SignatureWriter : ByteBuffer {
  2132. readonly MetadataBuilder metadata;
  2133. public SignatureWriter (MetadataBuilder metadata)
  2134. : base (6)
  2135. {
  2136. this.metadata = metadata;
  2137. }
  2138. public void WriteElementType (ElementType element_type)
  2139. {
  2140. WriteByte ((byte) element_type);
  2141. }
  2142. public void WriteUTF8String (string @string)
  2143. {
  2144. if (@string == null) {
  2145. WriteByte (0xff);
  2146. return;
  2147. }
  2148. var bytes = Encoding.UTF8.GetBytes (@string);
  2149. WriteCompressedUInt32 ((uint) bytes.Length);
  2150. WriteBytes (bytes);
  2151. }
  2152. public void WriteMethodSignature (IMethodSignature method)
  2153. {
  2154. byte calling_convention = (byte) method.CallingConvention;
  2155. if (method.HasThis)
  2156. calling_convention |= 0x20;
  2157. if (method.ExplicitThis)
  2158. calling_convention |= 0x40;
  2159. var generic_provider = method as IGenericParameterProvider;
  2160. var generic_arity = generic_provider != null && generic_provider.HasGenericParameters
  2161. ? generic_provider.GenericParameters.Count
  2162. : 0;
  2163. if (generic_arity > 0)
  2164. calling_convention |= 0x10;
  2165. var param_count = method.HasParameters ? method.Parameters.Count : 0;
  2166. WriteByte (calling_convention);
  2167. if (generic_arity > 0)
  2168. WriteCompressedUInt32 ((uint) generic_arity);
  2169. WriteCompressedUInt32 ((uint) param_count);
  2170. WriteTypeSignature (method.ReturnType);
  2171. if (param_count == 0)
  2172. return;
  2173. var parameters = method.Parameters;
  2174. for (int i = 0; i < param_count; i++)
  2175. WriteTypeSignature (parameters [i].ParameterType);
  2176. }
  2177. uint MakeTypeDefOrRefCodedRID (TypeReference type)
  2178. {
  2179. return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type));
  2180. }
  2181. public void WriteTypeToken (TypeReference type)
  2182. {
  2183. WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
  2184. }
  2185. public void WriteTypeSignature (TypeReference type)
  2186. {
  2187. if (type == null)
  2188. throw new ArgumentNullException ();
  2189. var etype = type.etype;
  2190. switch (etype) {
  2191. case ElementType.MVar:
  2192. case ElementType.Var: {
  2193. var generic_parameter = (GenericParameter) type;
  2194. WriteElementType (etype);
  2195. var position = generic_parameter.Position;
  2196. if (position == -1)
  2197. throw new NotSupportedException ();
  2198. WriteCompressedUInt32 ((uint) position);
  2199. break;
  2200. }
  2201. case ElementType.GenericInst: {
  2202. var generic_instance = (GenericInstanceType) type;
  2203. WriteElementType (ElementType.GenericInst);
  2204. WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class);
  2205. WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType));
  2206. WriteGenericInstanceSignature (generic_instance);
  2207. break;
  2208. }
  2209. case ElementType.Ptr:
  2210. case ElementType.ByRef:
  2211. case ElementType.Pinned:
  2212. case ElementType.Sentinel: {
  2213. var type_spec = (TypeSpecification) type;
  2214. WriteElementType (etype);
  2215. WriteTypeSignature (type_spec.ElementType);
  2216. break;
  2217. }
  2218. case ElementType.FnPtr: {
  2219. var fptr = (FunctionPointerType) type;
  2220. WriteElementType (ElementType.FnPtr);
  2221. WriteMethodSignature (fptr);
  2222. break;
  2223. }
  2224. case ElementType.CModOpt:
  2225. case ElementType.CModReqD: {
  2226. var modifier = (IModifierType) type;
  2227. WriteModifierSignature (etype, modifier);
  2228. break;
  2229. }
  2230. case ElementType.Array: {
  2231. var array = (ArrayType) type;
  2232. if (!array.IsVector) {
  2233. WriteArrayTypeSignature (array);
  2234. break;
  2235. }
  2236. WriteElementType (ElementType.SzArray);
  2237. WriteTypeSignature (array.ElementType);
  2238. break;
  2239. }
  2240. case ElementType.None: {
  2241. WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class);
  2242. WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
  2243. break;
  2244. }
  2245. default:
  2246. if (!TryWriteElementType (type))
  2247. throw new NotSupportedException ();
  2248. break;
  2249. }
  2250. }
  2251. void WriteArrayTypeSignature (ArrayType array)
  2252. {
  2253. WriteElementType (ElementType.Array);
  2254. WriteTypeSignature (array.ElementType);
  2255. var dimensions = array.Dimensions;
  2256. var rank = dimensions.Count;
  2257. WriteCompressedUInt32 ((uint) rank);
  2258. var sized = 0;
  2259. var lbounds = 0;
  2260. for (int i = 0; i < rank; i++) {
  2261. var dimension = dimensions [i];
  2262. if (dimension.UpperBound.HasValue) {
  2263. sized++;
  2264. lbounds++;
  2265. } else if (dimension.LowerBound.HasValue)
  2266. lbounds++;
  2267. }
  2268. var sizes = new int [sized];
  2269. var low_bounds = new int [lbounds];
  2270. for (int i = 0; i < lbounds; i++) {
  2271. var dimension = dimensions [i];
  2272. low_bounds [i] = dimension.LowerBound.GetValueOrDefault ();
  2273. if (dimension.UpperBound.HasValue)
  2274. sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1;
  2275. }
  2276. WriteCompressedUInt32 ((uint) sized);
  2277. for (int i = 0; i < sized; i++)
  2278. WriteCompressedUInt32 ((uint) sizes [i]);
  2279. WriteCompressedUInt32 ((uint) lbounds);
  2280. for (int i = 0; i < lbounds; i++)
  2281. WriteCompressedInt32 (low_bounds [i]);
  2282. }
  2283. public void WriteGenericInstanceSignature (IGenericInstance instance)
  2284. {
  2285. var generic_arguments = instance.GenericArguments;
  2286. var arity = generic_arguments.Count;
  2287. WriteCompressedUInt32 ((uint) arity);
  2288. for (int i = 0; i < arity; i++)
  2289. WriteTypeSignature (generic_arguments [i]);
  2290. }
  2291. void WriteModifierSignature (ElementType element_type, IModifierType type)
  2292. {
  2293. WriteElementType (element_type);
  2294. WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType));
  2295. WriteTypeSignature (type.ElementType);
  2296. }
  2297. bool TryWriteElementType (TypeReference type)
  2298. {
  2299. var element = type.etype;
  2300. if (element == ElementType.None)
  2301. return false;
  2302. WriteElementType (element);
  2303. return true;
  2304. }
  2305. public void WriteConstantString (string value)
  2306. {
  2307. if (value != null)
  2308. WriteBytes (Encoding.Unicode.GetBytes (value));
  2309. else
  2310. WriteByte (0xff);
  2311. }
  2312. public void WriteConstantPrimitive (object value)
  2313. {
  2314. WritePrimitiveValue (value);
  2315. }
  2316. public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
  2317. {
  2318. if (!attribute.HasConstructorArguments)
  2319. return;
  2320. var arguments = attribute.ConstructorArguments;
  2321. var parameters = attribute.Constructor.Parameters;
  2322. if (parameters.Count != arguments.Count)
  2323. throw new InvalidOperationException ();
  2324. for (int i = 0; i < arguments.Count; i++)
  2325. WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
  2326. }
  2327. void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
  2328. {
  2329. if (type.IsArray) {
  2330. WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
  2331. return;
  2332. }
  2333. WriteCustomAttributeElement (type, argument);
  2334. }
  2335. void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument)
  2336. {
  2337. var values = argument.Value as CustomAttributeArgument [];
  2338. if (values == null) {
  2339. WriteUInt32 (0xffffffff);
  2340. return;
  2341. }
  2342. WriteInt32 (values.Length);
  2343. if (values.Length == 0)
  2344. return;
  2345. var element_type = type.ElementType;
  2346. for (int i = 0; i < values.Length; i++)
  2347. WriteCustomAttributeElement (element_type, values [i]);
  2348. }
  2349. void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument)
  2350. {
  2351. if (type.IsArray) {
  2352. WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
  2353. return;
  2354. }
  2355. if (type.etype == ElementType.Object) {
  2356. argument = (CustomAttributeArgument) argument.Value;
  2357. type = argument.Type;
  2358. WriteCustomAttributeFieldOrPropType (type);
  2359. WriteCustomAttributeElement (type, argument);
  2360. return;
  2361. }
  2362. WriteCustomAttributeValue (type, argument.Value);
  2363. }
  2364. void WriteCustomAttributeValue (TypeReference type, object value)
  2365. {
  2366. var etype = type.etype;
  2367. switch (etype) {
  2368. case ElementType.String:
  2369. var @string = (string) value;
  2370. if (@string == null)
  2371. WriteByte (0xff);
  2372. else
  2373. WriteUTF8String (@string);
  2374. break;
  2375. case ElementType.None:
  2376. if (type.IsTypeOf ("System", "Type"))
  2377. WriteTypeReference ((TypeReference) value);
  2378. else
  2379. WriteCustomAttributeEnumValue (type, value);
  2380. break;
  2381. default:
  2382. WritePrimitiveValue (value);
  2383. break;
  2384. }
  2385. }
  2386. void WritePrimitiveValue (object value)
  2387. {
  2388. if (value == null)
  2389. throw new ArgumentNullException ();
  2390. switch (value.GetType ().GetTypeCode ()) {
  2391. case TypeCode.Boolean:
  2392. WriteByte ((byte) (((bool) value) ? 1 : 0));
  2393. break;
  2394. case TypeCode.Byte:
  2395. WriteByte ((byte) value);
  2396. break;
  2397. case TypeCode.SByte:
  2398. WriteSByte ((sbyte) value);
  2399. break;
  2400. case TypeCode.Int16:
  2401. WriteInt16 ((short) value);
  2402. break;
  2403. case TypeCode.UInt16:
  2404. WriteUInt16 ((ushort) value);
  2405. break;
  2406. case TypeCode.Char:
  2407. WriteInt16 ((short) (char) value);
  2408. break;
  2409. case TypeCode.Int32:
  2410. WriteInt32 ((int) value);
  2411. break;
  2412. case TypeCode.UInt32:
  2413. WriteUInt32 ((uint) value);
  2414. break;
  2415. case TypeCode.Single:
  2416. WriteSingle ((float) value);
  2417. break;
  2418. case TypeCode.Int64:
  2419. WriteInt64 ((long) value);
  2420. break;
  2421. case TypeCode.UInt64:
  2422. WriteUInt64 ((ulong) value);
  2423. break;
  2424. case TypeCode.Double:
  2425. WriteDouble ((double) value);
  2426. break;
  2427. default:
  2428. throw new NotSupportedException (value.GetType ().FullName);
  2429. }
  2430. }
  2431. void WriteCustomAttributeEnumValue (TypeReference enum_type, object value)
  2432. {
  2433. var type = enum_type.CheckedResolve ();
  2434. if (!type.IsEnum)
  2435. throw new ArgumentException ();
  2436. WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value);
  2437. }
  2438. void WriteCustomAttributeFieldOrPropType (TypeReference type)
  2439. {
  2440. if (type.IsArray) {
  2441. var array = (ArrayType) type;
  2442. WriteElementType (ElementType.SzArray);
  2443. WriteCustomAttributeFieldOrPropType (array.ElementType);
  2444. return;
  2445. }
  2446. var etype = type.etype;
  2447. switch (etype) {
  2448. case ElementType.Object:
  2449. WriteElementType (ElementType.Boxed);
  2450. return;
  2451. case ElementType.None:
  2452. if (type.IsTypeOf ("System", "Type"))
  2453. WriteElementType (ElementType.Type);
  2454. else {
  2455. WriteElementType (ElementType.Enum);
  2456. WriteTypeReference (type);
  2457. }
  2458. return;
  2459. default:
  2460. WriteElementType (etype);
  2461. return;
  2462. }
  2463. }
  2464. public void WriteCustomAttributeNamedArguments (CustomAttribute attribute)
  2465. {
  2466. var count = GetNamedArgumentCount (attribute);
  2467. WriteUInt16 ((ushort) count);
  2468. if (count == 0)
  2469. return;
  2470. WriteICustomAttributeNamedArguments (attribute);
  2471. }
  2472. static int GetNamedArgumentCount (ICustomAttribute attribute)
  2473. {
  2474. int count = 0;
  2475. if (attribute.HasFields)
  2476. count += attribute.Fields.Count;
  2477. if (attribute.HasProperties)
  2478. count += attribute.Properties.Count;
  2479. return count;
  2480. }
  2481. void WriteICustomAttributeNamedArguments (ICustomAttribute attribute)
  2482. {
  2483. if (attribute.HasFields)
  2484. WriteCustomAttributeNamedArguments (0x53, attribute.Fields);
  2485. if (attribute.HasProperties)
  2486. WriteCustomAttributeNamedArguments (0x54, attribute.Properties);
  2487. }
  2488. void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments)
  2489. {
  2490. for (int i = 0; i < named_arguments.Count; i++)
  2491. WriteCustomAttributeNamedArgument (kind, named_arguments [i]);
  2492. }
  2493. void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument)
  2494. {
  2495. var argument = named_argument.Argument;
  2496. WriteByte (kind);
  2497. WriteCustomAttributeFieldOrPropType (argument.Type);
  2498. WriteUTF8String (named_argument.Name);
  2499. WriteCustomAttributeFixedArgument (argument.Type, argument);
  2500. }
  2501. void WriteSecurityAttribute (SecurityAttribute attribute)
  2502. {
  2503. WriteTypeReference (attribute.AttributeType);
  2504. var count = GetNamedArgumentCount (attribute);
  2505. if (count == 0) {
  2506. WriteCompressedUInt32 (1); // length
  2507. WriteCompressedUInt32 (0); // count
  2508. return;
  2509. }
  2510. var buffer = new SignatureWriter (metadata);
  2511. buffer.WriteCompressedUInt32 ((uint) count);
  2512. buffer.WriteICustomAttributeNamedArguments (attribute);
  2513. WriteCompressedUInt32 ((uint) buffer.length);
  2514. WriteBytes (buffer);
  2515. }
  2516. public void WriteSecurityDeclaration (SecurityDeclaration declaration)
  2517. {
  2518. WriteByte ((byte) '.');
  2519. var attributes = declaration.security_attributes;
  2520. if (attributes == null)
  2521. throw new NotSupportedException ();
  2522. WriteCompressedUInt32 ((uint) attributes.Count);
  2523. for (int i = 0; i < attributes.Count; i++)
  2524. WriteSecurityAttribute (attributes [i]);
  2525. }
  2526. public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration)
  2527. {
  2528. var xml = GetXmlSecurityDeclaration (declaration);
  2529. if (xml == null)
  2530. throw new NotSupportedException ();
  2531. WriteBytes (Encoding.Unicode.GetBytes (xml));
  2532. }
  2533. static string GetXmlSecurityDeclaration (SecurityDeclaration declaration)
  2534. {
  2535. if (declaration.security_attributes == null || declaration.security_attributes.Count != 1)
  2536. return null;
  2537. var attribute = declaration.security_attributes [0];
  2538. if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute"))
  2539. return null;
  2540. if (attribute.properties == null || attribute.properties.Count != 1)
  2541. return null;
  2542. var property = attribute.properties [0];
  2543. if (property.Name != "XML")
  2544. return null;
  2545. return (string) property.Argument.Value;
  2546. }
  2547. void WriteTypeReference (TypeReference type)
  2548. {
  2549. WriteUTF8String (TypeParser.ToParseable (type, top_level: false));
  2550. }
  2551. public void WriteMarshalInfo (MarshalInfo marshal_info)
  2552. {
  2553. WriteNativeType (marshal_info.native);
  2554. switch (marshal_info.native) {
  2555. case NativeType.Array: {
  2556. var array = (ArrayMarshalInfo) marshal_info;
  2557. if (array.element_type != NativeType.None)
  2558. WriteNativeType (array.element_type);
  2559. if (array.size_parameter_index > -1)
  2560. WriteCompressedUInt32 ((uint) array.size_parameter_index);
  2561. if (array.size > -1)
  2562. WriteCompressedUInt32 ((uint) array.size);
  2563. if (array.size_parameter_multiplier > -1)
  2564. WriteCompressedUInt32 ((uint) array.size_parameter_multiplier);
  2565. return;
  2566. }
  2567. case NativeType.SafeArray: {
  2568. var array = (SafeArrayMarshalInfo) marshal_info;
  2569. if (array.element_type != VariantType.None)
  2570. WriteVariantType (array.element_type);
  2571. return;
  2572. }
  2573. case NativeType.FixedArray: {
  2574. var array = (FixedArrayMarshalInfo) marshal_info;
  2575. if (array.size > -1)
  2576. WriteCompressedUInt32 ((uint) array.size);
  2577. if (array.element_type != NativeType.None)
  2578. WriteNativeType (array.element_type);
  2579. return;
  2580. }
  2581. case NativeType.FixedSysString:
  2582. var sys_string = (FixedSysStringMarshalInfo) marshal_info;
  2583. if (sys_string.size > -1)
  2584. WriteCompressedUInt32 ((uint) sys_string.size);
  2585. return;
  2586. case NativeType.CustomMarshaler:
  2587. var marshaler = (CustomMarshalInfo) marshal_info;
  2588. WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty);
  2589. WriteUTF8String (marshaler.unmanaged_type);
  2590. WriteTypeReference (marshaler.managed_type);
  2591. WriteUTF8String (marshaler.cookie);
  2592. return;
  2593. }
  2594. }
  2595. void WriteNativeType (NativeType native)
  2596. {
  2597. WriteByte ((byte) native);
  2598. }
  2599. void WriteVariantType (VariantType variant)
  2600. {
  2601. WriteByte ((byte) variant);
  2602. }
  2603. public void WriteSequencePoints (MethodDebugInformation info)
  2604. {
  2605. var start_line = -1;
  2606. var start_column = -1;
  2607. WriteCompressedUInt32 (info.local_var_token.RID);
  2608. Document previous_document;
  2609. if (!info.TryGetUniqueDocument (out previous_document))
  2610. previous_document = null;
  2611. for (int i = 0; i < info.SequencePoints.Count; i++) {
  2612. var sequence_point = info.SequencePoints [i];
  2613. var document = sequence_point.Document;
  2614. if (previous_document != document) {
  2615. var document_token = metadata.GetDocumentToken (document);
  2616. if (previous_document != null)
  2617. WriteCompressedUInt32 (0);
  2618. WriteCompressedUInt32 (document_token.RID);
  2619. previous_document = document;
  2620. }
  2621. if (i > 0)
  2622. WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset));
  2623. else
  2624. WriteCompressedUInt32 ((uint) sequence_point.Offset);
  2625. if (sequence_point.IsHidden) {
  2626. WriteInt16 (0);
  2627. continue;
  2628. }
  2629. var delta_lines = sequence_point.EndLine - sequence_point.StartLine;
  2630. var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn;
  2631. WriteCompressedUInt32 ((uint) delta_lines);
  2632. if (delta_lines == 0)
  2633. WriteCompressedUInt32((uint) delta_columns);
  2634. else
  2635. WriteCompressedInt32 (delta_columns);
  2636. if (start_line < 0) {
  2637. WriteCompressedUInt32 ((uint) sequence_point.StartLine);
  2638. WriteCompressedUInt32 ((uint) sequence_point.StartColumn);
  2639. } else {
  2640. WriteCompressedInt32 (sequence_point.StartLine - start_line);
  2641. WriteCompressedInt32 (sequence_point.StartColumn - start_column);
  2642. }
  2643. start_line = sequence_point.StartLine;
  2644. start_column = sequence_point.StartColumn;
  2645. }
  2646. }
  2647. }
  2648. #endif
  2649. static partial class Mixin {
  2650. public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document)
  2651. {
  2652. document = info.SequencePoints [0].Document;
  2653. for (int i = 1; i < info.SequencePoints.Count; i++) {
  2654. var sequence_point = info.SequencePoints [i];
  2655. if (sequence_point.Document != document)
  2656. return false;
  2657. }
  2658. return true;
  2659. }
  2660. }
  2661. }