home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / print_jvm_class.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  30.9 KB  |  1,269 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class PRINT_JVM_CLASS
  17.    --
  18.    -- The SmallEiffel bytecode disassembler.
  19.    --
  20.  
  21. inherit CP_INFO_TAGS;
  22.  
  23. creation make
  24.  
  25. feature
  26.  
  27.    make is
  28.       local
  29.      path: STRING;
  30.       do
  31.      if argument_count /= 1 then
  32.         std_output.put_string(
  33.              "Usage: print_jvm_class <ClassFilePath>[.class]%N");
  34.      else
  35.         path := argument(1).twin;
  36.         if not path.has_suffix(".class") then
  37.            path.append(".class");
  38.         end;
  39.         !!file_of_bytes.connect_to(path);
  40.         if file_of_bytes.is_connected then
  41.            print_jvm_class;
  42.            file_of_bytes.disconnect;
  43.         else
  44.            std_output.put_string("File %"");
  45.            std_output.put_string(path);
  46.            std_output.put_string("%" not found.%N");
  47.         end;
  48.      end;
  49.       end;
  50.  
  51. feature {NONE}
  52.    
  53.    file_of_bytes: BINARY_FILE_READ;
  54.  
  55.    access_flag: STRING;
  56.  
  57.    fields_count: INTEGER;
  58.  
  59.    total_byte: INTEGER;
  60.  
  61. feature {NONE} -- To get result of basic read :
  62.  
  63.    last_u1: CHARACTER;
  64.  
  65.    last_u1_code: INTEGER is
  66.       do
  67.      Result := last_u1.code;
  68.       end;
  69.  
  70.    last_u2: STRING is
  71.       once
  72.      !!Result.make(2);
  73.       end;
  74.  
  75.    last_idx: INTEGER;
  76.  
  77.    last_u4: STRING is
  78.       once
  79.      !!Result.make(4);
  80.       end;
  81.  
  82.    last_u8: STRING is
  83.       once
  84.      !!Result.make(8);
  85.       end;
  86.  
  87.    last_uft8: STRING is
  88.       once
  89.      !!Result.make(32);
  90.       end;
  91.  
  92. feature {NONE} -- Basic read in *.class :
  93.  
  94.    read_u1 is
  95.       do
  96.      if file_of_bytes.end_of_input then
  97.         bad_class_file("Unexpected end of file.");
  98.      else
  99.         file_of_bytes.read_byte;
  100.         last_u1 := file_of_bytes.last_byte.to_character;
  101.         total_byte := total_byte + 1;
  102.      end;
  103.       end;
  104.  
  105.    read_u2 is
  106.       do
  107.      last_u2.clear;
  108.      read_u1;
  109.      last_u2.extend(last_u1);
  110.      read_u1;
  111.      last_u2.extend(last_u1);
  112.       end;
  113.  
  114.    read_u4 is
  115.       do
  116.      read_u2;
  117.      last_u4.copy(last_u2);
  118.      read_u2;
  119.      last_u4.append(last_u2);
  120.       end;
  121.  
  122.    read_u8 is
  123.       do
  124.      read_u4;
  125.      last_u8.copy(last_u4);
  126.      read_u4;
  127.      last_u4.append(last_u4);
  128.       end;
  129.  
  130.    read_uft8 is
  131.       local
  132.      length: INTEGER;
  133.       do
  134.      from
  135.         read_u2;
  136.         last_uft8.copy(last_u2);
  137.         length := last_u2_as_integer;
  138.      until
  139.         length = 0
  140.      loop
  141.         read_u1;
  142.         last_uft8.extend(last_u1);
  143.         length := length - 1;
  144.      end;
  145.       end;
  146.  
  147.    read_u2_idx is
  148.       do
  149.      read_u2;
  150.      last_idx := last_u2_as_integer;
  151.      if not constant_pool.valid_index(last_idx) then
  152.         tmp_string.copy("Constant pool index out of range: ");
  153.         last_idx.append_in(tmp_string);
  154.         bad_class_file(tmp_string);
  155.      end;
  156.       end;
  157.  
  158.    last_u2_as_integer: INTEGER is
  159.       do
  160.      Result := (last_u2.item(1).code * 256) + last_u2.item(2).code;
  161.       end;
  162.  
  163.    last_u4_as_integer: INTEGER is
  164.       do
  165.      Result := (last_u4.item(1).code * 256);
  166.      Result := Result + (last_u4.item(2).code * 256);
  167.      Result := Result + (last_u4.item(3).code * 256);
  168.      Result := Result + last_u4.item(4).code;
  169.       end;
  170.  
  171. feature -- Basic print : 
  172.  
  173.    read_and_print_u1 is
  174.       do
  175.      read_u1;
  176.      inspect
  177.         last_u1_code
  178.      when 32 .. 126 then
  179.         std_output.put_character(last_u1);
  180.      else
  181.         tmp_string.copy(" 0x");
  182.         last_u1.to_hexadecimal_in(tmp_string);
  183.         std_output.put_string(tmp_string);
  184.      end
  185.       end;
  186.  
  187.    read_and_print_u2_idx is
  188.       do
  189.      read_u2_idx;
  190.      std_output.put_integer(last_idx);
  191.       end;
  192.  
  193.    read_and_print_u2 is
  194.       do
  195.      read_u2;
  196.      print_hexadecimal(last_u2);
  197.       end;
  198.  
  199.    read_and_print_u4 is
  200.       do
  201.      read_u4;
  202.      print_hexadecimal(last_u4);
  203.       end;
  204.  
  205.    read_and_print_u8 is
  206.       do
  207.      read_u8;
  208.      print_hexadecimal(last_u8);
  209.       end;
  210.  
  211.    print_hexadecimal(str: STRING) is
  212.       require
  213.      str.count > 1
  214.       local
  215.      i: INTEGER;
  216.       do
  217.      tmp_string.copy("0x");
  218.      from
  219.         i := 1;
  220.      until
  221.         i > str.count
  222.      loop
  223.         str.item(i).to_hexadecimal_in(tmp_string);
  224.         i := i + 1;
  225.      end;
  226.      std_output.put_string(tmp_string);
  227.       end;
  228.  
  229. feature {NONE}
  230.    
  231.    print_jvm_class is
  232.       require
  233.      file_of_bytes.is_connected
  234.       local 
  235.      c: CHARACTER;
  236.      i: INTEGER;
  237.      cp_count: INTEGER;
  238.      cp_info: CP_INFO;
  239.      methods_count, attributes_count: INTEGER;
  240.       do
  241.      std_output.put_string("Contents of file %"");
  242.      std_output.put_string(file_of_bytes.path);
  243.      std_output.put_string("%".%N");
  244.      std_output.put_string("Magic number: ");
  245.      read_and_print_u4;
  246.      std_output.put_new_line;
  247.      std_output.put_string("Minor version: ");
  248.      read_and_print_u2;
  249.      std_output.put_new_line;
  250.      std_output.put_string("Major version: ");
  251.      read_and_print_u2;
  252.      std_output.put_new_line;
  253.      std_output.put_string("Constant pool count: ");
  254.      read_u2;
  255.      cp_count := last_u2_as_integer;
  256.      std_output.put_integer(cp_count);
  257.      std_output.put_new_line;
  258.      constant_pool.reset(cp_count - 1);
  259.      from
  260.         i := 1;
  261.      until
  262.         i = cp_count
  263.      loop
  264.         std_output.put_integer(i);
  265.         if i < 10 then
  266.            std_output.put_string("   ");
  267.         elseif i < 100 then
  268.            std_output.put_string("  ");
  269.         else
  270.            std_output.put_string(" ");
  271.         end;
  272.         std_output.put_string(": ");
  273.         print_cp_info(i);
  274.         std_output.put_new_line;
  275.         i := i + 1;
  276.      end;
  277.      std_output.put_string("Access flag: 0x");
  278.      read_u1;
  279.      access_flag := last_u1.to_hexadecimal;
  280.      read_u1;
  281.      last_u1.to_hexadecimal_in(access_flag);
  282.      std_output.put_string(access_flag);
  283.      std_output.put_character(' ');
  284.      if access_flag.item(4) = '1' then
  285.         std_output.put_string(" public ");
  286.      end;
  287.      if access_flag.item(3) = '1' then
  288.         std_output.put_string(" final (no subclass)");
  289.      end;
  290.      if access_flag.item(3) = '2' then
  291.         std_output.put_string(" super ");
  292.      end;
  293.      if access_flag.item(2) = '2' then
  294.         std_output.put_string(" interface ");
  295.      end;
  296.      if access_flag.item(2) = '4' then
  297.         std_output.put_string(" abstract ");
  298.      end;
  299.      std_output.put_new_line;
  300.      std_output.put_string("this_class: ");
  301.      read_and_print_u2_idx;
  302.      if constant_pool.is_class(last_idx) then
  303.         tmp_string.copy(" is ");
  304.         constant_pool.view_in(tmp_string,last_idx);
  305.         std_output.put_string(tmp_string);
  306.      else
  307.         bad_class_file("Bad `this_class' value.");
  308.      end;
  309.      std_output.put_new_line;
  310.      std_output.put_string("super_class: ");
  311.      read_and_print_u2_idx;
  312.      if constant_pool.is_class(last_idx) then
  313.         tmp_string.copy(" is ");
  314.         constant_pool.view_in(tmp_string,last_idx);
  315.         std_output.put_string(tmp_string);
  316.      else
  317.         bad_class_file("Bad `super_class' value.");
  318.      end;
  319.      std_output.put_new_line;
  320.      std_output.put_string("Interfaces count: ");
  321.      read_u2;
  322.      i := last_u2_as_integer;
  323.      std_output.put_integer(i);
  324.      if i > 0 then
  325.         std_output.put_string(" {");
  326.         from
  327.         until
  328.            i = 0
  329.         loop
  330.            read_and_print_u2_idx;
  331.            i := i - 1;
  332.            if i > 0 then
  333.           std_output.put_character(',');
  334.            end;
  335.         end;
  336.         std_output.put_character('}');
  337.      end;
  338.      std_output.put_new_line;
  339.      std_output.put_string("----- Fields count: ");
  340.      read_u2;
  341.      fields_count := last_u2_as_integer;
  342.      std_output.put_integer(fields_count);
  343.      std_output.put_new_line;
  344.      from
  345.         i := 1
  346.      until
  347.         i > fields_count
  348.      loop
  349.         std_output.put_integer(i);
  350.         if i < 10 then
  351.            std_output.put_string("   ");
  352.         elseif i < 100 then
  353.            std_output.put_string("  ");
  354.         else
  355.            std_output.put_string(" ");
  356.         end;
  357.         std_output.put_string(": ");
  358.         print_field_info;
  359.         std_output.put_new_line;
  360.         i := i + 1;
  361.      end;
  362.      std_output.put_string("----- Methods count: ");
  363.      read_u2;
  364.      methods_count := last_u2_as_integer;
  365.      std_output.put_integer(methods_count);
  366.      std_output.put_new_line;
  367.      from
  368.         i := 1
  369.      until
  370.         i > methods_count
  371.      loop
  372.         std_output.put_integer(i);
  373.         if i < 10 then
  374.            std_output.put_string("   ");
  375.         elseif i < 100 then
  376.            std_output.put_string("  ");
  377.         else
  378.            std_output.put_string(" ");
  379.         end;
  380.         std_output.put_string(": ");
  381.         print_method_info;
  382.         std_output.put_new_line;
  383.         i := i + 1;
  384.      end;
  385.      std_output.put_string("Attributes count: ");
  386.      read_u2;
  387.      attributes_count := last_u2_as_integer;
  388.      std_output.put_integer(attributes_count);
  389.      std_output.put_new_line;
  390.      from
  391.         i := 1
  392.      until
  393.         i > attributes_count
  394.      loop
  395.         std_output.put_integer(i);
  396.         if i < 10 then
  397.            std_output.put_string("   ");
  398.         elseif i < 100 then
  399.            std_output.put_string("  ");
  400.         else
  401.            std_output.put_string(" ");
  402.         end;
  403.         std_output.put_string(": ");
  404.         print_attribute_info;
  405.         std_output.put_new_line;
  406.         i := i + 1;
  407.      end;
  408.      read_u1;
  409.      if file_of_bytes.end_of_input then
  410.         std_output.put_string("Total bytes: ");
  411.         std_output.put_integer(total_byte - 1);
  412.         std_output.put_new_line;
  413.      else
  414.         bad_class_file("End of file expected.");
  415.      end;
  416.       end;
  417.  
  418.    tmp_string: STRING is
  419.       once
  420.      !!Result.make(32);
  421.       end;
  422.  
  423. feature -- Read and brute printing of constant_pool :
  424.  
  425.    print_cp_info(i: INTEGER) is
  426.       do
  427.      read_u1;
  428.      inspect
  429.         last_u1_code
  430.      when 7 then
  431.         std_output.put_string("class at ");
  432.         read_and_print_u2_idx;
  433.         constant_pool.set_class(i,last_u2);
  434.      when 9 then
  435.         std_output.put_string("fieldref class: ");
  436.         read_and_print_u2_idx;
  437.         last_u4.copy(last_u2);
  438.         std_output.put_string(" name_and_type: ");
  439.         read_and_print_u2_idx;
  440.         last_u4.append(last_u2);
  441.         constant_pool.set_fieldref(i,last_u4);
  442.      when 10 then
  443.         std_output.put_string("methodref class: ");
  444.         read_and_print_u2_idx;
  445.         last_u4.copy(last_u2);
  446.         std_output.put_string(" name_and_type: ");
  447.         read_and_print_u2_idx;
  448.         last_u4.append(last_u2);
  449.         constant_pool.set_methodref(i,last_u4);
  450.      when 11 then
  451.         std_output.put_string("interface methodref class: ");
  452.         read_and_print_u2_idx;
  453.         last_u4.copy(last_u2);
  454.         std_output.put_string(" name_and_type: ");
  455.         read_and_print_u2_idx;
  456.         last_u4.append(last_u2);
  457.         constant_pool.set_interface_methodref(i,last_u4);
  458.      when 8 then
  459.         std_output.put_string("string at ");
  460.         read_and_print_u2_idx;
  461.         constant_pool.set_string(i,last_u2);
  462.      when 3 then
  463.         std_output.put_string("integer: ");
  464.         read_and_print_u4;
  465.         constant_pool.set_integer(i,last_u4);
  466.      when 4 then
  467.         std_output.put_string("float: ");
  468.         read_and_print_u4;
  469.         constant_pool.set_float(i,last_u4);
  470.      when 5 then
  471.         std_output.put_string("long: ");
  472.         read_and_print_u4;
  473.         last_u8.copy(last_u4);
  474.         read_and_print_u4;
  475.         last_u8.append(last_u4);
  476.         constant_pool.set_long(i,last_u8);
  477.      when 6 then
  478.         std_output.put_string("double: ");
  479.         read_and_print_u4;
  480.         last_u8.copy(last_u4);
  481.         read_and_print_u4;
  482.         last_u8.append(last_u4);
  483.         constant_pool.set_double(i,last_u8);
  484.      when 12 then
  485.         std_output.put_string("name: ");
  486.         read_and_print_u2_idx;
  487.         last_u4.copy(last_u2);
  488.         std_output.put_string(" type: ");
  489.         read_and_print_u2_idx;
  490.         last_u4.append(last_u2);
  491.         constant_pool.set_name_and_type(i,last_u4);
  492.      when 1 then
  493.         std_output.put_string("uft8: ");
  494.         read_uft8;
  495.         constant_pool.set_uft8(i,last_uft8);
  496.         tmp_string.clear;
  497.         constant_pool.view_in(tmp_string,i);
  498.         std_output.put_string(tmp_string);
  499.      else
  500.         tmp_string.copy("Error in constant pool (bad tag: ");
  501.         last_u1_code.append_in(tmp_string);
  502.         tmp_string.append(").");
  503.         bad_class_file(tmp_string);
  504.      end;
  505.       end;
  506.  
  507. feature {NONE}
  508.  
  509.    print_field_info is
  510.       local
  511.      flag, attributes_count: INTEGER;
  512.       do
  513.      -- access_flag :
  514.      read_and_print_u2;
  515.      flag_list_begin;
  516.      flag := last_u2.item(2).code;
  517.      inspect
  518.         flag \\ 10
  519.      when 1 then
  520.         flag_list_add("public");
  521.      when 2 then
  522.         flag_list_add("private");
  523.      when 4 then
  524.         flag_list_add("protected");
  525.      else
  526.      end;
  527.      if flag >= 10 then
  528.         if flag < 40 then
  529.            flag_list_add("final");
  530.         elseif flag > 40 then
  531.            flag_list_add("transient");
  532.         else 
  533.            flag_list_add("volatile");
  534.         end;
  535.      end;
  536.      flag_list_end;
  537.      -- name_index :
  538.      read_u2_idx;
  539.      tmp_string.clear;
  540.      constant_pool.view_in(tmp_string,last_idx);
  541.      std_output.put_string(tmp_string);
  542.      -- descriptor_index :
  543.      read_u2_idx;
  544.      tmp_string.copy(" ");
  545.      constant_pool.view_in(tmp_string,last_idx);
  546.      std_output.put_string(tmp_string);
  547.      -- attributes_count :
  548.      read_u2;
  549.      attributes_count := last_u2_as_integer;
  550.      if attributes_count > 0 then
  551.         std_output.put_string(" attributes_count: ");
  552.         std_output.put_integer(attributes_count);
  553.      end;
  554.      std_output.put_new_line;
  555.      from
  556.      until
  557.         attributes_count = 0
  558.      loop
  559.         print_attribute_info;
  560.         attributes_count := attributes_count - 1;
  561.      end;
  562.       end;
  563.  
  564.    print_method_info is
  565.       local
  566.      flag, attributes_count: INTEGER;
  567.       do
  568.      -- access_flag :
  569.      read_and_print_u2;
  570.      flag_list_begin;
  571.      flag := last_u2.item(2).code;
  572.      inspect
  573.         flag \\ 10
  574.      when 1 then
  575.         flag_list_add("public");
  576.      when 2 then
  577.         flag_list_add("private");
  578.      when 4 then
  579.         flag_list_add("protected");
  580.      else
  581.      end;
  582.      if flag >= 10 then
  583.         if flag < 40 then
  584.            flag_list_add("final");
  585.         elseif flag > 40 then
  586.            flag_list_add("transient");
  587.         else 
  588.            flag_list_add("volatile");
  589.         end;
  590.      end;
  591.      flag_list_end;
  592.      -- name_index :
  593.      read_u2_idx;
  594.      tmp_string.clear;
  595.      constant_pool.view_in(tmp_string,last_idx);
  596.      std_output.put_string(tmp_string);
  597.      -- descriptor_index :
  598.      read_u2_idx;
  599.      tmp_string.clear;
  600.      constant_pool.view_in(tmp_string,last_idx);
  601.      std_output.put_string(tmp_string);
  602.      -- attributes_count :
  603.      read_u2;
  604.      attributes_count := last_u2_as_integer;
  605.      if attributes_count > 1 then
  606.         std_output.put_string(" attributes_count: ");
  607.         std_output.put_integer(attributes_count);
  608.      end;
  609.      std_output.put_new_line;
  610.      from
  611.      until
  612.         attributes_count = 0
  613.      loop
  614.         print_attribute_info;
  615.         attributes_count := attributes_count - 1;
  616.      end;
  617.       end;
  618.  
  619.    print_attribute_info is
  620.       local
  621.      i: INTEGER;
  622.       do
  623.      read_u2_idx;
  624.      tmp_string.clear;
  625.      constant_pool.view_in(tmp_string,last_idx);
  626.      std_output.put_string(tmp_string);
  627.      if ("SourceFile").is_equal(tmp_string) then
  628.         read_u4;
  629.         read_u2_idx;
  630.         tmp_string.copy(" is ");
  631.         constant_pool.view_in(tmp_string,last_idx);
  632.         std_output.put_string(tmp_string);
  633.      elseif ("Code").is_equal(tmp_string) then
  634.         read_u4;
  635.         print_code_attribute(last_u4_as_integer);
  636.      else
  637.         std_output.put_string(" (Ignored attribute: ");
  638.         read_u4;
  639.         i := last_u4_as_integer;
  640.         std_output.put_integer(i);
  641.         std_output.put_string(" bytes)");
  642.         from
  643.         until
  644.            i = 0
  645.         loop
  646.            read_u1;
  647.            i := i - 1;
  648.         end;
  649.      end;
  650.       end;
  651.  
  652.    print_code_attribute(length: INTEGER) is
  653.       local
  654.      code_length, exception_length,
  655.      attributes_count: INTEGER;
  656.       do
  657.      std_output.put_string(" (");
  658.      std_output.put_integer(length);
  659.      std_output.put_string(" bytes) max_stack: ");
  660.      read_u2;
  661.      std_output.put_integer(last_u2_as_integer);
  662.      std_output.put_string(" max_locals: ");
  663.      read_u2;
  664.      std_output.put_integer(last_u2_as_integer);
  665.      std_output.put_string(" code_length: ");
  666.      read_u4;
  667.      code_length := last_u4_as_integer;
  668.      std_output.put_integer(code_length);
  669.      read_and_print_byte_code(code_length);
  670.      read_u2;
  671.      exception_length := last_u2_as_integer;
  672.      if exception_length > 0 then
  673.         std_output.put_string("exception(s): ");
  674.         std_output.put_integer(exception_length);
  675.         std_output.put_new_line;
  676.         read_and_print_exception(exception_length);
  677.      end;
  678.      std_output.put_string("attributes_count: ");
  679.      read_u2;
  680.      attributes_count := last_u2_as_integer;
  681.      std_output.put_integer(attributes_count);
  682.      std_output.put_new_line;
  683.      from
  684.      until
  685.         attributes_count = 0
  686.      loop
  687.         print_attribute_info;
  688.         attributes_count := attributes_count - 1;
  689.      end;
  690.       end;
  691.  
  692. feature {NONE}
  693.  
  694.    max_print: INTEGER is 50;
  695.  
  696.    bad_class_file(msg: STRING) is
  697.       local
  698.      fz_visible, fz_hexadec, path: STRING;
  699.       do
  700.      std_output.put_string("%NCorrupted class file.%N");
  701.      std_output.put_string(msg);
  702.      std_output.put_string("%NTotal bytes read :");
  703.      std_output.put_integer(total_byte);
  704.      std_output.put_string("%NClass file dump:%N");
  705.  
  706.      path := file_of_bytes.path;
  707.      file_of_bytes.disconnect;
  708.      from
  709.         file_of_bytes.connect_to(path);
  710.         std_output.put_new_line;
  711.         fz_visible := "  ";
  712.         fz_hexadec := "Ox";
  713.      until
  714.         file_of_bytes.end_of_input
  715.      loop
  716.         read_u1;
  717.         last_u1.to_hexadecimal_in(fz_hexadec);
  718.         fz_hexadec.extend(' ');
  719.         inspect
  720.            last_u1_code
  721.         when 32 .. 126 then
  722.            fz_visible.extend(last_u1);
  723.         else
  724.            fz_visible.extend('.');
  725.         end
  726.         if fz_hexadec.count >= max_print then
  727.            std_output.put_string(fz_hexadec);
  728.            std_output.put_string("  ");
  729.            std_output.put_string(fz_visible);
  730.            std_output.put_new_line;
  731.            fz_visible.copy("  ");
  732.            fz_hexadec.copy("Ox");
  733.         end;
  734.      end;
  735.      from
  736.      until
  737.         fz_hexadec.count >= max_print + 2
  738.      loop
  739.         fz_hexadec.extend(' ');
  740.      end;
  741.      std_output.put_string(fz_hexadec);
  742.      std_output.put_string(fz_visible);
  743.      file_of_bytes.disconnect;
  744.      std_output.put_new_line;
  745.      die_with_code(exit_failure_code);
  746.       end;
  747.  
  748.    read_and_print_byte_code(length: INTEGER) is
  749.       require
  750.      length > 0
  751.       local
  752.      old_total_byte, pc, opcode: INTEGER;
  753.       do
  754.      std_output.put_new_line;
  755.      from
  756.         old_total_byte := total_byte;
  757.      until
  758.         total_byte - old_total_byte >= length
  759.      loop
  760.         std_output.put_string("   ");
  761.         pc := total_byte - old_total_byte;
  762.         from
  763.            tmp_string.clear;
  764.            pc.append_in(tmp_string);
  765.         until
  766.            tmp_string.count >= 4 
  767.         loop
  768.            tmp_string.extend(' ');
  769.         end;
  770.         std_output.put_string(tmp_string);
  771.         inst.clear;
  772.         read_u1;
  773.         last_u1.to_hexadecimal_in(inst);
  774.         std_output.put_string(inst);
  775.         inst.clear;
  776.         opcode := last_u1_code;
  777.         inspect
  778.            opcode
  779.         when 0 then
  780.            inst_opcode("nop");
  781.         when 1 then
  782.            inst_opcode("aconst_null");
  783.         when 2 then
  784.            inst_opcode("iconst_m1");
  785.         when 3 .. 8 then
  786.            inst_opcode("iconst_");
  787.            (last_u1_code - 3).append_in(inst);
  788.         when 9 then
  789.            inst_opcode("lconst_0");
  790.         when 10 then
  791.            inst_opcode("lconst_1");
  792.         when 11 .. 13 then
  793.            inst_opcode("fconst_");
  794.            (last_u1_code - 11).append_in(inst);
  795.         when 14 .. 15 then
  796.            inst_opcode("dconst_");
  797.            (last_u1_code - 14).append_in(inst);
  798.         when 16 then
  799.            read_u1;
  800.            last_u1.to_hexadecimal_in(inst);
  801.            inst_opcode("bipush");
  802.         when 17 then
  803.            read_u2;
  804.            last_u2.item(1).to_hexadecimal_in(inst);
  805.            last_u2.item(2).to_hexadecimal_in(inst);
  806.            inst_opcode("sipush");
  807.         when 18 then
  808.            read_u1;
  809.            last_u1.to_hexadecimal_in(inst);
  810.            inst_opcode("ldc ");
  811.            constant_pool.view_in(inst,last_u1_code);
  812.         when 19 then
  813.            read_u2_idx;
  814.            last_u2.item(1).to_hexadecimal_in(inst);
  815.            last_u2.item(2).to_hexadecimal_in(inst);
  816.            inst_opcode("ldc_w ");
  817.            constant_pool.view_in(inst,last_idx);
  818.         when 21 then
  819.            read_u1;
  820.            last_u1.to_hexadecimal_in(inst);
  821.            inst_opcode("iload ");
  822.            last_u1_code.append_in(inst);
  823.         when 22 then
  824.            read_u1;
  825.            last_u1.to_hexadecimal_in(inst);
  826.            inst_opcode("lload ");
  827.            last_u1_code.append_in(inst);
  828.         when 23 then
  829.            read_u1;
  830.            last_u1.to_hexadecimal_in(inst);
  831.            inst_opcode("fload ");
  832.            last_u1_code.append_in(inst);
  833.         when 25 then
  834.            read_u1;
  835.            last_u1.to_hexadecimal_in(inst);
  836.            inst_opcode("aload ");
  837.            last_u1_code.append_in(inst);
  838.         when 26 .. 29 then
  839.            inst_opcode("iload_");
  840.            (last_u1_code - 26).append_in(inst);
  841.         when 34 .. 37 then
  842.            inst_opcode("fload_");
  843.            (last_u1_code - 34).append_in(inst);
  844.         when 38 .. 41 then
  845.            inst_opcode("dload_");
  846.            (last_u1_code - 38).append_in(inst);
  847.         when 42 .. 45 then
  848.            inst_opcode("aload_");
  849.            (last_u1_code - 42).append_in(inst);
  850.         when 46 then
  851.            inst_opcode("iaload");
  852.         when 47 then
  853.            inst_opcode("laload");
  854.         when 48 then
  855.            inst_opcode("faload");
  856.         when 49 then
  857.            inst_opcode("daload");
  858.         when 50 then
  859.            inst_opcode("aaload");
  860.         when 51 then
  861.            inst_opcode("baload");
  862.         when 52 then
  863.            inst_opcode("caload");
  864.         when 53 then
  865.            inst_opcode("saload");
  866.         when 54 then
  867.            read_u1;
  868.            last_u1.to_hexadecimal_in(inst);
  869.            inst_opcode("istore");
  870.            last_u1_code.append_in(inst);
  871.         when 55 then
  872.            read_u1;
  873.            last_u1.to_hexadecimal_in(inst);
  874.            inst_opcode("lstore ");
  875.            last_u1_code.append_in(inst);
  876.         when 56 then
  877.            read_u1;
  878.            last_u1.to_hexadecimal_in(inst);
  879.            inst_opcode("fstore ");
  880.            last_u1_code.append_in(inst);
  881.         when 58 then
  882.            read_u1;
  883.            last_u1.to_hexadecimal_in(inst);
  884.            inst_opcode("astore ");
  885.            last_u1_code.append_in(inst);
  886.         when 59 .. 62 then
  887.            inst_opcode("istore_");
  888.            (last_u1_code - 59).append_in(inst);
  889.         when 63 .. 66 then
  890.            inst_opcode("lstore_");
  891.            (last_u1_code - 63).append_in(inst);
  892.         when 67 .. 70 then
  893.            inst_opcode("fstore_");
  894.            (last_u1_code - 67).append_in(inst);
  895.         when 71 .. 74 then
  896.            inst_opcode("dstore_");
  897.            (last_u1_code - 71).append_in(inst);
  898.         when 75 .. 78 then
  899.            inst_opcode("astore_");
  900.            (last_u1_code - 75).append_in(inst);
  901.         when 79 then
  902.            inst_opcode("iastore");
  903.         when 80 then
  904.            inst_opcode("lastore");
  905.         when 81 then
  906.            inst_opcode("fastore");
  907.         when 82 then
  908.            inst_opcode("dastore");
  909.         when 83 then
  910.            inst_opcode("aastore");
  911.         when 84 then
  912.            inst_opcode("bastore");
  913.         when 85 then
  914.            inst_opcode("castore");
  915.         when 86 then
  916.            inst_opcode("sastore");
  917.         when 87 then
  918.            inst_opcode("pop");
  919.         when 88 then
  920.            inst_opcode("pop2");
  921.         when 89 then
  922.            inst_opcode("dup");
  923.         when 90 then
  924.            inst_opcode("dup_x1");
  925.         when 91 then
  926.            inst_opcode("dup_x2");
  927.         when 92 then
  928.            inst_opcode("dup2");
  929.         when 95 then
  930.            inst_opcode("swap");
  931.         when 96 then
  932.            inst_opcode("iadd");
  933.         when 97 then
  934.            inst_opcode("ladd");
  935.         when 98 then
  936.            inst_opcode("fadd");
  937.         when 99 then
  938.            inst_opcode("dadd");
  939.         when 100 then
  940.            inst_opcode("isub");
  941.         when 104 then
  942.            inst_opcode("imul");
  943.         when 108 then
  944.            inst_opcode("idiv");
  945.         when 112 then
  946.            inst_opcode("irem");
  947.         when 116 then
  948.            inst_opcode("ineg");
  949.         when 117 then
  950.            inst_opcode("lneg");
  951.         when 118 then
  952.            inst_opcode("fneg");
  953.         when 119 then
  954.            inst_opcode("dneg");
  955.         when 120 then
  956.            inst_opcode("ishl");
  957.         when 124 then
  958.            inst_opcode("iushr");
  959.         when 126 then
  960.            inst_opcode("iand");
  961.         when 128 then
  962.            inst_opcode("ior");
  963.         when 130 then
  964.            inst_opcode("ixor");
  965.         when 132 then
  966.            read_u2;
  967.            last_u2.item(1).to_hexadecimal_in(inst);
  968.            last_u2.item(2).to_hexadecimal_in(inst);
  969.            inst_opcode("iinc loc");
  970.            last_u2.item(1).code.append_in(inst);
  971.            inst.append(",0x");
  972.            last_u2.item(2).to_hexadecimal_in(inst);
  973.         when 133 then
  974.            inst_opcode("i2l");
  975.         when 134 then
  976.            inst_opcode("i2f");
  977.         when 135 then
  978.            inst_opcode("i2d");
  979.         when 141 then
  980.            inst_opcode("f2d");
  981.         when 144 then
  982.            inst_opcode("d2f");
  983.         when 145 then
  984.            inst_opcode("i2b");
  985.         when 146 then
  986.            inst_opcode("i2c");
  987.         when 149 then
  988.            inst_opcode("fcmpl");
  989.         when 150 then
  990.            inst_opcode("fcmpg");
  991.         when 151 .. 152 then
  992.            inst_opcode("dcmp");
  993.            inspect
  994.           opcode
  995.            when 151 then
  996.           inst.append("l");
  997.            when 152 then
  998.           inst.append("g");
  999.            end;
  1000.         when 153 .. 158 then
  1001.            read_u2;
  1002.            last_u2.item(1).to_hexadecimal_in(inst);
  1003.            last_u2.item(2).to_hexadecimal_in(inst);
  1004.            inst_opcode("if");
  1005.            inspect
  1006.           opcode
  1007.            when 153 then
  1008.           inst.append("eq");
  1009.            when 154 then
  1010.           inst.append("ne");
  1011.            when 155 then
  1012.           inst.append("lt");
  1013.            when 156 then
  1014.           inst.append("ge");
  1015.            when 157 then
  1016.           inst.append("gt");
  1017.            when 158 then
  1018.           inst.append("le");
  1019.            end;
  1020.            inst.extend(' ');
  1021.            view_pc(last_u2_as_integer,pc);
  1022.         when 159 .. 166 then
  1023.            read_u2;
  1024.            last_u2.item(1).to_hexadecimal_in(inst);
  1025.            last_u2.item(2).to_hexadecimal_in(inst);
  1026.            inst_opcode("if_");
  1027.            inspect
  1028.           opcode
  1029.            when 159 .. 164 then
  1030.           inst.extend('i');
  1031.            else
  1032.           inst.extend('a');
  1033.            end;
  1034.            inst.append("cmp");
  1035.            inspect
  1036.           opcode
  1037.            when 159 then
  1038.           inst.append("eq");
  1039.            when 160 then
  1040.           inst.append("ne");
  1041.            when 161 then
  1042.           inst.append("lt");
  1043.            when 162 then
  1044.           inst.append("ge");
  1045.            when 163 then
  1046.           inst.append("gt");
  1047.            when 164 then
  1048.           inst.append("le");
  1049.            when 165 then
  1050.           inst.append("eq");
  1051.            when 166 then
  1052.           inst.append("ne");
  1053.            end;
  1054.            inst.extend(' ');
  1055.            view_pc(last_u2_as_integer,pc);
  1056.         when 167 then
  1057.            read_u2;
  1058.            last_u2.item(1).to_hexadecimal_in(inst);
  1059.            last_u2.item(2).to_hexadecimal_in(inst);
  1060.            inst_opcode("goto ");
  1061.            view_pc(last_u2_as_integer,pc);
  1062.         when 172 then
  1063.            inst_opcode("ireturn");
  1064.         when 173 then
  1065.            inst_opcode("lreturn");
  1066.         when 174 then
  1067.            inst_opcode("freturn");
  1068.         when 175 then
  1069.            inst_opcode("dreturn");
  1070.         when 176 then
  1071.            inst_opcode("areturn");
  1072.         when 177 then
  1073.            inst_opcode("return");
  1074.         when 178 then
  1075.            read_u2_idx;
  1076.            last_u2.item(1).to_hexadecimal_in(inst);
  1077.            last_u2.item(2).to_hexadecimal_in(inst);
  1078.            inst_opcode("getstatic ");
  1079.            constant_pool.view_in(inst,last_idx);
  1080.         when 179 then
  1081.            read_u2_idx;
  1082.            last_u2.item(1).to_hexadecimal_in(inst);
  1083.            last_u2.item(2).to_hexadecimal_in(inst);
  1084.            inst_opcode("putstatic ");
  1085.            constant_pool.view_in(inst,last_idx);
  1086.         when 180 then
  1087.            read_u2_idx;
  1088.            last_u2.item(1).to_hexadecimal_in(inst);
  1089.            last_u2.item(2).to_hexadecimal_in(inst);
  1090.            inst_opcode("getfield ");
  1091.            constant_pool.view_in(inst,last_idx);
  1092.         when 181 then
  1093.            read_u2_idx;
  1094.            last_u2.item(1).to_hexadecimal_in(inst);
  1095.            last_u2.item(2).to_hexadecimal_in(inst);
  1096.            inst_opcode("putfield ");
  1097.            constant_pool.view_in(inst,last_idx);
  1098.         when 182 then
  1099.            read_u2_idx;
  1100.            last_u2.item(1).to_hexadecimal_in(inst);
  1101.            last_u2.item(2).to_hexadecimal_in(inst);
  1102.            inst_opcode("invokevirtual ");
  1103.            constant_pool.view_in(inst,last_idx);
  1104.         when 183 then
  1105.            read_u2_idx;
  1106.            last_u2.item(1).to_hexadecimal_in(inst);
  1107.            last_u2.item(2).to_hexadecimal_in(inst);
  1108.            inst_opcode("invokespecial ");
  1109.            constant_pool.view_in(inst,last_idx);
  1110.         when 184 then
  1111.            read_u2_idx;
  1112.            last_u2.item(1).to_hexadecimal_in(inst);
  1113.            last_u2.item(2).to_hexadecimal_in(inst);
  1114.            inst_opcode("invokestatic ");
  1115.            constant_pool.view_in(inst,last_idx);
  1116.         when 187 then
  1117.            read_u2_idx;
  1118.            last_u2.item(1).to_hexadecimal_in(inst);
  1119.            last_u2.item(2).to_hexadecimal_in(inst);
  1120.            inst_opcode("new ");
  1121.            constant_pool.view_in(inst,last_idx);
  1122.         when 188 then
  1123.            read_u1;
  1124.            last_u1.to_hexadecimal_in(inst);
  1125.            inst_opcode("newarray ");
  1126.            inspect
  1127.           last_u1_code
  1128.            when 4 then
  1129.           inst.append("boolean");
  1130.            when 5 then
  1131.           inst.append("character");
  1132.            when 6 then
  1133.           inst.append("float");
  1134.            when 7 then
  1135.           inst.append("double");
  1136.            when 8 then
  1137.           inst.append("byte");
  1138.            when 9 then
  1139.           inst.append("short");
  1140.            when 10 then
  1141.           inst.append("int");
  1142.            when 11 then
  1143.           inst.append("long");
  1144.            end;
  1145.         when 189 then
  1146.            read_u2_idx;
  1147.            last_u2.item(1).to_hexadecimal_in(inst);
  1148.            last_u2.item(2).to_hexadecimal_in(inst);
  1149.            inst_opcode("anewarray ");
  1150.            constant_pool.view_in(inst,last_idx);
  1151.         when 190 then
  1152.            inst_opcode("arraylength");
  1153.         when 191 then
  1154.            inst_opcode("athrow");
  1155.         when 193 then
  1156.            read_u2_idx;
  1157.            last_u2.item(1).to_hexadecimal_in(inst);
  1158.            last_u2.item(2).to_hexadecimal_in(inst);
  1159.            inst_opcode("instanceof ");
  1160.            constant_pool.view_in(inst,last_idx);
  1161.         when 198 then
  1162.            read_u2;
  1163.            last_u2.item(1).to_hexadecimal_in(inst);
  1164.            last_u2.item(2).to_hexadecimal_in(inst);
  1165.            inst_opcode("ifnull ");
  1166.            view_pc(last_u2_as_integer,pc);
  1167.         when 199 then
  1168.            read_u2;
  1169.            last_u2.item(1).to_hexadecimal_in(inst);
  1170.            last_u2.item(2).to_hexadecimal_in(inst);
  1171.            inst_opcode("ifnonnull ");
  1172.            view_pc(last_u2_as_integer,pc);
  1173.         else
  1174.            tmp_string.append("Unknown Opcode: ");
  1175.            last_u1_code.append_in(tmp_string);
  1176.            bad_class_file(tmp_string);
  1177.         end;
  1178.         std_output.put_string(inst);
  1179.         std_output.put_new_line;
  1180.      end;
  1181.       end;
  1182.  
  1183.    read_and_print_exception(length: INTEGER) is
  1184.       local
  1185.      i: INTEGER;
  1186.       do
  1187.      from
  1188.         i := length
  1189.      until
  1190.         i = 0
  1191.      loop
  1192.         std_output.put_string("start: ");
  1193.         read_u2;
  1194.         std_output.put_integer(last_u2_as_integer);
  1195.         std_output.put_string(" end: ");
  1196.         read_u2;
  1197.         std_output.put_integer(last_u2_as_integer);
  1198.         std_output.put_string(" handler: ");
  1199.         read_u2;
  1200.         std_output.put_integer(last_u2_as_integer);
  1201.         std_output.put_string(" type: ");
  1202.         read_u2_idx;
  1203.         tmp_string.clear;
  1204.         constant_pool.view_in(tmp_string,last_idx);
  1205.         std_output.put_string(tmp_string);
  1206.         std_output.put_string("%N");
  1207.         i := i - 1;
  1208.      end;
  1209.       end;
  1210.  
  1211.    inst_opcode(msg: STRING) is
  1212.       do
  1213.      from
  1214.      until
  1215.         inst.count >= 4
  1216.      loop
  1217.         inst.extend('.');
  1218.      end;
  1219.      inst.extend(' ');
  1220.      inst.append(msg);
  1221.       end;
  1222.  
  1223.    inst: STRING is
  1224.       once
  1225.      !!Result.make(80);
  1226.       end;
  1227.  
  1228.    flag_list: STRING is
  1229.       once
  1230.      !!Result.make(80);
  1231.       end;
  1232.  
  1233.    flag_list_begin is
  1234.       do
  1235.      flag_list.copy(" (");
  1236.       end;
  1237.  
  1238.    flag_list_add(item: STRING) is
  1239.       do
  1240.      if flag_list.last /= '(' then
  1241.         flag_list.extend(',');
  1242.      end;
  1243.      flag_list.append(item);
  1244.       end;
  1245.  
  1246.    flag_list_end is
  1247.       do
  1248.      flag_list.append(")%N");
  1249.      std_output.put_string(flag_list);
  1250.       end;
  1251.  
  1252. feature {NONE}
  1253.  
  1254.    view_pc(offset, pc: INTEGER) is
  1255.       local
  1256.      view: INTEGER;
  1257.      bits: BIT Integer_bits;
  1258.       do
  1259.      if offset < ((2 ^ 15) - 1) then
  1260.         view := pc + offset;
  1261.      else
  1262.         view := (offset - (2 ^ 16)) + pc;
  1263.      end;
  1264.      view.append_in(inst);
  1265.       end;
  1266.    
  1267. end -- PRINT_JVM_CLASS
  1268.  
  1269.