~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/Mono.Cecil/Mono.Cecil/Mono.Cecil.Signatures/SignatureWriter.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// SignatureWriter.cs
3
 
//
4
 
// Author:
5
 
//   Jb Evain (jbevain@gmail.com)
6
 
//
7
 
// (C) 2005 - 2007 Jb Evain
8
 
//
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:
16
 
//
17
 
// The above copyright notice and this permission notice shall be
18
 
// included in all copies or substantial portions of the Software.
19
 
//
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.
27
 
//
28
 
 
29
 
namespace Mono.Cecil.Signatures {
30
 
 
31
 
        using System;
32
 
        using System.Text;
33
 
 
34
 
        using Mono.Cecil;
35
 
        using Mono.Cecil.Binary;
36
 
        using Mono.Cecil.Metadata;
37
 
 
38
 
        internal sealed class SignatureWriter : BaseSignatureVisitor {
39
 
 
40
 
                MetadataWriter m_mdWriter;
41
 
                MemoryBinaryWriter m_sigWriter;
42
 
 
43
 
                public SignatureWriter (MetadataWriter mdWriter)
44
 
                {
45
 
                        m_mdWriter = mdWriter;
46
 
                        m_sigWriter = new MemoryBinaryWriter ();
47
 
                }
48
 
 
49
 
                uint GetPointer ()
50
 
                {
51
 
                        return m_mdWriter.AddBlob (m_sigWriter.ToArray ());
52
 
                }
53
 
 
54
 
                public uint AddMethodDefSig (MethodDefSig methSig)
55
 
                {
56
 
                        return AddSignature (methSig);
57
 
                }
58
 
 
59
 
                public uint AddMethodRefSig (MethodRefSig methSig)
60
 
                {
61
 
                        return AddSignature (methSig);
62
 
                }
63
 
 
64
 
                public uint AddPropertySig (PropertySig ps)
65
 
                {
66
 
                        return AddSignature (ps);
67
 
                }
68
 
 
69
 
                public uint AddFieldSig (FieldSig fSig)
70
 
                {
71
 
                        return AddSignature (fSig);
72
 
                }
73
 
 
74
 
                public uint AddLocalVarSig (LocalVarSig lvs)
75
 
                {
76
 
                        return AddSignature (lvs);
77
 
                }
78
 
 
79
 
                uint AddSignature (Signature s)
80
 
                {
81
 
                        m_sigWriter.Empty ();
82
 
                        s.Accept (this);
83
 
                        return GetPointer ();
84
 
                }
85
 
 
86
 
                public uint AddTypeSpec (TypeSpec ts)
87
 
                {
88
 
                        m_sigWriter.Empty ();
89
 
                        Write (ts);
90
 
                        return GetPointer ();
91
 
                }
92
 
 
93
 
                public uint AddMethodSpec (MethodSpec ms)
94
 
                {
95
 
                        m_sigWriter.Empty ();
96
 
                        Write (ms);
97
 
                        return GetPointer ();
98
 
                }
99
 
 
100
 
                public uint AddMarshalSig (MarshalSig ms)
101
 
                {
102
 
                        m_sigWriter.Empty ();
103
 
                        Write (ms);
104
 
                        return GetPointer ();
105
 
                }
106
 
 
107
 
                public uint AddCustomAttribute (CustomAttrib ca, MethodReference ctor)
108
 
                {
109
 
                        CompressCustomAttribute (ca, ctor, m_sigWriter);
110
 
                        return GetPointer ();
111
 
                }
112
 
 
113
 
                public byte [] CompressCustomAttribute (CustomAttrib ca, MethodReference ctor)
114
 
                {
115
 
                        MemoryBinaryWriter writer = new MemoryBinaryWriter ();
116
 
                        CompressCustomAttribute (ca, ctor, writer);
117
 
                        return writer.ToArray ();
118
 
                }
119
 
 
120
 
                public byte [] CompressFieldSig (FieldSig field)
121
 
                {
122
 
                        m_sigWriter.Empty ();
123
 
                        VisitFieldSig (field);
124
 
                        return m_sigWriter.ToArray ();
125
 
                }
126
 
 
127
 
                public byte [] CompressLocalVar (LocalVarSig.LocalVariable var)
128
 
                {
129
 
                        m_sigWriter.Empty ();
130
 
                        Write (var);
131
 
                        return m_sigWriter.ToArray ();
132
 
                }
133
 
 
134
 
                void CompressCustomAttribute (CustomAttrib ca, MethodReference ctor, MemoryBinaryWriter writer)
135
 
