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