home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / smc / genIL.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  26.8 KB  |  839 lines

  1. /*****************************************************************************/
  2. #ifndef _GENIL_H_
  3. #define _GENIL_H_
  4. /*****************************************************************************/
  5. #ifndef __PREPROCESS__
  6. /*****************************************************************************/
  7. #include "opcodes.h"
  8. /*****************************************************************************/
  9.  
  10. #ifdef  DEBUG
  11. #define DISP_IL_CODE    1
  12. #endif
  13.  
  14. #if     DISP_IL_CODE
  15. const   unsigned    IL_OPCDSP_LEN = 20;
  16. #endif
  17.  
  18. /*****************************************************************************
  19.  *
  20.  *  The following structure keeps tracks of all the exception handlers defined
  21.  *  in the current function.
  22.  */
  23.  
  24. DEFMGMT
  25. class   handlerDsc
  26. {
  27. public:
  28.     Handler         EHnext;
  29.  
  30.     ILblock         EHtryBegPC;
  31.     ILblock         EHtryEndPC;
  32.  
  33.     ILblock         EHhndBegPC;
  34.     ILblock         EHhndEndPC;
  35.  
  36.     ILblock         EHfilterPC;
  37.  
  38.     mdToken         EHhndType;
  39.  
  40.     bool            EHisFinally;
  41. };
  42.  
  43. /*****************************************************************************
  44.  *
  45.  *  The 'ILblock' structure and related logic is used to generate IL into
  46.  *  snippets connected via jumps, in order to allow things such as jump
  47.  *  optimizations to be done easily. Basically, the 'ILblock' structure
  48.  *  describes a single basic block (i.e. a clump of IL).
  49.  */
  50.  
  51. DEFMGMT class ILfixupDsc
  52. {
  53. public:
  54.  
  55.     ILfixup             ILfixNext;
  56.  
  57.     unsigned            ILfixOffs   :28;
  58.     WPEstdSects         ILfixSect   :4;
  59. };
  60.  
  61. DEFMGMT class ILswitchDsc
  62. {
  63. public:
  64.  
  65.     unsigned            ILswtSpan;
  66.     unsigned            ILswtCount;
  67.     vectorTree          ILswtTable;
  68.     ILblock             ILswtBreak;
  69. };
  70.  
  71. DEFMGMT class ILblockDsc
  72. {
  73. public:
  74.  
  75.     ILblock             ILblkNext;
  76.     ILblock             ILblkPrev;
  77.  
  78.     ILfixup             ILblkFixups;
  79.  
  80. #ifndef NDEBUG
  81.     ILblock             ILblkSelf;      // for consistency checks
  82. #endif
  83.  
  84.     unsigned            ILblkOffs;
  85. #if DISP_IL_CODE
  86.     unsigned            ILblkNum;
  87. #endif
  88.  
  89.     unsigned            ILblkJumpSize:16;// jump size (estimate)
  90.     unsigned            ILblkJumpCode:12;// CEE_NOP / CEE_BLE / etc.
  91.     unsigned            ILblkFlags   :4; // see ILBF_xxxx below
  92.  
  93.     UNION(ILblkJumpCode)
  94.     {
  95.     CASE(CEE_SWITCH)
  96.         ILswitch            ILblkSwitch;    // switch statement info
  97.  
  98.     DEFCASE
  99.         ILblock             ILblkJumpDest;  // jump target block or 0
  100.     };
  101.  
  102.     genericBuff         ILblkCodeAddr;  // addr of IL for this block
  103.     unsigned            ILblkCodeSize;  // size of IL for this block
  104. };
  105.  
  106. const   unsigned    ILBF_REACHABLE  = 0x01;
  107.  
  108. #ifdef  DEBUG
  109. const   unsigned    ILBF_USED       = 0x02; // for forward-referenced labels
  110. const   unsigned    ILBF_LABDEF     = 0x04; // label def has been displayed
  111. #endif
  112.  
  113. inline
  114. size_t              genILblockOffsBeg(ILblock block)
  115. {
  116.     assert(block);
  117.  
  118.     return  block->ILblkOffs;
  119. }
  120.  
  121. inline
  122. size_t              genILblockOffsEnd(ILblock block)
  123. {
  124.     assert(block);
  125.     assert(block->ILblkNext);
  126.  
  127.     return  block->ILblkNext->ILblkOffs;
  128. }
  129.  
  130. /*****************************************************************************
  131.  *
  132.  *  The following holds additional information about a switch statement,
  133.  *  and is pointed to by the corresponding TN_SWITCH node (which in turn
  134.  *  is referenced by the 'cbJumpDest' field of ILblock).
  135.  */
  136.  
  137. struct swtGenDsc
  138. {
  139.     ILblock             sgdLabBreak;    // break   label
  140.     ILblock             sgdLabDefault;  // default label
  141.  
  142.     unsigned short      sgdCodeSize;    // opcode size
  143.  
  144.     unsigned            sgdMinVal;      // min. case value
  145.     unsigned            sgdMaxVal;      // max. case value
  146.     unsigned            sgdCount;       // count of cases
  147. };
  148.  
  149. /*****************************************************************************
  150.  *
  151.  *  The following is used to keep track of allocated temporaries.
  152.  */
  153.  
  154. DEFMGMT
  155. class   ILtempDsc
  156. {
  157. public:
  158.     ILtemp          tmpNext;            // next of same type
  159.     ILtemp          tmpNxtN;            // next in order of slot index
  160. #ifdef  DEBUG
  161.     genericRef      tmpSelf;            // to detect bogus values
  162. #endif
  163.     TypDef          tmpType;            // type the temp can hold
  164.     unsigned        tmpNum;             // the slot number
  165. };
  166.  
  167. /*****************************************************************************
  168.  *
  169.  *  The following is used to maintain the string pool.
  170.  */
  171.  
  172. const   size_t      STR_POOL_BLOB_SIZE = OS_page_size;
  173.  
  174. DEFMGMT
  175. class   strEntryDsc
  176. {
  177. public:
  178.     StrEntry        seNext;             // next in list
  179.     size_t          seSize;             // total allocated data size
  180.     size_t          seFree;             // available data size
  181.     size_t          seOffs;             // relative base offset of this blob
  182.     genericBuff     seData;             // the data of this blob
  183. };
  184.  
  185. /*****************************************************************************/
  186.  
  187. typedef
  188. unsigned            genStkMarkTP;       // used to mark/restore stack level
  189.  
  190. /*****************************************************************************
  191.  *
  192.  *  The following is used to describe each opcode; see ILopcodeCodes[] and
  193.  *  ILopcodeStack[] for details.
  194.  */
  195.  
  196. struct  ILencoding
  197. {
  198.     unsigned        ILopc1  :8;
  199.     unsigned        ILopc2  :8;
  200.     unsigned        ILopcL  :2;
  201. };
  202.  
  203. /*****************************************************************************
  204.  *
  205.  *  The following structure describes each recorded line#.
  206.  */
  207.  
  208. DEFMGMT
  209. class   lineInfoRec
  210. {
  211. public:
  212.  
  213.     LineInfo        lndNext;
  214.  
  215.     unsigned        lndLineNum;
  216.  
  217.     ILblock         lndBlkAddr;
  218.     size_t          lndBlkOffs;
  219. };
  220.  
  221. /*****************************************************************************
  222.  *
  223.  *  The following is used for multi-dimensional rectangular array initializers.
  224.  */
  225.  
  226. struct  mulArrDsc
  227. {
  228.     mulArrDsc   *   madOuter;
  229.     unsigned        madIndex;
  230.     unsigned        madCount;
  231. };
  232.  
  233. /*****************************************************************************/
  234.  
  235. struct  genCloneDsc;    // for now this type fully declared in genIL.cpp
  236.  
  237. /*****************************************************************************/
  238.  
  239. // The name is just too long, declare a short-cut:
  240.  
  241. #if MGDDATA
  242. typedef       IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT            EH_CLAUSE;
  243. typedef       IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT managed [] EH_CLAUSE_TAB;
  244. typedef       IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT managed [] EH_CLAUSE_TBC;
  245. #else
  246. typedef       IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT            EH_CLAUSE;
  247. typedef       IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT         *  EH_CLAUSE_TAB;
  248. typedef const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT         *  EH_CLAUSE_TBC;
  249. #endif
  250.  
  251. /*****************************************************************************/
  252.  
  253. DEFMGMT
  254. class   genIL
  255. {
  256. private:
  257.  
  258.     Compiler        genComp;
  259.     SymTab          genStab;
  260.     norls_allocator*genAlloc;
  261.     Parser          genParser;
  262.     WritePE         genPEwriter;
  263.  
  264.     /************************************************************************/
  265.     /*  Keeps track of the local variable and argument count                */
  266.     /************************************************************************/
  267.  
  268. private:
  269.     unsigned        genLclCount;
  270.     unsigned        genArgCount;
  271.     unsigned        genTmpCount;
  272.     unsigned        genTmpBase;
  273.  
  274.     unsigned        genGetLclIndex(SymDef varSym);
  275.  
  276. public:
  277.  
  278.     unsigned        genNextLclNum()
  279.     {
  280.         return  genLclCount++;
  281.     }
  282.  
  283.     unsigned        genNextArgNum()
  284.     {
  285.         return  genArgCount++;
  286.     }
  287.  
  288.     unsigned        genGetLclCnt()
  289.     {
  290.         return  genLclCount + genTmpCount;
  291.     }
  292.  
  293.     /************************************************************************/
  294.     /*  The current fucntion scope and symbol                               */
  295.     /************************************************************************/
  296.  
  297.     SymDef          genFncScope;
  298.     SymDef          genFncSym;
  299.  
  300.     /************************************************************************/
  301.     /*  This holds the current and maximum virtual execution stack level.   */
  302.     /************************************************************************/
  303.  
  304. public:
  305.  
  306.     unsigned        genCurStkLvl;
  307.     unsigned        genMaxStkLvl;
  308.  
  309. private:
  310.  
  311.     void            markStkLvl(INOUT genStkMarkTP REF stkMark)
  312.     {
  313.         stkMark = genCurStkLvl;
  314.     }
  315.  
  316.     void            restStkLvl(INOUT genStkMarkTP REF stkMark)
  317.     {
  318.         genCurStkLvl = stkMark;
  319.     }
  320.  
  321.     void            genMarkStkMax()
  322.     {
  323.         if  (genMaxStkLvl < genCurStkLvl)
  324.              genMaxStkLvl = genCurStkLvl;
  325.     }
  326.  
  327.     void            genUpdateStkLvl(unsigned op);
  328.  
  329.     /************************************************************************/
  330.     /*  These are used for bufferring of opcodes to form sections           */
  331.     /************************************************************************/
  332.  
  333.     BYTE    *       genBuffAddr;
  334.     BYTE    *       genBuffNext;
  335.     BYTE    *       genBuffLast;
  336.  
  337.     void            genBuffInit();
  338.     void            genBuffFlush();
  339.  
  340.     ILblock         genAllocBlk();
  341.  
  342.     genericRef      genBegBlock(ILblock block = NULL);
  343.     ILblock         genEndBlock(unsigned jumpCode, ILblock jumpDest = NULL);
  344.  
  345.     BYTE    *       genJmp32(BYTE *dst, ILblock dest, unsigned offs);
  346.  
  347. public:
  348.  
  349.     void            genSwitch(unsigned      caseSpn,
  350.                               unsigned      caseCnt,
  351.                               unsigned      caseMin,
  352.                               vectorTree    caseTab,
  353.                               ILblock       caseBrk);
  354.  
  355.     void            genSwtCmpJmp(int cval, ILblock lab)
  356.     {
  357.         genIntConst(cval);
  358.         genOpcode_lab(CEE_BEQ, lab);
  359.     }
  360.  
  361. private:
  362.  
  363.     bool            genCurBlkNonEmpty();
  364.     size_t          genCurOffset();
  365.  
  366. public:
  367.  
  368.     ILblock         genBuffCurAddr();
  369.     size_t          genBuffCurOffs();
  370.  
  371.     unsigned        genCodeAddr(genericRef block, size_t offset);
  372.  
  373.     /************************************************************************/
  374.     /*  Low-level routines that generate individual IL opcodes              */
  375.     /************************************************************************/
  376.  
  377.     void            genILdata_I1(int         v);
  378.     void            genILdata_I2(int         v);
  379.     void            genILdata_I4(int         v);
  380.     void            genILdata_I8(__int64     v);
  381.     void            genILdata_R4(float       v);
  382.     void            genILdata_R8(double      v);
  383.     void            genILdataStr(unsigned    o);
  384.     void            genILdataRVA(unsigned    o, WPEstdSects s);
  385. //  void            genILdata   (const void *data, size_t size);
  386.  
  387.     void            genILdataFix(WPEstdSects s);
  388.  
  389.     void            genOpcodeOper(unsigned op);
  390.     unsigned        genOpcodeEnc (unsigned op);
  391.     size_t          genOpcodeSiz (unsigned op);
  392.  
  393.     void            genOpcode    (unsigned op);
  394.     void            genOpcodeNN  (unsigned op);
  395.     void            genOpcode_I1 (unsigned op, int         v);
  396.     void            genOpcode_U1 (unsigned op, unsigned    v);
  397.     void            genOpcode_U2 (unsigned op, unsigned    v);
  398.     void            genOpcode_I4 (unsigned op, int         v);
  399.     void            genOpcode_I8 (unsigned op, __int64     v);
  400.     void            genOpcode_R4 (unsigned op, float       v);
  401.     void            genOpcode_R8 (unsigned op, double      v);
  402.     void            genOpcode_lab(unsigned op, ILblock     l);
  403.     void            genOpcode_tok(unsigned op, mdToken     t);
  404.     void            genOpcode_str(unsigned op, unsigned    offs);
  405.     void            genOpcode_RVA(unsigned op, WPEstdSects sect,
  406.                                                unsigned    offs);
  407.  
  408. #if DISP_IL_CODE
  409.  
  410.     char    *       genDispILnext;
  411.     char            genDispILbuff[IL_OPCDSP_LEN+64];
  412.     unsigned        genDispILinsLst;
  413.  
  414.     void            genDispILins_I1(int     v);
  415.     void            genDispILins_I2(int     v);
  416.     void            genDispILins_I4(int     v);
  417.     void            genDispILins_I8(__int64 v);
  418.     void            genDispILins_R4(float   v);
  419.     void            genDispILins_R8(double  v);
  420.  
  421.     void            genDispILopc   (const char *name, const char *suff = NULL);
  422.     void            genDispILinsBeg(unsigned op);
  423.     void    __cdecl genDispILinsEnd(const char *fmt, ...);
  424.  
  425. #endif
  426.  
  427. public:
  428.     mdToken         genMethodRef (SymDef fncSym, bool   virtRef);   // called from comp
  429. private:
  430.     mdToken         genVarargRef (SymDef fncSym, Tree      call);
  431.     mdToken         genInfFncRef (TypDef fncTyp, TypDef thisArg);
  432.     mdToken         genMemberRef (SymDef fldSym);
  433.     mdToken         genTypeRef   (TypDef type);
  434.     mdToken         genValTypeRef(TypDef type);
  435.  
  436. public:
  437.  
  438.     void            genJump(ILblock dest)
  439.     {
  440.         genOpcode_lab(CEE_BR, dest);
  441.     }
  442.  
  443.     void            genJcnd(ILblock dest, unsigned opcode)
  444.     {
  445.         genOpcode_lab(opcode, dest);
  446.     }
  447.  
  448.     void            genLeave(ILblock dest)
  449.     {
  450.         genOpcode_lab(CEE_LEAVE, dest);
  451.     }
  452.  
  453.     void            genAssertFail(Tree expr)
  454.     {
  455.         genExpr(expr, false);
  456. //      genOpcode(CEE_BREAK);   // ISSUE: when should we generate a break?
  457.     }
  458.  
  459.     /************************************************************************/
  460.     /*  Keep track of line# info (for debugging)                            */
  461.     /************************************************************************/
  462.  
  463. private:
  464.  
  465.     bool            genLineNums;
  466.     bool            genLineNumsBig;
  467.     bool            genLineOffsBig;
  468.  
  469.     LineInfo        genLineNumList;
  470.     LineInfo        genLineNumLast;
  471.  
  472.     unsigned        genLineNumLastLine;
  473.     ILblock         genLineNumLastBlk;
  474.     size_t          genLineNumLastOfs;
  475.  
  476.     void            genLineNumInit();
  477.     void            genLineNumDone();
  478.  
  479.     void            genRecExprAdr(Tree expr);
  480.  
  481. public:
  482.     void            genRecExprPos(Tree expr)
  483.     {
  484.         if  (genLineNums)
  485.             genRecExprAdr(expr);
  486.     }
  487.  
  488.     size_t          genLineNumOutput(unsigned *offsTab, unsigned *lineTab);
  489.  
  490.     /************************************************************************/
  491.     /*  Generate code for a block, statement, expression, etc.              */
  492.     /************************************************************************/
  493.  
  494. private:
  495.  
  496.     void            genCloneAddrBeg(genCloneDsc *clone, Tree     addr,
  497.                                                         unsigned offs = 0);
  498.     void            genCloneAddrUse(genCloneDsc *clone);
  499.     void            genCloneAddrEnd(genCloneDsc *clone);
  500.  
  501.     void            genGlobalAddr(Tree expr);
  502.  
  503.     void            genAddr(Tree addr, unsigned offs = 0);
  504.  
  505.     bool            genGenAddressOf(Tree addr, bool oneUse, unsigned *tnumPtr = NULL,
  506.                                                             TypDef   *ttypPtr = NULL);
  507.     bool            genCanTakeAddr(Tree expr);
  508.  
  509.     var_types       genExprVtyp(Tree expr);
  510.  
  511.     void            genRelTest(Tree cond, Tree op1,
  512.                                           Tree op2, int     sense,
  513.                                                     ILblock labTrue);
  514.  
  515.     unsigned        genArrBounds(TypDef type, OUT TypDef REF elemRef);
  516.  
  517.     void            genMulDimArrInit(Tree       expr,
  518.                                      TypDef     type,
  519.                                      DimDef     dims,
  520.                                      unsigned   temp,
  521.                                      mulArrDsc *next,
  522.                                      mulArrDsc *outer);
  523.     void            genArrayInit    (Tree       expr);
  524.  
  525.     void            genFncAddr(Tree expr);
  526.     void            genNewExpr(Tree expr, bool valUsed, Tree dstx = NULL);
  527.     void            genAsgOper(Tree expr, bool valUsed);
  528.     unsigned        genConvOpcode(var_types dst, var_types src);
  529.     ILopcodes       genBinopOpcode(treeOps oper, var_types type);
  530.  
  531.     void            genVOSindexAsgOp(Tree expr, int delta, bool post, bool asgop, bool valUsed);
  532.     void            genIncDecByExpr(int delta, TypDef type);
  533.     void            genIncDec(Tree expr, int delta, bool post, bool valUsed);
  534.     void            genLclVarAdr(unsigned slot);
  535.     void            genLclVarAdr(SymDef varSym);
  536.     void            genLclVarRef(SymDef varSym, bool store);
  537.     void            genArgVarRef(unsigned slot, bool store);
  538.     void            genStringLit(TypDef type, const char *str, size_t len, int wide = 0);
  539.  
  540. public:
  541.  
  542.     void            genAnyConst(int     val, var_types vtp);
  543.     void            genLngConst(__int64 val);
  544.     void            genIntConst(__int32 val);
  545.  
  546.     void            genInstStub();
  547.  
  548.     void            genLclVarRef(unsigned  index, bool store);
  549.  
  550.     ILblock         genTestCond(Tree cond, bool sense);
  551.  
  552.     void            genExprTest(Tree            expr,
  553.                                 int             sense,
  554.                                 int             genJump, ILblock labTrue,
  555.                                                          ILblock labFalse);
  556.  
  557.     /*----------------------------------------------------------------------*/
  558.  
  559.     void            genBitFieldLd(Tree      expr, bool didAddr, bool valUsed);
  560.     void            genBitFieldSt(Tree      dstx, Tree newx,
  561.                                                   Tree asgx,
  562.                                                   int  delta,
  563.                                                   bool post,    bool valUsed);
  564.  
  565.     /*----------------------------------------------------------------------*/
  566.  
  567.     void            genStmtRet   (Tree      retv);
  568.     void            genSideEff   (Tree      expr);
  569.     void            genCast      (Tree      expr, TypDef type, unsigned flags);
  570.     void            genCall      (Tree      expr, bool valUsed);
  571.     void            genRef       (Tree      expr, bool store);
  572.     unsigned        genAdr       (Tree      expr, bool compute = false);
  573.     void            genExpr      (Tree      stmt, bool valUsed);
  574.  
  575.     /************************************************************************/
  576.     /*  The following are used to process labels and jumps                  */
  577.     /************************************************************************/
  578.  
  579. #if DISP_IL_CODE
  580.     const   char *  genDspLabel(ILblock lab);
  581.     void            genDspLabDf(ILblock lab);
  582. #endif
  583.  
  584.     ILblock         genBwdLab();
  585.     ILblock         genFwdLabGet();
  586.     void            genFwdLabDef(ILblock block);
  587.  
  588.     size_t          genJumpMaxSize(unsigned opcode);
  589.     unsigned        genShortenJump(unsigned opcode, size_t *newSize);
  590.  
  591.     /************************************************************************/
  592.     /*  The following keeps track of temporary labels                       */
  593.     /************************************************************************/
  594.  
  595. #if DISP_IL_CODE
  596.     const   char *  genTempLabName();
  597.     unsigned        genTempLabCnt;
  598. #endif
  599.  
  600.     void            genTempLabInit()
  601.     {
  602. #if DISP_IL_CODE
  603.         genTempLabCnt = 0;
  604. #endif
  605.     }
  606.  
  607.     /************************************************************************/
  608.     /*  The following keeps track of temporary variables                    */
  609.     /************************************************************************/
  610.  
  611.     unsigned        genTempVarCnt [TYP_COUNT];
  612.     ILtemp          genTempVarUsed[TYP_COUNT];
  613.     ILtemp          genTempVarFree[TYP_COUNT];
  614.  
  615.     ILtemp          genTempList;
  616.     ILtemp          genTempLast;
  617.  
  618.     void            genTempVarInit();   // called at startup
  619.     void            genTempVarDone();   // called at shutdown
  620.  
  621.     void            genTempVarBeg(unsigned lclCnt);
  622.     void            genTempVarEnd();
  623.  
  624. #ifdef  DEBUG
  625.     void            genTempVarChk();    // checks that all temps have been freed
  626. #else
  627.     void            genTempVarChk(){}
  628. #endif
  629.  
  630. public:
  631.  
  632.     unsigned        genTempVarGet(TypDef type);
  633.     void            genTempVarRls(TypDef type, unsigned tnum);
  634.  
  635.     void            genTempVarNew(SymDef tsym)
  636.     {
  637.         tsym->sdVar.sdvILindex = genTempVarGet(tsym->sdType);
  638.     }
  639.  
  640.     void            genTempVarEnd(SymDef tsym)
  641.     {
  642.         genTempVarRls(tsym->sdType, tsym->sdVar.sdvILindex);
  643.     }
  644.  
  645.     genericRef      genTempIterBeg()
  646.     {
  647.         return  genTempList;
  648.     }
  649.  
  650.     genericRef      genTempIterNxt(genericRef iter, OUT TypDef REF typRef);
  651.  
  652.     /************************************************************************/
  653.     /*  The following handles exception handlers                            */
  654.     /************************************************************************/
  655.  
  656. private:
  657.  
  658.     Handler         genEHlist;
  659.     Handler         genEHlast;
  660.     unsigned        genEHcount;
  661.  
  662. public:
  663.  
  664.     void            genEHtableInit();
  665.     size_t          genEHtableCnt()
  666.     {
  667.         return  genEHcount;
  668.     }
  669.  
  670.     void            genEHtableWrt(EH_CLAUSE_TAB tbl);
  671.  
  672.     void            genEHtableAdd(ILblock tryBegPC,
  673.                                   ILblock tryEndPC,
  674.                                   ILblock filterPC,
  675.                                   ILblock hndBegPC,
  676.                                   ILblock hndEndPC,
  677.                                   TypDef  catchTyp, bool isFinally = false);
  678.  
  679.     void            genCatchBeg(SymDef argSym);
  680.     void            genCatchEnd(bool reachable){}
  681.  
  682.     void            genExcptBeg(SymDef tsym);
  683.     void            genFiltExpr(Tree expr, SymDef esym)
  684.     {
  685.         genCurStkLvl++;
  686.         genLclVarRef(esym->sdVar.sdvILindex, true);
  687.         genExpr(expr, true);
  688.         genOpcode(CEE_ENDFILTER);
  689.     }
  690.  
  691.     void            genEndFinally()
  692.     {
  693.         genOpcode(CEE_ENDFINALLY);
  694.     }
  695.  
  696.     /************************************************************************/
  697.     /*  The following are used for collection operator codegen              */
  698.     /************************************************************************/
  699.  
  700.     /************************************************************************/
  701.     /*  These are used to create and manage code sections                   */
  702.     /************************************************************************/
  703.  
  704.     void            genSectionBeg();
  705.     size_t          genSectionEnd();
  706.  
  707.     BYTE    *       genSectionCopy(BYTE *dst, unsigned baseRVA);
  708.  
  709.     /************************************************************************/
  710.     /* We keep the code blocks on a doubly-linked list and assign them      */
  711.     /* numbers order of creation (and later in order of visiting).          */
  712.     /************************************************************************/
  713.  
  714.     ILblock         genILblockList;
  715.     ILblock         genILblockLast;
  716.     ILblock         genILblockCur;
  717.     unsigned        genILblockLabNum;
  718.  
  719.     size_t          genILblockOffs;
  720.  
  721.     /************************************************************************/
  722.     /*  Debugging members                                                   */
  723.     /************************************************************************/
  724.  
  725. #if DISP_IL_CODE
  726.     bool            genDispCode;
  727. #endif
  728.  
  729.     /************************************************************************/
  730.     /*  The following implements the string pool                            */
  731.     /************************************************************************/
  732.  
  733.     unsigned        genStrPoolOffs;
  734.  
  735.     StrEntry        genStrPoolList;
  736.     StrEntry        genStrPoolLast;
  737.  
  738. public:
  739.  
  740.     void            genStrPoolInit();
  741.     unsigned        genStrPoolAdd (const void *str, size_t len, int wide = 0);
  742.     unsigned        genStrPoolSize();
  743.     void            genStrPoolWrt (memBuffPtr dest);
  744.  
  745.     /************************************************************************/
  746.     /*  Main entry points to initialize/shutdown and generate code          */
  747.     /************************************************************************/
  748.  
  749. public:
  750.  
  751.     bool            genInit    (Compiler        comp,
  752.                                 WritePE         writer,
  753.                                 norls_allocator*alloc);
  754.  
  755.     void            genDone    (bool            errors);
  756.  
  757.     void            genFuncBeg (SymTab          stab,
  758.                                 SymDef          fncSym,
  759.                                 unsigned        lclCnt);
  760.  
  761.     unsigned        genFuncEnd (mdSignature     sigTok,
  762.                                 bool            hadErrs);
  763. };
  764.  
  765. /*****************************************************************************
  766.  *
  767.  *  Return a block that can be used to make forward jump references.
  768.  */
  769.  
  770. inline
  771. ILblock             genIL::genFwdLabGet()
  772. {
  773.     return  genAllocBlk();
  774. }
  775.  
  776. /*****************************************************************************
  777.  *
  778.  *  Generate load/store of a local variable/argument.
  779.  */
  780.  
  781. inline
  782. void                genIL::genLclVarRef(unsigned index, bool store)
  783. {
  784.     if  (index <= 3)
  785.     {
  786.         assert(CEE_LDLOC_0 + 1 == CEE_LDLOC_1);
  787.         assert(CEE_LDLOC_0 + 2 == CEE_LDLOC_2);
  788.         assert(CEE_LDLOC_0 + 3 == CEE_LDLOC_3);
  789.  
  790.         assert(CEE_STLOC_0 + 1 == CEE_STLOC_1);
  791.         assert(CEE_STLOC_0 + 2 == CEE_STLOC_2);
  792.         assert(CEE_STLOC_0 + 3 == CEE_STLOC_3);
  793.  
  794.         genOpcode((store ? CEE_STLOC_0
  795.                          : CEE_LDLOC_0) + index);
  796.     }
  797.     else
  798.     {
  799.         unsigned        opcode = store ? CEE_STLOC
  800.                                        : CEE_LDLOC;
  801.  
  802.         assert(CEE_STLOC_S == CEE_STLOC + (CEE_LDLOC_S-CEE_LDLOC));
  803.         if  (index < 256)
  804.             genOpcode_U1(opcode + (CEE_LDLOC_S-CEE_LDLOC), index);
  805.         else
  806.             genOpcode_I4(opcode, index);
  807.     }
  808. }
  809.  
  810. inline
  811. void                genIL::genArgVarRef(unsigned index, bool store)
  812. {
  813.     if  (index <= 3 && !store)
  814.     {
  815.         assert(CEE_LDARG_0 + 1 == CEE_LDARG_1);
  816.         assert(CEE_LDARG_0 + 2 == CEE_LDARG_2);
  817.         assert(CEE_LDARG_0 + 3 == CEE_LDARG_3);
  818.  
  819.         genOpcode(CEE_LDARG_0 + index);
  820.     }
  821.     else
  822.     {
  823.         unsigned        opcode = store ? CEE_STARG
  824.                                        : CEE_LDARG;
  825.  
  826.         assert(CEE_STARG_S == CEE_STARG + (CEE_LDARG_S-CEE_LDARG));
  827.         if  (index < 256)
  828.             genOpcode_U1(opcode + (CEE_LDARG_S-CEE_LDARG), index);
  829.         else
  830.             genOpcode_I4(opcode, index);
  831.     }
  832. }
  833.  
  834. /*****************************************************************************/
  835. #endif//__PREPROCESS__
  836. /*****************************************************************************/
  837. #endif//_GENIL_H_
  838. /*****************************************************************************/
  839.