                {
136
 
                        m_sigWriter.Empty ();
137
 
                        Write (ca, ctor, writer);
138
 
                }
139
 
 
140
 
                public override void VisitMethodDefSig (MethodDefSig methodDef)
141
 
                {
142
 
                        m_sigWriter.Write (methodDef.CallingConvention);
143
 
                        if (methodDef.GenericParameterCount > 0)
144
 
                                Write (methodDef.GenericParameterCount);
145
 
                        Write (methodDef.ParamCount);
146
 
                        Write (methodDef.RetType);
147
 
                        Write (methodDef.Parameters, methodDef.Sentinel);
148
 
                }
149
 
 
150
 
                public override void VisitMethodRefSig (MethodRefSig methodRef)
151
 
                {
152
 
                        m_sigWriter.Write (methodRef.CallingConvention);
153
 
                        Write (methodRef.ParamCount);
154
 
                        Write (methodRef.RetType);
155
 
                        Write (methodRef.Parameters, methodRef.Sentinel);
156
 
                }
157
 
 
158
 
                public override void VisitFieldSig (FieldSig field)
159
 
                {
160
 
                        m_sigWriter.Write (field.CallingConvention);
161
 
                        Write (field.CustomMods);
162
 
                        Write (field.Type);
163
 
                }
164
 
 
165
 
                public override void VisitPropertySig (PropertySig property)
166
 
                {
167
 
                        m_sigWriter.Write (property.CallingConvention);
168
 
                        Write (property.ParamCount);
169
 
                        Write (property.CustomMods);
170
 
                        Write (property.Type);
171
 
                        Write (property.Parameters);
172
 
                }
173
 
 
174
 
                public override void VisitLocalVarSig (LocalVarSig localvar)
175
 
                {
176
 
                        m_sigWriter.Write (localvar.CallingConvention);
177
 
                        Write (localvar.Count);
178
 
                        Write (localvar.LocalVariables);
179
 
                }
180
 
 
181
 
                void Write (LocalVarSig.LocalVariable [] vars)
182
 
                {
183
 
                        foreach (LocalVarSig.LocalVariable var in vars)
184
 
                                Write (var);
185
 
                }
186
 
 
187
 
                void Write (LocalVarSig.LocalVariable var)
188
 
                {
189
 
                        Write (var.CustomMods);
190
 
                        if ((var.Constraint & Constraint.Pinned) != 0)
191
 
                                Write (ElementType.Pinned);
192
 
                        if (var.ByRef)
193
 
                                Write (ElementType.ByRef);
194
 
                        Write (var.Type);
195
 
                }
196
 
 
197
 
                void Write (RetType retType)
198
 
                {
199
 
                        Write (retType.CustomMods);
200
 
                        if (retType.Void)
201
 
                                Write (ElementType.Void);
202
 
                        else if (retType.TypedByRef)
203
 
                                Write (ElementType.TypedByRef);
204
 
                        else if (retType.ByRef) {
205
 
                                Write (ElementType.ByRef);
206
 
                                Write (retType.Type);
207
 
                        } else
208
 
                                Write (retType.Type);
209
 
                }
210
 
 
211
 
                void Write (Param [] parameters, int sentinel)
212
 
                {
213
 
                        for (int i = 0; i < parameters.Length; i++) {
214
 
                                if (i == sentinel)
215
 
                                        Write (ElementType.Sentinel);
216
 
 
217
 
                                Write (parameters [i]);
218
 
                        }
219
 
                }
220
 
 
221
 
                void Write (Param [] parameters)
222
 
                {
223
 
                        foreach (Param p in parameters)
224
 
                                Write (p);
225
 
                }
226
 
 
227
 
                void Write (ElementType et)
228
 
                {
229
 
                        Write ((int) et);
230
 
                }
231
 
 
232
 
                void Write (SigType t)
233
 
