home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / code_printer.e < prev    next >
Text File  |  1999-06-05  |  8KB  |  305 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. deferred class CODE_PRINTER
  17.    --
  18.    -- Common root for C_PRETTY_PRINTER and JVM.
  19.    --
  20.  
  21. inherit GLOBALS;
  22.  
  23. feature
  24.  
  25.    output_name: STRING;
  26.          -- The executable name (Void means that "a.out" for
  27.          -- C mode). For JVM mode, this name is used as the name of
  28.          -- the main output class file and as the name of the
  29.          -- directory used to store auxilliary class files.
  30.  
  31.    incr_static_expression_count is
  32.       do
  33.          static_expression_count := static_expression_count + 1;
  34.       end;
  35.  
  36. feature {COMPILE_TO_C, COMPILE_TO_JVM}
  37.  
  38.    set_output_name(name: STRING) is
  39.       require
  40.          name /= Void
  41.       do
  42.          if name.has_suffix(eiffel_suffix) then
  43.             eh.append("Bad executable name: %"");
  44.             eh.append(name);
  45.             fatal_error("%". Must not use Eiffel source file suffix %
  46.                         %with option %"-o <executable_name>%".");
  47.          end;
  48.          output_name := name;
  49.       ensure
  50.          output_name = name;
  51.          not output_name.has_suffix(eiffel_suffix)
  52.       end;
  53.  
  54. feature {NONE}
  55.  
  56.    inlined_procedure_count: INTEGER;
  57.  
  58.    inlined_function_count: INTEGER;
  59.  
  60.    procedure_count: INTEGER;
  61.  
  62.    function_count: INTEGER;
  63.  
  64.    real_procedure_count: INTEGER;
  65.  
  66.    real_function_count: INTEGER;
  67.  
  68.    static_expression_count: INTEGER;
  69.  
  70. feature {RUN_FEATURE_3, RUN_FEATURE_10}
  71.  
  72.    incr_inlined_procedure_count is
  73.       do
  74.          inlined_procedure_count := inlined_procedure_count + 1;
  75.       end;
  76.  
  77.    incr_real_procedure_count is
  78.       do
  79.          real_procedure_count := real_procedure_count + 1;
  80.       end;
  81.  
  82.    incr_procedure_count is
  83.       do
  84.          procedure_count := procedure_count + 1;
  85.       end;
  86.  
  87. feature {RUN_FEATURE_4, RUN_FEATURE_11}
  88.  
  89.    incr_inlined_function_count is
  90.       do
  91.          inlined_function_count := inlined_function_count + 1;
  92.       end;
  93.  
  94.    incr_real_function_count is
  95.       do
  96.          real_function_count := real_function_count + 1;
  97.       end;
  98.  
  99.    incr_function_count is
  100.       do
  101.          function_count := function_count + 1;
  102.       end;
  103.  
  104. feature {RUN_FEATURE_6}
  105.  
  106.    add_pre_computed_once_function(rf6: RUN_FEATURE_6) is
  107.       do
  108.          pre_computed_once.add_last(rf6);
  109.       end;
  110.  
  111. feature {NONE}
  112.  
  113.    pre_computed_once: FIXED_ARRAY[RUN_FEATURE_6] is
  114.       once
  115.          !!Result.with_capacity(32);
  116.       end;
  117.  
  118. feature {NONE} -- Context stacks :
  119.  
  120.    top: INTEGER;
  121.          -- Index for top of followings stacks.
  122.  
  123.    stack_code: FIXED_ARRAY[INTEGER] is
  124.          -- The indicating stack. It contains only one
  125.          -- of the following unique code.
  126.       once
  127.          !!Result.make(stack_first_size);
  128.       end;
  129.  
  130.    C_direct_call: INTEGER is unique;
  131.          -- Target is sure not to be Void and there is only one possible
  132.          -- type (target is often Current, a manifest string or an expanded).
  133.  
  134.    C_check_id: INTEGER is unique;
  135.          -- Target is a reference type which can be Void but only one type
  136.          -- is the good one.
  137.  
  138.    C_switch: INTEGER is unique;
  139.          -- Target is a reference type with more than one possibility.
  140.  
  141.    C_inside_new: INTEGER is unique;
  142.          -- Target has been just created inside a creation call and
  143.          -- need some initializing procedure call.
  144.  
  145.    C_expanded_initialize: INTEGER is unique;
  146.          -- Target is some expanded to initialize.
  147.  
  148.    C_inline_dca: INTEGER is unique;
  149.          -- Inlining of a direct call applied on attribute of target.
  150.          -- Target is the one given at `top-1' plus the access to
  151.          -- the corresponding attribute stored at level `top'.
  152.          -- Arguments are taken at `top-1' context.
  153.  
  154.    C_same_target: INTEGER is unique;
  155.          -- Target is stored at level top - 1;
  156.  
  157.    C_inline_one_pc: INTEGER is unique;
  158.          -- Inlining `one_pc' of RUN_FEATURE_3;
  159.  
  160.    C_inside_twin: INTEGER is unique;
  161.          -- In order to call the user's `copy'.
  162.  
  163.    C_precursor: INTEGER is unique;
  164.          -- For Precursor calls.
  165.  
  166.    -- Contents of stacks depends on `stack_code'.
  167.    stack_rf: FIXED_ARRAY[RUN_FEATURE] is
  168.       once
  169.          !!Result.make(stack_first_size);
  170.       end;
  171.  
  172.    stack_target: FIXED_ARRAY[EXPRESSION] is
  173.       once
  174.          !!Result.make(stack_first_size);
  175.       end;
  176.  
  177.    stack_args: FIXED_ARRAY[EFFECTIVE_ARG_LIST] is
  178.       once
  179.          !!Result.make(stack_first_size);
  180.       end;
  181.  
  182.    stack_static_rf: FIXED_ARRAY[RUN_FEATURE] is
  183.       once
  184.          !!Result.make(stack_first_size);
  185.       end;
  186.  
  187.    stack_cpc: FIXED_ARRAY[CALL_PROC_CALL] is
  188.       once
  189.          !!Result.make(stack_first_size);
  190.       end;
  191.  
  192.    stack_first_size: INTEGER is 12;
  193.  
  194.    stack_push(code: INTEGER) is
  195.          -- Push the `code' and resize all stacks if needed.
  196.       local
  197.          new_size: INTEGER;
  198.       do
  199.          top := top + 1;
  200.          if top > stack_code.upper then
  201.             new_size := stack_code.upper * 2;
  202.             stack_code.resize(new_size);
  203.             stack_rf.resize(new_size);
  204.             stack_target.resize(new_size);
  205.             stack_args.resize(new_size);
  206.             stack_static_rf.resize(new_size);
  207.             stack_cpc.resize(new_size);
  208.             if new_size > 1024 then
  209.                stack_overflow
  210.             end;
  211.          end;
  212.          stack_code.put(code,top);
  213.       end;
  214.  
  215. feature {E_PRECURSOR}
  216.  
  217.    push_precursor(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  218.       require
  219.          rf /= Void;
  220.       do
  221.          stack_push(C_precursor);
  222.          stack_rf.put(rf,top);
  223.          stack_args.put(args,top);
  224.          direct_call_count := direct_call_count + 1;
  225.       end;
  226.  
  227. feature {RUN_FEATURE_3}
  228.  
  229.    stack_not_full: BOOLEAN is
  230.       do
  231.          Result := top < 50;
  232.       end;
  233.  
  234. feature {NONE}
  235.  
  236.    stack_overflow is
  237.       local
  238.          i: INTEGER;
  239.          rf: RUN_FEATURE;
  240.          rtm: STRING;
  241.          rtma: FIXED_ARRAY[STRING];
  242.       do
  243.          eh.append("Infinite inlining loop (bad recursion ??). ");
  244.          from
  245.             i := top - 1;
  246.          until
  247.             i < stack_code.lower
  248.          loop
  249.             rf := stack_rf.item(i);
  250.             if rf /= Void then
  251.                eh.add_position(rf.start_position);
  252.                rtm := rf.current_type.run_time_mark;
  253.                if rtma = Void then
  254.                   !!rtma.with_capacity(top);
  255.                   rtma.add_last(rtm);
  256.                   eh.append(rtm);
  257.                elseif rtma.fast_has(rtm) then
  258.                else
  259.                   rtma.add_last(rtm);
  260.                   eh.append(", ");
  261.                   eh.append(rtm);
  262.                end;
  263.             end;
  264.             i := i - 1;
  265.          end;
  266.          eh.fatal_error(",...");
  267.       end;
  268.  
  269. feature
  270.  
  271.    pop is
  272.       do
  273.          check
  274.             stack_code.lower <= top;
  275.          end;
  276.          top := top - 1;
  277.       ensure
  278.          old(top) = top + 1
  279.       end;
  280.  
  281. feature {NONE}
  282.  
  283.    check_id_count: INTEGER;
  284.  
  285.    direct_call_count: INTEGER;
  286.  
  287.    sure_void_count: INTEGER;
  288.  
  289.    switch_count: INTEGER;
  290.  
  291. feature {GC_HANDLER}
  292.  
  293.    incr_direct_call_count is
  294.       do
  295.          direct_call_count := direct_call_count + 1;
  296.       end;
  297.  
  298.    incr_switch_count is
  299.       do
  300.          switch_count := switch_count + 1;
  301.       end;
  302.  
  303. end -- CODE_PRINTER
  304.  
  305.