[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / utilcode / ilformatter.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /***************************************************************************/
6 /*                             ILFormatter.h                               */
7 /***************************************************************************/
8
9 #include "stdafx.h"
10 #include <cor.h>
11 #include <debugmacros.h>            // for ASSERTE
12 #include "ilformatter.h"
13 #include "outstring.h"
14 #include "opinfo.h"
15
16 /***************************************************************************/
17 void ILFormatter::init(IMetaDataImport* aMeta, const BYTE* aStart,
18                   const BYTE* aLimit, unsigned maxStack, const COR_ILMETHOD_SECT_EH* eh) {
19     this->~ILFormatter();       // clean out old stuff
20
21     meta = aMeta;
22     start = aStart;
23     limit = aLimit;
24     if (maxStack == 0) maxStack++;
25     stackStart = stackCur = new StackEntry[maxStack];
26     stackEnd = stackStart + maxStack;
27     targetStart = targetCur = targetEnd = 0;
28     if (eh != 0) {
29         COR_ILMETHOD_SECT_EH_CLAUSE_FAT buff;
30         const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* clause;
31         for(unsigned i = 0; i < eh->EHCount(); i++) {
32             clause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)eh->EHClause(i, &buff);
33                 // is it a regular catch clause ?
34             if ((clause->GetFlags() & (COR_ILEXCEPTION_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_FAULT)) == 0)
35                 setTarget(clause->GetHandlerOffset(), 1);
36             if(clause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER)
37                 setTarget(clause->GetFilterOffset(), 1);
38         }
39     }
40 }
41
42 /***************************************************************************/
43 inline size_t ILFormatter::stackDepth() {
44     return(stackCur - stackStart);
45 }
46
47 /***************************************************************************/
48 inline void ILFormatter::pushAndClear(OutString* val, int prec) {
49     if (stackCur >= stackEnd) {
50         _ASSERTE(!"Stack Overflow (can be ignored)");
51         return;             // Ignore overflow in free build
52     }
53     stackCur->val.swap(*val);
54     val->clear();
55     stackCur->prec = prec;
56     stackCur++;
57 }
58
59 /***************************************************************************/
60 inline OutString*  ILFormatter::top() {
61     if (stackDepth() == 0) {
62         _ASSERTE(!"Stack underflow (can be ignored)");
63         stackStart->val.clear();
64         stackStart->val << "<UNDERFLOW ERROR>";
65         return (&stackStart->val);
66     }
67     return(&stackCur[-1].val);
68 }
69
70 /***************************************************************************/
71 inline OutString* ILFormatter::pop(int prec) {
72     if (stackDepth() == 0) {
73         _ASSERTE(!"Stack underflow (can be ignored)");
74         stackStart->val.clear();
75         stackStart->val << "<UNDERFLOW ERROR>";
76         return (&stackStart->val);
77     }
78     --stackCur;
79     if (stackCur->prec < prec) {
80         stackCur->val.prepend('(');
81         stackCur->val << ')';
82     }
83     return(&stackCur->val);
84 }
85
86 /***************************************************************************/
87 inline void ILFormatter::popN(size_t num) {
88     if (stackCur-stackStart < (SSIZE_T)num) {
89         _ASSERTE(!"Stack underflow (can be ignored)");
90         stackCur = stackStart;
91         return;
92     }
93     stackCur -= num;
94 }
95
96 /***************************************************************************/
97 void ILFormatter::setStackAsTarget(size_t ilOffset) {
98
99     Target*ptr = targetStart;
100     for(;;) {
101         if (ptr >= targetCur)
102             return;
103         if (ptr->ilOffset == ilOffset)
104             break;
105         ptr++;
106     }
107
108     for(size_t i = 0; i < ptr->stackDepth; i++) {
109         stackStart[i].val.clear();
110         stackStart[i].val << "@STK" << (unsigned)i;
111     }
112     stackCur = stackStart + ptr->stackDepth;
113 }
114
115 /***************************************************************************/
116 void ILFormatter::setTarget(size_t ilOffset, size_t depth) {
117     if (depth == 0)
118         return;
119
120     if (targetCur >= targetEnd) {
121         Target* targetOld = targetStart;
122         size_t oldLen = targetCur-targetStart;
123         targetStart = new Target[oldLen+10];
124         targetEnd = &targetStart[oldLen+10];
125         targetCur = &targetStart[oldLen];
126         memcpy(targetStart, targetOld, sizeof(Target)*oldLen);
127         delete [] targetOld;
128     }
129     targetCur->ilOffset = ilOffset;
130     targetCur->stackDepth = depth;
131     targetCur++;
132 }
133
134 /***************************************************************************/
135 void ILFormatter::spillStack(OutString* out) {
136
137     for(unsigned i = 0; i < stackDepth(); i++) {
138         // don't bother spilling something already spilled.
139         if (memcmp(stackStart[i].val.val(), "@STK", 4) != 0)
140             *out << "@STK" << i << " = " << stackStart[i].val.val() << "\n";
141         stackStart[i].val.clear();
142         stackStart[i].val << "@STK" << i ;
143     }
144 }
145
146 /***************************************************************************/
147 const BYTE* ILFormatter::formatInstr(const BYTE* instrPtr, OutString* out) {
148
149     _ASSERTE(start < instrPtr && instrPtr < limit);
150     OpArgsVal arg;
151     OpInfo op;
152     instrPtr = op.fetch(instrPtr, &arg);
153     *out << op.getName();
154     if (op.getArgsInfo() != InlineNone)
155         *out << ' ';
156     formatInstrArgs(op, arg, out, instrPtr - start);
157     return(instrPtr);
158 }
159
160 /***************************************************************************/
161 void ILFormatter::formatArgs(unsigned numArgs, OutString* out) {
162
163     *out << '(';
164     if (numArgs > stackDepth()) {
165         _ASSERTE(!"Underflow error");
166         *out << "<UNDERFLOW ERROR>";
167     }
168     else {
169         popN(numArgs);
170         for(unsigned i = 0; i < numArgs; i++) {
171             if (i != 0) *out << ", ";
172             *out << stackCur[i].val.val();
173         }
174     }
175     *out << ')';
176 }
177
178 /***************************************************************************/
179 void ILFormatter::formatInstrArgs(OpInfo op, OpArgsVal arg, OutString* out, size_t curILOffset) {
180
181     MDUTF8CSTR typeName=0;
182     HRESULT hr = S_OK;
183     switch(op.getArgsInfo() & PrimaryMask) {
184         case InlineNone:
185             break;
186         case InlineVar:
187             *out << arg.i;
188             break;
189         case InlineI:
190         case InlineRVA:
191             out->hex(arg.i, 0, OutString::put0x);
192             break;
193         case InlineR:
194             *out << arg.r;
195             break;
196         case InlineBrTarget: {
197             _ASSERTE(curILOffset != INVALID_IL_OFFSET);
198             size_t target = curILOffset + arg.i;
199             setTarget(target, stackDepth());
200             *out << "IL_"; out->hex(static_cast<unsigned __int64>(target), 4, OutString::zeroFill);
201             } break;
202         case InlineI8:
203             out->hex(arg.i, 0, OutString::put0x);
204             break;
205         case InlineString: {
206             ULONG numChars;
207             wchar_t str[84];
208
209             hr = meta->GetUserString(arg.i, str, 80, &numChars);
210             _ASSERTE(SUCCEEDED(hr));
211             if (numChars < 80)
212                 str[numChars] = 0;
213             wcscpy_s(&str[79], 4, W("..."));
214             *out << '"';
215             wchar_t* ptr = str;
216             while(*ptr != 0) {
217                 if (*ptr == '\n')
218                     *out << "\\n";
219                 else if (*ptr == '"')
220                     *out << "\\\"";
221                 else if (*ptr < 0x20 || * ptr >= 0x80) {
222                     *out << '\\';
223                     out->hex(*ptr, 4, OutString::zeroFill);
224                 }
225                 else
226                     *out << char(*ptr);
227                 ptr++;
228             }
229             *out << '"';
230             } break;
231         case InlineMethod:
232         case InlineField:
233         case InlineTok: {
234                 // Get the typeName if possible
235             mdToken mdType = mdTypeDefNil;
236             if (TypeFromToken(arg.i) == mdtMethodDef)
237                 hr = meta->GetMethodProps(mdMethodDef(arg.i), &mdType, 0, 0, 0, 0, 0, 0, 0, 0);
238             else if (TypeFromToken(arg.i) == mdtMemberRef)
239                 hr = meta->GetMemberRefProps(mdMemberRef(arg.i), &mdType, 0, 0, 0, 0, 0);
240             else if (TypeFromToken(arg.i) == mdtFieldDef)
241                 hr = meta->GetFieldProps(mdMethodDef(arg.i), &mdType, 0, 0, 0, 0, 0, 0, 0, 0, 0);
242             if (SUCCEEDED(hr) && mdType != mdTypeDefNil) {
243                 hr = meta->GetNameFromToken(mdType, &typeName);
244             }
245         }
246             // FALL THROUGH
247         case InlineType: {
248             // FIX handle case if (TypeFromToken(arg.i) == mdtTypeSpec)
249             MDUTF8CSTR name;
250             hr = meta->GetNameFromToken(arg.i, &name);
251             if (SUCCEEDED(hr)) {
252                 if (typeName) {
253                     const char* lastDot = strrchr(typeName, '.');
254                     if (lastDot) typeName = lastDot + 1;
255                     *out << typeName << "::";
256                 }
257                 *out << name;
258             }
259             else {
260                 *out << "TOK<";
261                 out->hex(arg.i, 0, OutString::put0x);
262                 *out << '>';
263             }
264         }   break;
265         case InlineSig:
266             *out << "SIG<";
267             out->hex(arg.i, 0, OutString::put0x);
268             *out << '>';
269             break;
270         case InlineSwitch: {
271             _ASSERTE(curILOffset != INVALID_IL_OFFSET);
272             unsigned count = arg.switch_.count;
273             unsigned i;
274             for (i = 0; i < count; i++) {
275                 size_t target = curILOffset + GET_UNALIGNED_VAL32(&arg.switch_.targets[i]);
276                 setTarget(target, stackDepth()-1);
277                 *out << "IL_"; out->hex(static_cast<unsigned __int64>(target), 4, OutString::zeroFill);
278                 if (i < count)
279                     *out << ' ';
280                 }
281             } break;
282         case InlinePhi: {
283             unsigned count = arg.phi.count;
284             unsigned i;
285             for (i = 0; i < count; i++) {
286                 *out << GET_UNALIGNED_VAL32(&arg.phi.vars[i]);
287                 if (i < count)
288                     *out << ' ';
289                 }
290             } break;
291         default:
292             _ASSERTE(!"BadType");
293     }
294 }
295
296 #ifdef _PREFAST_
297 #pragma warning(push)
298 #pragma warning(disable:21000) // Suppress PREFast warning about overly large function
299 #endif
300 /***************************************************************************/
301 const BYTE* ILFormatter::formatStatement(const BYTE* instrPtr, OutString* out) {
302
303     OutString result;
304     OpInfo op;
305     OutString *lhs, *rhs, *idx;
306     const char* name;
307     int prec = 0;
308
309         // set stack as it would be if it was begin jumped to
310     setStackAsTarget(instrPtr - start);
311
312     while(instrPtr < limit) {
313         OpArgsVal inlineArg;
314         instrPtr = op.fetch(instrPtr, &inlineArg);
315
316         switch(op.getOpcode()) {
317             case CEE_UNALIGNED:
318             case CEE_TAILCALL:
319             case CEE_VOLATILE:
320                 // for now just skip these
321                 break;
322
323             case CEE_LDARGA_S:
324             case CEE_LDARGA:
325                 result << "&";
326                 goto DO_LDARG;
327
328             case CEE_LDARG_0:
329             case CEE_LDARG_1:
330             case CEE_LDARG_2:
331             case CEE_LDARG_3:
332                 inlineArg.i = op.getOpcode() - CEE_LDARG_0;
333                 goto DO_LDARG;
334
335             case CEE_LDARG:
336             case CEE_LDARG_S:
337             DO_LDARG:
338                 name = "arg";
339             DO_LDARG_LDLOC:
340                 result << name << inlineArg.i;
341                 prec = 0x1000;
342                 goto DO_PUSH;
343             DO_PUSH:
344                 pushAndClear(&result, prec);   // also clears result!
345                 break;
346
347             case CEE_LDLOCA_S:
348             case CEE_LDLOCA:
349                 result << "&";
350                 goto DO_LDLOC;
351
352             case CEE_LDLOC_0:
353             case CEE_LDLOC_1:
354             case CEE_LDLOC_2:
355             case CEE_LDLOC_3:
356                 inlineArg.i = op.getOpcode() - CEE_LDLOC_0;
357                 goto DO_LDLOC;
358
359             case CEE_LDLOC:
360             case CEE_LDLOC_S:
361             DO_LDLOC:
362                 name = "loc";
363                 goto DO_LDARG_LDLOC;
364
365             case CEE_STARG:
366             case CEE_STARG_S:
367                 name = "arg";
368             DO_STARG_STLOC:
369                 lhs = pop(0x10);
370                 result << name << inlineArg.i << " = " << lhs->val();
371             DO_STMT:
372                 spillStack(out);
373                 *out << result.val() << '\n';
374                     // if flow of control does not fall through,
375                     // assume the stack is empty
376                 if (op.getFlow() == FLOW_BRANCH || op.getFlow() == FLOW_RETURN ||
377                     op.getFlow() == FLOW_THROW) {
378                     popN(stackDepth());
379                 }
380                 return(instrPtr);
381
382             case CEE_STLOC_0:
383             case CEE_STLOC_1:
384             case CEE_STLOC_2:
385             case CEE_STLOC_3:
386                 inlineArg.i = op.getOpcode() - CEE_STLOC_0;
387                 goto DO_STLOC;
388
389             case CEE_STLOC:
390             case CEE_STLOC_S:
391             DO_STLOC:
392                 name = "loc";
393                 goto DO_STARG_STLOC;
394
395             case CEE_LDC_I4_M1:
396             case CEE_LDC_I4_0:
397             case CEE_LDC_I4_1:
398             case CEE_LDC_I4_2:
399             case CEE_LDC_I4_3:
400             case CEE_LDC_I4_4:
401             case CEE_LDC_I4_5:
402             case CEE_LDC_I4_6:
403             case CEE_LDC_I4_7:
404             case CEE_LDC_I4_8:
405                 inlineArg.i = op.getOpcode() - CEE_LDC_I4_0;
406                 // FALL THROUGH
407             case CEE_LDC_I4:
408             case CEE_LDC_I4_S:
409                 result << inlineArg.i;
410                 prec = 0x1000;
411                 goto DO_PUSH;
412
413             case CEE_LDC_I8:
414                 result.hex(inlineArg.i8);
415                 prec = 0x1000;
416                 goto DO_PUSH;
417
418             case CEE_LDC_R4:
419             case CEE_LDC_R8:
420                 result << inlineArg.r;
421                 prec = 0x1000;
422                 goto DO_PUSH;
423
424             case CEE_LDNULL:
425                 result << "null";
426                 prec = 0x1000;
427                 goto DO_PUSH;
428
429             case CEE_LDSTR:
430                 formatInstrArgs(op, inlineArg, &result);
431                 prec = 0x1000;
432                 goto DO_PUSH;
433
434             case CEE_BEQ:
435             case CEE_BEQ_S:
436                 name = "==";    prec = 0x40;    goto DO_BR_BINOP;
437             case CEE_BGE:
438             case CEE_BGE_S:
439                 name = ">=";    prec = 0x40;    goto DO_BR_BINOP;
440             case CEE_BGE_UN:
441             case CEE_BGE_UN_S:
442                 name = ">=un";  prec = 0x40;    goto DO_BR_BINOP;
443
444             case CEE_BGT:
445             case CEE_BGT_S:
446                 name = ">";     prec = 0x40;    goto DO_BR_BINOP;
447             case CEE_BGT_UN:
448             case CEE_BGT_UN_S:
449                 name = ">un";   prec = 0x40;    goto DO_BR_BINOP;
450             case CEE_BLE:
451             case CEE_BLE_S:
452                 name = "<=";    prec = 0x40;    goto DO_BR_BINOP;
453             case CEE_BLE_UN:
454             case CEE_BLE_UN_S:
455                 name = "<=un";  prec = 0x40;    goto DO_BR_BINOP;
456             case CEE_BLT:
457             case CEE_BLT_S:
458                 name = "<";     prec = 0x40;    goto DO_BR_BINOP;
459             case CEE_BLT_UN:
460             case CEE_BLT_UN_S:
461                 name = "<un";   prec = 0x40;    goto DO_BR_BINOP;
462             case CEE_BNE_UN:
463             case CEE_BNE_UN_S:
464                 name = "!=un";  prec = 0x40;    goto DO_BR_BINOP;
465             DO_BR_BINOP:
466                 rhs = pop(prec);
467                 lhs = pop(prec-1);
468                 result << "if (" << lhs->val() << ' ' << name << ' ' << rhs->val() << ") ";
469                 goto DO_BR;
470
471             case CEE_LEAVE_S:
472             case CEE_LEAVE:
473                 while (stackDepth() > 0) {
474                     lhs = pop();
475                     *lhs << '\n' << result;     // put the result in front of anything else
476                     result.swap(*lhs);
477                 }
478                     /* fall through */
479             case CEE_BR_S:
480             case CEE_BR:
481             DO_BR: {
482                 size_t target = (instrPtr - start) + inlineArg.i;
483                 setTarget(target, stackDepth());
484                 result << "goto IL_"; result.hex(static_cast<unsigned __int64>(target), 4, OutString::zeroFill);
485                 } goto DO_STMT;
486
487             case CEE_BRFALSE_S:
488             case CEE_BRFALSE:
489                 name = "!";
490                 goto DO_BR_UNOP;
491             case CEE_BRTRUE_S:
492             case CEE_BRTRUE:
493                 name = "";
494             DO_BR_UNOP:
495                 lhs = pop();
496                 result << "if (" << name << lhs->val() << ") ";
497                 goto DO_BR;
498
499             case CEE_OR:
500                 name = "|";     prec = 0x20;    goto DO_BINOP;
501             case CEE_XOR:
502                 name = "^";     prec = 0x20;    goto DO_BINOP;
503             case CEE_AND:
504                 name = "&";     prec = 0x30;    goto DO_BINOP;
505             case CEE_SHL:
506                 name = "<<";    prec = 0x50;    goto DO_BINOP;
507             case CEE_SHR:
508                 name = ">>";    prec = 0x50;    goto DO_BINOP;
509             case CEE_SHR_UN:
510                 name = ">>un";  prec = 0x50;    goto DO_BINOP;
511             case CEE_CEQ:
512                 name = "==";    prec = 0x40;    goto DO_BINOP;
513             case CEE_CGT:
514                 name = ">";     prec = 0x40;    goto DO_BINOP;
515             case CEE_CGT_UN:
516                 name = ">un";   prec = 0x40;    goto DO_BINOP;
517             case CEE_CLT:
518                 name = "<";     prec = 0x40;    goto DO_BINOP;
519             case CEE_CLT_UN:
520                 name = "<un";   prec = 0x40;    goto DO_BINOP;
521             case CEE_ADD:
522                 name = "+";     prec = 0x60;    goto DO_BINOP;
523             case CEE_ADD_OVF:
524                 name = "+ovf";  prec = 0x60;    goto DO_BINOP;
525             case CEE_ADD_OVF_UN:
526                 name = "+ovf.un";prec = 0x60;   goto DO_BINOP;
527             case CEE_SUB:
528                 name = "-";     prec = 0x60;    goto DO_BINOP;
529             case CEE_SUB_OVF:
530                 name = "-ovf";  prec = 0x60;    goto DO_BINOP;
531             case CEE_SUB_OVF_UN:
532                 name = "-ovf.un";prec = 0x60;   goto DO_BINOP;
533             case CEE_MUL:
534                 name = "*";     prec = 0x70;    goto DO_BINOP;
535             case CEE_MUL_OVF:
536                 name = "*ovf";  prec = 0x70;    goto DO_BINOP;
537             case CEE_MUL_OVF_UN:
538                 name = "*ovf.un";prec = 0x70;   goto DO_BINOP;
539             case CEE_DIV:
540                 name = "/";     prec = 0x70;    goto DO_BINOP;
541             case CEE_DIV_UN:
542                 name = "/un";   prec = 0x70;    goto DO_BINOP;
543             case CEE_REM:
544                 name = "%";     prec = 0x70;    goto DO_BINOP;
545             case CEE_REM_UN:
546                 name = "%un";   prec = 0x70;    goto DO_BINOP;
547             DO_BINOP:
548                 rhs = pop(prec);
549                 lhs = pop(prec-1);
550                 result << lhs->val() << ' ' << name << ' ' << rhs->val();
551             goto DO_PUSH;
552
553             case CEE_NOT:
554                 name = "~"; prec = 0x80;    goto DO_UNOP;
555             case CEE_NEG:
556                 name = "-"; prec = 0x80;    goto DO_UNOP;
557             DO_UNOP:
558                 lhs = pop(prec-1);
559                 result << name << lhs->val();
560             goto DO_PUSH;
561
562             case CEE_RET:
563                 _ASSERTE(stackDepth() <= 1);
564                 result << "return";
565                 if (stackDepth() > 0) {
566                     lhs = pop();
567                     result << ' ' << lhs->val();
568                 }
569             goto DO_STMT;
570
571             case CEE_POP:
572                 lhs = pop();
573                 result.swap(*lhs);
574                 goto DO_STMT;
575
576             case CEE_DUP:
577                 spillStack(out);
578                 lhs = top();
579                 result << lhs->val();
580                 prec = 0x1000;      // spillstack makes them temps, so they have high prec
581                 goto DO_PUSH;
582
583             case CEE_LDFLDA:
584                 name = "&";
585                 goto DO_LDFLD_LDFLDA;
586             case CEE_LDFLD:
587                 name = "";
588             DO_LDFLD_LDFLDA:
589                 prec = 0x110;
590                 lhs = pop(prec-1);
591                 result << name << lhs->val() << '.';
592                 formatInstrArgs(op, inlineArg, &result);
593                 goto DO_PUSH;
594
595             case CEE_LDSFLDA:
596                 name = "&";
597                 goto DO_LDSFLD_LDSFLDA;
598             case CEE_LDSFLD:
599                 name = "";
600             DO_LDSFLD_LDSFLDA:
601                 prec = 0x1000;
602                 result << name;
603                 formatInstrArgs(op, inlineArg, &result);
604                 goto DO_PUSH;
605
606             case CEE_STFLD:
607                 rhs = pop(0x10);
608                 lhs = pop(0x110-1);
609                 result << lhs->val() << '.';
610                 formatInstrArgs(op, inlineArg, &result);
611                 result << " = " << rhs->val();
612                 goto DO_STMT;
613
614             case CEE_STSFLD:
615                 rhs = pop(0x20);
616                 formatInstrArgs(op, inlineArg, &result);
617                 result << " = " << rhs->val();
618                 goto DO_STMT;
619
620             case CEE_CALLI:
621                 lhs = pop();
622                 result << "CALLI<" << lhs->val() << '>';
623                 goto DO_CALL;
624
625             case CEE_NEWOBJ:
626                 result << "new ";
627                 // FALL THROUGH
628             case CEE_CALL:
629             case CEE_CALLVIRT: {
630                 formatInstrArgs(op, inlineArg, &result);
631
632             DO_CALL:
633                     // Get the signature stuff
634                 PCCOR_SIGNATURE sig;
635                 ULONG cSig;
636                 HRESULT hr;
637                 if (TypeFromToken(inlineArg.i) == mdtMethodDef)
638                     hr = meta->GetMethodProps(mdMethodDef(inlineArg.i), 0, 0, 0, 0, 0, &sig, &cSig, 0, 0);
639                 else if (TypeFromToken(inlineArg.i) == mdtMemberRef)
640                     hr = meta->GetMemberRefProps(mdMemberRef(inlineArg.i), 0, 0, 0, 0, &sig, &cSig);
641                 else
642                     hr = meta->GetSigFromToken(mdSignature(inlineArg.i), &sig, &cSig);
643                 _ASSERTE(SUCCEEDED(hr));
644         unsigned callConv = CorSigUncompressData(sig);
645                 unsigned hasThis = callConv & IMAGE_CEE_CS_CALLCONV_HASTHIS;
646         if (callConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
647         {
648           CorSigUncompressData(sig);
649         }
650                 unsigned numArgs = CorSigUncompressData(sig);
651                 while(*sig == ELEMENT_TYPE_CMOD_REQD || *sig == ELEMENT_TYPE_CMOD_OPT) {
652                     sig++;
653                     CorSigUncompressToken(sig);
654                 }
655
656                 formatArgs(numArgs, &result);
657                 if (hasThis && op.getOpcode() != CEE_NEWOBJ) {
658                     lhs = pop(0x90);
659                     result.swap(*lhs);
660                     result << '.' << lhs->val();
661                 }
662                 prec = 0x1000;
663                 if (op.getOpcode() == CEE_NEWOBJ || *sig != ELEMENT_TYPE_VOID)
664                     goto DO_PUSH;
665                 } goto DO_STMT;
666
667             case CEE_LDELEM_I1:
668             case CEE_LDELEM_I2:
669             case CEE_LDELEM_I4:
670             case CEE_LDELEM_I8:
671             case CEE_LDELEM_REF:
672             case CEE_LDELEM_R4:
673             case CEE_LDELEM_R8:
674             case CEE_LDELEM_U1:
675             case CEE_LDELEM_U2:
676             case CEE_LDELEM_I:
677                 rhs = pop(0x100);
678                 lhs = pop();
679                 result << lhs->val() << '[' << rhs->val() << ']';
680                 prec = 0x100;
681                 goto DO_PUSH;
682
683             case CEE_STELEM_I1:
684             case CEE_STELEM_I2:
685             case CEE_STELEM_I4:
686             case CEE_STELEM_I8:
687             case CEE_STELEM_REF:
688             case CEE_STELEM_R4:
689             case CEE_STELEM_R8:
690             case CEE_STELEM_I:
691                 rhs = pop(0x100);
692                 idx = pop();
693                 lhs = pop(0x20);
694                 result << lhs->val() << '[' << idx->val() << "] = " << rhs->val();
695                 goto DO_STMT;
696
697             case CEE_LDIND_I1:  name = "I1"; goto DO_LDIND;
698             case CEE_LDIND_I2:  name = "I2"; goto DO_LDIND;
699             case CEE_LDIND_I4:  name = "I4"; goto DO_LDIND;
700             case CEE_LDIND_I8:  name = "I8"; goto DO_LDIND;
701             case CEE_LDIND_I:   name = "I";  goto DO_LDIND;
702             case CEE_LDIND_R4:  name = "R4"; goto DO_LDIND;
703             case CEE_LDIND_R8:  name = "R8"; goto DO_LDIND;
704             case CEE_LDIND_U1:  name = "U1"; goto DO_LDIND;
705             case CEE_LDIND_U2:  name = "U2"; goto DO_LDIND;
706             case CEE_LDIND_REF: name = "REF";goto DO_LDIND;
707             DO_LDIND:
708                 prec = 0x90;
709                 lhs = pop(prec);
710                 result << name << "(*" << lhs->val() << ')';
711                 goto DO_PUSH;
712
713             case CEE_STIND_I1:  name = "I1"; goto DO_STIND;
714             case CEE_STIND_I2:  name = "I2"; goto DO_STIND;
715             case CEE_STIND_I4:  name = "I4"; goto DO_STIND;
716             case CEE_STIND_I8:  name = "I8"; goto DO_STIND;
717             case CEE_STIND_REF: name = "REF";goto DO_STIND;
718             case CEE_STIND_R4:  name = "R4"; goto DO_STIND;
719             case CEE_STIND_R8:  name = "R8"; goto DO_STIND;
720             DO_STIND:
721                 rhs = pop();
722                 lhs = pop(0x90);
723                 result << '*' << lhs->val() << " = " << name << '(' << rhs->val() << ')';
724                 goto DO_STMT;
725
726             case CEE_LDVIRTFTN:
727             case CEE_ARGLIST:
728             case CEE_BREAK:
729             case CEE_ENDFILTER:
730             case CEE_CPBLK:
731             case CEE_INITBLK:
732             case CEE_LDOBJ:
733             case CEE_CPOBJ:
734             case CEE_STOBJ:
735             case CEE_INITOBJ:
736             case CEE_LOCALLOC:
737             case CEE_NOP:
738             case CEE_SWITCH:
739             case CEE_CASTCLASS:
740             case CEE_ISINST:
741             case CEE_LDLEN:
742             case CEE_JMP:
743             case CEE_NEWARR:
744             case CEE_THROW:
745             case CEE_RETHROW:
746             case CEE_LDELEM_U4:
747             case CEE_LDIND_U4:
748             case CEE_LDELEMA:
749             case CEE_ENDFINALLY:
750             case CEE_STIND_I:
751             case CEE_CKFINITE:
752             case CEE_MKREFANY:
753             case CEE_REFANYTYPE:
754             case CEE_REFANYVAL:
755             case CEE_CONV_I1:
756             case CEE_CONV_I2:
757             case CEE_CONV_I4:
758             case CEE_CONV_I8:
759             case CEE_CONV_R4:
760             case CEE_CONV_R8:
761             case CEE_CONV_R_UN:
762             case CEE_CONV_OVF_I_UN:
763             case CEE_CONV_OVF_I1_UN:
764             case CEE_CONV_OVF_I2_UN:
765             case CEE_CONV_OVF_I4_UN:
766             case CEE_CONV_OVF_I8_UN:
767             case CEE_CONV_OVF_U_UN:
768             case CEE_CONV_OVF_U1_UN:
769             case CEE_CONV_OVF_U2_UN:
770             case CEE_CONV_OVF_U4_UN:
771             case CEE_CONV_OVF_U8_UN:
772             case CEE_CONV_OVF_I1:
773             case CEE_CONV_OVF_I2:
774             case CEE_CONV_OVF_I4:
775             case CEE_CONV_OVF_I8:
776             case CEE_CONV_OVF_U1:
777             case CEE_CONV_OVF_U2:
778             case CEE_CONV_OVF_U4:
779             case CEE_CONV_OVF_U8:
780             case CEE_CONV_U4:
781             case CEE_CONV_U8:
782             case CEE_CONV_U2:
783             case CEE_CONV_U1:
784             case CEE_CONV_I:
785             case CEE_CONV_OVF_I:
786             case CEE_CONV_OVF_U:
787             case CEE_CONV_U:
788             case CEE_BOX:
789             case CEE_LDELEM:
790             case CEE_STELEM:
791             case CEE_UNBOX_ANY:
792             case CEE_UNBOX:
793             case CEE_LDFTN:
794             case CEE_LDTOKEN:
795             case CEE_SIZEOF:
796             default:
797                 result << op.getName();
798                 if (op.getArgsInfo() != InlineNone) {
799                     result << '<';
800                     formatInstrArgs(op, inlineArg, &result, instrPtr-start);
801                     result << '>';
802                 }
803
804                 _ASSERTE(op.getNumPop() >= 0);
805                 if (op.getNumPop() > 0)
806                     formatArgs(op.getNumPop(), &result);
807
808                 prec = 0x1000;
809                 _ASSERTE(op.getNumPush() == 0 || op.getNumPush() == 1);
810                 if (op.getNumPush() > 0)
811                     goto DO_PUSH;
812                 goto DO_STMT;
813         }
814     }
815     return(instrPtr);
816 }
817 #ifdef _PREFAST_
818 #pragma warning(pop)
819 #endif
820
821