                {
234
 
                        Write ((int) t.ElementType);
235
 
 
236
 
                        switch (t.ElementType) {
237
 
                        case ElementType.ValueType :
238
 
                                Write ((int) Utilities.CompressMetadataToken (
239
 
                                                CodedIndex.TypeDefOrRef, ((VALUETYPE) t).Type));
240
 
                                break;
241
 
                        case ElementType.Class :
242
 
                                Write ((int) Utilities.CompressMetadataToken (
243
 
                                                CodedIndex.TypeDefOrRef, ((CLASS) t).Type));
244
 
                                break;
245
 
                        case ElementType.Ptr :
246
 
                                PTR p = (PTR) t;
247
 
                                if (p.Void)
248
 
                                        Write (ElementType.Void);
249
 
                                else {
250
 
                                        Write (p.CustomMods);
251
 
                                        Write (p.PtrType);
252
 
                                }
253
 
                                break;
254
 
                        case ElementType.FnPtr :
255
 
                                FNPTR fp = (FNPTR) t;
256
 
                                if (fp.Method is MethodRefSig)
257
 
                                        (fp.Method as MethodRefSig).Accept (this);
258
 
                                else
259
 
                                        (fp.Method as MethodDefSig).Accept (this);
260
 
                                break;
261
 
                        case ElementType.Array :
262
 
                                ARRAY ary = (ARRAY) t;
263
 
                                Write (ary.CustomMods);
264
 
                                ArrayShape shape = ary.Shape;
265
 
                                Write (ary.Type);
266
 
                                Write (shape.Rank);
267
 
                                Write (shape.NumSizes);
268
 
                                foreach (int size in shape.Sizes)
269
 
                                        Write (size);
270
 
                                Write (shape.NumLoBounds);
271
 
                                foreach (int loBound in shape.LoBounds)
272
 
                                        Write (loBound);
273
 
                                break;
274
 
                        case ElementType.SzArray :
275
 
                                SZARRAY sa = (SZARRAY) t;
276
 
                                Write (sa.CustomMods);
277
 
                                Write (sa.Type);
278
 
                                break;
279
 
                        case ElementType.Var :
280
 
                                Write (((VAR) t).Index);
281
 
                                break;
282
 
                        case ElementType.MVar :
283
 
                                Write (((MVAR) t).Index);
284
 
                                break;
285
 
                        case ElementType.GenericInst :
286
 
                                GENERICINST gi = t as GENERICINST;
287
 
                                Write (gi.ValueType ? ElementType.ValueType : ElementType.Class);
288
 
                                Write ((int) Utilities.CompressMetadataToken (
289
 
                                                CodedIndex.TypeDefOrRef, gi.Type));
290
 
                                Write (gi.Signature);
291
 
                                break;
292
 
                        }
293
 
                }
294
 
 
295
 
                void Write (TypeSpec ts)
296
 
                {
297
 
                        Write (ts.CustomMods);
298
 
                        Write (ts.Type);
299
 
                }
300
 
 
301
 
                void Write (MethodSpec ms)
302
 
                {
303
 
                        Write (0x0a);
304
 
                        Write (ms.Signature);
305
 
                }
306
 
 
307
 
                void Write (GenericInstSignature gis)
308
 
                {
309
 
                        Write (gis.Arity);
310
 
                        for (int i = 0; i < gis.Arity; i++)
311
 
                                Write (gis.Types [i]);
312
 
                }
313
 
 
314
 
                void Write (GenericArg arg)
315
 
                {
316
 
                        Write (arg.CustomMods);
317
 
                        Write (arg.Type);
318
 
                }
319
 
 
320
 
                void Write (Param p)
321
 
                {
322
 
                        Write (p.CustomMods);
323
 
                        if (p.TypedByRef)
324
 
                                Write (ElementType.TypedByRef);
325
 
                        else if (p.ByRef) {
326
 
                                Write (ElementType.ByRef);
327
 
                                Write (p.Type);
328
 
                        } else
329
 
                                Write (p.Type);
330
 
                }
331
 
 
332
 
                void Write (CustomMod [] customMods)
333
 
                {
334
 
                        foreach (CustomMod cm in customMods)
335
 
                                Write (cm);
336
 
                }
337
 
 
338
 
                void Write (CustomMod cm)
339
 
                {
340
 
                        switch (cm.CMOD) {
341
 
                        case CustomMod.CMODType.OPT :
342
 
                                Write (ElementType.CModOpt);
343
 
                                break;
344
 
                        case CustomMod.CMODType.REQD :
345
 
                                Write (ElementType.CModReqD);
346
 
                                break;
347
 
                        }
348
 
 
349
 
                        Write ((int) Utilities.CompressMetadataToken (
350
 
                                        CodedIndex.TypeDefOrRef, cm.TypeDefOrRef));
351
 
                }
352
 
 
353
 
                void Write (MarshalSig ms)
354
 
