home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / constant_pool.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  13.2 KB  |  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://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 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 {NONE}
  38.  
  39.    fz_java_lang_object       : STRING is "java/lang/Object";
  40.  
  41. feature {PRINT_JVM_CLASS}
  42.  
  43.    reset(new_upper: INTEGER) is
  44.       require
  45.      new_upper > 0
  46.       local
  47.      cp_info: CP_INFO;
  48.      i: INTEGER;
  49.       do
  50.      from
  51.         cp_up := 0;
  52.      until
  53.         i = new_upper
  54.      loop
  55.         add_last.clear;
  56.         i := i + 1;
  57.      end;
  58.       ensure
  59.      cp_up = new_upper
  60.       end;
  61.  
  62. feature {JVM}
  63.  
  64.    clear is
  65.       local
  66.      idx: INTEGER;
  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_uft8_code := idx_uft8("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_uft8_code: 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_uft8(i: INTEGER; info: STRING) is
  161.       do
  162.      cp.item(i).set_uft8(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_uft8(idx: INTEGER): BOOLEAN is
  218.       do
  219.      Result := cp.item(idx).is_uft8;
  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.      uft8: INTEGER;
  228.       do
  229.      uft8 := idx_uft8(name);
  230.      from
  231.         Result := cp_up;
  232.      until
  233.         Result = 0 or else cp.item(Result).is_class_idx(uft8)
  234.      loop
  235.         Result := Result - 1;
  236.      end;
  237.      if Result = 0 then
  238.         tmp_info.clear;
  239.         tmp_info_append_u2(uft8);
  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.fully_qualified_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.fully_qualified_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.      uft8: INTEGER;
  388.       do
  389.      uft8 := idx_uft8(str);
  390.      from
  391.         Result := cp_up;
  392.      until
  393.         Result = 0 or else cp.item(Result).is_string_idx(uft8)
  394.      loop
  395.         Result := Result - 1;
  396.      end;
  397.      if Result = 0 then
  398.         tmp_info.clear;
  399.         tmp_info_append_u2(uft8);
  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_uft8.clear;
  413.         i := 1;
  414.      until
  415.         i > str.count
  416.      loop
  417.         c := str.item(i);
  418.         inspect
  419.            c.to_integer
  420.         when 0 then
  421.            tmp_uft8.extend((192).to_character);
  422.            tmp_uft8.extend((128).to_character);
  423.         when 1 .. 127 then
  424.            tmp_uft8.extend(c);
  425.         when 128 .. 191 then
  426.            tmp_uft8.extend((194).to_character);
  427.            tmp_uft8.extend(c);
  428.         when 192 .. 255 then
  429.            tmp_uft8.extend((195).to_character);
  430.            tmp_uft8.extend((c.to_integer - 64).to_character);
  431.         end;
  432.         i := i + 1;
  433.      end;
  434.      Result := idx_string(tmp_uft8);
  435.       end;
  436.  
  437.    idx_name_and_type2(name, descriptor: STRING): INTEGER is
  438.       local
  439.      d: INTEGER;
  440.       do
  441.      d := idx_uft8(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_uft8(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_uft8(contents: STRING): INTEGER is
  485.       do
  486.      from
  487.         Result := cp_up;
  488.      until
  489.         Result = 0 or else cp.item(Result).is_uft8_idx(contents)
  490.      loop
  491.         Result := Result - 1;
  492.      end;
  493.      if Result = 0 then
  494.         string_to_uft8(contents,tmp_info);
  495.         add_last.set_uft8(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(us_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(us_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(us_count,fz_30);
  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(us_capacity,fz_30);
  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(us_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_uft8(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_uft8: 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.