home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / run_feature_4.e < prev    next >
Text File  |  1999-06-05  |  22KB  |  768 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 RUN_FEATURE_4
  17.  
  18. inherit RUN_FEATURE redefine base_feature end;
  19.  
  20. creation make
  21.  
  22. feature
  23.  
  24.    base_feature: FUNCTION;
  25.  
  26.    arguments: FORMAL_ARG_LIST;
  27.  
  28.    result_type: TYPE;
  29.  
  30.    require_assertion: RUN_REQUIRE;
  31.  
  32.    local_vars: LOCAL_VAR_LIST;
  33.  
  34.    routine_body: COMPOUND;
  35.  
  36.    rescue_compound: COMPOUND;
  37.  
  38.    ensure_assertion: E_ENSURE;
  39.  
  40.    static_value_mem: INTEGER;
  41.  
  42. feature
  43.  
  44.    is_pre_computable: BOOLEAN is false;
  45.  
  46.    is_once_function: BOOLEAN is false;
  47.  
  48. feature
  49.  
  50.    is_static: BOOLEAN is
  51.       do
  52.          if isa_in_line then
  53.             Result := is_static_flag;
  54.          end;
  55.       end;
  56.  
  57.    afd_check is
  58.       do
  59.          routine_afd_check;
  60.       end;
  61.  
  62.    can_be_dropped: BOOLEAN is
  63.       do
  64.          Result := ((arguments = Void) and then
  65.                     (local_vars = Void) and then
  66.                     (require_assertion = Void) and then
  67.                     (ensure_assertion = Void) and then
  68.                     (rescue_compound = Void));
  69.          if Result then
  70.             if routine_body /= Void then
  71.                Result := false;
  72.             end;
  73.          end;
  74.       end;
  75.  
  76.    mapping_c is
  77.       local
  78.          tmp_expanded_idx: INTEGER;
  79.       do
  80.          if isa_in_line then
  81.             in_line;
  82.          else
  83.             tmp_expanded_idx := cpp.se_tmp_open(Current);
  84.             default_mapping_function;
  85.             if tmp_expanded_idx >= 0 then
  86.                cpp.se_tmp_close(tmp_expanded_idx);
  87.             end;
  88.          end;
  89.       end;
  90.  
  91.    c_define is
  92.       do
  93.          if isa_in_line then
  94.             cpp.incr_inlined_function_count;
  95.             nothing_comment;
  96.          else
  97.             if use_current then
  98.                cpp.incr_function_count;
  99.             else
  100.                cpp.incr_real_function_count;
  101.             end;
  102.             define_prototype;
  103.             c_define_opening;
  104.             if routine_body /= Void then
  105.                routine_body.compile_to_c;
  106.             end;
  107.             c_define_closing;
  108.             cpp.put_string(fz_15);
  109.             c_frame_descriptor;
  110.          end;
  111.       end;
  112.  
  113. feature {CALL_PROC_CALL}
  114.  
  115.    collect_c_tmp is
  116.       do
  117.          if result_type.is_user_expanded then
  118.             if result_type.is_dummy_expanded then
  119.             elseif isa_in_line then
  120.             else
  121.                cpp.se_tmp_add(Current);
  122.             end;
  123.          end;
  124.       end;
  125.  
  126. feature {ADDRESS_OF_POOL}
  127.  
  128.    address_of_c_define(caller: ADDRESS_OF) is
  129.       do
  130.          if run_control.boost then
  131.             if isa_in_line then
  132.                address_of_c_define_wrapper(caller);
  133.             elseif use_current then
  134.             else
  135.                address_of_c_define_wrapper(caller);
  136.             end;
  137.          else
  138.             address_of_c_define_wrapper(caller);
  139.          end;
  140.       end;
  141.  
  142. feature {ADDRESS_OF}
  143.  
  144.    address_of_c_mapping is
  145.       do
  146.          if run_control.boost then
  147.             if isa_in_line then
  148.                address_of_c_mapping_wrapper;
  149.             elseif use_current then
  150.                mapping_name;
  151.             else
  152.                address_of_c_mapping_wrapper;
  153.             end;
  154.          else
  155.             address_of_c_mapping_wrapper;
  156.          end;
  157.       end;
  158.  
  159. feature {FUNCTION}
  160.  
  161.    is_empty_or_null_body: BOOLEAN is
  162.       do
  163.          if isa_in_line then
  164.             Result := in_line_status = C_empty_or_null_body;
  165.          end;
  166.       end;
  167.  
  168.    is_attribute_reader: RUN_FEATURE_2 is
  169.          -- Gives Void or the attribute read.
  170.       local
  171.          c0: CALL_0;
  172.       do
  173.          if isa_in_line then
  174.             if in_line_status = C_attribute_reader then
  175.                c0 ?= body_one_result;
  176.                Result ?= c0.run_feature;
  177.             end;
  178.          end;
  179.       end;
  180.  
  181.    is_direct_call_on_attribute: CALL is
  182.          -- Gives Void or the corresponding call.
  183.       do
  184.          if isa_in_line then
  185.             inspect
  186.                in_line_status
  187.             when C_dca then
  188.                Result ?= body_one_result;
  189.             else
  190.             end;
  191.          end;
  192.       end;
  193.  
  194. feature {NONE}
  195.  
  196.    jvm_result_store is
  197.       do
  198.          result_type.jvm_write_local(jvm_result_offset);
  199.       end;
  200.  
  201.    initialize is
  202.       do
  203.          arguments := base_feature.arguments;
  204.          result_type := base_feature.result_type;
  205.          if result_type.is_like_argument then
  206.             if not arguments.is_runnable(current_type) then
  207.                !!arguments.with(arguments,current_type);
  208.             end;
  209.             result_type := result_type.to_runnable(current_type);
  210.          else
  211.             result_type := result_type.to_runnable(current_type);
  212.             if arguments /= Void then
  213.                if not arguments.is_runnable(current_type) then
  214.                   !!arguments.with(arguments,current_type);
  215.                end;
  216.             end;
  217.          end;
  218.          local_vars := base_feature.local_vars;
  219.          if local_vars /= Void then
  220.             local_vars := local_vars.to_runnable(current_type);
  221.          end;
  222.          routine_body := base_feature.routine_body;
  223.          if routine_body /= Void then
  224.             routine_body := routine_body.to_runnable(current_type);
  225.          end;
  226.          if run_control.require_check then
  227.             require_assertion := run_require;
  228.          end;
  229.          if run_control.ensure_check then
  230.             ensure_assertion := run_ensure;
  231.          end;
  232.          rescue_compound := base_feature.rescue_compound;
  233.          if rescue_compound /= Void then
  234.             exceptions_handler.set_used;
  235.             rescue_compound := rescue_compound.to_runnable(current_type);
  236.          end;
  237.       end;
  238.  
  239.    in_line_status: INTEGER;
  240.          -- Value 0 means not computed.
  241.          -- Value -1 means not `isa_in_line'.
  242.  
  243.    is_static_flag: BOOLEAN;
  244.  
  245.    isa_in_line: BOOLEAN is
  246.       do
  247.          if run_control.boost then
  248.             inspect
  249.                in_line_status
  250.             when -1 then
  251.             when 0 then
  252.                Result := true;
  253.                if rescue_compound /= Void then
  254.                   in_line_status := -1;
  255.                   Result := false;
  256.                elseif empty_or_null_body then
  257.                   in_line_status := C_empty_or_null_body;
  258.                elseif value_reader then
  259.                   in_line_status := C_value_reader;
  260.                elseif attribute_reader then
  261.                   in_line_status := C_attribute_reader;
  262.                elseif result_is_current then
  263.                   in_line_status := C_result_is_current;
  264.                elseif direct_call then
  265.                   in_line_status := C_direct_call;
  266.                   -- *** SHOULD USE isa_dca_inline TOO ??
  267.                elseif dca then
  268.                   in_line_status := C_dca;
  269.                elseif a_eq_neq then
  270.                   in_line_status := C_a_eq_neq;
  271.                elseif dc_pco1 then
  272.                   in_line_status := C_dc_pco1;
  273.                elseif dc_pco2 then
  274.                   in_line_status := C_dc_pco2;
  275.                elseif direct_cse_call then
  276.                   in_line_status := C_direct_cse_call;
  277.                else
  278.                   in_line_status := -1;
  279.                   Result := false;
  280.                end;
  281.             else
  282.                Result := true;
  283.             end;
  284.          end;
  285.       end;
  286.  
  287.    empty_or_null_body: BOOLEAN is
  288.          -- The body is empty or has only unreacheable code.
  289.       local
  290.          rb: COMPOUND;
  291.       do
  292.          rb := routine_body;
  293.          if (rb = Void or else rb.empty_or_null_body)
  294.             and then local_vars = Void
  295.           then
  296.             static_value_mem := 0;
  297.             is_static_flag := true;
  298.             Result := true;
  299.          end;
  300.       end;
  301.  
  302.    value_reader: BOOLEAN is
  303.          -- True when the function body has only one instruction
  304.          -- of the form :
  305.          --      Result := <expression>;
  306.          -- Where <expression> is statically computable.
  307.       local
  308.          e: EXPRESSION;
  309.          c0: CALL_0;
  310.       do
  311.          e := body_one_result;
  312.          if e /= Void and then local_vars = Void then
  313.             c0 ?= e;
  314.             if c0 /= Void and then
  315.                c0.target.is_current and then
  316.                c0.run_feature = Current
  317.              then
  318.                eh.add_position(e.start_position);
  319.                fatal_error("Infinite recursive call.");
  320.             elseif e.is_static then
  321.                Result := true;
  322.                static_value_mem := e.static_value;
  323.                is_static_flag := true;
  324.             end;
  325.          end;
  326.       end;
  327.  
  328.    attribute_reader: BOOLEAN is
  329.          -- True when the function has no arguments, no locals, and
  330.          -- when the body has only one instruction of the form :
  331.          --      Result := attribute;
  332.          -- Where `attribute' is a RUN_FEATURE_2.
  333.       local
  334.          e: EXPRESSION;
  335.          c0: CALL_0;
  336.          rf2: RUN_FEATURE_2;
  337.       do
  338.          e := body_one_result;
  339.          if e /= Void and then local_vars = Void then
  340.             c0 ?= e;
  341.             if c0 /= Void then
  342.                if c0.target.is_current then
  343.                   rf2 ?= c0.run_feature;
  344.                   Result := rf2 /= Void;
  345.                end;
  346.             end;
  347.          end;
  348.       end;
  349.  
  350.    result_is_current: BOOLEAN is
  351.       local
  352.          e: EXPRESSION;
  353.       do
  354.          e := body_one_result;
  355.          if e /= Void and then local_vars = Void then
  356.             Result := e.is_current;
  357.          end;
  358.       end;
  359.  
  360.    direct_call: BOOLEAN is
  361.          -- True when the function has no arguments, no locals, and
  362.          -- when the body has only one instruction of the form :
  363.          --    Result := foo(<args>);
  364.          -- Where <args> can be an empty list or a statically
  365.          -- computable one.
  366.          -- Where `foo' is a RUN_FEATURE_4.
  367.       local
  368.          e: EXPRESSION;
  369.          c: CALL;
  370.          args: EFFECTIVE_ARG_LIST;
  371.          rf4: RUN_FEATURE_4;
  372.       do
  373.          e := body_one_result;
  374.          if e /= Void and then
  375.             arguments = Void and then
  376.             local_vars = Void
  377.           then
  378.             c ?= e;
  379.             if c /= Void then
  380.                if c.target.is_current then
  381.                   rf4 ?= c.run_feature;
  382.                   if rf4 /= Void then
  383.                      args := c.arguments;
  384.                      if args = Void then
  385.                         Result := true;
  386.                      else
  387.                         Result := args.is_static;
  388.                      end;
  389.                   end;
  390.                end;
  391.             end;
  392.          end;
  393.       end;
  394.  
  395.    dca: BOOLEAN is
  396.          -- Direct Call on Attribute.
  397.       local
  398.          c: CALL;
  399.          rf: RUN_FEATURE;
  400.          args: EFFECTIVE_ARG_LIST;
  401.       do
  402.          c := body_one_result_dca;
  403.          if c /= Void and then local_vars = Void then
  404.             rf := c.run_feature;
  405.             if rf /= Void then
  406.                if rf /= Current then
  407.                   if rf.current_type.is_user_expanded then
  408.                      -- Not yet inlined :-(
  409.                   else
  410.                      args := c.arguments;
  411.                      if args = Void then
  412.                         Result := arguments = Void;
  413.                      else
  414.                         Result := args.isa_dca_inline(Current,rf);
  415.                      end;
  416.                   end;
  417.                end;
  418.             end;
  419.          end;
  420.       end;
  421.  
  422.    a_eq_neq: BOOLEAN is
  423.          -- Attribute "=" or "/=".
  424.       local
  425.          c: CALL;
  426.          rf: RUN_FEATURE;
  427.          e: EXPRESSION;
  428.       do
  429.          c := body_one_result_dca;
  430.          if c /= Void and then local_vars = Void then
  431.             rf := c.run_feature;
  432.             if rf = Void and then c.arg_count = 1 then
  433.                -- For "=" and "/=" :
  434.                e := c.arguments.expression(1);
  435.                inspect
  436.                   e.isa_dca_inline_argument
  437.                when 0 then
  438.                when -1 then
  439.                   Result := arguments = Void;
  440.                else
  441.                   if arguments /= Void then
  442.                      Result := arguments.count = 1;
  443.                   end;
  444.                end;
  445.             end;
  446.          end;
  447.       end;
  448.  
  449.    dc_pco1: BOOLEAN is
  450.       local
  451.          c: CALL;
  452.          rf6: RUN_FEATURE_6;
  453.       do
  454.          c := body_one_dc_pco;
  455.          if c /= Void and then c.target.is_current then
  456.             rf6 ?= c.run_feature;
  457.             if rf6 /= Void then
  458.                Result := not rf6.use_current;
  459.             end;
  460.          end;
  461.       end;
  462.  
  463.    dc_pco2: BOOLEAN is
  464.       local
  465.          c1, c2: CALL;
  466.          rf6: RUN_FEATURE_6;
  467.       do
  468.          c1 := body_one_dc_pco;
  469.          if c1 /= Void then
  470.             c2 ?= c1.target;
  471.             if c2 /= Void then
  472.                rf6 ?= c2.run_feature;
  473.                if rf6 /= Void and then
  474.                   not rf6.use_current and then
  475.                   c2.target.is_current
  476.                 then
  477.                   Result := true;
  478.                end;
  479.             end;
  480.          end;
  481.       end;
  482.  
  483.    direct_cse_call: BOOLEAN is
  484.       local
  485.          c: CALL;
  486.          rf8: RUN_FEATURE_8;
  487.       do
  488.          if arguments = Void and then local_vars = Void then
  489.             c ?= body_one_result;
  490.             if c /= Void and then c.arguments = Void then
  491.                c ?= c.target;
  492.                if c /= Void and then c.target.is_current then
  493.                   if c.arguments = Void then
  494.                      rf8 ?= c.run_feature;
  495.                      if rf8 /= Void then
  496.                         Result := rf8.name.to_string = as_to_pointer;
  497.                      end;
  498.                   end;
  499.                end;
  500.             end;
  501.          end;
  502.       end;
  503.  
  504.    in_line is
  505.       local
  506.          a: ASSIGNMENT;
  507.          e: EXPRESSION;
  508.          flag: BOOLEAN;
  509.          c: CALL;
  510.          rf: RUN_FEATURE;
  511.          cien: CALL_INFIX2;
  512.          exp_to_ref_flag: BOOLEAN;
  513.       do
  514.          cpp.put_string("/*(IRF4.");
  515.          cpp.put_integer(in_line_status);
  516.          cpp.put_string(name.to_string);
  517.          cpp.put_string(fz_close_c_comment);
  518.          inspect
  519.             in_line_status
  520.          when C_empty_or_null_body then
  521.             flag := cpp.cannot_drop_all;
  522.             if flag then
  523.                cpp.put_character(',');
  524.             end;
  525.             result_type.run_type.c_initialize;
  526.             if flag then
  527.                cpp.put_character(')');
  528.             end;
  529.          when C_value_reader then
  530.             flag := cpp.cannot_drop_all;
  531.             if flag then
  532.                cpp.put_character(',');
  533.             end;
  534.             a ?= routine_body.first;
  535.             e := a.right_side;
  536.             cpp.put_character('(');
  537.             e.compile_to_c;
  538.             cpp.put_character(')');
  539.             if flag then
  540.                cpp.put_character(')');
  541.             end;
  542.          when C_attribute_reader then
  543.             flag := cpp.arguments_cannot_be_dropped;
  544.             if flag then
  545.                cpp.put_character(',');
  546.             end;
  547.             a ?= routine_body.first;
  548.             c ?= a.right_side;
  549.             rf := c.run_feature;
  550.             if rf.result_type.is_expanded and then result_type.is_reference then
  551.                exp_to_ref_flag := true;
  552.                rf.result_type.to_reference;
  553.                cpp.put_character('(');
  554.             end;
  555.             rf.mapping_c;
  556.             if exp_to_ref_flag then
  557.                cpp.put_character(')');
  558.             end;
  559.             if flag then
  560.                cpp.put_character(')');
  561.             end;
  562.          when C_result_is_current then
  563.             flag := cpp.arguments_cannot_be_dropped;
  564.             if flag then
  565.                cpp.put_character(',');
  566.             end;
  567.             tmp_string.clear;
  568.             tmp_string.extend('(');
  569.             tmp_string.extend('(');
  570.             result_type.run_type.c_type_for_result_in(tmp_string);
  571.             tmp_string.extend(')');
  572.             tmp_string.extend('(');
  573.             cpp.put_string(tmp_string);
  574.             cpp.put_target_as_value;
  575.             cpp.put_string(fz_13);
  576.             if flag then
  577.                cpp.put_character(')');
  578.             end;
  579.          when C_direct_call then
  580.             a ?= routine_body.first;
  581.             c ?= a.right_side;
  582.             rf := c.run_feature;
  583.             cpp.push_same_target(rf,c.arguments);
  584.             rf.mapping_c;
  585.             cpp.pop;
  586.          when C_dca then
  587.             a ?= routine_body.first;
  588.             c ?= a.right_side;
  589.             c.finalize;
  590.             cpp.push_inline_dca(Current,c);
  591.             c.run_feature.mapping_c;
  592.             cpp.pop;
  593.          when C_a_eq_neq then
  594.             a ?= routine_body.first;
  595.             cien ?= a.right_side;
  596.             cpp.push_inline_dca(Current,cien);
  597.             cien.dca_inline(cien.arg1.result_type);
  598.             cpp.pop;
  599.          when C_dc_pco1, C_dc_pco2 then
  600.             flag := cpp.target_cannot_be_dropped;
  601.             if flag then
  602.                cpp.put_character(',');
  603.             end;
  604.             a ?= routine_body.first;
  605.             c ?= a.right_side;
  606.             rf := c.run_feature;
  607.             cpp.push_direct(rf,c.target,c.arguments);
  608.             rf.mapping_c;
  609.             cpp.pop;
  610.             if flag then
  611.                cpp.put_character(')');
  612.             end;
  613.          when C_direct_cse_call then
  614.             a ?= routine_body.first;
  615.             c ?= a.right_side;
  616.             rf := c.run_feature;
  617.             cpp.push_same_target(rf,c.arguments);
  618.             rf.mapping_c;
  619.             cpp.pop;
  620.          end;
  621.          cpp.put_string("/*)*/");
  622.       end;
  623.  
  624.    compute_use_current is
  625.       local
  626.          ct: like current_type;
  627.       do
  628.          ct := current_type;
  629.          if ct.is_reference then
  630.             if run_control.no_check then
  631.                use_current_state := ucs_true;
  632.             else
  633.                std_compute_use_current;
  634.             end;
  635.          else
  636.             std_compute_use_current;
  637.          end;
  638.       end;
  639.  
  640.    body_one_result: EXPRESSION is
  641.          -- Gives the RHS expression if the body has only one
  642.          -- instruction of the form :
  643.          --        Result := <RHS>;
  644.       local
  645.          rb: like routine_body;
  646.          a: ASSIGNMENT;
  647.       do
  648.          rb := routine_body;
  649.          if rb /= Void and then rb.count = 1 then
  650.             a ?= rb.first;
  651.             if a /= Void then
  652.                if a.left_side.is_result then
  653.                   Result := a.right_side;
  654.                end;
  655.             end;
  656.          end;
  657.       end;
  658.  
  659.    body_one_result_dca: CALL is
  660.       local
  661.          c: CALL;
  662.          c0c: CALL_0_C;
  663.          writable_attribute: RUN_FEATURE_2;
  664.          rf: RUN_FEATURE;
  665.          r: ARRAY[RUN_CLASS];
  666.          bf: WRITABLE_ATTRIBUTE;
  667.       do
  668.          c ?= body_one_result;
  669.          if c /= Void then
  670.             c0c ?= c.target;
  671.             if c0c /= Void then
  672.                if c0c.target.is_current then
  673.                   writable_attribute ?= c0c.run_feature;
  674.                   if writable_attribute /= Void then
  675.                      r := writable_attribute.run_class.running;
  676.                      rf := c.run_feature;
  677.                      if rf = Void then -- Basic "=" and "/=" :
  678.                         Result := c;
  679.                      elseif r /= Void and then r.count = 1 then
  680.                         r := rf.run_class.running;
  681.                         if r /= Void and then r.count = 1 then
  682.                            bf := writable_attribute.base_feature;
  683.                            Result := c;
  684.                         end;
  685.                      end;
  686.                   end;
  687.                end;
  688.             end;
  689.          end;
  690.       end;
  691.  
  692.    body_one_dc_pco: CALL is
  693.       local
  694.          c: CALL;
  695.          args: EFFECTIVE_ARG_LIST;
  696.       do
  697.          c ?= body_one_result;
  698.          if c /= Void and then
  699.             local_vars = Void and then
  700.             arguments = Void
  701.           then
  702.             args := c.arguments;
  703.             if args = Void or else args.is_static then
  704.                Result := c;
  705.             end;
  706.          end;
  707.       end;
  708.  
  709. feature {NONE}
  710.  
  711.    C_empty_or_null_body  : INTEGER is 1;
  712.    C_value_reader        : INTEGER is 2;
  713.    C_attribute_reader    : INTEGER is 3;
  714.    C_result_is_current   : INTEGER is 4;
  715.    C_direct_call         : INTEGER is 5;
  716.    C_dca                 : INTEGER is 6;
  717.    C_a_eq_neq            : INTEGER is 7;
  718.    C_dc_pco1             : INTEGER is 8;
  719.    C_dc_pco2             : INTEGER is 9;
  720.    C_direct_cse_call     : INTEGER is 10;
  721.  
  722. feature {NONE}
  723.  
  724.    tmp_string: STRING is
  725.       once
  726.          !!Result.make(8);
  727.       end;
  728.  
  729. feature {RUN_CLASS}
  730.  
  731.    jvm_field_or_method is
  732.       do
  733.          jvm.add_method(Current);
  734.       end;
  735.  
  736. feature
  737.  
  738.    mapping_jvm is
  739.       do
  740.          routine_mapping_jvm;
  741.       end;
  742.  
  743. feature {JVM}
  744.  
  745.    jvm_define is
  746.       do
  747.          method_info_start;
  748.          jvm_define_opening;
  749.          if routine_body /= Void then
  750.             routine_body.compile_to_jvm;
  751.          end;
  752.          jvm_define_closing;
  753.          result_type.jvm_push_local(jvm_result_offset);
  754.          result_type.run_type.jvm_return_code;
  755.          method_info.finish;
  756.       end;
  757.  
  758. feature {NONE}
  759.  
  760.    update_tmp_jvm_descriptor is
  761.       do
  762.          routine_update_tmp_jvm_descriptor;
  763.       end;
  764.  
  765. end -- RUN_FEATURE_4
  766.  
  767.  
  768.