                {
355
 
                        Write ((int) ms.NativeInstrinsic);
356
 
                        switch (ms.NativeInstrinsic) {
357
 
                        case NativeType.ARRAY :
358
 
                                MarshalSig.Array ar = (MarshalSig.Array) ms.Spec;
359
 
                                Write ((int) ar.ArrayElemType);
360
 
                                if (ar.ParamNum != -1)
361
 
                                        Write (ar.ParamNum);
362
 
                                if (ar.NumElem != -1)
363
 
                                        Write (ar.NumElem);
364
 
                                if (ar.ElemMult != -1)
365
 
                                        Write (ar.ElemMult);
366
 
                                break;
367
 
                        case NativeType.CUSTOMMARSHALER :
368
 
                                MarshalSig.CustomMarshaler cm = (MarshalSig.CustomMarshaler) ms.Spec;
369
 
                                Write (cm.Guid);
370
 
                                Write (cm.UnmanagedType);
371
 
                                Write (cm.ManagedType);
372
 
                                Write (cm.Cookie);
373
 
                                break;
374
 
                        case NativeType.FIXEDARRAY :
375
 
                                MarshalSig.FixedArray fa = (MarshalSig.FixedArray) ms.Spec;
376
 
                                Write (fa.NumElem);
377
 
                                if (fa.ArrayElemType != NativeType.NONE)
378
 
                                        Write ((int) fa.ArrayElemType);
379
 
                                break;
380
 
                        case NativeType.SAFEARRAY :
381
 
                                Write ((int) ((MarshalSig.SafeArray) ms.Spec).ArrayElemType);
382
 
                                break;
383
 
                        case NativeType.FIXEDSYSSTRING :
384
 
                                Write (((MarshalSig.FixedSysString) ms.Spec).Size);
385
 
                                break;
386
 
                        }
387
 
                }
388
 
 
389
 
                void Write (CustomAttrib ca, MethodReference ctor, MemoryBinaryWriter writer)
390
 
                {
391
 
                        if (ca == null)
392
 
                                return;
393
 
 
394
 
                        if (ca.Prolog != CustomAttrib.StdProlog)
395
 
                                return;
396
 
 
397
 
                        writer.Write (ca.Prolog);
398
 
 
399
 
                        for (int i = 0; i < ctor.Parameters.Count; i++)
400
 
                                Write (ca.FixedArgs [i], writer);
401
 
 
402
 
                        writer.Write (ca.NumNamed);
403
 
 
404
 
                        for (int i = 0; i < ca.NumNamed; i++)
405
 
                                Write (ca.NamedArgs [i], writer);
406
 
                }
407
 
 
408
 
                void Write (CustomAttrib.FixedArg fa, MemoryBinaryWriter writer)
409
 
                {
410
 
                        if (fa.SzArray)
411
 
                                writer.Write (fa.NumElem);
412
 
 
413
 
                        foreach (CustomAttrib.Elem elem in fa.Elems)
414
 
                                Write (elem, writer);
415
 
                }
416
 
 
417
 
                static string GetEnumFullName (TypeReference type)
418
 
                {
419
 
                        string fullname = type.FullName;
420
 
 
421
 
                        if (type.IsNested)
422
 
                                fullname = fullname.Replace ('/', '+');
423
 
 
424
 
                        if (type is TypeDefinition)
425
 
                                return fullname;
426
 
 
427
 
                        return string.Concat (fullname, ", ", type.Module.Assembly.Name.FullName);
428
 
                }
429
 
 
430
 
                void Write (CustomAttrib.NamedArg na, MemoryBinaryWriter writer)
431
 
                {
432
 
                        if (na.Field)
433
 
                                writer.Write ((byte) 0x53);
434
 
                        else if (na.Property)
435
 
                                writer.Write ((byte) 0x54);
436
 
                        else
437
 
                                throw new MetadataFormatException ("Unknown kind of namedarg");
438
 
 
439
 
                        if (na.FieldOrPropType == ElementType.Class)
440
 
                                na.FieldOrPropType = ElementType.Enum;
441
 
 
442
 
                        if (na.FixedArg.SzArray)
443
 
                                writer.Write ((byte) ElementType.SzArray);
444
 
 
445
 
                        if (na.FieldOrPropType == ElementType.Object)
446
 
                                writer.Write ((byte) ElementType.Boxed);
447
 
                        else
448
 
                                writer.Write ((byte) na.FieldOrPropType);
449
 
 
450
 
                        if (na.FieldOrPropType == ElementType.Enum)
451
 
                                Write (GetEnumFullName (na.FixedArg.Elems [0].ElemType));
452
 
 
453
 
                        Write (na.FieldOrPropName);
454
 
 
455
 
                        Write (na.FixedArg, writer);
456
 
                }
457
 
 
458
 
