summaryrefslogtreecommitdiff
path: root/src/inc/ilformatter.h
blob: 7593aa65bc719ebfde0b02a2aed78b6750cb6a07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


/***************************************************************************/
/*                             ILFormatter.h                               */
/***************************************************************************/

#ifndef ILFormatter_h
#define ILFormatter_h

#include "opinfo.h"
#include "outstring.h"

struct IMetaDataImport;

#define INVALID_IL_OFFSET 0x80000000

/***************************************************************************/
class ILFormatter {
public:
	ILFormatter() : start(0), targetStart(0), stackStart(0) {}

	ILFormatter(IMetaDataImport* aMeta, const BYTE* aStart, 
                const BYTE* aLimit, unsigned maxStack, const COR_ILMETHOD_SECT_EH* eh) 
		: targetStart(0), stackStart(0) {
		init(aMeta, aStart, aLimit, maxStack, eh);
		}
    ~ILFormatter() { delete [] stackStart; delete [] targetStart; }

	void init(IMetaDataImport* aMeta, const BYTE* aStart, 
              const BYTE* aLimit, unsigned maxStack, const COR_ILMETHOD_SECT_EH* eh);
	const BYTE* formatStatement(const BYTE* stmtIL, OutString* out);
	const BYTE* formatInstr(const BYTE* instrIL, OutString* out);
private:

	void formatInstrArgs(OpInfo op, OpArgsVal arg, OutString* out, size_t curIP=INVALID_IL_OFFSET);
    void formatArgs(unsigned numArgs, OutString* out);
    void spillStack(OutString* out);
    void setStackAsTarget(size_t ilOffset);
    void setTarget(size_t ilOffset, size_t depth);

private:
	const BYTE* start;				// keeps us sane
	const BYTE* limit;
	IMetaDataImport* meta;			// used to parse tokens etc

    struct StackEntry {
        OutString val;
        int prec;
    };

    struct Target {
        size_t ilOffset;
        size_t stackDepth;
    };

    Target* targetStart;
    Target* targetEnd;
    Target* targetCur;

    size_t stackDepth();
    void pushAndClear(OutString* val, int prec);
	OutString* pop(int prec = 0);
	OutString* top();
    void popN(size_t num);

	StackEntry* stackStart;
	StackEntry* stackEnd;
	StackEntry* stackCur;   	// points at the next slot to fill

};

#endif