home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / constant_pool.e < prev    next >
Text File  |  1999-06-05  |  15KB  |  628 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://SmallEiffel.loria.fr
  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 CONSTANT_POOL
  17.    --
  18.    -- Unique Global Object in charge of the CONSTANT_POOL
  19.    -- handling (the CONSTANT_POOL is an important part of a
  20.    -- JVM *.class file).
  21.    --
  22.  
  23. inherit CP_INFO_TAGS;
  24.  
  25. feature {NONE}
  26.  
  27.    cp_up: INTEGER;
  28.  
  29.    cp: FIXED_ARRAY[CP_INFO] is
  30.          -- Range [1.. `cp_up'] has no Void elements.
  31.          -- By the way, index 0 is not used and elements
  32.          -- are recycled.
  33.       once
  34.          !!Result.make(1);
  35.       end;
  36.  
  37. feature {PRINT_JVM_CLASS}
  38.  
  39.    item(i: INTEGER): CP_INFO is
  40.       do
  41.          Result := cp.item(i);
  42.       end;
  43.  
  44. feature {PRINT_JVM_CLASS}
  45.  
  46.    reset(new_upper: INTEGER) is
  47.       require
  48.          new_upper > 0
  49.       local
  50.          i: INTEGER;
  51.       do
  52.          from
  53.             cp_up := 0;
  54.          until
  55.             i = new_upper
  56.          loop
  57.             add_last.clear;
  58.             i := i + 1;
  59.          end;
  60.       ensure
  61.          cp_up = new_upper
  62.       end;
  63.  
  64. feature {JVM}
  65.  
  66.    clear is
  67.       do
  68.          cp_up := 0;
  69.          -- Compute minimum standard idx :
  70.          idx_java_lang_object := idx_class2(fz_java_lang_object);
  71.          idx_jvm_root_class := idx_class2(jvm_root_class);
  72.          idx_constant_utf8 := idx_utf8("Code");
  73.       end;
  74.  
  75.    write_bytes is
  76.       local
  77.          i: INTEGER;
  78.       do
  79.          echo.put_string("Constant pool: ");
  80.          echo.put_integer(cp_up);
  81.          echo.put_new_line;
  82.          jvm.b_put_u2(cp_up + 1);
  83.          from
  84.             i := 1;
  85.          until
  86.             i > cp_up
  87.          loop
  88.             cp.item(i).b_put;
  89.             i := i + 1;
  90.          end;
  91.       end;
  92.  
  93. feature -- Acces to some common idx :
  94.  
  95.    idx_constant_utf8: INTEGER;
  96.  
  97.    idx_java_lang_object: INTEGER;
  98.  
  99.    idx_jvm_root_class: INTEGER;
  100.  
  101. feature
  102.  
  103.    valid_index(idx: INTEGER): BOOLEAN is
  104.       do
  105.          Result := (1 <= idx) and then (idx <= cp_up);
  106.       end;
  107.  
  108. feature {PRINT_JVM_CLASS} -- Setting :
  109.  
  110.    set_class(i: INTEGER; info: STRING) is
  111.       do
  112.          cp.item(i).set_class(info);
  113.       end;
  114.  
  115.    set_fieldref(i: INTEGER; info: STRING) is
  116.       do
  117.          cp.item(i).set_fieldref(info);
  118.       end;
  119.  
  120.    set_methodref(i: INTEGER; info: STRING) is
  121.       do
  122.          cp.item(i).set_methodref(info);
  123.       end;
  124.  
  125.    set_interface_methodref(i: INTEGER; info: STRING) is
  126.       do
  127.          cp.item(i).set_interface_methodref(info);
  128.       end;
  129.  
  130.    set_string(i: INTEGER; info: STRING) is
  131.       do
  132.          cp.item(i).set_string(info);
  133.       end;
  134.  
  135.    set_integer(i: INTEGER; info: STRING) is
  136.       do
  137.          cp.item(i).set_integer(info);
  138.       end;
  139.  
  140.    set_float(i: INTEGER; info: STRING) is
  141.       do
  142.          cp.item(i).set_float(info);
  143.       end;
  144.  
  145.    set_long(i: INTEGER; info: STRING) is
  146.       do
  147.          cp.item(i).set_long(info);
  148.       end;
  149.  
  150.    set_double(i: INTEGER; info: STRING) is
  151.       do
  152.          cp.item(i).set_double(info);
  153.       end;
  154.  
  155.    set_name_and_type(i: INTEGER; info: STRING) is
  156.       do
  157.          cp.item(i).set_name_and_type(info);
  158.       end;
  159.  
  160.    set_utf8(i: INTEGER; info: STRING) is
  161.       do
  162.          cp.item(i).set_utf8(info);
  163.       end;
  164.  
  165. feature -- Testing :
  166.  
  167.    is_class(idx: INTEGER): BOOLEAN is
  168.       do
  169.          Result := cp.item(idx).is_class;
  170.       end;
  171.  
  172.    is_fieldref(idx: INTEGER): BOOLEAN is
  173.       do
  174.          Result := cp.item(idx).is_fieldref;
  175.       end;
  176.  
  177.    is_methodref(idx: INTEGER): BOOLEAN is
  178.       do
  179.          Result := cp.item(idx).is_methodref;
  180.       end;
  181.  
  182.    is_interface_methodref(idx: INTEGER): BOOLEAN is
  183.       do
  184.          Result := cp.item(idx).is_interface_methodref;
  185.       end;
  186.  
  187.    is_string(idx: INTEGER): BOOLEAN is
  188.       do
  189.          Result := cp.item(idx).is_string;
  190.       end;
  191.  
  192.    is_integer(idx: INTEGER): BOOLEAN is
  193.       do
  194.          Result := cp.item(idx).is_integer;
  195.       end;
  196.  
  197.    is_float(idx: INTEGER): BOOLEAN is
  198.       do
  199.          Result := cp.item(idx).is_float;
  200.       end;
  201.  
  202.    is_long(idx: INTEGER): BOOLEAN is
  203.       do
  204.          Result := cp.item(idx).is_long;
  205.       end;
  206.  
  207.    is_double(idx: INTEGER): BOOLEAN is
  208.       do
  209.          Result := cp.item(idx).is_double;
  210.       end;
  211.  
  212.    is_name_and_type(idx: INTEGER): BOOLEAN is
  213.       do
  214.          Result := cp.item(idx).is_name_and_type;
  215.       end;
  216.  
  217.    is_utf8(idx: INTEGER): BOOLEAN is
  218.       do
  219.          Result := cp.item(idx).is_utf8;
  220.       end;
  221.  
  222. feature -- Update and search :
  223.  
  224.    idx_class2(name: STRING): INTEGER is
  225.          -- Where `name' can be fully qualified or unqualified.
  226.       local
  227.          utf8: INTEGER;
  228.       do
  229.          utf8 := idx_utf8(name);
  230.          from
  231.             Result := cp_up;
  232.          until
  233.             Result = 0 or else cp.item(Result).is_class_idx(utf8)
  234.          loop
  235.             Result := Result - 1;
  236.          end;
  237.          if Result = 0 then
  238.             tmp_info.clear;
  239.             tmp_info_append_u2(utf8);
  240.             add_last.set_class(tmp_info);
  241.             Result := cp_up;
  242.          end;
  243.       end;
  244.  
  245.    idx_fieldref_for_manifest_string(key: STRING): INTEGER is
  246.       require
  247.          key /= Void
  248.       local
  249.          c, nt: INTEGER;
  250.       do
  251.          c := idx_class2(jvm_root_class);
  252.          nt := idx_name_and_type2(key,jvm_string_descriptor);
  253.          Result := idx_fieldref2(c,nt);
  254.       ensure
  255.          valid_index(Result)
  256.       end;
  257.  
  258.    idx_fieldref(rf: RUN_FEATURE): INTEGER is
  259.       require
  260.          rf /= Void
  261.       local
  262.          c, nt: INTEGER;
  263.       do
  264.          c := rf.run_class.jvm_constant_pool_index;
  265.          nt := idx_name_and_type(rf);
  266.          Result := idx_fieldref2(c,nt);
  267.       ensure
  268.          valid_index(Result)
  269.       end;
  270.  
  271.    idx_fieldref2(c, nt: INTEGER): INTEGER is
  272.       require
  273.          valid_index(c);
  274.          valid_index(nt)
  275.       do
  276.          from
  277.             Result := cp_up;
  278.          until
  279.             Result = 0 or else cp.item(Result).is_fieldref_idx(c,nt)
  280.          loop
  281.             Result := Result - 1;
  282.          end;
  283.          if Result = 0 then
  284.             tmp_info.clear;
  285.             tmp_info_append_u2(c);
  286.             tmp_info_append_u2(nt);
  287.             add_last.set_fieldref(tmp_info);
  288.             Result := cp_up;
  289.          end;
  290.       ensure
  291.          valid_index(Result)
  292.       end;
  293.  
  294.    idx_fieldref3(class_name, field_name, descriptor: STRING): INTEGER is
  295.          -- Where `class_name' is the fully qualified name.
  296.       require
  297.          not class_name.empty;
  298.          not field_name.empty;
  299.          not descriptor.empty
  300.       local
  301.          c: INTEGER;
  302.       do
  303.          c := idx_class2(class_name);
  304.          Result := idx_fieldref4(c,field_name,descriptor);
  305.       end;
  306.  
  307.    idx_fieldref4(c: INTEGER; field_name, descriptor: STRING): INTEGER is
  308.       local
  309.          nt: INTEGER;
  310.       do
  311.          nt := idx_name_and_type2(field_name,descriptor);
  312.          Result := idx_fieldref2(c,nt);
  313.       end;
  314.  
  315.    idx_fieldref5(c, n, t: INTEGER): INTEGER is
  316.       local
  317.          nt: INTEGER;
  318.       do
  319.          nt := idx_name_and_type3(n,t);
  320.          Result := idx_fieldref2(c,nt);
  321.       end;
  322.  
  323.    idx_methodref(rf: RUN_FEATURE): INTEGER is
  324.       require
  325.          rf /= Void
  326.       local
  327.          c, nt: INTEGER;
  328.       do
  329.          c := rf.run_class.jvm_constant_pool_index;
  330.          nt := idx_name_and_type(rf);
  331.          Result := idx_methodref2(c,nt);
  332.       ensure
  333.          valid_index(Result)
  334.       end;
  335.  
  336.    idx_methodref1(c: INTEGER; method_name, descriptor: STRING): INTEGER is
  337.       require
  338.          valid_index(c);
  339.          not method_name.empty;
  340.          not descriptor.empty
  341.       local
  342.          nt: INTEGER;
  343.       do
  344.          nt := idx_name_and_type2(method_name,descriptor);
  345.          Result := idx_methodref2(c,nt);
  346.       end;
  347.  
  348.    idx_methodref2(c, nt: INTEGER): INTEGER is
  349.       require
  350.          valid_index(c);
  351.          valid_index(nt)
  352.       do
  353.          from
  354.             Result := cp_up;
  355.          until
  356.             Result = 0 or else cp.item(Result).is_methodref_idx(c,nt)
  357.          loop
  358.             Result := Result - 1;
  359.          end;
  360.          if Result = 0 then
  361.             tmp_info.clear;
  362.             tmp_info_append_u2(c);
  363.             tmp_info_append_u2(nt);
  364.             add_last.set_methodref(tmp_info);
  365.             Result := cp_up;
  366.          end;
  367.       ensure
  368.          valid_index(Result)
  369.       end;
  370.  
  371.    idx_methodref3(class_name, method_name, descriptor: STRING): INTEGER is
  372.          -- Where `class_name' is the fully qualified name.
  373.       require
  374.          not class_name.empty;
  375.          not method_name.empty;
  376.          not descriptor.empty
  377.       local
  378.          c: INTEGER;
  379.       do
  380.          c := idx_class2(class_name);
  381.          Result := idx_methodref1(c,method_name,descriptor);
  382.       end;
  383.  
  384.    idx_string(str: STRING): INTEGER is
  385.          -- Assume `str' has no '%/0/' and no ['%/128/'..'%/255/']
  386.       local
  387.          utf8: INTEGER;
  388.       do
  389.          utf8 := idx_utf8(str);
  390.          from
  391.             Result := cp_up;
  392.          until
  393.             Result = 0 or else cp.item(Result).is_string_idx(utf8)
  394.          loop
  395.             Result := Result - 1;
  396.          end;
  397.          if Result = 0 then
  398.             tmp_info.clear;
  399.             tmp_info_append_u2(utf8);
  400.             add_last.set_string(tmp_info);
  401.             Result := cp_up;
  402.          end;
  403.       end;
  404.  
  405.    idx_string2(str: STRING): INTEGER is
  406.          -- For all kinds of STRINGs (see idx_string)
  407.       local
  408.          i: INTEGER;
  409.          c: CHARACTER;
  410.       do
  411.          from
  412.             tmp_utf8.clear;
  413.             i := 1;
  414.          until
  415.             i > str.count
  416.          loop
  417.             c := str.item(i);
  418.             inspect
  419.                c.code
  420.             when 0 then
  421.                tmp_utf8.extend((192).to_character);
  422.                tmp_utf8.extend((128).to_character);
  423.             when 1 .. 127 then
  424.                tmp_utf8.extend(c);
  425.             when 128 .. 191 then
  426.                tmp_utf8.extend((194).to_character);
  427.                tmp_utf8.extend(c);
  428.             when 192 .. 255 then
  429.                tmp_utf8.extend((195).to_character);
  430.                tmp_utf8.extend((c.code - 64).to_character);
  431.             end;
  432.             i := i + 1;
  433.          end;
  434.          Result := idx_string(tmp_utf8);
  435.       end;
  436.  
  437.    idx_name_and_type2(name, descriptor: STRING): INTEGER is
  438.       local
  439.          d: INTEGER;
  440.       do
  441.          d := idx_utf8(descriptor);
  442.          Result := idx_name_and_type1(name,d);
  443.       ensure
  444.          valid_index(Result)
  445.       end;
  446.  
  447.    idx_name_and_type3(n, d: INTEGER): INTEGER is
  448.       do
  449.          from
  450.             Result := cp_up;
  451.          until
  452.             Result = 0 or else cp.item(Result).is_name_and_type_idx(n,d)
  453.          loop
  454.             Result := Result - 1;
  455.          end;
  456.          if Result = 0 then
  457.             tmp_info.clear;
  458.             tmp_info_append_u2(n);
  459.             tmp_info_append_u2(d);
  460.             add_last.set_name_and_type(tmp_info);
  461.             Result := cp_up;
  462.          end;
  463.       ensure
  464.          valid_index(Result)
  465.       end;
  466.  
  467.    idx_name_and_type1(name: STRING; d: INTEGER): INTEGER is
  468.       local
  469.          n: INTEGER;
  470.       do
  471.          n := idx_utf8(name);
  472.          Result := idx_name_and_type3(n,d);
  473.       ensure
  474.          valid_index(Result)
  475.       end;
  476.  
  477.    idx_name_and_type(rf: RUN_FEATURE): INTEGER is
  478.       do
  479.          Result := idx_name_and_type2(rf.name.to_key,rf.jvm_descriptor);
  480.       ensure
  481.          valid_index(Result)
  482.       end;
  483.  
  484.    idx_utf8(contents: STRING): INTEGER is
  485.       do
  486.          from
  487.             Result := cp_up;
  488.          until
  489.             Result = 0 or else cp.item(Result).is_utf8_idx(contents)
  490.          loop
  491.             Result := Result - 1;
  492.          end;
  493.          if Result = 0 then
  494.             string_to_utf8(contents,tmp_info);
  495.             add_last.set_utf8(tmp_info);
  496.             Result := cp_up;
  497.          end;
  498.       ensure
  499.          valid_index(Result)
  500.       end;
  501.  
  502. feature
  503.  
  504.    idx_fieldref_generating_type(c: INTEGER): INTEGER is
  505.       local
  506.          idx, nt: INTEGER;
  507.       do
  508.          idx := idx_eiffel_string_descriptor;
  509.          nt := idx_name_and_type1(as_generating_type,idx);
  510.          Result := idx_fieldref2(c,nt);
  511.       end;
  512.  
  513.    idx_fieldref_generator(c: INTEGER): INTEGER is
  514.       local
  515.          idx, nt: INTEGER;
  516.       do
  517.          idx := idx_eiffel_string_descriptor;
  518.          nt := idx_name_and_type1(as_generator,idx);
  519.          Result := idx_fieldref2(c,nt);
  520.       end;
  521.  
  522. feature {PRINT_JVM_CLASS,CP_INFO}
  523.  
  524.    view_in(str: STRING; idx: INTEGER) is
  525.          -- Append in `str' a human readable version.
  526.       require
  527.          valid_index(idx);
  528.          str /= Void
  529.       do
  530.          cp.item(idx).view_in(str);
  531.       end;
  532.  
  533. feature {CODE_ATTRIBUTE}
  534.  
  535.    idx_eiffel_string_class: INTEGER is
  536.       do
  537.          Result := idx_class2(jvm_string_class);
  538.       end;
  539.  
  540.    idx_eiffel_string_count_fieldref: INTEGER is
  541.       local
  542.          idx: INTEGER;
  543.       do
  544.          idx := idx_name_and_type2(as_count,fz_i);
  545.          Result := idx_fieldref2(idx_eiffel_string_class,idx);
  546.       end;
  547.  
  548.    idx_eiffel_string_capacity_fieldref: INTEGER is
  549.       local
  550.          idx: INTEGER;
  551.       do
  552.          idx := idx_name_and_type2(as_capacity,fz_i);
  553.          Result := idx_fieldref2(idx_eiffel_string_class,idx);
  554.       end;
  555.  
  556.    idx_eiffel_string_storage_fieldref: INTEGER is
  557.       local
  558.          idx: INTEGER;
  559.       do
  560.          idx := idx_name_and_type2(as_storage,fz_31);
  561.          Result := idx_fieldref2(idx_eiffel_string_class,idx);
  562.       end;
  563.  
  564. feature
  565.  
  566.    idx_eiffel_string_descriptor: INTEGER is
  567.       do
  568.          Result := idx_utf8(jvm_string_descriptor);
  569.       end;
  570.  
  571. feature {NONE}
  572.  
  573.    add_last: CP_INFO is
  574.       do
  575.          if cp.upper > cp_up then
  576.             cp_up := cp_up + 1;
  577.             Result := cp.item(cp_up);
  578.          else
  579.             !!Result.clear;
  580.             cp.add_last(Result);
  581.             cp_up := cp_up + 1;
  582.          end;
  583.       ensure
  584.          cp_up = 1 + old cp_up
  585.       end;
  586.  
  587.    tmp_utf8: STRING is
  588.       once
  589.          !!Result.make(32);
  590.       end;
  591.  
  592.    tmp_info: STRING is
  593.       once
  594.          !!Result.make(32);
  595.       end;
  596.  
  597.    tmp_info_append_u2(u2: INTEGER) is
  598.       do
  599.          append_u2(tmp_info,u2);
  600.       end;
  601.  
  602. feature {NONE}
  603.  
  604.    jvm_string_descriptor: STRING is
  605.          -- Descriptor for class STRING: "L<Package>/string;"
  606.       once
  607.          !!Result.make(12);
  608.          Result.extend('L');
  609.          Result.append(jvm_string_class);
  610.          Result.extend(';');
  611.       end;
  612.  
  613.    jvm_string_class: STRING is
  614.          -- Fully qualified name for class STRING
  615.       once
  616.          !!Result.make(12);
  617.          Result.append(jvm.output_name);
  618.          Result.extend('/');
  619.          Result.append(fz_24);
  620.       end;
  621.  
  622. invariant
  623.  
  624.    cp_up <= cp.upper;
  625.  
  626. end -- CONSTANT_POOL
  627.  
  628.