home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / run_feature_3.e < prev    next >
Text File  |  1999-06-05  |  18KB  |  631 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_3
  17.  
  18. inherit RUN_FEATURE redefine base_feature end;
  19.  
  20. creation make
  21.  
  22. feature
  23.  
  24.    base_feature: PROCEDURE;
  25.  
  26.    arguments: FORMAL_ARG_LIST;
  27.  
  28.    require_assertion: RUN_REQUIRE;
  29.  
  30.    local_vars: LOCAL_VAR_LIST;
  31.  
  32.    routine_body: COMPOUND;
  33.  
  34.    rescue_compound: COMPOUND;
  35.  
  36.    ensure_assertion: E_ENSURE;
  37.  
  38. feature
  39.  
  40.    is_static: BOOLEAN is false;
  41.  
  42.    static_value_mem: INTEGER is 0;
  43.  
  44.    can_be_dropped: BOOLEAN is false
  45.  
  46.    is_once_function: BOOLEAN is false;
  47.  
  48. feature
  49.  
  50.    result_type: TYPE is
  51.       do
  52.       end;
  53.  
  54.    is_pre_computable: BOOLEAN is
  55.       do
  56.          if arguments = Void then
  57.             if routine_body = Void then
  58.                Result := true;
  59.             else
  60.                if local_vars = Void then
  61.                   Result := routine_body.is_pre_computable;
  62.                end;
  63.             end;
  64.          end;
  65.       end;
  66.  
  67.    afd_check is
  68.       do
  69.          routine_afd_check;
  70.       end;
  71.  
  72.    mapping_c is
  73.       do
  74.          if isa_in_line then
  75.             if cpp.stack_not_full then
  76.                in_line;
  77.             else
  78.                in_line_status := -1;
  79.                small_eiffel.register_for_c_define(Current);
  80.                mapping_c;
  81.             end;
  82.          else
  83.             default_mapping_procedure;
  84.          end;
  85.       end;
  86.  
  87.    c_define is
  88.       do
  89.          if isa_in_line then
  90.             cpp.incr_inlined_procedure_count;
  91.             nothing_comment;
  92.          elseif c_define_done then
  93.          else
  94.             in_line_status := -2;
  95.             if use_current then
  96.                cpp.incr_procedure_count;
  97.             else
  98.                cpp.incr_real_procedure_count;
  99.             end;
  100.             define_prototype;
  101.             c_define_opening;
  102.             if routine_body /= Void then
  103.                routine_body.compile_to_c;
  104.             end;
  105.             c_define_closing;
  106.             cpp.put_string(fz_12);
  107.             c_frame_descriptor;
  108.          end;
  109.       end;
  110.  
  111.    mapping_jvm is
  112.       do
  113.          routine_mapping_jvm;
  114.       end;
  115.  
  116. feature {CALL_PROC_CALL}
  117.  
  118.    collect_c_tmp is
  119.       do
  120.       end;
  121.  
  122. feature {RUN_FEATURE_3}
  123.  
  124.    initialize is
  125.       do
  126.          arguments := base_feature.arguments;
  127.          if arguments /= Void then
  128.             if not arguments.is_runnable(current_type) then
  129.                !!arguments.with(arguments,current_type);
  130.             end;
  131.          end;
  132.          local_vars := base_feature.local_vars;
  133.          if local_vars /= Void then
  134.             local_vars := local_vars.to_runnable(current_type);
  135.          end;
  136.          routine_body := base_feature.routine_body;
  137.          if routine_body /= Void then
  138.             routine_body := routine_body.to_runnable(current_type);
  139.          end;
  140.          if run_control.require_check then
  141.             require_assertion := run_require;
  142.          end;
  143.          if run_control.ensure_check then
  144.             ensure_assertion := run_ensure;
  145.          end;
  146.          rescue_compound := base_feature.rescue_compound;
  147.          if rescue_compound /= Void then
  148.             exceptions_handler.set_used;
  149.             rescue_compound := rescue_compound.to_runnable(current_type);
  150.          end;
  151.       end;
  152.  
  153.    in_line_status: INTEGER;
  154.          -- Possible values :
  155.          --  Value 0 means not computed.
  156.          --  Value -1 means not `isa_in_line' and `c_define' not yet done.
  157.          --  Value -2 means not `isa_in_line' and `c_define' already done.
  158.          --  Other possible values are :
  159.  
  160.    C_empty_or_null_body : INTEGER is 1;
  161.    C_do_not_use_current : INTEGER is 2;
  162.    C_attribute_writer   : INTEGER is 3;
  163.    C_direct_call        : INTEGER is 4;
  164.    C_dca                : INTEGER is 5;
  165.    C_one_pc             : INTEGER is 6;
  166.  
  167.    in_line_status_not_computed: BOOLEAN is
  168.       do
  169.          Result := in_line_status = 0;
  170.       end;
  171.  
  172.    c_define_done: BOOLEAN is
  173.       require
  174.          not isa_in_line
  175.       do
  176.          Result := in_line_status = -2;
  177.       end;
  178.  
  179.    isa_in_line: BOOLEAN is
  180.       do
  181.          if run_control.boost then
  182.             if in_line_status_not_computed then
  183.                if rescue_compound /= Void then
  184.                   in_line_status := -1;
  185.                elseif as_copy = name.to_string then
  186.                   in_line_status := -1;
  187.                elseif empty_or_null_body then
  188.                   in_line_status := C_empty_or_null_body;
  189.                elseif do_not_use_current then
  190.                   in_line_status := C_do_not_use_current;
  191.                elseif attribute_writer then
  192.                   in_line_status := C_attribute_writer;
  193.                elseif direct_call then
  194.                   in_line_status := C_direct_call;
  195.                   -- *** SHOULD USE isa_dca_inline TOO ??
  196.                elseif dca then
  197.                   in_line_status := C_dca;
  198.                elseif one_pc then
  199.                   in_line_status := C_one_pc;
  200.                else
  201.                   in_line_status := -1;
  202.                end;
  203.             end;
  204.             Result := in_line_status > 0;
  205.          end;
  206.       end;
  207.  
  208.    in_line is
  209.       require
  210.          isa_in_line;
  211.       local
  212.          flag: BOOLEAN;
  213.          a: ASSIGNMENT;
  214.          w: FEATURE_NAME;
  215.          e: EXPRESSION;
  216.          pc: PROC_CALL;
  217.          rf: RUN_FEATURE;
  218.       do
  219.          cpp.put_string("/*[IRF3.");
  220.          cpp.put_integer(in_line_status);
  221.          cpp.put_string(name.to_string);
  222.          cpp.put_string(fz_close_c_comment);
  223.          inspect
  224.             in_line_status
  225.          when C_empty_or_null_body then
  226.             if cpp.cannot_drop_all then
  227.                cpp.put_string(fz_14);
  228.             end;
  229.             if need_local_vars then
  230.                cpp.put_character('{');
  231.                c_define_opening;
  232.                c_define_closing;
  233.                cpp.put_character('}');
  234.             end;
  235.          when C_do_not_use_current then
  236.             if cpp.target_cannot_be_dropped then
  237.                cpp.put_string(fz_14);
  238.             end;
  239.             flag := need_local_vars;
  240.             if flag then
  241.                cpp.put_character('{');
  242.                c_define_opening;
  243.             end;
  244.             routine_body.compile_to_c;
  245.             if flag then
  246.                c_define_closing;
  247.                cpp.put_character('}');
  248.             end;
  249.          when C_attribute_writer then
  250.             flag := need_local_vars;
  251.             if flag then
  252.                cpp.put_character('{');
  253.                c_define_opening;
  254.             end;
  255.             a ?= routine_body.first;
  256.             w ?= a.left_side;
  257.             w := w.name_in(current_type.base_class);
  258.             cpp.put_character('(');
  259.             cpp.put_character('(');
  260.             cpp.put_character('(');
  261.             current_type.mapping_cast;
  262.             cpp.put_character('(');
  263.             cpp.put_target_as_target;
  264.             cpp.put_string(fz_13);
  265.             cpp.put_string(fz_b5);
  266.             cpp.put_string(w.to_string);
  267.             cpp.put_character(')');
  268.             cpp.put_character('=');
  269.             cpp.put_character('(');
  270.             e := a.right_side;
  271.             if arguments = Void then
  272.                e.compile_to_c;
  273.             else
  274.                cpp.put_arguments;
  275.             end;
  276.             cpp.put_character(')');
  277.             cpp.put_string(fz_00);
  278.             if flag then
  279.                c_define_closing;
  280.                cpp.put_character('}');
  281.             end;
  282.          when C_direct_call then
  283.             flag := need_local_vars;
  284.             if flag then
  285.                cpp.put_character('{');
  286.                c_define_opening;
  287.             end;
  288.             pc ?= routine_body.first;
  289.             rf := pc.run_feature;
  290.             cpp.push_same_target(rf,pc.arguments);
  291.             rf.mapping_c;
  292.             cpp.pop;
  293.             if flag then
  294.                c_define_closing;
  295.                cpp.put_character('}');
  296.             end;
  297.          when C_dca then
  298.             pc ?= routine_body.first;
  299.             pc.finalize;
  300.             cpp.push_inline_dca(Current,pc);
  301.             pc.run_feature.mapping_c;
  302.             cpp.pop;
  303.          when C_one_pc then
  304.             if not use_current then
  305.                if cpp.target_cannot_be_dropped then
  306.                   cpp.put_string(fz_14);
  307.                end;
  308.             end;
  309.             cpp.put_character('{');
  310.             if use_current then
  311.                tmp_string.clear;
  312.                current_type.c_type_for_target_in(tmp_string);
  313.                tmp_string.extend(' ');
  314.                cpp.put_string(tmp_string);
  315.                cpp.inline_level_incr;
  316.                cpp.print_current;
  317.                cpp.inline_level_decr;
  318.                cpp.put_character('=');
  319.                cpp.put_target_as_target;
  320.                cpp.put_string(fz_00);
  321.             end;
  322.             if arguments /= Void then
  323.                arguments.inline_one_pc;
  324.             end;
  325.             if need_local_vars then
  326.                local_vars.inline_one_pc;
  327.                cpp.inline_level_incr;
  328.                local_vars.initialize_expanded;
  329.                cpp.inline_level_decr;
  330.             end;
  331.             cpp.push_inline_one_pc;
  332.             cpp.inline_level_incr;
  333.             routine_body.compile_to_c;
  334.             cpp.inline_level_decr;
  335.             cpp.pop;
  336.             cpp.put_character('}');
  337.          end;
  338.          cpp.put_string("/*]*/%N");
  339.       end;
  340.  
  341.    compute_use_current is
  342.       local
  343.          ct: like current_type;
  344.       do
  345.          ct := current_type;
  346.          if ct.is_reference then
  347.             if run_control.no_check then
  348.                use_current_state := ucs_true;
  349.             else
  350.                std_compute_use_current;
  351.             end;
  352.          else
  353.             std_compute_use_current;
  354.          end;
  355.       end;
  356.  
  357.    empty_or_null_body: BOOLEAN is
  358.          -- The body is empty or has only unreacheable code.
  359.       local
  360.          rb: COMPOUND;
  361.       do
  362.          rb := routine_body;
  363.          Result := (rb = Void or else rb.empty_or_null_body);
  364.       end;
  365.  
  366.    do_not_use_current: BOOLEAN is
  367.       do
  368.          if not routine_body.use_current then
  369.             Result := arguments = Void;
  370.          end;
  371.       end;
  372.  
  373.    attribute_writer: BOOLEAN is
  374.          -- True when body as only one instruction is of
  375.          -- the form :
  376.          --            feature_name := <expression>;
  377.          -- And when <expression> is an argument or a statically
  378.          -- computable value.
  379.       local
  380.          rb: like routine_body;
  381.          a: ASSIGNMENT;
  382.          args: like arguments;
  383.          an2: ARGUMENT_NAME2;
  384.          wa: SIMPLE_FEATURE_NAME;
  385.       do
  386.          rb := routine_body;
  387.          args := arguments;
  388.          if rb /= Void and then rb.count = 1 then
  389.             a ?= rb.first;
  390.             if a /= Void then
  391.                wa ?= a.left_side;
  392.                if wa /= Void then
  393.                   if args = Void then
  394.                      Result := not a.right_side.use_current;
  395.                   elseif args.count = 1 then
  396.                      an2 ?= a.right_side;
  397.                      Result := an2 /= Void;
  398.                   end;
  399.                end;
  400.             end;
  401.          end;
  402.       end;
  403.  
  404.    direct_call: BOOLEAN is
  405.          -- True when the procedure has no arguments, no locals,
  406.          -- and when the body has only one instruction of the
  407.          -- form : foo(<args>);
  408.          -- Where <args> can be an empty list or a statically
  409.          -- computable one and where `foo' is a RUN_FEATURE_3.
  410.       local
  411.          rb: like routine_body;
  412.          pc: PROC_CALL;
  413.          args: EFFECTIVE_ARG_LIST;
  414.          rf3: RUN_FEATURE_3;
  415.       do
  416.          rb := routine_body;
  417.          if rb /= Void and then
  418.             rb.count = 1 and then
  419.             arguments = Void and then
  420.             local_vars = Void
  421.           then
  422.             pc ?= rb.first;
  423.             if pc /= Void then
  424.                if pc.target.is_current then
  425.                   rf3 ?= pc.run_feature;
  426.                   if rf3 /= Void then
  427.                      args := pc.arguments;
  428.                      if args = Void then
  429.                         Result := true;
  430.                      else
  431.                         Result := args.is_static;
  432.                      end;
  433.                   end;
  434.                end;
  435.             end;
  436.          end;
  437.       end;
  438.  
  439.    dca: BOOLEAN is
  440.       local
  441.          pc: PROC_CALL;
  442.          rf: RUN_FEATURE;
  443.          args: EFFECTIVE_ARG_LIST;
  444.       do
  445.          pc := body_one_dpca;
  446.          if pc /= Void and then local_vars = Void then
  447.             rf := pc.run_feature;
  448.             if rf /= Current then
  449.                if rf.current_type.is_user_expanded then
  450.                   -- Not yet inlined :-(
  451.                else
  452.                   args := pc.arguments;
  453.                   if args = Void then
  454.                      Result := arguments = Void;
  455.                   else
  456.                      Result := args.isa_dca_inline(Current,rf);
  457.                   end;
  458.                end;
  459.             end;
  460.          end;
  461.       end;
  462.  
  463.    one_pc: BOOLEAN is
  464.       local
  465.          rb: like routine_body;
  466.          pc: PROC_CALL;
  467.          rf: RUN_FEATURE;
  468.          r: ARRAY[RUN_CLASS];
  469.       do
  470.          rb := routine_body;
  471.          if rb /= Void and then rb.count = 1 then
  472.             pc ?= rb.first;
  473.             if pc /= Void then
  474.                rf := pc.run_feature;
  475.                if rf /= Void and then rf /= Current then
  476.                   r := rf.run_class.running;
  477.                   if r /= Void and then r.count = 1 then
  478.                      Result := true;
  479.                   end;
  480.                end;
  481.             end;
  482.          end;
  483.       end;
  484.  
  485.    body_one_dpca: PROC_CALL is
  486.          -- Gives Void or the only one direct PROC_CALL on
  487.          -- an attribute of Current target.
  488.       local
  489.          rb: like routine_body;
  490.          pc: PROC_CALL;
  491.          c0c: CALL_0_C;
  492.          rf2: RUN_FEATURE_2;
  493.          r: ARRAY[RUN_CLASS];
  494.       do
  495.          if local_vars = Void then
  496.             rb := routine_body;
  497.             if rb /= Void and then rb.count = 1 then
  498.                pc ?= rb.first;
  499.                if pc /= Void then
  500.                   c0c ?= pc.target;
  501.                   if c0c /= Void and then c0c.target.is_current then
  502.                      rf2 ?= c0c.run_feature;
  503.                      if rf2 /= Void then
  504.                         r := rf2.run_class.running;
  505.                         if r /= Void and then r.count = 1 then
  506.                            r := pc.run_feature.run_class.running;
  507.                            if r /= Void and then r.count = 1 then
  508.                               Result := pc;
  509.                            end;
  510.                         end;
  511.                      end;
  512.                   end;
  513.                end;
  514.             end;
  515.          end;
  516.       end;
  517.  
  518.    need_local_vars: BOOLEAN is
  519.       do
  520.          if local_vars /= Void then
  521.             Result := local_vars.produce_c;
  522.          end;
  523.       end;
  524.  
  525.    tmp_string: STRING is
  526.       once
  527.          !!Result.make(32);
  528.       end;
  529.  
  530.    update_tmp_jvm_descriptor is
  531.       do
  532.          routine_update_tmp_jvm_descriptor;
  533.       end;
  534.  
  535. feature {RUN_CLASS}
  536.  
  537.    memory_dispose: like Current is
  538.          -- Squeeze dummy empty `dispose' and set the appropriate
  539.          -- `in_line_status' (no inlining).
  540.       do
  541.          if not is_empty_or_null_body then
  542.             Result := Current;
  543.             in_line_status := -1;
  544.          end;
  545.       end;
  546.  
  547.    jvm_field_or_method is
  548.       do
  549.          jvm.add_method(Current);
  550.       end;
  551.  
  552. feature {JVM}
  553.  
  554.    jvm_define is
  555.       do
  556.          method_info_start;
  557.          jvm_define_opening;
  558.          if routine_body /= Void then
  559.             routine_body.compile_to_jvm;
  560.          end;
  561.          jvm_define_closing;
  562.          code_attribute.opcode_return;
  563.          method_info.finish;
  564.       end;
  565.  
  566. feature {ADDRESS_OF_POOL}
  567.  
  568.    address_of_c_define(caller: ADDRESS_OF) is
  569.       do
  570.          if run_control.boost then
  571.             if isa_in_line then
  572.                address_of_c_define_wrapper(caller);
  573.             elseif use_current then
  574.             else
  575.                address_of_c_define_wrapper(caller);
  576.             end;
  577.          else
  578.             address_of_c_define_wrapper(caller);
  579.          end;
  580.       end;
  581.  
  582. feature {ADDRESS_OF}
  583.  
  584.    address_of_c_mapping is
  585.       do
  586.          if run_control.boost then
  587.             if isa_in_line then
  588.                address_of_c_mapping_wrapper;
  589.             elseif use_current then
  590.                mapping_name;
  591.             else
  592.                address_of_c_mapping_wrapper;
  593.             end;
  594.          else
  595.             address_of_c_mapping_wrapper;
  596.          end;
  597.       end;
  598.  
  599. feature {PROCEDURE}
  600.  
  601.    is_empty_or_null_body: BOOLEAN is
  602.       do
  603.          if isa_in_line then
  604.             Result := in_line_status = C_empty_or_null_body;
  605.          end;
  606.       end;
  607.  
  608.    is_attribute_writer: RUN_FEATURE_2 is
  609.       -- If true, gives the corresponding attribute.
  610.       local
  611.          a: ASSIGNMENT;
  612.          sfn: SIMPLE_FEATURE_NAME;
  613.       do
  614.          if isa_in_line then
  615.             if in_line_status = C_attribute_writer then
  616.                a ?= routine_body.first;
  617.                sfn ?= a.left_side;
  618.                Result := sfn.run_feature_2;
  619.             end;
  620.          end;
  621.       end;
  622.  
  623. feature {NONE}
  624.  
  625.    jvm_result_store is
  626.       do
  627.       end;
  628.  
  629. end -- RUN_FEATURE_3
  630.  
  631.