5 // Jb Evain (jbevain@gmail.com)
7 // (C) 2005 - 2007 Jb Evain
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 namespace Mono.Cecil {
32 using System.Collections;
33 using System.Globalization;
36 using Mono.Cecil.Binary;
38 using Mono.Cecil.Metadata;
39 using Mono.Cecil.Signatures;
41 internal sealed class ReflectionWriter : BaseReflectionVisitor {
43 StructureWriter m_structureWriter;
44 ModuleDefinition m_mod;
45 SignatureWriter m_sigWriter;
46 CodeWriter m_codeWriter;
47 MetadataWriter m_mdWriter;
48 MetadataTableWriter m_tableWriter;
49 MetadataRowWriter m_rowWriter;
53 ISymbolWriter m_symbolWriter;
55 ArrayList m_typeDefStack;
56 ArrayList m_methodStack;
57 ArrayList m_fieldStack;
58 ArrayList m_genericParamStack;
59 IDictionary m_typeSpecCache;
67 MemoryBinaryWriter m_constWriter;
69 public StructureWriter StructureWriter {
70 get { return m_structureWriter; }
72 m_structureWriter = value;
78 public CodeWriter CodeWriter {
79 get { return m_codeWriter; }
82 public bool SaveSymbols {
83 get { return m_saveSymbols; }
84 set { m_saveSymbols = value; }
87 public string OutputFile
89 get { return m_asmOutput; }
90 set { m_asmOutput = value; }
93 public ISymbolWriter SymbolWriter {
94 get { return m_symbolWriter; }
95 set { m_symbolWriter = value; }
98 public SignatureWriter SignatureWriter {
99 get { return m_sigWriter; }
102 public MetadataWriter MetadataWriter {
103 get { return m_mdWriter; }
106 public MetadataTableWriter MetadataTableWriter {
107 get { return m_tableWriter; }
110 public MetadataRowWriter MetadataRowWriter {
111 get { return m_rowWriter; }
114 public ReflectionWriter (ModuleDefinition mod)
121 m_mdWriter = new MetadataWriter (
123 m_mod.Image.MetadataRoot,
124 m_structureWriter.Assembly.Kind,
125 m_mod.Assembly.Runtime,
126 m_structureWriter.GetWriter ());
127 m_tableWriter = m_mdWriter.GetTableVisitor ();
128 m_rowWriter = m_tableWriter.GetRowVisitor () as MetadataRowWriter;
129 m_sigWriter = new SignatureWriter (m_mdWriter);
130 m_codeWriter = new CodeWriter (this, m_mdWriter.CilWriter);
132 m_typeDefStack = new ArrayList ();
133 m_methodStack = new ArrayList ();
134 m_fieldStack = new ArrayList ();
135 m_genericParamStack = new ArrayList ();
136 m_typeSpecCache = new Hashtable ();
144 m_constWriter = new MemoryBinaryWriter ();
147 public TypeReference GetCoreType (string name)
149 return m_mod.Controller.Reader.SearchCoreType (name);
152 public static uint GetRidFor (IMetadataTokenProvider tp)
154 return tp.MetadataToken.RID;
157 public uint GetRidFor (AssemblyNameReference asmName)
159 return (uint) m_mod.AssemblyReferences.IndexOf (asmName) + 1;
162 public uint GetRidFor (ModuleDefinition mod)
164 return (uint) m_mod.Assembly.Modules.IndexOf (mod) + 1;
167 public uint GetRidFor (ModuleReference modRef)
169 return (uint) m_mod.ModuleReferences.IndexOf (modRef) + 1;
172 static bool IsTypeSpec (TypeReference type)
174 return type is TypeSpecification || type is GenericParameter;
177 public MetadataToken GetTypeDefOrRefToken (TypeReference type)
179 if (IsTypeSpec (type)) {
180 uint sig = m_sigWriter.AddTypeSpec (GetTypeSpecSig (type));
181 if (m_typeSpecCache.Contains (sig))
182 return ((TypeReference) m_typeSpecCache [sig]).MetadataToken;
184 TypeSpecTable tsTable = m_tableWriter.GetTypeSpecTable ();
185 TypeSpecRow tsRow = m_rowWriter.CreateTypeSpecRow (sig);
186 tsTable.Rows.Add (tsRow);
187 type.MetadataToken = new MetadataToken (TokenType.TypeSpec, (uint) tsTable.Rows.Count);
188 m_typeSpecCache [sig] = type;
189 return type.MetadataToken;
190 } else if (type != null)
191 return type.MetadataToken;
192 else // <Module> and interfaces
193 return new MetadataToken (TokenType.TypeRef, 0);
196 public MetadataToken GetMemberRefToken (MemberReference member)
198 return member.MetadataToken;
201 public MetadataToken GetMethodSpecToken (GenericInstanceMethod gim)
203 uint sig = m_sigWriter.AddMethodSpec (GetMethodSpecSig (gim));
204 MethodSpecTable msTable = m_tableWriter.GetMethodSpecTable ();
206 MetadataToken meth = GetMemberRefToken (gim.ElementMethod);
208 for (int i = 0; i < msTable.Rows.Count; i++) {
209 MethodSpecRow row = msTable [i];
210 if (row.Method == meth && row.Instantiation == sig)
211 return MetadataToken.FromMetadataRow (TokenType.MethodSpec, i);
214 MethodSpecRow msRow = m_rowWriter.CreateMethodSpecRow (
217 msTable.Rows.Add (msRow);
218 gim.MetadataToken = new MetadataToken (TokenType.MethodSpec, (uint) msTable.Rows.Count);
219 return gim.MetadataToken;
222 public override void VisitModuleDefinition (ModuleDefinition mod)
227 public override void VisitTypeDefinitionCollection (TypeDefinitionCollection types)
229 TypeDefTable tdTable = m_tableWriter.GetTypeDefTable ();
231 if (types [Constants.ModuleType] == null)
232 types.Add (new TypeDefinition (
233 Constants.ModuleType, string.Empty, TypeAttributes.NotPublic));
235 foreach (TypeDefinition t in types)
236 m_typeDefStack.Add (t);
238 m_typeDefStack.Sort (TableComparers.TypeDef.Instance);
240 for (int i = 0; i < m_typeDefStack.Count; i++) {
241 TypeDefinition t = (TypeDefinition) m_typeDefStack [i];
242 if (t.Module.Assembly != m_mod.Assembly)
243 throw new ReflectionException ("A type as not been correctly imported");
245 t.MetadataToken = new MetadataToken (TokenType.TypeDef, (uint) (i + 1));
248 foreach (TypeDefinition t in m_typeDefStack) {
249 TypeDefRow tdRow = m_rowWriter.CreateTypeDefRow (
251 m_mdWriter.AddString (t.Name),
252 m_mdWriter.AddString (t.Namespace),
253 GetTypeDefOrRefToken (t.BaseType),
257 tdTable.Rows.Add (tdRow);
261 public void CompleteTypeDefinitions ()
263 TypeDefTable tdTable = m_tableWriter.GetTypeDefTable ();
265 for (int i = 0; i < m_typeDefStack.Count; i++) {
266 TypeDefRow tdRow = tdTable [i];
267 TypeDefinition t = (TypeDefinition) m_typeDefStack [i];
268 tdRow.FieldList = m_fieldIndex;
269 tdRow.MethodList = m_methodIndex;
270 foreach (FieldDefinition field in t.Fields)
271 VisitFieldDefinition (field);
272 foreach (MethodDefinition ctor in t.Constructors)
273 VisitMethodDefinition (ctor);
274 foreach (MethodDefinition meth in t.Methods)
275 VisitMethodDefinition (meth);
281 foreach (FieldDefinition field in m_fieldStack) {
282 VisitCustomAttributeCollection (field.CustomAttributes);
283 if (field.MarshalSpec != null)
284 VisitMarshalSpec (field.MarshalSpec);
287 foreach (MethodDefinition meth in m_methodStack) {
288 VisitCustomAttributeCollection (meth.ReturnType.CustomAttributes);
289 foreach (ParameterDefinition param in meth.Parameters)
290 VisitCustomAttributeCollection (param.CustomAttributes);
291 VisitGenericParameterCollection (meth.GenericParameters);
292 VisitOverrideCollection (meth.Overrides);
293 VisitCustomAttributeCollection (meth.CustomAttributes);
294 VisitSecurityDeclarationCollection (meth.SecurityDeclarations);
295 if (meth.PInvokeInfo != null) {
296 meth.Attributes |= MethodAttributes.PInvokeImpl;
297 VisitPInvokeInfo (meth.PInvokeInfo);
301 foreach (TypeDefinition t in m_typeDefStack)
305 public override void VisitTypeReferenceCollection (TypeReferenceCollection refs)
307 ArrayList orderedTypeRefs = new ArrayList (refs.Count);
308 foreach (TypeReference tr in refs)
309 orderedTypeRefs.Add (tr);
311 orderedTypeRefs.Sort (TableComparers.TypeRef.Instance);
313 TypeRefTable trTable = m_tableWriter.GetTypeRefTable ();
314 foreach (TypeReference t in orderedTypeRefs) {
317 if (t.Module.Assembly != m_mod.Assembly)
318 throw new ReflectionException ("A type as not been correctly imported");
323 if (t.DeclaringType != null)
324 scope = new MetadataToken (TokenType.TypeRef, GetRidFor (t.DeclaringType));
325 else if (t.Scope is AssemblyNameReference)
326 scope = new MetadataToken (TokenType.AssemblyRef,
327 GetRidFor ((AssemblyNameReference) t.Scope));
328 else if (t.Scope is ModuleDefinition)
329 scope = new MetadataToken (TokenType.Module,
330 GetRidFor ((ModuleDefinition) t.Scope));
331 else if (t.Scope is ModuleReference)
332 scope = new MetadataToken (TokenType.ModuleRef,
333 GetRidFor ((ModuleReference) t.Scope));
335 scope = new MetadataToken (TokenType.ExportedType, 0);
337 TypeRefRow trRow = m_rowWriter.CreateTypeRefRow (
339 m_mdWriter.AddString (t.Name),
340 m_mdWriter.AddString (t.Namespace));
342 trTable.Rows.Add (trRow);
343 t.MetadataToken = new MetadataToken (TokenType.TypeRef, (uint) trTable.Rows.Count);
347 public override void VisitMemberReferenceCollection (MemberReferenceCollection members)
349 if (members.Count == 0)
352 MemberRefTable mrTable = m_tableWriter.GetMemberRefTable ();
353 foreach (MemberReference member in members) {
355 if (member is FieldReference)
356 sig = m_sigWriter.AddFieldSig (GetFieldSig (member as FieldReference));
357 else if (member is MethodReference)
358 sig = m_sigWriter.AddMethodRefSig (GetMethodRefSig ((MethodReference) member));
360 MemberRefRow mrRow = m_rowWriter.CreateMemberRefRow (
361 GetTypeDefOrRefToken (member.DeclaringType),
362 m_mdWriter.AddString (member.Name),
365 mrTable.Rows.Add (mrRow);
366 member.MetadataToken = new MetadataToken (
367 TokenType.MemberRef, (uint) mrTable.Rows.Count);
371 public override void VisitGenericParameterCollection (GenericParameterCollection parameters)
373 if (parameters.Count == 0)
376 foreach (GenericParameter gp in parameters)
377 m_genericParamStack.Add (gp);
380 public override void VisitInterfaceCollection (InterfaceCollection interfaces)
382 if (interfaces.Count == 0)
385 InterfaceImplTable iiTable = m_tableWriter.GetInterfaceImplTable ();
386 foreach (TypeReference interf in interfaces) {
387 InterfaceImplRow iiRow = m_rowWriter.CreateInterfaceImplRow (
388 GetRidFor (interfaces.Container),
389 GetTypeDefOrRefToken (interf));
391 iiTable.Rows.Add (iiRow);
395 public override void VisitExternTypeCollection (ExternTypeCollection externs)
397 VisitCollection (externs);
400 public override void VisitExternType (TypeReference externType)
405 public override void VisitOverrideCollection (OverrideCollection meths)
407 if (meths.Count == 0)
410 MethodImplTable miTable = m_tableWriter.GetMethodImplTable ();
411 foreach (MethodReference ov in meths) {
412 MethodImplRow miRow = m_rowWriter.CreateMethodImplRow (
413 GetRidFor (meths.Container.DeclaringType as TypeDefinition),
414 new MetadataToken (TokenType.Method, GetRidFor (meths.Container)),
415 GetMemberRefToken (ov));
417 miTable.Rows.Add (miRow);
421 public override void VisitNestedTypeCollection (NestedTypeCollection nestedTypes)
423 if (nestedTypes.Count == 0)
426 NestedClassTable ncTable = m_tableWriter.GetNestedClassTable ();
427 foreach (TypeDefinition nested in nestedTypes) {
428 NestedClassRow ncRow = m_rowWriter.CreateNestedClassRow (
429 nested.MetadataToken.RID,
430 GetRidFor (nestedTypes.Container));
432 ncTable.Rows.Add (ncRow);
436 public override void VisitParameterDefinitionCollection (ParameterDefinitionCollection parameters)
438 if (parameters.Count == 0)
442 ParamTable pTable = m_tableWriter.GetParamTable ();
443 foreach (ParameterDefinition param in parameters)
444 InsertParameter (pTable, param, seq++);
447 void InsertParameter (ParamTable pTable, ParameterDefinition param, ushort seq)
449 ParamRow pRow = m_rowWriter.CreateParamRow (
452 m_mdWriter.AddString (param.Name));
454 pTable.Rows.Add (pRow);
455 param.MetadataToken = new MetadataToken (TokenType.Param, (uint) pTable.Rows.Count);
457 if (param.MarshalSpec != null)
458 param.MarshalSpec.Accept (this);
460 if (param.HasConstant)
461 WriteConstant (param, param.ParameterType);
466 static bool RequiresParameterRow (MethodReturnType mrt)
468 return mrt.HasConstant || mrt.MarshalSpec != null ||
469 mrt.CustomAttributes.Count > 0 || mrt.Parameter.Attributes != (ParameterAttributes) 0;
472 public override void VisitMethodDefinition (MethodDefinition method)
474 MethodTable mTable = m_tableWriter.GetMethodTable ();
475 MethodRow mRow = m_rowWriter.CreateMethodRow (
477 method.ImplAttributes,
479 m_mdWriter.AddString (method.Name),
480 m_sigWriter.AddMethodDefSig (GetMethodDefSig (method)),
483 mTable.Rows.Add (mRow);
484 m_methodStack.Add (method);
485 method.MetadataToken = new MetadataToken (TokenType.Method, (uint) mTable.Rows.Count);
488 if (RequiresParameterRow (method.ReturnType))
489 InsertParameter (m_tableWriter.GetParamTable (), method.ReturnType.Parameter, 0);
491 VisitParameterDefinitionCollection (method.Parameters);
494 public override void VisitPInvokeInfo (PInvokeInfo pinvk)
496 ImplMapTable imTable = m_tableWriter.GetImplMapTable ();
497 ImplMapRow imRow = m_rowWriter.CreateImplMapRow (
499 new MetadataToken (TokenType.Method, GetRidFor (pinvk.Method)),
500 m_mdWriter.AddString (pinvk.EntryPoint),
501 GetRidFor (pinvk.Module));
503 imTable.Rows.Add (imRow);
506 public override void VisitEventDefinitionCollection (EventDefinitionCollection events)
508 if (events.Count == 0)
511 EventMapTable emTable = m_tableWriter.GetEventMapTable ();
512 EventMapRow emRow = m_rowWriter.CreateEventMapRow (
513 GetRidFor (events.Container),
516 emTable.Rows.Add (emRow);
517 VisitCollection (events);
520 public override void VisitEventDefinition (EventDefinition evt)
522 EventTable eTable = m_tableWriter.GetEventTable ();
523 EventRow eRow = m_rowWriter.CreateEventRow (
525 m_mdWriter.AddString (evt.Name),
526 GetTypeDefOrRefToken (evt.EventType));
528 eTable.Rows.Add (eRow);
529 evt.MetadataToken = new MetadataToken (TokenType.Event, (uint) eTable.Rows.Count);
531 if (evt.AddMethod != null)
532 WriteSemantic (MethodSemanticsAttributes.AddOn, evt, evt.AddMethod);
534 if (evt.InvokeMethod != null)
535 WriteSemantic (MethodSemanticsAttributes.Fire, evt, evt.InvokeMethod);
537 if (evt.RemoveMethod != null)
538 WriteSemantic (MethodSemanticsAttributes.RemoveOn, evt, evt.RemoveMethod);
543 public override void VisitFieldDefinition (FieldDefinition field)
545 FieldTable fTable = m_tableWriter.GetFieldTable ();
546 FieldRow fRow = m_rowWriter.CreateFieldRow (
548 m_mdWriter.AddString (field.Name),
549 m_sigWriter.AddFieldSig (GetFieldSig (field)));
551 fTable.Rows.Add (fRow);
552 field.MetadataToken = new MetadataToken (TokenType.Field, (uint) fTable.Rows.Count);
555 if (field.HasConstant)
556 WriteConstant (field, field.FieldType);
558 if (field.HasLayoutInfo)
561 m_fieldStack.Add (field);
564 public override void VisitPropertyDefinitionCollection (PropertyDefinitionCollection properties)
566 if (properties.Count == 0)
569 PropertyMapTable pmTable = m_tableWriter.GetPropertyMapTable ();
570 PropertyMapRow pmRow = m_rowWriter.CreatePropertyMapRow (
571 GetRidFor (properties.Container),
574 pmTable.Rows.Add (pmRow);
575 VisitCollection (properties);
578 public override void VisitPropertyDefinition (PropertyDefinition property)
580 PropertyTable pTable = m_tableWriter.GetPropertyTable ();
581 PropertyRow pRow = m_rowWriter.CreatePropertyRow (
583 m_mdWriter.AddString (property.Name),
584 m_sigWriter.AddPropertySig (GetPropertySig (property)));
586 pTable.Rows.Add (pRow);
587 property.MetadataToken = new MetadataToken (TokenType.Property, (uint) pTable.Rows.Count);
589 if (property.GetMethod != null)
590 WriteSemantic (MethodSemanticsAttributes.Getter, property, property.GetMethod);
592 if (property.SetMethod != null)
593 WriteSemantic (MethodSemanticsAttributes.Setter, property, property.SetMethod);
595 if (property.HasConstant)
596 WriteConstant (property, property.PropertyType);
601 public override void VisitSecurityDeclarationCollection (SecurityDeclarationCollection secDecls)
603 if (secDecls.Count == 0)
606 DeclSecurityTable dsTable = m_tableWriter.GetDeclSecurityTable ();
607 foreach (SecurityDeclaration secDec in secDecls) {
608 DeclSecurityRow dsRow = m_rowWriter.CreateDeclSecurityRow (
610 secDecls.Container.MetadataToken,
611 m_mdWriter.AddBlob (secDec.Resolved ?
612 m_mod.GetAsByteArray (secDec) : secDec.Blob));
614 dsTable.Rows.Add (dsRow);
618 public override void VisitCustomAttributeCollection (CustomAttributeCollection customAttrs)
620 if (customAttrs.Count == 0)
623 CustomAttributeTable caTable = m_tableWriter.GetCustomAttributeTable ();
624 foreach (CustomAttribute ca in customAttrs) {
625 MetadataToken parent;
626 if (customAttrs.Container is AssemblyDefinition)
627 parent = new MetadataToken (TokenType.Assembly, 1);
628 else if (customAttrs.Container is ModuleDefinition)
629 parent = new MetadataToken (TokenType.Module, 1);
630 else if (customAttrs.Container is IMetadataTokenProvider)
631 parent = ((IMetadataTokenProvider) customAttrs.Container).MetadataToken;
633 throw new ReflectionException ("Unknown Custom Attribute parent");
635 uint value = ca.Resolved ?
636 m_sigWriter.AddCustomAttribute (GetCustomAttributeSig (ca), ca.Constructor) :
637 m_mdWriter.AddBlob (m_mod.GetAsByteArray (ca));
638 CustomAttributeRow caRow = m_rowWriter.CreateCustomAttributeRow (
640 GetMemberRefToken (ca.Constructor),
643 caTable.Rows.Add (caRow);
647 public override void VisitMarshalSpec (MarshalSpec marshalSpec)
649 FieldMarshalTable fmTable = m_tableWriter.GetFieldMarshalTable ();
650 FieldMarshalRow fmRow = m_rowWriter.CreateFieldMarshalRow (
651 marshalSpec.Container.MetadataToken,
652 m_sigWriter.AddMarshalSig (GetMarshalSig (marshalSpec)));
654 fmTable.Rows.Add (fmRow);
657 void WriteConstant (IHasConstant hc, TypeReference type)
659 ConstantTable cTable = m_tableWriter.GetConstantTable ();
661 if (type is TypeDefinition && (type as TypeDefinition).IsEnum) {
662 Type t = hc.Constant.GetType ();
664 t = Enum.GetUnderlyingType (t);
666 et = GetCorrespondingType (string.Concat (t.Namespace, '.', t.Name));
668 et = GetCorrespondingType (type.FullName);
670 if (et == ElementType.Object)
671 et = hc.Constant == null ?
673 GetCorrespondingType (hc.Constant.GetType ().FullName);
675 ConstantRow cRow = m_rowWriter.CreateConstantRow (
678 m_mdWriter.AddBlob (EncodeConstant (et, hc.Constant)));
680 cTable.Rows.Add (cRow);
683 void WriteLayout (FieldDefinition field)
685 FieldLayoutTable flTable = m_tableWriter.GetFieldLayoutTable ();
686 FieldLayoutRow flRow = m_rowWriter.CreateFieldLayoutRow (
690 flTable.Rows.Add (flRow);
693 void WriteLayout (TypeDefinition type)
695 ClassLayoutTable clTable = m_tableWriter.GetClassLayoutTable ();
696 ClassLayoutRow clRow = m_rowWriter.CreateClassLayoutRow (
701 clTable.Rows.Add (clRow);
704 void WriteSemantic (MethodSemanticsAttributes attrs,
705 IMetadataTokenProvider member, MethodDefinition meth)
707 MethodSemanticsTable msTable = m_tableWriter.GetMethodSemanticsTable ();
708 MethodSemanticsRow msRow = m_rowWriter.CreateMethodSemanticsRow (
711 member.MetadataToken);
713 msTable.Rows.Add (msRow);
718 TablesHeap th = m_mdWriter.GetMetadataRoot ().Streams.TablesHeap;
721 if (th.HasTable (NestedClassTable.RId))
722 m_tableWriter.GetNestedClassTable ().Rows.Sort (
723 TableComparers.NestedClass.Instance);
724 th.Sorted |= ((long) 1 << NestedClassTable.RId);
726 if (th.HasTable (InterfaceImplTable.RId))
727 m_tableWriter.GetInterfaceImplTable ().Rows.Sort (
728 TableComparers.InterfaceImpl.Instance);
729 th.Sorted |= ((long) 1 << InterfaceImplTable.RId);
731 if (th.HasTable (ConstantTable.RId))
732 m_tableWriter.GetConstantTable ().Rows.Sort (
733 TableComparers.Constant.Instance);
734 th.Sorted |= ((long) 1 << ConstantTable.RId);
736 if (th.HasTable (MethodSemanticsTable.RId))
737 m_tableWriter.GetMethodSemanticsTable ().Rows.Sort (
738 TableComparers.MethodSem.Instance);
739 th.Sorted |= ((long) 1 << MethodSemanticsTable.RId);
741 if (th.HasTable (FieldMarshalTable.RId))
742 m_tableWriter.GetFieldMarshalTable ().Rows.Sort (
743 TableComparers.FieldMarshal.Instance);
744 th.Sorted |= ((long) 1 << FieldMarshalTable.RId);
746 if (th.HasTable (ClassLayoutTable.RId))
747 m_tableWriter.GetClassLayoutTable ().Rows.Sort (
748 TableComparers.TypeLayout.Instance);
749 th.Sorted |= ((long) 1 << ClassLayoutTable.RId);
751 if (th.HasTable (FieldLayoutTable.RId))
752 m_tableWriter.GetFieldLayoutTable ().Rows.Sort (
753 TableComparers.FieldLayout.Instance);
754 th.Sorted |= ((long) 1 << FieldLayoutTable.RId);
756 if (th.HasTable (ImplMapTable.RId))
757 m_tableWriter.GetImplMapTable ().Rows.Sort (
758 TableComparers.PInvoke.Instance);
759 th.Sorted |= ((long) 1 << ImplMapTable.RId);
761 if (th.HasTable (FieldRVATable.RId))
762 m_tableWriter.GetFieldRVATable ().Rows.Sort (
763 TableComparers.FieldRVA.Instance);
764 th.Sorted |= ((long) 1 << FieldRVATable.RId);
766 if (th.HasTable (MethodImplTable.RId))
767 m_tableWriter.GetMethodImplTable ().Rows.Sort (
768 TableComparers.Override.Instance);
769 th.Sorted |= ((long) 1 << MethodImplTable.RId);
771 if (th.HasTable (CustomAttributeTable.RId))
772 m_tableWriter.GetCustomAttributeTable ().Rows.Sort (
773 TableComparers.CustomAttribute.Instance);
774 th.Sorted |= ((long) 1 << CustomAttributeTable.RId);
776 if (th.HasTable (DeclSecurityTable.RId))
777 m_tableWriter.GetDeclSecurityTable ().Rows.Sort (
778 TableComparers.SecurityDeclaration.Instance);
779 th.Sorted |= ((long) 1 << DeclSecurityTable.RId);
782 void CompleteGenericTables ()
784 if (m_genericParamStack.Count == 0)
787 TablesHeap th = m_mdWriter.GetMetadataRoot ().Streams.TablesHeap;
788 GenericParamTable gpTable = m_tableWriter.GetGenericParamTable ();
789 GenericParamConstraintTable gpcTable = m_tableWriter.GetGenericParamConstraintTable ();
791 m_genericParamStack.Sort (TableComparers.GenericParam.Instance);
793 foreach (GenericParameter gp in m_genericParamStack) {
794 GenericParamRow gpRow = m_rowWriter.CreateGenericParamRow (
795 (ushort) gp.Owner.GenericParameters.IndexOf (gp),
797 gp.Owner.MetadataToken,
798 m_mdWriter.AddString (gp.Name));
800 gpTable.Rows.Add (gpRow);
801 gp.MetadataToken = new MetadataToken (TokenType.GenericParam, (uint) gpTable.Rows.Count);
803 VisitCustomAttributeCollection (gp.CustomAttributes);
805 if (gp.Constraints.Count == 0)
808 foreach (TypeReference constraint in gp.Constraints) {
809 GenericParamConstraintRow gpcRow = m_rowWriter.CreateGenericParamConstraintRow (
810 (uint) gpTable.Rows.Count,
811 GetTypeDefOrRefToken (constraint));
813 gpcTable.Rows.Add (gpcRow);
817 th.Sorted |= ((long) 1 << GenericParamTable.RId);
818 th.Sorted |= ((long) 1 << GenericParamConstraintTable.RId);
821 public override void TerminateModuleDefinition (ModuleDefinition module)
823 VisitCustomAttributeCollection (module.Assembly.CustomAttributes);
824 VisitSecurityDeclarationCollection (module.Assembly.SecurityDeclarations);
825 VisitCustomAttributeCollection (module.CustomAttributes);
827 CompleteGenericTables ();
830 MethodTable mTable = m_tableWriter.GetMethodTable ();
831 for (int i = 0; i < m_methodStack.Count; i++) {
832 MethodDefinition meth = (MethodDefinition) m_methodStack [i];
834 mTable [i].RVA = m_codeWriter.WriteMethodBody (meth);
837 if (m_fieldStack.Count > 0) {
838 FieldRVATable frTable = null;
839 foreach (FieldDefinition field in m_fieldStack) {
840 if (field.InitialValue != null && field.InitialValue.Length > 0) {
842 frTable = m_tableWriter.GetFieldRVATable ();
844 FieldRVARow frRow = m_rowWriter.CreateFieldRVARow (
845 m_mdWriter.GetDataCursor (),
846 field.MetadataToken.RID);
848 m_mdWriter.AddData (field.InitialValue.Length + 3 & (~3));
849 m_mdWriter.AddFieldInitData (field.InitialValue);
851 frTable.Rows.Add (frRow);
856 if (m_symbolWriter != null)
857 m_symbolWriter.Dispose ();
859 if (m_mod.Assembly.EntryPoint != null)
860 m_mdWriter.EntryPointToken =
861 ((uint) TokenType.Method) | GetRidFor (m_mod.Assembly.EntryPoint);
863 m_mod.Image.MetadataRoot.Accept (m_mdWriter);
866 public static ElementType GetCorrespondingType (string fullName)
869 case Constants.Boolean :
870 return ElementType.Boolean;
871 case Constants.Char :
872 return ElementType.Char;
873 case Constants.SByte :
874 return ElementType.I1;
875 case Constants.Int16 :
876 return ElementType.I2;
877 case Constants.Int32 :
878 return ElementType.I4;
879 case Constants.Int64 :
880 return ElementType.I8;
881 case Constants.Byte :
882 return ElementType.U1;
883 case Constants.UInt16 :
884 return ElementType.U2;
885 case Constants.UInt32 :
886 return ElementType.U4;
887 case Constants.UInt64 :
888 return ElementType.U8;
889 case Constants.Single :
890 return ElementType.R4;
891 case Constants.Double :
892 return ElementType.R8;
893 case Constants.String :
894 return ElementType.String;
895 case Constants.Type :
896 return ElementType.Type;
897 case Constants.Object :
898 return ElementType.Object;
900 return ElementType.Class;
904 byte [] EncodeConstant (ElementType et, object value)
906 m_constWriter.Empty ();
909 et = ElementType.Class;
911 IConvertible ic = value as IConvertible;
912 IFormatProvider fp = CultureInfo.CurrentCulture.NumberFormat;
915 case ElementType.Boolean :
916 m_constWriter.Write ((byte) (ic.ToBoolean (fp) ? 1 : 0));
918 case ElementType.Char :
919 m_constWriter.Write ((ushort) ic.ToChar (fp));
921 case ElementType.I1 :
922 m_constWriter.Write (ic.ToSByte (fp));
924 case ElementType.I2 :
925 m_constWriter.Write (ic.ToInt16 (fp));
927 case ElementType.I4 :
928 m_constWriter.Write (ic.ToInt32 (fp));
930 case ElementType.I8 :
931 m_constWriter.Write (ic.ToInt64 (fp));
933 case ElementType.U1 :
934 m_constWriter.Write (ic.ToByte (fp));
936 case ElementType.U2 :
937 m_constWriter.Write (ic.ToUInt16 (fp));
939 case ElementType.U4 :
940 m_constWriter.Write (ic.ToUInt32 (fp));
942 case ElementType.U8 :
943 m_constWriter.Write (ic.ToUInt64 (fp));
945 case ElementType.R4 :
946 m_constWriter.Write (ic.ToSingle (fp));
948 case ElementType.R8 :
949 m_constWriter.Write (ic.ToDouble (fp));
951 case ElementType.String :
952 m_constWriter.Write (Encoding.Unicode.GetBytes ((string) value));
954 case ElementType.Class :
955 m_constWriter.Write (new byte [4]);
958 throw new ArgumentException ("Non valid element for a constant");
961 return m_constWriter.ToArray ();
964 public SigType GetSigType (TypeReference type)
966 string name = type.FullName;
969 case Constants.Void :
970 return new SigType (ElementType.Void);
971 case Constants.Object :
972 return new SigType (ElementType.Object);
973 case Constants.Boolean :
974 return new SigType (ElementType.Boolean);
975 case Constants.String :
976 return new SigType (ElementType.String);
977 case Constants.Char :
978 return new SigType (ElementType.Char);
979 case Constants.SByte :
980 return new SigType (ElementType.I1);
981 case Constants.Byte :
982 return new SigType (ElementType.U1);
983 case Constants.Int16 :
984 return new SigType (ElementType.I2);
985 case Constants.UInt16 :
986 return new SigType (ElementType.U2);
987 case Constants.Int32 :
988 return new SigType (ElementType.I4);
989 case Constants.UInt32 :
990 return new SigType (ElementType.U4);
991 case Constants.Int64 :
992 return new SigType (ElementType.I8);
993 case Constants.UInt64 :
994 return new SigType (ElementType.U8);
995 case Constants.Single :
996 return new SigType (ElementType.R4);
997 case Constants.Double :
998 return new SigType (ElementType.R8);
999 case Constants.IntPtr :
1000 return new SigType (ElementType.I);
1001 case Constants.UIntPtr :
1002 return new SigType (ElementType.U);
1003 case Constants.TypedReference :
1004 return new SigType (ElementType.TypedByRef);
1007 if (type is GenericParameter) {
1008 GenericParameter gp = type as GenericParameter;
1009 int pos = gp.Owner.GenericParameters.IndexOf (gp);
1010 if (gp.Owner is TypeReference)
1011 return new VAR (pos);
1012 else if (gp.Owner is MethodReference)
1013 return new MVAR (pos);
1015 throw new ReflectionException ("Unkown generic parameter type");
1016 } else if (type is GenericInstanceType) {
1017 GenericInstanceType git = type as GenericInstanceType;
1018 GENERICINST gi = new GENERICINST ();
1019 gi.ValueType = git.IsValueType;
1020 gi.Type = GetTypeDefOrRefToken (git.ElementType);
1021 gi.Signature = new GenericInstSignature ();
1022 gi.Signature.Arity = git.GenericArguments.Count;
1023 gi.Signature.Types = new GenericArg [gi.Signature.Arity];
1024 for (int i = 0; i < git.GenericArguments.Count; i++)
1025 gi.Signature.Types [i] = GetGenericArgSig (git.GenericArguments [i]);
1028 } else if (type is ArrayType) {
1029 ArrayType aryType = type as ArrayType;
1030 if (aryType.IsSizedArray) {
1031 SZARRAY szary = new SZARRAY ();
1032 szary.CustomMods = GetCustomMods (aryType.ElementType);
1033 szary.Type = GetSigType (aryType.ElementType);
1038 ArrayShape shape = new ArrayShape ();
1039 shape.Rank = aryType.Dimensions.Count;
1042 for (int i = 0; i < shape.Rank; i++) {
1043 ArrayDimension dim = aryType.Dimensions [i];
1044 if (dim.UpperBound > 0)
1048 shape.Sizes = new int [shape.NumSizes];
1049 shape.NumLoBounds = shape.Rank;
1050 shape.LoBounds = new int [shape.NumLoBounds];
1052 for (int i = 0; i < shape.Rank; i++) {
1053 ArrayDimension dim = aryType.Dimensions [i];
1054 shape.LoBounds [i] = dim.LowerBound;
1055 if (dim.UpperBound > 0)
1056 shape.Sizes [i] = dim.UpperBound - dim.LowerBound + 1;
1059 ARRAY ary = new ARRAY ();
1061 ary.CustomMods = GetCustomMods (aryType.ElementType);
1062 ary.Type = GetSigType (aryType.ElementType);
1064 } else if (type is PointerType) {
1066 TypeReference elementType = (type as PointerType).ElementType;
1067 p.Void = elementType.FullName == Constants.Void;
1069 p.CustomMods = GetCustomMods (elementType);
1070 p.PtrType = GetSigType (elementType);
1073 } else if (type is FunctionPointerType) {
1074 FNPTR fp = new FNPTR ();
1075 FunctionPointerType fptr = type as FunctionPointerType;
1077 int sentinel = fptr.GetSentinel ();
1079 fp.Method = GetMethodDefSig (fptr);
1081 fp.Method = GetMethodRefSig (fptr);
1084 } else if (type is TypeSpecification) {
1085 return GetSigType ((type as TypeSpecification).ElementType);
1086 } else if (type.IsValueType) {
1087 VALUETYPE vt = new VALUETYPE ();
1088 vt.Type = GetTypeDefOrRefToken (type);
1091 CLASS c = new CLASS ();
1092 c.Type = GetTypeDefOrRefToken (type);
1097 public GenericArg GetGenericArgSig (TypeReference type)
1099 GenericArg arg = new GenericArg (GetSigType (type));
1100 arg.CustomMods = GetCustomMods (type);
1104 public CustomMod [] GetCustomMods (TypeReference type)
1106 if (!(type is ModType))
1107 return new CustomMod [0];
1109 ArrayList cmods = new ArrayList ();
1110 TypeReference cur = type;
1111 while (cur is ModType) {
1112 if (cur is ModifierOptional) {
1113 CustomMod cmod = new CustomMod ();
1114 cmod.CMOD = CustomMod.CMODType.OPT;
1115 cmod.TypeDefOrRef = GetTypeDefOrRefToken ((cur as ModifierOptional).ModifierType);
1117 } else if (cur is ModifierRequired) {
1118 CustomMod cmod = new CustomMod ();
1119 cmod.CMOD = CustomMod.CMODType.REQD;
1120 cmod.TypeDefOrRef = GetTypeDefOrRefToken ((cur as ModifierRequired).ModifierType);
1124 cur = (cur as ModType).ElementType;
1127 return cmods.ToArray (typeof (CustomMod)) as CustomMod [];
1130 public Signature GetMemberRefSig (MemberReference member)
1132 if (member is FieldReference)
1133 return GetFieldSig (member as FieldReference);
1135 return GetMemberRefSig (member as MethodReference);
1138 public FieldSig GetFieldSig (FieldReference field)
1140 FieldSig sig = new FieldSig ();
1141 sig.CallingConvention |= 0x6;
1143 sig.CustomMods = GetCustomMods (field.FieldType);
1144 sig.Type = GetSigType (field.FieldType);
1148 Param [] GetParametersSig (ParameterDefinitionCollection parameters)
1150 Param [] ret = new Param [parameters.Count];
1151 for (int i = 0; i < ret.Length; i++) {
1152 ParameterDefinition pDef = parameters [i];
1153 Param p = new Param ();
1154 p.CustomMods = GetCustomMods (pDef.ParameterType);
1155 if (pDef.ParameterType.FullName == Constants.TypedReference)
1156 p.TypedByRef = true;
1157 else if (IsByReferenceType (pDef.ParameterType)) {
1159 p.Type = GetSigType (pDef.ParameterType);
1161 p.Type = GetSigType (pDef.ParameterType);
1167 void CompleteMethodSig (IMethodSignature meth, MethodSig sig)
1169 sig.HasThis = meth.HasThis;
1170 sig.ExplicitThis = meth.ExplicitThis;
1172 sig.CallingConvention |= 0x20;
1173 if (sig.ExplicitThis)
1174 sig.CallingConvention |= 0x40;
1176 if ((meth.CallingConvention & MethodCallingConvention.VarArg) != 0)
1177 sig.CallingConvention |= 0x5;
1179 sig.ParamCount = meth.Parameters.Count;
1180 sig.Parameters = GetParametersSig (meth.Parameters);
1182 RetType rtSig = new RetType ();
1183 rtSig.CustomMods = GetCustomMods (meth.ReturnType.ReturnType);
1185 if (meth.ReturnType.ReturnType.FullName == Constants.Void)
1187 else if (meth.ReturnType.ReturnType.FullName == Constants.TypedReference)
1188 rtSig.TypedByRef = true;
1189 else if (IsByReferenceType (meth.ReturnType.ReturnType)) {
1191 rtSig.Type = GetSigType (meth.ReturnType.ReturnType);
1193 rtSig.Type = GetSigType (meth.ReturnType.ReturnType);
1195 sig.RetType = rtSig;
1198 static bool IsByReferenceType (TypeReference type)
1200 TypeSpecification ts = type as TypeSpecification;
1201 while (ts != null) {
1202 if (ts is ReferenceType)
1204 ts = ts.ElementType as TypeSpecification;
1209 public MethodRefSig GetMethodRefSig (IMethodSignature meth)
1211 MethodReference methodRef = meth as MethodReference;
1212 if (methodRef != null && methodRef.GenericParameters.Count > 0)
1213 return GetMethodDefSig (meth);
1215 MethodRefSig methSig = new MethodRefSig ();
1217 CompleteMethodSig (meth, methSig);
1219 int sentinel = meth.GetSentinel ();
1221 methSig.Sentinel = sentinel;
1223 if ((meth.CallingConvention & MethodCallingConvention.C) != 0)
1224 methSig.CallingConvention |= 0x1;
1225 else if ((meth.CallingConvention & MethodCallingConvention.StdCall) != 0)
1226 methSig.CallingConvention |= 0x2;
1227 else if ((meth.CallingConvention & MethodCallingConvention.ThisCall) != 0)
1228 methSig.CallingConvention |= 0x3;
1229 else if ((meth.CallingConvention & MethodCallingConvention.FastCall) != 0)
1230 methSig.CallingConvention |= 0x4;
1235 public MethodDefSig GetMethodDefSig (IMethodSignature meth)
1237 MethodDefSig sig = new MethodDefSig ();
1239 CompleteMethodSig (meth, sig);
1241 MethodReference methodRef = meth as MethodReference;
1242 if (methodRef != null && methodRef.GenericParameters.Count > 0) {
1243 sig.CallingConvention |= 0x10;
1244 sig.GenericParameterCount = methodRef.GenericParameters.Count;
1250 public PropertySig GetPropertySig (PropertyDefinition prop)
1252 PropertySig ps = new PropertySig ();
1253 ps.CallingConvention |= 0x8;
1257 MethodCallingConvention mcc;
1258 ParameterDefinitionCollection parameters = prop.Parameters;
1260 MethodDefinition meth;
1261 if (prop.GetMethod != null)
1262 meth = prop.GetMethod;
1263 else if (prop.SetMethod != null)
1264 meth = prop.SetMethod;
1269 hasThis = meth.HasThis;
1270 explicitThis = meth.ExplicitThis;
1271 mcc = meth.CallingConvention;
1273 hasThis = explicitThis = false;
1274 mcc = MethodCallingConvention.Default;
1278 ps.CallingConvention |= 0x20;
1280 ps.CallingConvention |= 0x40;
1282 if ((mcc & MethodCallingConvention.VarArg) != 0)
1283 ps.CallingConvention |= 0x5;
1285 int paramCount = parameters != null ? parameters.Count : 0;
1287 ps.ParamCount = paramCount;
1288 ps.Parameters = GetParametersSig (parameters);
1289 ps.CustomMods = GetCustomMods (prop.PropertyType);
1290 ps.Type = GetSigType (prop.PropertyType);
1295 public TypeSpec GetTypeSpecSig (TypeReference type)
1297 TypeSpec ts = new TypeSpec (GetSigType (type));
1301 public MethodSpec GetMethodSpecSig (GenericInstanceMethod gim)
1303 GenericInstSignature gis = new GenericInstSignature ();
1304 gis.Arity = gim.GenericArguments.Count;
1305 gis.Types = new GenericArg [gis.Arity];
1306 for (int i = 0; i < gis.Arity; i++)
1307 gis.Types [i] = GetGenericArgSig (gim.GenericArguments [i]);
1309 return new MethodSpec (gis);
1312 static string GetObjectTypeName (object o)
1314 Type t = o.GetType ();
1315 return string.Concat (t.Namespace, ".", t.Name);
1318 static CustomAttrib.Elem CreateElem (TypeReference type, object value)
1320 CustomAttrib.Elem elem = new CustomAttrib.Elem ();
1322 elem.ElemType = type;
1323 elem.FieldOrPropType = GetCorrespondingType (type.FullName);
1325 if (elem.FieldOrPropType == ElementType.Class)
1326 throw new NotImplementedException ("Writing enums");
1328 switch (elem.FieldOrPropType) {
1329 case ElementType.Boolean :
1330 case ElementType.Char :
1331 case ElementType.R4 :
1332 case ElementType.R8 :
1333 case ElementType.I1 :
1334 case ElementType.I2 :
1335 case ElementType.I4 :
1336 case ElementType.I8 :
1337 case ElementType.U1 :
1338 case ElementType.U2 :
1339 case ElementType.U4 :
1340 case ElementType.U8 :
1343 case ElementType.String:
1346 case ElementType.Type:
1349 case ElementType.Object:
1350 elem.BoxedValueType = true;
1352 elem.FieldOrPropType = ElementType.String;
1354 elem.FieldOrPropType = GetCorrespondingType (
1355 GetObjectTypeName (value));
1362 static CustomAttrib.FixedArg CreateFixedArg (TypeReference type, object value)
1364 CustomAttrib.FixedArg fa = new CustomAttrib.FixedArg ();
1365 if (value is object []) {
1367 object [] values = value as object [];
1368 TypeReference obj = ((ArrayType) type).ElementType;
1369 fa.NumElem = (uint) values.Length;
1370 fa.Elems = new CustomAttrib.Elem [values.Length];
1371 for (int i = 0; i < values.Length; i++)
1372 fa.Elems [i] = CreateElem (obj, values [i]);
1374 fa.Elems = new CustomAttrib.Elem [1];
1375 fa.Elems [0] = CreateElem (type, value);
1381 static CustomAttrib.NamedArg CreateNamedArg (TypeReference type, string name,
1382 object value, bool field)
1384 CustomAttrib.NamedArg na = new CustomAttrib.NamedArg ();
1386 na.Property = !field;
1388 na.FieldOrPropName = name;
1389 na.FieldOrPropType = GetCorrespondingType (type.FullName);
1390 na.FixedArg = CreateFixedArg (type, value);
1395 public static CustomAttrib GetCustomAttributeSig (CustomAttribute ca)
1397 CustomAttrib cas = new CustomAttrib (ca.Constructor);
1398 cas.Prolog = CustomAttrib.StdProlog;
1400 cas.FixedArgs = new CustomAttrib.FixedArg [ca.Constructor.Parameters.Count];
1402 for (int i = 0; i < cas.FixedArgs.Length; i++)
1403 cas.FixedArgs [i] = CreateFixedArg (
1404 ca.Constructor.Parameters [i].ParameterType, ca.ConstructorParameters [i]);
1406 int nn = ca.Fields.Count + ca.Properties.Count;
1407 cas.NumNamed = (ushort) nn;
1408 cas.NamedArgs = new CustomAttrib.NamedArg [nn];
1410 if (cas.NamedArgs.Length > 0) {
1412 foreach (DictionaryEntry entry in ca.Fields) {
1413 string field = (string) entry.Key;
1414 cas.NamedArgs [curs++] = CreateNamedArg (
1415 ca.GetFieldType (field), field, entry.Value, true);
1418 foreach (DictionaryEntry entry in ca.Properties) {
1419 string property = (string) entry.Key;
1420 cas.NamedArgs [curs++] = CreateNamedArg (
1421 ca.GetPropertyType (property), property, entry.Value, false);
1428 static MarshalSig GetMarshalSig (MarshalSpec mSpec)
1430 MarshalSig ms = new MarshalSig (mSpec.NativeIntrinsic);
1432 if (mSpec is ArrayMarshalSpec) {
1433 ArrayMarshalSpec amd = mSpec as ArrayMarshalSpec;
1434 MarshalSig.Array ar = new MarshalSig.Array ();
1435 ar.ArrayElemType = amd.ElemType;
1436 ar.NumElem = amd.NumElem;
1437 ar.ParamNum = amd.ParamNum;
1438 ar.ElemMult = amd.ElemMult;
1440 } else if (mSpec is CustomMarshalerSpec) {
1441 CustomMarshalerSpec cmd = mSpec as CustomMarshalerSpec;
1442 MarshalSig.CustomMarshaler cm = new MarshalSig.CustomMarshaler ();
1443 cm.Guid = cmd.Guid.ToString ();
1444 cm.UnmanagedType = cmd.UnmanagedType;
1445 cm.ManagedType = cmd.ManagedType;
1446 cm.Cookie = cmd.Cookie;
1448 } else if (mSpec is FixedArraySpec) {
1449 FixedArraySpec fad = mSpec as FixedArraySpec;
1450 MarshalSig.FixedArray fa = new MarshalSig.FixedArray ();
1451 fa.ArrayElemType = fad.ElemType;
1452 fa.NumElem = fad.NumElem;
1454 } else if (mSpec is FixedSysStringSpec) {
1455 MarshalSig.FixedSysString fss = new MarshalSig.FixedSysString ();
1456 fss.Size = (mSpec as FixedSysStringSpec).Size;
1458 } else if (mSpec is SafeArraySpec) {
1459 MarshalSig.SafeArray sa = new MarshalSig.SafeArray ();
1460 sa.ArrayElemType = (mSpec as SafeArraySpec).ElemType;
1467 public void WriteSymbols (ModuleDefinition module)
1472 if (m_asmOutput == null)
1473 m_asmOutput = module.Assembly.Name.Name + "." + (module.Assembly.Kind == AssemblyKind.Dll ? "dll" : "exe");
1475 if (m_symbolWriter == null)
1476 m_symbolWriter = SymbolStoreHelper.GetWriter (module, m_asmOutput);
1478 foreach (TypeDefinition type in module.Types) {
1479 foreach (MethodDefinition method in type.Methods)
1480 WriteSymbols (method);
1481 foreach (MethodDefinition ctor in type.Constructors)
1482 WriteSymbols (ctor);
1485 m_symbolWriter.Dispose ();
1488 void WriteSymbols (MethodDefinition meth)
1493 m_symbolWriter.Write (meth.Body, GetVariablesSig (meth));
1496 byte [][] GetVariablesSig (MethodDefinition meth)
1498 VariableDefinitionCollection variables = meth.Body.Variables;
1499 byte [][] signatures = new byte [variables.Count][];
1500 for (int i = 0; i < variables.Count; i++) {
1501 signatures [i] = GetVariableSig (variables [i]);
1506 byte [] GetVariableSig (VariableDefinition var)
1508 return m_sigWriter.CompressLocalVar (m_codeWriter.GetLocalVariableSig (var));