                static ElementType GetElementTypeFromTypeCode (TypeCode tc)
459
 
                {
460
 
                        switch (tc) {
461
 
                        case TypeCode.Byte:
462
 
                                return ElementType.U1;
463
 
                        case TypeCode.SByte:
464
 
                                return ElementType.I1;
465
 
                        case TypeCode.Int16:
466
 
                                return ElementType.I2;
467
 
                        case TypeCode.UInt16:
468
 
                                return ElementType.U2;
469
 
                        case TypeCode.Int32:
470
 
                                return ElementType.I4;
471
 
                        case TypeCode.UInt32:
472
 
                                return ElementType.U4;
473
 
                        case TypeCode.Int64:
474
 
                                return ElementType.I8;
475
 
                        case TypeCode.UInt64:
476
 
                                return ElementType.U8;
477
 
                        default:
478
 
                                throw new ArgumentException ("tc");
479
 
                        }
480
 
                }
481
 
 
482
 
                void Write (CustomAttrib.Elem elem, MemoryBinaryWriter writer)
483
 
                {
484
 
                        if (elem.String)
485
 
                                elem.FieldOrPropType = ElementType.String;
486
 
                        else if (elem.Type)
487
 
                                elem.FieldOrPropType = ElementType.Type;
488
 
 
489
 
                        if (elem.FieldOrPropType == ElementType.Class) // an enum in fact
490
 
                                elem.FieldOrPropType = GetElementTypeFromTypeCode (Type.GetTypeCode (elem.Value.GetType ()));
491
 
 
492
 
                        if (elem.BoxedValueType)
493
 
                                Write (elem.FieldOrPropType);
494
 
 
495
 
                        switch (elem.FieldOrPropType) {
496
 
                        case ElementType.Boolean :
497
 
                                writer.Write ((byte) ((bool) elem.Value ? 1 : 0));
498
 
                                break;
499
 
                        case ElementType.Char :
500
 
                                writer.Write ((ushort) (char) elem.Value);
501
 
                                break;
502
 
                        case ElementType.R4 :
503
 
                                writer.Write ((float) elem.Value);
504
 
                                break;
505
 
                        case ElementType.R8 :
506
 
                                writer.Write ((double) elem.Value);
507
 
                                break;
508
 
                        case ElementType.I1 :
509
 
                                writer.Write ((sbyte) elem.Value);
510
 
                                break;
511
 
                        case ElementType.I2 :
512
 
                                writer.Write ((short) elem.Value);
513
 
                                break;
514
 
                        case ElementType.I4 :
515
 
                                writer.Write ((int) elem.Value);
516
 
                                break;
517
 
                        case ElementType.I8 :
518
 
                                writer.Write ((long) elem.Value);
519
 
                                break;
520
 
                        case ElementType.U1 :
521
 
                                writer.Write ((byte) elem.Value);
522
 
                                break;
523
 
                        case ElementType.U2 :
524
 
                                writer.Write ((ushort) elem.Value);
525
 
                                break;
526
 
                        case ElementType.U4 :
527
 
                                writer.Write ((uint) elem.Value);
528
 
                                break;
529
 
                        case ElementType.U8 :
530
 
                                writer.Write ((ulong) elem.Value);
531
 
                                break;
532
 
                        case ElementType.String :
533
 
                        case ElementType.Type :
534
 
                                string s = elem.Value as string;
535
 
                                if (s == null)
536
 
                                        writer.Write ((byte) 0xff);
537
 
                                else if (s.Length == 0)
538
 
                                        writer.Write ((byte) 0x00);
539
 
                                else
540
 
                                        Write (s);
541
 
                                break;
542
 
                        case ElementType.Object :
543
 
                                if (elem.Value != null)
544
 
                                        throw new NotSupportedException ("Unknown state");
545
 
                                writer.Write ((byte) 0xff);
546
 
                                break;
547
 
                        default :
548
 
                                throw new NotImplementedException ("WriteElem " + elem.FieldOrPropType.ToString ());
549
 
                        }
550
 
                }
551
 
 
552
 
                void Write (string s)
553
 
                {
554
 
                        byte [] str = Encoding.UTF8.GetBytes (s);
555
 
                        Write (str.Length);
556
 
                        m_sigWriter.Write (str);
557
 
                }
558
 
 
559
 
                void Write (int i)
560
 
                {
561
 
                        Utilities.WriteCompressedInteger (m_sigWriter, i);
562
 
                }
563
 
        }
564
 
}