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