home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / class.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  43.4 KB  |  1,577 lines

  1. // $Id: class.h,v 1.19 2001/01/05 09:13:19 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef class_INCLUDED
  11. #define class_INCLUDED
  12.  
  13. #include "platform.h"
  14. #include "semantic.h"
  15. #include "access.h"
  16. #include "tuple.h"
  17. #include "op.h"
  18.  
  19.  
  20. #ifdef    HAVE_JIKES_NAMESPACE
  21. namespace Jikes {    // Open namespace Jikes block
  22. #endif
  23.  
  24.  
  25. class cp_info
  26. {
  27. protected:
  28.     u1 tag;
  29.  
  30.     //
  31.     //    u1 info[]
  32.     //
  33.     // cp_info can be viewed as a generic (abstract, in Java talk) class that must
  34.     // be "extended" to implement the real constant pool objects. The real objects
  35.     // contain the info...
  36.     //
  37.  
  38. public:
  39.  
  40.     cp_info(u1 _tag) : tag(_tag) {}
  41.     virtual ~cp_info() {}
  42.  
  43.     u1 Tag() { return tag; }
  44.  
  45.     virtual void Put(OutputBuffer &output_buffer)
  46.     {
  47.          assert("trying to put unsupported attribute kind" == NULL);
  48.     }
  49.  
  50. #ifdef JIKES_DEBUG
  51.     virtual void Print(Tuple<cp_info *>& constant_pool)
  52.     {
  53.         Coutput << (int) tag;
  54.     }
  55.  
  56.     virtual void Describe(Tuple<cp_info *>& constant_pool)
  57.     {
  58.         Coutput << (int) tag;
  59.     }
  60. #endif
  61. };
  62.  
  63.  
  64. class CONSTANT_Class_info : public cp_info
  65. {
  66.     //
  67.     //    u1 tag;
  68.     //
  69.     // The tag is inherited from cp_info
  70.     //
  71.     u2 name_index;
  72.  
  73. public:
  74.  
  75.     CONSTANT_Class_info(u1 _tag, u2 _name_index) : cp_info(_tag),
  76.                                                    name_index(_name_index)
  77.     {}
  78.     virtual ~CONSTANT_Class_info() {}
  79.  
  80.     virtual void Put(OutputBuffer &output_buffer)
  81.     {
  82.         output_buffer.PutB1(tag);
  83.         output_buffer.PutB2(name_index);
  84.     }
  85.  
  86. #ifdef JIKES_DEBUG
  87.     virtual void Print(Tuple<cp_info *>& constant_pool)
  88.     {
  89.         Coutput << "CONSTANT_Class_info: name_index " << (unsigned) name_index << "\n";
  90.     }
  91.  
  92.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  93.     {
  94.         Coutput << "Class:";  constant_pool[name_index] -> Describe(constant_pool);
  95.     }
  96. #endif
  97. };
  98.  
  99.  
  100. class CONSTANT_Double_info : public cp_info
  101. {
  102.     //
  103.     //    u1 tag;
  104.     //
  105.     // The tag is inherited from cp_info
  106.     //
  107.     u4 high_bytes;
  108.     u4 low_bytes;
  109.  
  110. public:
  111.  
  112.     CONSTANT_Double_info(u1 _tag, u4 _high_bytes, u4 _low_bytes) : cp_info(_tag),
  113.                                                                    high_bytes(_high_bytes),
  114.                                                                    low_bytes(_low_bytes)
  115.     {}
  116.     virtual ~CONSTANT_Double_info() {}
  117.  
  118.     virtual void Put(OutputBuffer &output_buffer)
  119.     {
  120.         output_buffer.PutB1(tag);
  121.         output_buffer.PutB4(high_bytes);
  122.         output_buffer.PutB4(low_bytes);
  123.     }
  124.  
  125. #ifdef JIKES_DEBUG
  126.     virtual void Print(Tuple<cp_info *> &constant_pool)
  127.     {
  128.         Coutput << "CONSTANT_Double_info: bytes " << BaseLong(high_bytes, low_bytes).DoubleView() << "\n";
  129.     }
  130.  
  131.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  132.     {
  133.         Coutput << "D:";
  134.     }
  135. #endif
  136. };
  137.  
  138.  
  139. class CONSTANT_Fieldref_info : public cp_info
  140. {
  141.     //
  142.     //    u1 tag;
  143.     //
  144.     // The tag is inherited from cp_info
  145.     //
  146.     u2 class_index;
  147.     u2 name_and_type_index;
  148.  
  149. public:
  150.  
  151.     CONSTANT_Fieldref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  152.                                                                                 class_index(_class_index),
  153.                                                                                 name_and_type_index(_name_and_type_index)
  154.     {}
  155.     virtual ~CONSTANT_Fieldref_info() {}
  156.  
  157.     virtual void Put(OutputBuffer &output_buffer)
  158.     {
  159.          output_buffer.PutB1(tag);
  160.          output_buffer.PutB2(class_index);
  161.          output_buffer.PutB2(name_and_type_index);
  162.     }
  163.  
  164. #ifdef JIKES_DEBUG
  165.     virtual void Print(Tuple<cp_info *> &constant_pool)
  166.     {
  167.         Coutput << "CONSTANT_Fieldref_info: class_index: "
  168.                 << (unsigned) class_index
  169.                 << ", name_and_type_index: "
  170.                 << (unsigned) name_and_type_index
  171.                 << "\n";
  172.     }
  173.  
  174.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  175.     {
  176.         constant_pool[class_index] -> Describe(constant_pool);
  177.         Coutput << ".";
  178.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  179.     }
  180. #endif
  181. };
  182.  
  183.  
  184. class CONSTANT_Float_info : public cp_info
  185. {
  186.     //
  187.     //    u1 tag;
  188.     //
  189.     // The tag is inherited from cp_info
  190.     //
  191.     u4 bytes;
  192.  
  193. public:
  194.  
  195.     CONSTANT_Float_info(u1 _tag, u4 _bytes) : cp_info(_tag),
  196.                                               bytes(_bytes)
  197.     {}
  198.     virtual ~CONSTANT_Float_info() {}
  199.  
  200.     virtual void Put(OutputBuffer &output_buffer)
  201.     {
  202.         output_buffer.PutB1(tag);
  203.         output_buffer.PutB4(bytes);
  204.     }
  205.  
  206. #ifdef JIKES_DEBUG
  207.     virtual void Print(Tuple<cp_info *> &constant_pool)
  208.     {
  209.         Coutput << "CONSTANT_Float_info: bytes " << (float) bytes << "\n";
  210.     }
  211.  
  212.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  213.     {
  214.         Coutput << "F:";
  215.     }
  216. #endif
  217. };
  218.  
  219.  
  220. class CONSTANT_Integer_info : public cp_info
  221. {
  222.     //
  223.     //    u1 tag;
  224.     //
  225.     // The tag is inherited from cp_info
  226.     //
  227.     u4 bytes;
  228.  
  229. public:
  230.  
  231.     CONSTANT_Integer_info(u1 _tag, u4 _bytes) : cp_info(_tag),
  232.                                                 bytes(_bytes)
  233.     {}
  234.     virtual ~CONSTANT_Integer_info() {}
  235.  
  236.     virtual void Put(OutputBuffer &output_buffer)
  237.     {
  238.         output_buffer.PutB1(tag);
  239.         output_buffer.PutB4(bytes);
  240.     }
  241.  
  242. #ifdef JIKES_DEBUG
  243.     virtual void Print(Tuple<cp_info *> &constant_pool)
  244.     {
  245.         int val = ((bytes >> 24) & 0xff) << 24 | ((bytes >> 16) & 0xff) << 16 | ((bytes >> 8) & 0xff) << 8 | (bytes & 0xff);
  246.         Coutput << "CONSTANT_Integer_info: bytes "
  247.                 << val
  248.                 << "\n";
  249.     }
  250.  
  251.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  252.     {
  253.         Coutput << "I:";
  254.     }
  255. #endif
  256. };
  257.  
  258.  
  259. class CONSTANT_InterfaceMethodref_info : public cp_info
  260. {
  261.     //
  262.     //    u1 tag;
  263.     //
  264.     // The tag is inherited from cp_info
  265.     //
  266.     u2 class_index;
  267.     u2 name_and_type_index;
  268.  
  269. public:
  270.  
  271.     CONSTANT_InterfaceMethodref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  272.                                                                                           class_index(_class_index),
  273.                                                                                           name_and_type_index(_name_and_type_index)
  274.     {}
  275.     virtual ~CONSTANT_InterfaceMethodref_info() {}
  276.  
  277.     virtual void Put(OutputBuffer &output_buffer)
  278.     {
  279.         output_buffer.PutB1(tag);
  280.         output_buffer.PutB2(class_index);
  281.         output_buffer.PutB2(name_and_type_index);
  282.     }
  283.  
  284. #ifdef JIKES_DEBUG
  285.     virtual void Print(Tuple<cp_info *> &constant_pool)
  286.     {
  287.         Coutput << "CONSTANT_InterfaceMethodref_info: class_index: "
  288.                 << (unsigned) class_index
  289.                 << ", name_and_type_index: "
  290.                 << (unsigned) name_and_type_index
  291.                 << "\n";
  292.     }
  293.  
  294.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  295.     {
  296.         constant_pool[class_index] -> Describe(constant_pool);
  297.         Coutput << ".";
  298.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  299.     }
  300. #endif
  301. };
  302.  
  303.  
  304. class CONSTANT_Long_info : public cp_info
  305. {
  306.     //
  307.     // u1 tag;
  308.     //
  309.     // The tag is inherited from cp_info
  310.     //
  311.     u4 high_bytes;
  312.     u4 low_bytes;
  313.  
  314. public:
  315.  
  316.     CONSTANT_Long_info(u1 _tag, u4 _high_bytes, u4 _low_bytes) : cp_info(_tag),
  317.                                                                  high_bytes(_high_bytes),
  318.                                                                  low_bytes(_low_bytes)
  319.     {}
  320.     virtual ~CONSTANT_Long_info() {}
  321.  
  322.     virtual void Put(OutputBuffer &output_buffer)
  323.     {
  324.         output_buffer.PutB1(tag);
  325.         output_buffer.PutB4(high_bytes);
  326.         output_buffer.PutB4(low_bytes);
  327.     }
  328.  
  329. #ifdef JIKES_DEBUG
  330.     virtual void Print(Tuple<cp_info *> &constant_pool)
  331.     {
  332.         Coutput << "CONSTANT_Long_info: bytes \n";
  333.     }
  334.  
  335.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  336.     {
  337.         Coutput << "L:";
  338.     }
  339. #endif
  340. };
  341.  
  342.  
  343. class CONSTANT_Methodref_info : public cp_info
  344. {
  345.     //
  346.     //    u1 tag;
  347.     //
  348.     // The tag is inherited from cp_info
  349.     //
  350.     u2 class_index;
  351.     u2 name_and_type_index;
  352.  
  353. public:
  354.  
  355.     CONSTANT_Methodref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  356.                                                                                  class_index(_class_index),
  357.                                                                                  name_and_type_index(_name_and_type_index)
  358.     {}
  359.     virtual ~CONSTANT_Methodref_info() {}
  360.  
  361.     virtual void Put(OutputBuffer &output_buffer)
  362.     {
  363.         output_buffer.PutB1(tag);
  364.         output_buffer.PutB2(class_index);
  365.         output_buffer.PutB2(name_and_type_index);
  366.     }
  367.  
  368. #ifdef JIKES_DEBUG
  369.     virtual void Print(Tuple<cp_info *> &constant_pool)
  370.     {
  371.         Coutput << "CONSTANT_Methodref_info: class_index: "
  372.                 << (unsigned) class_index
  373.                 << ", name_and_type_index: "
  374.                 << (unsigned) name_and_type_index
  375.                 << "\n";
  376.     }
  377.  
  378.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  379.     {
  380.         constant_pool[class_index] -> Describe(constant_pool);
  381.         Coutput << ".";
  382.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  383.     }
  384. #endif
  385. };
  386.  
  387.  
  388. class CONSTANT_NameAndType_info : public cp_info
  389. {
  390.     //
  391.     //    u1 tag;
  392.     //
  393.     // The tag is inherited from cp_info
  394.     //
  395.     u2 name_index;
  396.     u2 descriptor_index;
  397.  
  398. public:
  399.  
  400.     CONSTANT_NameAndType_info(u1 _tag, u2 _name_index, u2 _descriptor_index) : cp_info(_tag),
  401.                                                                                name_index(_name_index),
  402.                                                                                descriptor_index(_descriptor_index)
  403.     {}
  404.     virtual ~CONSTANT_NameAndType_info() {}
  405.  
  406.     virtual void Put(OutputBuffer &output_buffer)
  407.     {
  408.         output_buffer.PutB1(tag);
  409.         output_buffer.PutB2(name_index);
  410.         output_buffer.PutB2(descriptor_index);
  411.     }
  412.  
  413. #ifdef JIKES_DEBUG
  414.     virtual void Print(Tuple<cp_info *> &constant_pool)
  415.     {
  416.         Coutput << "CONSTANT_NameAndType_info: name_index: "
  417.                 << (unsigned) name_index
  418.                 << ", descriptor_index: "
  419.                 << (unsigned) descriptor_index
  420.                 << "\n";
  421.     }
  422.  
  423.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  424.     {
  425.         constant_pool[name_index] -> Describe(constant_pool);
  426.         Coutput << " ";
  427.         constant_pool[descriptor_index] -> Describe(constant_pool);
  428.     }
  429. #endif
  430. };
  431.  
  432.  
  433. class CONSTANT_String_info : public cp_info
  434. {
  435.     //
  436.     //    u1 tag;
  437.     //
  438.     // The tag is inherited from cp_info
  439.     //
  440.     u2 string_index;
  441.  
  442. public:
  443.     CONSTANT_String_info(u1 _tag, u2 _string_index) : cp_info(_tag),
  444.                                                       string_index(_string_index)
  445.     {}
  446.     virtual ~CONSTANT_String_info() {}
  447.  
  448.     virtual void Put(OutputBuffer &output_buffer)
  449.     {
  450.         output_buffer.PutB1(tag);
  451.         output_buffer.PutB2(string_index);
  452.     }
  453.  
  454. #ifdef JIKES_DEBUG
  455.     virtual void Print(Tuple<cp_info *> &constant_pool)
  456.     {
  457.         Coutput << "CONSTANT_String_info: string_index: "
  458.                 << (unsigned) string_index
  459.                 << "\n";
  460.     }
  461.  
  462.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  463.     {
  464.         constant_pool[string_index] -> Describe(constant_pool);
  465.     }
  466. #endif
  467. };
  468.  
  469.  
  470. class CONSTANT_Utf8_info : public cp_info
  471. {
  472.     //
  473.     //    u1 tag;
  474.     //
  475.     // The tag is inherited from cp_info
  476.     //
  477.     u2 length_;
  478.     char *bytes; /* bytes[length + 1] ... after input a '\0' will be added. */
  479.  
  480. public:
  481.  
  482.     CONSTANT_Utf8_info(u1 _tag, char *_bytes, int _length) : cp_info(_tag),
  483.                                                              length_(_length)
  484.     {
  485.         bytes = new char[_length];
  486.         for (int i = 0; i < _length; i++)
  487.             bytes[i] = _bytes[i];
  488.  
  489.         return;
  490.     }
  491.     virtual ~CONSTANT_Utf8_info()
  492.     {
  493.         delete [] bytes;
  494.     }
  495.  
  496.     u2 length() { return length_; }
  497.  
  498.     virtual void Put(OutputBuffer &output_buffer)
  499.     {
  500.         output_buffer.PutB1(tag);
  501.         output_buffer.PutB2(length());
  502.         for (int i = 0; i < length(); i++)
  503.             output_buffer.PutB1(bytes[i]);
  504.     }
  505.  
  506. #ifdef JIKES_DEBUG
  507.     virtual void Print(Tuple<cp_info *> &constant_pool)
  508.     {
  509.         Coutput << "CONSTANT_Utf8_info: length: "
  510.                 << (unsigned) length_
  511.                 << " ";
  512.  
  513.         for (int i = 0; i < length_; i++)
  514.             Coutput << (char) bytes[i];
  515.         Coutput << "\n";
  516.     }
  517.  
  518.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  519.     {
  520.         Coutput << "\"";
  521.         for (int i = 0; i < length_; i++)
  522.             Coutput << (char) bytes[i];
  523.         Coutput << "\"";
  524.     }
  525. #endif
  526. };
  527.  
  528.  
  529. //
  530. // field_info and method_info should be defined here, but they contain attributes, so it is necessary
  531. // to define the attributes first.
  532. //
  533.  
  534. class attribute_info
  535. {
  536. protected:
  537.     u1 tag; // this field was added in order to distinguish the attributes...
  538.  
  539.     u2 attribute_name_index;
  540.  
  541.     //
  542.     //    u2 attribute_length;
  543.     //    u1 info[attribute_length];
  544.     //
  545.     // attribute_info can be viewed as a generic (abstract, in Java talk) class that must
  546.     // be "extended" to implement the real attribute objects. The real objects
  547.     // contain the info...
  548.     //
  549.  
  550. public:
  551.     enum
  552.     {
  553.         Generic,
  554.         Code,
  555.         ConstantValue,
  556.         Deprecated,
  557.         Exceptions,
  558.         InnerClasses,
  559.         LineNumberTable,
  560.         LocalVariableTable,
  561.         SourceFile,
  562.         Synthetic
  563.     };
  564.  
  565.     attribute_info(u1 _tag, u2 _name_index) : tag(_tag),
  566.                                               attribute_name_index(_name_index)
  567.     {}
  568.     virtual ~attribute_info() {};
  569.  
  570.     u1 Tag() { return tag; }
  571.     u2 AttributeNameIndex() { return attribute_name_index; }
  572.  
  573.     virtual u4 AttributeLength() { assert(false); return 0; } // abstract method: should not be invoked.
  574.  
  575.     virtual void Put(OutputBuffer &output_buffer) { assert(false); } // abstract method: should not be invoked.
  576.  
  577. #ifdef JIKES_DEBUG
  578.     virtual void Print(Tuple<cp_info *> &constant_pool)
  579.     {
  580.         Coutput << "print for attribute info tag "
  581.                 << (unsigned) tag
  582.                 << " not defined\n";
  583.         Coutput.flush();
  584.         assert(false); // abstract method: should not be invoked.
  585.     }
  586. #endif
  587. };
  588.  
  589.  
  590. class Code_attribute : public attribute_info
  591. {
  592.     //
  593.     //    u2 attribute_name_index;
  594.     //
  595.     // The attribut_name_index is inherited from attribute_info
  596.     //
  597.     u4 attribute_length;
  598.     u2 max_stack;
  599.     u2 max_locals;
  600.  
  601.     //
  602.     //    u4 code_length;
  603.     //
  604.     // code_length can be computed as code.Length();
  605.     //
  606.     Tuple<u1> code; /* code[code_length] */
  607.  
  608.     //
  609.     //    u2 exception_table_length;
  610.     //
  611.     // exception_table_length can be computed as exception_table.Length();
  612.     //
  613.     struct ExceptionElement
  614.     {
  615.         u2 start_pc;
  616.         u2 end_pc;
  617.         u2 handler_pc;
  618.         u2 catch_type;
  619.     };
  620.     Tuple<ExceptionElement> exception_table; /* exceptiontable[exception_table_length] */
  621.  
  622.     //
  623.     //    u2 attribute_count;
  624.     //
  625.     // attribute_count can be computed as attributes.Length();
  626.     //
  627.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  628.  
  629. public:
  630.  
  631.     Code_attribute(u2 _name_index, u2 _max_locals) : attribute_info(Code, _name_index),
  632.                                                      attribute_length(0),
  633.                                                      max_stack(0),
  634.                                                      max_locals(_max_locals),
  635.                                                      code(8, 4),
  636.                                                      exception_table(6, 16),
  637.                                                      attributes(6, 16)
  638.     {}
  639.     virtual ~Code_attribute()
  640.     {
  641.         for (int i = 0; i < attributes.Length(); i++)
  642.             delete attributes[i];
  643.     }
  644.  
  645.     virtual u4 AttributeLength()
  646.     {
  647.         if (attribute_length == 0) // if not yet computed...
  648.         {
  649.             attribute_length = + 2                            // for max_stack
  650.                                + 2                            // for max_locals
  651.                                + 4                            // for code_length
  652.                                + code.Length()                // for code
  653.                                + 2                            // for exception_table_length
  654.                                + exception_table.Length() * 8 // for exception table
  655.                                + 2;                           // for attributes_count
  656.             //
  657.             // std. fields of attribute_info
  658.             //
  659.             for (int i = 0; i < attributes.Length(); i++)
  660.             {
  661.                 if (attributes[i] -> AttributeLength() > 0)
  662.                     attribute_length += (attributes[i] -> AttributeLength() + 6);
  663.             }
  664.         }
  665.  
  666.         return attribute_length;
  667.     }
  668.  
  669.     u2 MaxStack() { return max_stack; }
  670.     void SetMaxStack(u2 val) { max_stack = val; }
  671.  
  672.     u2 MaxLocals() { return max_locals; }
  673.     void ResetMaxLocals(u2 val) { max_locals = val; }
  674.  
  675.     u2 CodeLength() { return code.Length(); }
  676.  
  677.     void ResetCode(int i, u1 byte)
  678.     {
  679.         code[i] = byte;
  680.     }
  681.  
  682.     void AddCode(u1 byte)
  683.     {
  684.         code.Next() = byte;
  685.     }
  686.  
  687.     u2 ExceptionTableLength() { return exception_table.Length(); }
  688.  
  689.     void AddException(u2 start_pc, u2 end_pc, u2 handler_pc, u2 catch_type)
  690.     {
  691.         int exception_index = exception_table.NextIndex();
  692.  
  693.         exception_table[exception_index].start_pc = start_pc;
  694.         exception_table[exception_index].end_pc = end_pc;
  695.         exception_table[exception_index].handler_pc = handler_pc;
  696.         exception_table[exception_index].catch_type = catch_type;
  697.     }
  698.  
  699.     u2 AttributesCount() { return attributes.Length(); }
  700.  
  701.     void AddAttribute(attribute_info *attribute)
  702.     {
  703.         attributes.Next() = attribute;
  704.     }
  705.  
  706.     virtual void Put(OutputBuffer &output_buffer)
  707.     {
  708.         assert(attribute_name_index != 0);
  709.  
  710.         output_buffer.PutB2(attribute_name_index);
  711.         output_buffer.PutB4(AttributeLength());
  712.         output_buffer.PutB2(max_stack);
  713.         output_buffer.PutB2(max_locals);
  714.         output_buffer.PutB4(code.Length());
  715.  
  716.         for (int i = 0; i < code.Length(); i++)
  717.             output_buffer.PutB1(code[i]);
  718.         output_buffer.PutB2(exception_table.Length());
  719.  
  720.         for (int j = 0; j < exception_table.Length(); j++)
  721.         {
  722.             output_buffer.PutB2(exception_table[j].start_pc);
  723.             output_buffer.PutB2(exception_table[j].end_pc);
  724.             output_buffer.PutB2(exception_table[j].handler_pc);
  725.             output_buffer.PutB2(exception_table[j].catch_type);
  726.         }
  727.  
  728.         output_buffer.PutB2(attributes.Length());
  729.         for (int k = 0; k < attributes.Length(); k++)
  730.             attributes[k] -> Put(output_buffer);
  731.  
  732.         return;
  733.     }
  734.  
  735. #ifdef JIKES_DEBUG
  736.     virtual void  Print(Tuple<cp_info *> &constant_pool)
  737.     {
  738.         Coutput << "Code_attribute attribute_name_index "
  739.                 << (unsigned) attribute_name_index
  740.                 << " attribute_length "
  741.                 << (unsigned) attribute_length
  742.                 << "\n"
  743.                 << " max_stack "
  744.                 << (unsigned) max_stack
  745.                 << " max_locals "
  746.                 << (unsigned) max_locals
  747.                 << " code_length "
  748.                 << code.Length()
  749.                 << "\n";
  750.  
  751.         if (exception_table.Length())
  752.         {
  753.             Coutput << " exception_table: " << exception_table.Length() << " entries\n";
  754.             for (int i  = 0; i < exception_table.Length(); i++)
  755.             {
  756.                 Coutput << "  start_pc "
  757.                         << (unsigned) exception_table[i].start_pc
  758.                         << "  end_pc "
  759.                         << (unsigned) exception_table[i].end_pc
  760.                         << "  handler_pc "
  761.                         << (unsigned) exception_table[i].handler_pc
  762.                         << "  catch_type "
  763.                         << (unsigned) exception_table[i].catch_type
  764.                         << "\n";
  765.             }
  766.         }
  767.  
  768.         Operators::opdmp(constant_pool, code);
  769.  
  770.         Coutput << "  \n";
  771.  
  772.         for (int i = 0; i < attributes.Length(); i++)
  773.             attributes[i] -> Print(constant_pool);
  774.     }
  775. #endif
  776. };
  777.  
  778.  
  779. class ConstantValue_attribute : public attribute_info
  780. {
  781.     //
  782.     //    u2 attribute_name_index;
  783.     //
  784.     // The field attribute_name_index is inherited from attribute_info
  785.     //
  786.     //    u4 attribute_length;
  787.     //
  788.     // The value of attribute_length is always 2
  789.     //
  790.     u2 constantvalue_index;
  791.  
  792. public:
  793.  
  794.     ConstantValue_attribute(u2 _name_index, u2 _constantvalue_index) : attribute_info(ConstantValue, _name_index),
  795.                                                                        constantvalue_index(_constantvalue_index)
  796.     {}
  797.     virtual ~ConstantValue_attribute() {}
  798.  
  799.     virtual u4 AttributeLength() { return 2; }
  800.  
  801.     virtual void Put(OutputBuffer &output_buffer)
  802.     {
  803.         assert(attribute_name_index != 0);
  804.  
  805.         output_buffer.PutB2(attribute_name_index);
  806.         output_buffer.PutB4(AttributeLength());
  807.         output_buffer.PutB2(constantvalue_index);
  808.     }
  809.  
  810. #ifdef JIKES_DEBUG
  811.     virtual void Print(Tuple<cp_info *> &constant_pool)
  812.     {
  813.         Coutput << "ConstantValue_attribute attribute_name_index "
  814.                 << (unsigned) attribute_name_index
  815.                 << " attribute_length "
  816.                 << AttributeLength()
  817.                 << " constantvalue_index "
  818.                 << (unsigned) constantvalue_index
  819.                 << "\n";
  820.     }
  821. #endif
  822. };
  823.  
  824.  
  825. class Exceptions_attribute : public attribute_info
  826. {
  827.     //
  828.     //    u2 attribute_name_index;
  829.     //
  830.     // The fields attribute_name_index is inherited from attribute_info
  831.     //
  832.     //    u4 attribute_length;
  833.     //
  834.     // The value of attribute_length is derived from the exception_index_table. See below
  835.     //
  836.     //    u2 number_of_exceptions;
  837.     //
  838.     // The value of number_of_exceptions is derived from the exception_index_table. See below
  839.     //
  840.  
  841.     Tuple<u2> exception_index_table; /* exception_index_table[number_of_exceptions] */
  842.  
  843. public:
  844.  
  845.     Exceptions_attribute(u2 _name_index) : attribute_info(Exceptions, _name_index)
  846.     {}
  847.     virtual ~Exceptions_attribute() {}
  848.  
  849.     virtual u4 AttributeLength()
  850.     {
  851.         return exception_index_table.Length() * 2 + 2;
  852.     }
  853.  
  854.     u2 NumberOfExceptions() { return exception_index_table.Length(); }
  855.  
  856.     void AddExceptionIndex(u2 index)
  857.     {
  858.         exception_index_table.Next() = index;
  859.     }
  860.  
  861.     virtual void Put(OutputBuffer &output_buffer)
  862.     {
  863.         assert(attribute_name_index != 0);
  864.  
  865.         output_buffer.PutB2(attribute_name_index);
  866.         output_buffer.PutB4(AttributeLength());
  867.         output_buffer.PutB2(exception_index_table.Length());
  868.         for (int i = 0; i < exception_index_table.Length(); i++)
  869.             output_buffer.PutB2(exception_index_table[i]);
  870.     }
  871.  
  872. #ifdef JIKES_DEBUG
  873.     virtual void Print(Tuple<cp_info *> &constant_pool)
  874.     {
  875.         Coutput << "Exceptions_attribute attribute_name_index "
  876.                 << (unsigned) attribute_name_index
  877.                 << " attribute_length "
  878.                 << AttributeLength()
  879.                 << "\n";
  880.  
  881.         for (int i = 0; i < exception_index_table.Length(); i++)
  882.             Coutput << "    "
  883.                     << (unsigned) exception_index_table[i];
  884.         Coutput << "\n";
  885.     }
  886. #endif
  887. };
  888.  
  889.  
  890. class InnerClasses_attribute : public attribute_info
  891. {
  892.     //
  893.     //    u2 attribute_name_index;
  894.     //
  895.     // The fields attribute_name_index is inherited from attribute_info
  896.     //
  897.     //    u4 attribute_length;
  898.     //
  899.     // The value of attribute_length is derived from inner_classes. See below
  900.     //
  901.     //    u2 number_of_classes;
  902.     //
  903.     // The value of number_of_classes is derived from inner_classes. See below
  904.     //
  905.  
  906.     struct inner_classes_element
  907.     {
  908.         u2 inner_class_info_index;
  909.         u2 outer_class_info_index;
  910.         u2 inner_name_index;
  911.         u2 inner_class_access_flags;
  912.     };
  913.     Tuple<inner_classes_element> inner_classes; /* inner_classes_table[inner_classes_table_length] */
  914.  
  915. public:
  916.  
  917.     InnerClasses_attribute(u2 _name_index) : attribute_info(InnerClasses, _name_index),
  918.                                              inner_classes(6, 16)
  919.     {}
  920.     virtual ~InnerClasses_attribute() {}
  921.  
  922.     virtual u4 AttributeLength()
  923.     {
  924.         return inner_classes.Length() * 8 + 2;
  925.     }
  926.  
  927.     u2 InnerClassesLength() { return inner_classes.Length();}
  928.  
  929.     void AddInnerClass(u2 inner_class_info_index, u2 outer_class_info_index, u2 inner_name_index, u2 inner_class_access_flags)
  930.     {
  931.         int index = inner_classes.NextIndex();
  932.  
  933.         inner_classes[index].inner_class_info_index = inner_class_info_index;
  934.         inner_classes[index].outer_class_info_index = outer_class_info_index;
  935.         inner_classes[index].inner_name_index = inner_name_index;
  936.         inner_classes[index].inner_class_access_flags = inner_class_access_flags;
  937.     }
  938.  
  939.     virtual void Put(OutputBuffer &output_buffer)
  940.     {
  941.         assert(attribute_name_index != 0);
  942.  
  943.         output_buffer.PutB2(attribute_name_index);
  944.         output_buffer.PutB4(AttributeLength());
  945.         output_buffer.PutB2(inner_classes.Length());
  946.         for (int i = 0; i < inner_classes.Length(); i++)
  947.         {
  948.             output_buffer.PutB2(inner_classes[i].inner_class_info_index);
  949.             output_buffer.PutB2(inner_classes[i].outer_class_info_index);
  950.             output_buffer.PutB2(inner_classes[i].inner_name_index);
  951.             output_buffer.PutB2(inner_classes[i].inner_class_access_flags);
  952.         }
  953.     }
  954.  
  955. #ifdef JIKES_DEBUG
  956.     virtual void Print(Tuple<cp_info *> &constant_pool)
  957.     {
  958.         Coutput << "InnerClasses_attribute attribute_name_index "
  959.                 << (unsigned) attribute_name_index
  960.                 << " attribute_length "
  961.                 << AttributeLength()
  962.                 << "\n"
  963.                 << " inner_classes_length "
  964.                 << inner_classes.Length()
  965.                 << "\n";
  966.  
  967.         for (int i = 0; i < inner_classes.Length(); i++)
  968.         {
  969.             Coutput << "     "
  970.                     << i
  971.                     << "  inner_class_info_index "
  972.                     << (unsigned) inner_classes[i].inner_class_info_index
  973.                     << "  outer_class_info_index "
  974.                     << (unsigned) inner_classes[i].outer_class_info_index
  975.                     << "  inner_name_index "
  976.                     << (unsigned) inner_classes[i].inner_name_index
  977.                     << "  inner_class_access_flags "
  978.                     << (unsigned) inner_classes[i].inner_class_access_flags
  979.                     << "\n";
  980.         }
  981.     }
  982. #endif
  983. };
  984.  
  985.  
  986. class LineNumberTable_attribute : public attribute_info
  987. {
  988.     //
  989.     //    u2 attribute_name_index;
  990.     //
  991.     // The fields attribute_name_index is inherited from attribute_info
  992.     //
  993.     //    u4 attribute_length;
  994.     //
  995.     // The value of attribute_length is derived from line_number_table. See below
  996.     //
  997.     //    u2 line_number_table_length;
  998.     //
  999.     // The value of line_number_table_length is derived from line_number_table. See below
  1000.     //
  1001.  
  1002.     struct line_number_element
  1003.     {
  1004.         u2 start_pc;
  1005.         u2 line_number;
  1006.     };
  1007.     Tuple<line_number_element> line_number_table; /* line_number_table[line_number_table_length] */
  1008.  
  1009. public:
  1010.  
  1011.     LineNumberTable_attribute(u2 _name_index) : attribute_info(LineNumberTable, _name_index),
  1012.                                                 line_number_table(6, 16)
  1013.     {}
  1014.     virtual ~LineNumberTable_attribute() {}
  1015.  
  1016.     virtual u4 AttributeLength()
  1017.     {
  1018.         return line_number_table.Length() * 4 + 2;
  1019.     }
  1020.  
  1021.     u2 LineNumberTableLength()
  1022.     {
  1023.         return line_number_table.Length();
  1024.     }
  1025.  
  1026.     void AddLineNumber(u2 start_pc, u2 line_number)
  1027.     {
  1028.         int line_number_index = line_number_table.NextIndex();
  1029.  
  1030.         line_number_table[line_number_index].start_pc = start_pc;
  1031.         line_number_table[line_number_index].line_number = line_number;
  1032.     }
  1033.  
  1034.     virtual void Put(OutputBuffer &output_buffer)
  1035.     {
  1036.         assert(attribute_name_index != 0);
  1037.  
  1038.         output_buffer.PutB2(attribute_name_index);
  1039.         output_buffer.PutB4(AttributeLength());
  1040.         output_buffer.PutB2(line_number_table.Length());
  1041.         for (int i = 0; i < line_number_table.Length(); i++)
  1042.         {
  1043.             output_buffer.PutB2(line_number_table[i].start_pc);
  1044.             output_buffer.PutB2(line_number_table[i].line_number);
  1045.         }
  1046.     }
  1047.  
  1048. #ifdef JIKES_DEBUG
  1049.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1050.      {
  1051.         Coutput << "LineNumberTable_attribute attribute_name_index "
  1052.                 << (unsigned) attribute_name_index
  1053.                 << " attribute_length "
  1054.                 << AttributeLength()
  1055.                 << "\n"
  1056.                 << " line_number_table_length "
  1057.                 << line_number_table.Length()
  1058.                 << "\n";
  1059.  
  1060.         for (int i = 0; i < line_number_table.Length(); i++)
  1061.         {
  1062.             Coutput << "     "
  1063.                     << i
  1064.                     << "  start_pc "
  1065.                     << (unsigned) line_number_table[i].start_pc
  1066.                     << "  line_number "
  1067.                     << (unsigned) line_number_table[i].line_number
  1068.                     << "\n";
  1069.         }
  1070.     }
  1071. #endif
  1072. };
  1073.  
  1074.  
  1075. class LocalVariableTable_attribute : public attribute_info
  1076. {
  1077.     //
  1078.     //    u2 attribute_name_index;
  1079.     //
  1080.     // The fields attribute_name_index is inherited from attribute_info
  1081.     //
  1082.     //    u4 attribute_length;
  1083.     //
  1084.     // The value of attribute_length is derived from local_variable_table. See below
  1085.     //
  1086.     //    u2 local_variable_length;
  1087.     //
  1088.     // The value of local_variable_length is derived from local_variable_length. See below
  1089.     //
  1090.  
  1091.     struct local_variable_element
  1092.     {
  1093.         u2 start_pc;
  1094.         u2 length;
  1095.         u2 name_index;
  1096.         u2 descriptor_index;
  1097.         u2 index;
  1098.     };
  1099.     Tuple<local_variable_element> local_variable_table; /* local_variable_table[local_variable_table_length] */
  1100.  
  1101. public:
  1102.  
  1103.     LocalVariableTable_attribute(u2 _name_index) : attribute_info(LocalVariableTable, _name_index)
  1104.     {}
  1105.     virtual ~LocalVariableTable_attribute() {}
  1106.  
  1107.     virtual u4 AttributeLength()
  1108.     {
  1109.         return local_variable_table.Length() * 10 + 2;
  1110.     }
  1111.  
  1112.     u2 LocalVariableTableLength() { return local_variable_table.Length(); }
  1113.  
  1114.     //
  1115.     // make entry in local variable table
  1116.     //
  1117.     void AddLocalVariable(u2 start, u2 end, u2 name, u2 descriptor, u2 index)
  1118.     {
  1119.         assert(end >= start);
  1120.  
  1121.         if (end > start)
  1122.         {
  1123.             int local_index = local_variable_table.NextIndex();
  1124.  
  1125.             local_variable_table[local_index].start_pc = start;
  1126.             local_variable_table[local_index].length = end - start;
  1127.             local_variable_table[local_index].name_index = name;
  1128.             local_variable_table[local_index].descriptor_index = descriptor;
  1129.             local_variable_table[local_index].index = index;
  1130.         }
  1131. else 
  1132. end = end;
  1133.  
  1134.         return;
  1135.     }
  1136.  
  1137.     virtual void Put(OutputBuffer &output_buffer)
  1138.     {
  1139.         assert(attribute_name_index != 0);
  1140.  
  1141.         output_buffer.PutB2(attribute_name_index);
  1142.         output_buffer.PutB4(AttributeLength());
  1143.         output_buffer.PutB2(local_variable_table.Length());
  1144.         for (int i = 0; i < local_variable_table.Length(); i++)
  1145.         {
  1146.             output_buffer.PutB2(local_variable_table[i].start_pc);
  1147.             output_buffer.PutB2(local_variable_table[i].length);
  1148.             output_buffer.PutB2(local_variable_table[i].name_index);
  1149.             output_buffer.PutB2(local_variable_table[i].descriptor_index);
  1150.             output_buffer.PutB2(local_variable_table[i].index);
  1151.         }
  1152.     }
  1153.  
  1154. #ifdef JIKES_DEBUG
  1155.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1156.     {
  1157.         Coutput << "LocalVariableTable_attribute attribute_name_index "
  1158.                 << (unsigned) attribute_name_index
  1159.                 << " attribute_length "
  1160.                 << AttributeLength()
  1161.                 << "\n"
  1162.                 << " local_variable_table_length "
  1163.                 << local_variable_table.Length()
  1164.                 << "\n";
  1165.  
  1166.         for (int i = 0; i < local_variable_table.Length(); i++)
  1167.         {
  1168.             Coutput << "     "
  1169.                     << i
  1170.                     << "  start_pc "
  1171.                     << (unsigned) local_variable_table[i].start_pc
  1172.                     << "  length "
  1173.                     << (unsigned) local_variable_table[i].length
  1174.                     << "  name_index "
  1175.                     << (unsigned) local_variable_table[i].name_index
  1176.                     << "  descriptor_index "
  1177.                     << (unsigned) local_variable_table[i].descriptor_index
  1178.                     << "  index "
  1179.                     << (unsigned) local_variable_table[i].index
  1180.                     << "\n";
  1181.         }
  1182.     }
  1183. #endif
  1184. };
  1185.  
  1186.  
  1187. class SourceFile_attribute : public attribute_info
  1188. {
  1189.     //
  1190.     //    u2 attribute_name_index;
  1191.     //
  1192.     // The fields attribute_name_index is inherited from attribute_info
  1193.     //
  1194.     // The attribute_length is always 2.
  1195.     //
  1196.     u2 sourcefile_index;
  1197.  
  1198. public:
  1199.  
  1200.     SourceFile_attribute(u2 _name_index, u2 _sourcefile_index) : attribute_info(SourceFile, _name_index),
  1201.                                                                  sourcefile_index(_sourcefile_index)
  1202.     {}
  1203.     virtual ~SourceFile_attribute() {}
  1204.  
  1205.     virtual u4 AttributeLength() { return 2; }
  1206.  
  1207.     virtual void Put(OutputBuffer &output_buffer)
  1208.     {
  1209.         assert(attribute_name_index != 0);
  1210.  
  1211.         output_buffer.PutB2(attribute_name_index);
  1212.         output_buffer.PutB4(AttributeLength());
  1213.         output_buffer.PutB2(sourcefile_index);
  1214.     }
  1215.  
  1216. #ifdef JIKES_DEBUG
  1217.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1218.     {
  1219.         Coutput << "SourceFile_attribute attribute_name_index "
  1220.                 << (unsigned) attribute_name_index
  1221.                 << " length "
  1222.                 << AttributeLength()
  1223.                 << " sourcefile_index "
  1224.                 << (unsigned) sourcefile_index
  1225.                 << "\n";
  1226.     }
  1227. #endif
  1228. };
  1229.  
  1230.  
  1231. class Synthetic_attribute : public attribute_info
  1232. {
  1233.     //
  1234.     //    u2 attribute_name_index;
  1235.     //
  1236.     // The fields attribute_name_index and attribute_length are inherited from attribute_info
  1237.     //
  1238.     // The attribute_length is always 0.
  1239.     //
  1240.  
  1241. public:
  1242.  
  1243.     Synthetic_attribute(u2 _name_index) : attribute_info(Synthetic, _name_index)
  1244.     {}
  1245.     virtual ~Synthetic_attribute() {}
  1246.  
  1247.     virtual u4 AttributeLength() { return 0; }
  1248.  
  1249.     virtual void Put(OutputBuffer &output_buffer)
  1250.     {
  1251.         assert(attribute_name_index != 0);
  1252.  
  1253.         output_buffer.PutB2(attribute_name_index);
  1254.         output_buffer.PutB4(AttributeLength());
  1255.     }
  1256.  
  1257. #ifdef JIKES_DEBUG
  1258.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1259.     {
  1260.         Coutput << "Synthetic_attribute attribute_name_index "
  1261.                 << (unsigned) attribute_name_index
  1262.                 << " length "
  1263.                 << AttributeLength()
  1264.                 << "\n";
  1265.     }
  1266. #endif
  1267. };
  1268.  
  1269.  
  1270. class Deprecated_attribute : public attribute_info
  1271. {
  1272.     //
  1273.     //    u2 attribute_name_index;
  1274.     //
  1275.     // The fields attribute_name_index and attribute_length are inherited from attribute_info
  1276.     //
  1277.     // The attribute_length is always 0.
  1278.     //
  1279.  
  1280. public:
  1281.  
  1282.     Deprecated_attribute(u2 _name_index) : attribute_info(Deprecated, _name_index)
  1283.     {}
  1284.     virtual ~Deprecated_attribute() {}
  1285.  
  1286.     virtual u4 AttributeLength() { return 0; }
  1287.  
  1288.     virtual void Put(OutputBuffer &output_buffer)
  1289.     {
  1290.         assert(attribute_name_index != 0);
  1291.  
  1292.         output_buffer.PutB2(attribute_name_index);
  1293.         output_buffer.PutB4(AttributeLength());
  1294.     }
  1295.  
  1296. #ifdef JIKES_DEBUG
  1297.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1298.     {
  1299.         Coutput << "Deprecated_attribute attribute_name_index "
  1300.                 << (unsigned) attribute_name_index
  1301.                 << " length "
  1302.                 << AttributeLength()
  1303.                 << "\n";
  1304.     }
  1305. #endif
  1306. };
  1307.  
  1308.  
  1309. class field_info : public AccessFlags
  1310. {
  1311.     //
  1312.     // u2 access_flags;
  1313.     //
  1314.     // The access_flags is inherited from AccessFlags
  1315.     //
  1316.     u2 name_index;
  1317.     u2 descriptor_index;
  1318.  
  1319.     //
  1320.     // attributes_count can be computed as attributes.Length();
  1321.     //
  1322.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1323.  
  1324. public:
  1325.  
  1326.      ~field_info()
  1327.      {
  1328.          for (int i = 0; i < attributes.Length(); i++)
  1329.              delete attributes[i];
  1330.      }
  1331.  
  1332.     inline void SetNameIndex(u2 _name_index) { name_index = _name_index; }
  1333.     inline void SetDescriptorIndex(u2 _descriptor_index) { descriptor_index = _descriptor_index; }
  1334.  
  1335.     inline u2 AttributesCount() { return attributes.Length(); }
  1336.     inline void AddAttribute(attribute_info *attribute) { attributes.Next() = attribute; }
  1337.  
  1338.     inline void Put(OutputBuffer &output_buffer)
  1339.     {
  1340.         output_buffer.PutB2(access_flags);
  1341.         output_buffer.PutB2(name_index);
  1342.         output_buffer.PutB2(descriptor_index);
  1343.         output_buffer.PutB2(attributes.Length());
  1344.  
  1345.         for (int ai = 0; ai < attributes.Length(); ai++)
  1346.             attributes[ai] -> Put(output_buffer);
  1347.     }
  1348.  
  1349. #ifdef JIKES_DEBUG
  1350.     void Print(Tuple<cp_info *> &constant_pool)
  1351.     {
  1352.         Coutput << "field_info  name_index "
  1353.                 << (unsigned) name_index
  1354.                 << "  descriptor_index "
  1355.                 << (unsigned) descriptor_index
  1356.                 << "\n";
  1357.  
  1358.         AccessFlags::Print();
  1359.  
  1360.         for (int i = 0; i < attributes.Length(); i++)
  1361.             attributes[i] -> Print(constant_pool);
  1362.         Coutput << "\n";
  1363.     }
  1364. #endif
  1365. };
  1366.  
  1367.  
  1368. class method_info : public AccessFlags
  1369. {
  1370.     //
  1371.     // u2 access_flags;
  1372.     //
  1373.     // The access_flags is inherited from AccessFlags
  1374.     //
  1375.     u2 name_index;
  1376.     u2 descriptor_index;
  1377.  
  1378.     //
  1379.     // attributes_count can be computed as attributes.Length();
  1380.     //
  1381.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1382.  
  1383. public:
  1384.  
  1385.     ~method_info()
  1386.     {
  1387.         for (int i = 0; i < attributes.Length(); i++)
  1388.             delete attributes[i];
  1389.     }
  1390.  
  1391.     inline void SetNameIndex(u2 _name_index) { name_index = _name_index; }
  1392.     inline void SetDescriptorIndex(u2 _descriptor_index) { descriptor_index = _descriptor_index; }
  1393.  
  1394.     inline u2 AttributesCount() { return attributes.Length(); }
  1395.     inline void AddAttribute(attribute_info *attribute) { attributes.Next() = attribute; }
  1396.  
  1397.     inline void Put(OutputBuffer &output_buffer)
  1398.     {
  1399.         output_buffer.PutB2(access_flags);
  1400.         output_buffer.PutB2(name_index);
  1401.         output_buffer.PutB2(descriptor_index);
  1402.         output_buffer.PutB2(attributes.Length());
  1403.  
  1404.         for (int i = 0; i < attributes.Length(); i++)
  1405.             attributes[i] -> Put(output_buffer);
  1406.     }
  1407.  
  1408. #ifdef JIKES_DEBUG
  1409.      void Print(Tuple<cp_info *> &constant_pool)
  1410.      {
  1411.         Coutput << "method_info  name_index "
  1412.                 << (unsigned) name_index
  1413.                 << "  descriptor_index "
  1414.                 << (unsigned) descriptor_index
  1415.                 << "\n";
  1416.  
  1417.         AccessFlags::Print();
  1418.  
  1419.         for (int i = 0; i < attributes.Length(); i++)
  1420.             attributes[i] -> Print(constant_pool);
  1421.         Coutput << "\n";
  1422.     }
  1423. #endif
  1424. };
  1425.  
  1426.  
  1427. class ClassFile : public AccessFlags
  1428. {
  1429. public:
  1430.     enum ConstantKind
  1431.     {
  1432.         CONSTANT_Class              = 7,
  1433.         CONSTANT_Fieldref           = 9,
  1434.         CONSTANT_Methodref          = 10,
  1435.         CONSTANT_InterfaceMethodref = 11,
  1436.         CONSTANT_String             = 8,
  1437.         CONSTANT_Integer            = 3,
  1438.         CONSTANT_Float              = 4,
  1439.         CONSTANT_Long               = 5,
  1440.         CONSTANT_Double             = 6,
  1441.         CONSTANT_NameAndType        = 12,
  1442.         CONSTANT_Utf8               = 1
  1443.     };
  1444.  
  1445.     u4 magic;
  1446.     u2 minor_version;
  1447.     u2 major_version;
  1448.     u2 ConstantPoolCount() { return constant_pool.Length(); }
  1449.     Tuple<cp_info *> constant_pool; /* cp_info[constant_pool_count] */
  1450.     //
  1451.     // u2 access_flags;
  1452.     //
  1453.     // The access_flags is inherited from AccessFlags
  1454.     //
  1455.     u2 this_class;
  1456.     u2 super_class;
  1457.     u2 InterfacesCount() { return interfaces.Length(); }
  1458.     Tuple<u2> interfaces; /* interfaces[interfaces_count] */
  1459.     u2 FieldsCount() { return fields.Length(); }
  1460.     Tuple<field_info> fields; /* fields[fields_count] */
  1461.     u2 MethodsCount() { return methods.Length();}
  1462.     Tuple<method_info> methods; /* methods[methods_count] */
  1463.     u2 AttributesCount() { return attributes.Length(); }
  1464.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1465.  
  1466.     ClassFile(TypeSymbol *unit_type_) : constant_pool(8, 4),
  1467.                                         fields(6, 16),
  1468.                                         methods(6, 16),
  1469.                                         unit_type(unit_type_)
  1470.     {}
  1471.  
  1472.     ~ClassFile()
  1473.     {
  1474.         for (int i = 1; i < constant_pool.Length(); i++)
  1475.             delete constant_pool[i];
  1476.  
  1477.         for (int j = 0; j < attributes.Length(); j++)
  1478.             delete attributes[j];
  1479.  
  1480.         return;
  1481.     }
  1482.  
  1483.     void Write()
  1484.     {
  1485.         Semantic *sem = unit_type -> semantic_environment -> sem;
  1486.         Control &control = sem -> control;
  1487.  
  1488.         if (! control.option.nowrite)
  1489.         {
  1490.             output_buffer.PutB4(magic);
  1491.             output_buffer.PutB2(minor_version);
  1492.             output_buffer.PutB2(major_version);
  1493.  
  1494.             //
  1495.             // write constant pool
  1496.             //
  1497.             output_buffer.PutB2(constant_pool.Length());
  1498.             for (int i = 1; i < constant_pool.Length(); i++)
  1499.             {
  1500.                 assert(constant_pool[i]);
  1501.  
  1502.                 constant_pool[i] -> Put(output_buffer);
  1503.                 if (constant_pool[i] -> Tag()  ==  CONSTANT_Long || constant_pool[i] -> Tag()  ==  CONSTANT_Double)
  1504.                     i++;; // skip the next entry for eight-byte constants
  1505.             }
  1506.  
  1507.             output_buffer.PutB2(access_flags);
  1508.             output_buffer.PutB2(this_class);
  1509.             output_buffer.PutB2(super_class);
  1510.  
  1511.             //
  1512.             // write interfaces
  1513.             //
  1514.             output_buffer.PutB2(interfaces.Length());
  1515.             for (int j = 0; j < interfaces.Length(); j++)
  1516.                 output_buffer.PutB2(interfaces[j]);
  1517.  
  1518.             //
  1519.             // write field members
  1520.             //
  1521.             output_buffer.PutB2(fields.Length());
  1522.             for (int k = 0; k < fields.Length(); k++)
  1523.                 fields[k].Put(output_buffer);
  1524.  
  1525.             //
  1526.             // write method members
  1527.             //
  1528.             output_buffer.PutB2(methods.Length());
  1529.             for (int l = 0; l < methods.Length(); l++)
  1530.                 methods[l].Put(output_buffer);
  1531.  
  1532.             //
  1533.             // write attributes
  1534.             //
  1535.             output_buffer.PutB2(attributes.Length());
  1536.             for (int m = 0; m < attributes.Length(); m++)
  1537.                 attributes[m] -> Put(output_buffer);
  1538.  
  1539.             char *class_file_name = unit_type -> ClassName();
  1540.             if (control.option.verbose)
  1541.             {
  1542.                 Coutput << "[write "
  1543.                         << class_file_name
  1544.                         << "]\n";
  1545.             }
  1546.  
  1547.             if (! output_buffer.WriteToFile(class_file_name))
  1548.             {
  1549.                 int length = strlen(class_file_name);
  1550.                 wchar_t *name = new wchar_t[length + 1];
  1551.                 for (int i = 0; i < length; i++)
  1552.                     name[i] = class_file_name[i];
  1553.                 name[length] = U_NULL;
  1554.  
  1555.                 sem -> ReportSemError(SemanticError::CANNOT_WRITE_FILE,
  1556.                                      unit_type -> declaration -> LeftToken(),
  1557.                                      unit_type -> declaration -> RightToken(),
  1558.                                      name);
  1559.                 delete [] name;
  1560.             }
  1561.         }
  1562.  
  1563.         return;
  1564.     }
  1565.  
  1566. protected:
  1567.     TypeSymbol *unit_type;
  1568.     OutputBuffer output_buffer;
  1569. };
  1570.  
  1571. #ifdef    HAVE_JIKES_NAMESPACE
  1572. }            // Close namespace Jikes block
  1573. #endif
  1574.  
  1575. #endif
  1576.  
  1577.