home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / run_feature.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  19.7 KB  |  885 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. deferred class RUN_FEATURE
  17. --
  18. -- A feature at run time : assertions collected and only run types.
  19. --
  20. --   RUN_FEATURE_1 : constant attribute.
  21. --   RUN_FEATURE_2 : attribute.
  22. --   RUN_FEATURE_3 : procedure.
  23. --   RUN_FEATURE_4 : function.
  24. --   RUN_FEATURE_5 : once procedure.
  25. --   RUN_FEATURE_6 : once function.
  26. --   RUN_FEATURE_7 : external procedure.
  27. --   RUN_FEATURE_8 : external function.
  28. --   RUN_FEATURE_9 : deferred routine.
  29. --
  30.    
  31. inherit GLOBALS redefine fill_tagged_out_memory end;
  32.    
  33. feature 
  34.    
  35.    current_type: TYPE;
  36.      -- The type of Current in the corresponding feature.
  37.  
  38.    clients_memory: CLIENT_LIST;
  39.  
  40. feature {NONE}
  41.    
  42.    actuals_clients: FIXED_ARRAY[RUN_CLASS];
  43.      -- Places of callers.
  44.    
  45. feature 
  46.    
  47.    name: FEATURE_NAME;
  48.      -- Final name (the only one really used) of the feature.
  49.    
  50.    base_feature: E_FEATURE;
  51.      -- Original base feature definition.
  52.    
  53.    arguments: FORMAL_ARG_LIST;
  54.      -- Runnable arguments list if any.
  55.  
  56.    result_type: TYPE;
  57.      -- Runnable Result type if any.
  58.    
  59.    require_assertion: RUN_REQUIRE;
  60.      -- Runnable collected require assertion if any.
  61.    
  62.    local_vars: LOCAL_VAR_LIST is
  63.      -- Runnable local var list if any.
  64.       deferred
  65.       end;
  66.    
  67.    routine_body: COMPOUND;
  68.      -- Runnable routine body if any.
  69.          
  70.    ensure_assertion: E_ENSURE;
  71.      -- Runnable collected ensure assertion if any.
  72.    
  73.    rescue_compound: COMPOUND;
  74.      -- Runnable rescue compound if any.
  75.  
  76. feature {NONE}        
  77.    
  78.    make(t: like current_type; n: like name; bf: like base_feature) is
  79.       require
  80.      t.run_type = t;
  81.      n /= Void;
  82.      bf /= void;
  83.      not small_eiffel.is_ready
  84.       do
  85.      current_type := t; 
  86.      name := n; 
  87.      base_feature := bf; 
  88.      run_class.feature_dictionary.put(Current,n.to_key);
  89.      small_eiffel.incr_magic_count;
  90.      use_current_state := ucs_not_computed;
  91.      small_eiffel.push(Current);
  92.      initialize;
  93.      small_eiffel.pop;
  94.       ensure
  95.      run_class.get_feature(name) = Current
  96.       end;
  97.    
  98. feature 
  99.    
  100.    is_pre_computable: BOOLEAN is
  101.       deferred
  102.       end;
  103.    
  104.    can_be_dropped: BOOLEAN is
  105.       -- If calling has no side effect at all.
  106.       require
  107.      small_eiffel.is_ready
  108.       deferred
  109.       end;
  110.    
  111.    frozen use_current: BOOLEAN is
  112.       require
  113.      small_eiffel.is_ready
  114.       do
  115.      inspect
  116.         use_current_state 
  117.      when ucs_true then
  118.         Result := true;
  119.      when ucs_false then
  120.      when ucs_not_computed then
  121.         use_current_state := ucs_in_computation;
  122.         compute_use_current;
  123.         Result := use_current; 
  124.      when ucs_in_computation then
  125.         Result := true;
  126.      end;
  127.       end;
  128.  
  129.    fall_down is
  130.       local
  131.      running: ARRAY[RUN_CLASS];
  132.      i: INTEGER;
  133.      current_rc, sub_rc: RUN_CLASS;
  134.      current_bc, sub_bc: BASE_CLASS;
  135.      sub_name: FEATURE_NAME;
  136.      rf: RUN_FEATURE;
  137.       do
  138.      current_rc := current_type.run_class;
  139.      running := current_rc.running;
  140.      if running /= Void then
  141.         from  
  142.            current_bc := current_type.base_class;
  143.            i := running.lower;
  144.         until
  145.            i > running.upper
  146.         loop
  147.            sub_rc := running.item(i);
  148.            if sub_rc /= current_rc then
  149.           sub_bc := sub_rc.current_type.base_class;
  150.           sub_name := sub_bc.new_name_of(current_bc,name);
  151.           rf := sub_rc.get_feature(sub_name);
  152.            end;
  153.            i := i + 1;
  154.         end;
  155.      end;
  156.       end;
  157.  
  158.    afd_check is
  159.       deferred
  160.       end;
  161.          
  162.    fill_tagged_out_memory is
  163.       local
  164.      p: POSITION;
  165.      ctrtm: STRING;
  166.       do
  167.      p := start_position;
  168.      if p /= Void then
  169.         p.fill_tagged_out_memory;
  170.         tagged_out_memory.extend(' ');
  171.         if current_type.is_run_type then
  172.            ctrtm := current_type.run_time_mark;
  173.            if ctrtm /= Void then
  174.           tagged_out_memory.append(ctrtm);
  175.            end;
  176.         end;
  177.      end;
  178.       end;
  179.  
  180.    is_exported_in(cn: CLASS_NAME): BOOLEAN is
  181.      -- True if using of the receiver is legal when written in `cn'.
  182.      -- When false, `eh' is updated with the beginning of the 
  183.      -- error message.
  184.       require
  185.      cn /= Void
  186.       do
  187.      Result := clients.gives_permission_to(cn);
  188.       end;
  189.       
  190.    frozen start_position: POSITION is
  191.       do
  192.      Result := base_feature.start_position;
  193.       end;
  194.    
  195.    run_class: RUN_CLASS is
  196.       do
  197.      Result := current_type.run_class;
  198.       end;
  199.    
  200. feature {NONE}
  201.  
  202.    clients: like clients_memory is 
  203.      -- Effective client list for the receiver. 
  204.      -- Note: consider "export" clauses.
  205.       local
  206.      bc, bfbc: BASE_CLASS;
  207.       do
  208.      if clients_memory = Void then
  209.         bc := current_type.base_class;
  210.         bfbc := base_feature.base_class;
  211.         if bc = bfbc then
  212.            Result := base_feature.clients;
  213.         else
  214.            check
  215.           bc.is_subclass_of(bfbc)
  216.            end;
  217.            Result := bc.clients_for(name);
  218.         end;
  219.         clients_memory := Result;
  220.      else
  221.         Result := clients_memory;
  222.      end;
  223.       ensure
  224.      Result /= Void
  225.       end;
  226.    
  227. feature {RUN_CLASS,CREATION_CALL}
  228.  
  229.    add_client(rc: RUN_CLASS) is
  230.      -- Add `rc' to `actual_clients'.
  231.      -- Note: DO NOT check that `rc' is allowed to use it.
  232.       require
  233.      rc /= Void
  234.       local
  235.      i: INTEGER;
  236.       do
  237.      if actuals_clients = Void then
  238.         !!actuals_clients.with_capacity(4);
  239.         actuals_clients.add_last(rc);
  240.      else
  241.         i := actuals_clients.fast_index_of(rc);
  242.         if i > actuals_clients.upper then
  243.            actuals_clients.add_last(rc);
  244.         end;
  245.      end;
  246.      run_class.add_client(rc);
  247.       end;
  248.    
  249.  
  250. feature {NONE}
  251.    
  252.    initialize is
  253.       deferred
  254.       end;
  255.    
  256. feature 
  257.    
  258.    has_result: BOOLEAN is
  259.       do
  260.      Result := result_type /= Void;
  261.       end;
  262.    
  263.    arg_count: INTEGER is
  264.       do
  265.      if arguments /= Void then
  266.         Result := arguments.count;
  267.      end;
  268.       end;
  269.    
  270.    c_define is
  271.      -- Produce C code for definition.
  272.       require
  273.      run_class.at_run_time;
  274.      cpp.on_c
  275.       deferred
  276.       ensure     
  277.      cpp.on_c
  278.       end;
  279.    
  280.    mapping_c is
  281.      -- Produce C code when current is called and when the
  282.      -- concrete type of target is unique (`cpp' is in charge
  283.      -- of the context).
  284.       require
  285.      run_class.at_run_time;
  286.      cpp.on_c
  287.       deferred
  288.       ensure     
  289.      cpp.on_c
  290.       end;
  291.  
  292.    address_of is
  293.      -- Produce C code for operator $<feature_name>
  294.       require
  295.      run_class.at_run_time;
  296.      cpp.on_c
  297.       do
  298.      mapping_name;
  299.       ensure     
  300.      cpp.on_c
  301.       end;
  302.  
  303.    frozen id: INTEGER is
  304.       do
  305.      Result := current_type.id;
  306.       end;
  307.    
  308.    mapping_name is
  309.       do
  310.      cpp.put_character('r');
  311.      cpp.put_integer(id);
  312.      cpp.put_string(name.to_key);
  313.       end;
  314.    
  315. feature {EXPRESSION} 
  316.    
  317.    is_static: BOOLEAN is 
  318.       deferred
  319.       end;
  320.  
  321.    static_value_mem: INTEGER is 
  322.       require
  323.      is_static;
  324.       deferred
  325.       end;
  326.    
  327. feature {C_PRETTY_PRINTER}
  328.  
  329.    put_tag is
  330.       require
  331.      run_control.no_check
  332.       local
  333.      fn: FEATURE_NAME;
  334.       do
  335.      cpp.put_character('%"');    
  336.      fn := base_feature.first_name;
  337.      fn.cpp_put_infix_or_prefix;
  338.      cpp.put_string(fn.to_string);
  339.      cpp.put_string(" of ");
  340.      cpp.put_string(base_feature.base_class_name.to_string);
  341.      cpp.put_character('%"');
  342.       end;
  343.  
  344. feature {NONE} -- Tools for `compile_to_c' :
  345.    
  346.    define_prototype is
  347.       require
  348.      run_class.at_run_time;
  349.      cpp.on_c
  350.       local
  351.      mem_id: INTEGER;
  352.       do
  353.      mem_id := id;
  354.      -- Define heading of corresponding C function.
  355.      c_code.clear;
  356.      if result_type = Void then
  357.         c_code.append(fz_void);
  358.      else
  359.         result_type.run_type.c_type_for_result_in(c_code);
  360.      end;
  361.      c_code.extend(' ');
  362.      c_code.extend('r');
  363.      mem_id.append_in(c_code);
  364.      name.mapping_c_in(c_code);
  365.      c_code.extend('(');
  366.      if use_current then
  367.         current_type.c_type_for_target_in(c_code);
  368.         c_code.extend(' ');
  369.         c_code.extend('C');
  370.         if arguments /= Void then
  371.            c_code.extend(',');
  372.         end;
  373.      end;
  374.      if arguments = Void then
  375.         if not use_current then
  376.            c_code.append(fz_void);
  377.         end;
  378.      else
  379.         arguments.compile_to_c_in(c_code);
  380.      end;
  381.      c_code.extend(')');
  382.      cpp.put_c_heading(c_code);
  383.      cpp.swap_on_c;
  384.       ensure     
  385.      cpp.on_c
  386.       end;
  387.    
  388.    define_opening is
  389.      -- Define opening section in C function.
  390.       local
  391.      i: INTEGER;
  392.      t: TYPE;
  393.       do
  394.      -- (1) -------------------- Local variable for Result :
  395.      if result_type /= Void then
  396.         t := result_type.run_type;
  397.         c_code.clear;
  398.         t.c_type_for_result_in(c_code);
  399.         c_code.extend(' ');
  400.         c_code.extend('R');
  401.         c_code.extend('=');
  402.         t.c_initialize_in(c_code);
  403.         c_code.append(fz_00);
  404.         cpp.put_string(c_code);
  405.      end;
  406.      -- (2) ----------------------- User's local variables :
  407.      if local_vars /= Void then
  408.         local_vars.compile_to_c;
  409.      end;
  410.      -- (3) ---------------- Local variable for old/ensure :
  411.      if run_control.ensure_check then
  412.         if ensure_assertion /= Void then
  413.            ensure_assertion.compile_to_c_old;
  414.         end;
  415.      end;
  416.      -- (4) -------------------- Initialize local expanded :
  417.      if local_vars /= Void then
  418.         local_vars.initialize_expanded;
  419.      end;
  420.      -- (5) ------------------------------- Run Stack Push :
  421.      if run_control.no_check then
  422.         cpp.rs_link(Current);
  423.         if use_current then
  424.            cpp.rs_push_current(current_type);
  425.         end;
  426.         from
  427.            i := 1;
  428.         until
  429.            i > arg_count
  430.         loop
  431.            t := arguments.type(i).run_type;
  432.            cpp.rs_push_argument(arguments.name(i).to_string,i,t);
  433.            check
  434.           i = arguments.rank_of(arguments.name(i).to_string);
  435.            end;
  436.            i := i + 1;
  437.         end;
  438.         if result_type /= Void then
  439.            cpp.rs_push_result(result_type.run_type);
  440.         end;
  441.         if local_vars /= Void then
  442.            from
  443.           i := 1;
  444.            until
  445.           i > local_vars.count
  446.            loop
  447.           local_vars.name(i).c_trace;
  448.           i := i + 1;
  449.            end;
  450.         end;
  451.      end;
  452.      -- (6) ----------------------- Require assertion code :
  453.      if require_assertion /= Void then
  454.         require_assertion.compile_to_c;
  455.      end;
  456.       end;
  457.    
  458.    define_closing is
  459.      -- Define closing section in C function :
  460.      --    - code for ensure checking.
  461.      --    - free memory of expanded.
  462.      --    - run stack pop.
  463.       do
  464.      -- (0) ----------------------------- Class Invariant :
  465.      if use_current then
  466.         cpp.current_class_invariant(current_type);
  467.      end;
  468.      -- (1) --------------------------- Ensure Check Code :
  469.      if run_control.ensure_check then
  470.         if ensure_assertion /= Void then
  471.            ensure_assertion.compile_to_c;
  472.         end;
  473.      end;
  474.      -- (2) --------------------- Free for local expanded :
  475.      -- (3) ------------------------------- Run Stack Pop :
  476.      if run_control.no_check then
  477.         cpp.rs_unlink;
  478.      end;
  479.       end;
  480.    
  481. feature {NONE}
  482.  
  483.    external_prototype(er: EXTERNAL_ROUTINE) is
  484.      -- Define prototype for an external routine.
  485.       require
  486.      cpp.on_c;
  487.      er = base_feature
  488.       local
  489.      t: TYPE;
  490.       do
  491.      c_code.clear;
  492.      c_code.append("/*external*/");
  493.      -- Define heading of corresponding C function.
  494.      t := result_type;
  495.      if t = Void then
  496.         c_code.append(fz_void);
  497.      else
  498.         t.c_type_for_external_in(c_code);
  499.      end;
  500.      c_code.extend(' ');
  501.      c_code.append(er.external_c_name);
  502.      c_code.extend('(');
  503.      if er.use_current then
  504.         current_type.c_type_for_external_in(c_code);
  505.         c_code.extend(' ');
  506.         c_code.extend('C');
  507.         if arguments /= Void then
  508.            c_code.extend(',');
  509.         end;
  510.      end;
  511.      if arguments = Void then
  512.         if not er.use_current then
  513.            c_code.append(fz_void);
  514.         end;
  515.      else
  516.         arguments.external_prototype(c_code);
  517.      end;
  518.      c_code.append(");%N");
  519.      cpp.swap_on_h;
  520.      cpp.put_string(c_code);
  521.      cpp.swap_on_c;
  522.       ensure     
  523.      cpp.on_c
  524.       end;
  525.  
  526. feature {NONE}
  527.  
  528.    once_mark: STRING is
  529.       do
  530.      Result := base_feature.first_name.to_string;
  531.       end;
  532.  
  533.    once_flag_in(str: STRING) is
  534.      -- Produce the C name of the once flag.
  535.       do
  536.      str.extend('f');
  537.      base_feature.mapping_c_name_in(str);
  538.       end;
  539.    
  540.    once_flag is
  541.      -- Produce the C name of the once flag.
  542.       do
  543.      c_code.clear;
  544.      once_flag_in(c_code);
  545.      cpp.put_string(c_code);
  546.       end;
  547.    
  548.    once_boolean is
  549.      -- Produce C code for the boolean flag definition
  550.      -- and initialisation.
  551.       do
  552.      c_code.copy(fz_int);
  553.      c_code.extend(' ');
  554.      once_flag_in(c_code);
  555.      cpp.put_extern2(c_code,'0');
  556.       end;
  557.    
  558. feature {NONE}
  559.  
  560.    use_current_state: INTEGER;
  561.    
  562.    ucs_false, 
  563.    ucs_true, 
  564.    ucs_not_computed, 
  565.    ucs_in_computation: INTEGER is unique;
  566.       
  567.    std_compute_use_current is
  568.       require
  569.      use_current_state = ucs_in_computation;
  570.       do
  571.      if use_current_state = ucs_in_computation then
  572.         if require_assertion /= Void then
  573.            if require_assertion.use_current then
  574.           use_current_state := ucs_true;
  575.            end;
  576.         end;
  577.      end;
  578.      if use_current_state = ucs_in_computation then
  579.         if routine_body /= Void then
  580.            if routine_body.use_current then
  581.           use_current_state := ucs_true;
  582.            end;
  583.         end;        
  584.      end;
  585.      if use_current_state = ucs_in_computation then
  586.         if ensure_assertion /= Void then
  587.            if ensure_assertion.use_current then
  588.           use_current_state := ucs_true;
  589.            end;
  590.         end;        
  591.      end;
  592.      if use_current_state = ucs_in_computation then
  593.         use_current_state := ucs_false;
  594.      end;
  595.       ensure
  596.      use_current_state = ucs_false or else
  597.      use_current_state = ucs_true;     
  598.       end;
  599.    
  600.    compute_use_current is 
  601.       require
  602.      use_current_state = ucs_in_computation;
  603.       deferred 
  604.       ensure
  605.      use_current_state = ucs_true or else
  606.      use_current_state = ucs_false;
  607.       end;
  608.  
  609. feature {NONE}
  610.  
  611.    c_code: STRING is
  612.       once
  613.      !!Result.make(256);
  614.       end;
  615.  
  616.    c_code2: STRING is
  617.       once
  618.      !!Result.make(256);
  619.       end;
  620.  
  621. feature {NATIVE}
  622.    
  623.    frozen default_mapping_procedure is
  624.      -- Default mapping for procedure calls with target.
  625.       do
  626.          mapping_name;
  627.      cpp.put_character('(');
  628.      cpp.put_target_as_target;
  629.      if arg_count > 0 then
  630.         cpp.put_character(',');
  631.         cpp.put_arguments;
  632.      end;
  633.      cpp.put_string(fz_14);
  634.       end;
  635.  
  636.    frozen default_mapping_function is
  637.      -- Default mapping for function calls with target.
  638.       do
  639.      mapping_name;
  640.      cpp.put_character('(');
  641.      cpp.put_target_as_target;
  642.      if arg_count > 0 then
  643.         cpp.put_character(',');
  644.         cpp.put_arguments;
  645.      end;
  646.      cpp.put_character(')');
  647.       end;
  648.  
  649. feature {NONE}
  650.  
  651.    nothing_comment is
  652.      -- Useful for incremental recompilation.
  653.       do
  654.      cpp.put_string(fz_open_c_comment);
  655.      cpp.put_string("No:");
  656.      cpp.put_string(current_type.run_time_mark);
  657.      cpp.put_character('.');
  658.      cpp.put_string(name.to_string);
  659.      cpp.put_string(fz_close_c_comment);
  660.      cpp.put_character('%N');
  661.       end;
  662.  
  663. feature {NATIVE}
  664.  
  665.    routine_mapping_jvm is
  666.       local
  667.      rt, ct: TYPE;
  668.      idx, stack_level: INTEGER;
  669.       do
  670.      ct := current_type;
  671.      jvm.push_target_as_target;
  672.      stack_level := -(1 + jvm.push_arguments);
  673.      rt := result_type;
  674.      if rt /= Void then
  675.         stack_level := stack_level + rt.jvm_stack_space;
  676.      end
  677.      idx := constant_pool.idx_methodref(Current);
  678.      ct.run_class.jvm_invoke(idx,stack_level);
  679.       end;
  680.       
  681. feature {RUN_CLASS}
  682.    
  683.    jvm_field_or_method is
  684.      -- Update jvm's `fields' or `methods' if needed.
  685.       deferred
  686.       end;
  687.  
  688. feature 
  689.  
  690.    mapping_jvm is
  691.       require
  692.      run_class.at_run_time
  693.       deferred
  694.       end;
  695.  
  696. feature {JVM}
  697.  
  698.    jvm_define is
  699.      -- To compute the constant pool, the number of fields,
  700.      -- the number of methods, etc.
  701.       require
  702.      small_eiffel.is_ready
  703.       deferred
  704.       end;
  705.  
  706. feature {CONSTANT_POOL,SWITCH_COLLECTION}
  707.  
  708.    frozen jvm_descriptor: STRING is
  709.       do
  710.      tmp_jvm_descriptor.clear;
  711.      update_tmp_jvm_descriptor;
  712.      Result := tmp_jvm_descriptor;
  713.       end;
  714.  
  715. feature {NONE}
  716.  
  717.    update_tmp_jvm_descriptor is
  718.       deferred
  719.       end;
  720.  
  721.    tmp_jvm_descriptor: STRING is
  722.       once
  723.      !!Result.make(128);
  724.       end;
  725.  
  726.    routine_update_tmp_jvm_descriptor is
  727.      -- For RUN_FEATURE_3/4/5/6 :
  728.       local
  729.      ct, rt: TYPE;
  730.      rc: RUN_CLASS;
  731.       do
  732.      tmp_jvm_descriptor.extend('(');
  733.      ct := current_type;
  734.      ct.jvm_target_descriptor_in(tmp_jvm_descriptor);
  735.      if arguments /= Void then
  736.         arguments.jvm_descriptor_in(tmp_jvm_descriptor);
  737.      end;
  738.      rt := result_type;
  739.      if rt = Void then
  740.         tmp_jvm_descriptor.append(fz_19);
  741.      else
  742.         rt := rt.run_type;
  743.         tmp_jvm_descriptor.extend(')');
  744.         rt.jvm_descriptor_in(tmp_jvm_descriptor);
  745.      end;
  746.       end;
  747.  
  748. feature {NONE}
  749.  
  750.    method_info_start is
  751.       local
  752.      flags: INTEGER;
  753.       do
  754.      flags := current_type.jvm_method_flags;
  755.      method_info.start(flags,name.to_key,jvm_descriptor);
  756.       end;
  757.  
  758.    jvm_define_opening is
  759.       require
  760.      jvm.current_frame = Current
  761.       local
  762.      t: TYPE;
  763.       do
  764.      -- (1) -------------------- Local variable for Result :
  765.      if result_type /= Void then
  766.         t := result_type.run_type;
  767.         t.jvm_initialize_local(jvm_result_offset);
  768.      end;
  769.      -- (2) ----------------------- User's local variables :
  770.      if local_vars /= Void then
  771.         local_vars.jvm_initialize;
  772.      end;
  773.      -- (3) ---------------- Local variable for old/ensure :
  774.      if run_control.ensure_check then
  775.         if ensure_assertion /= Void then
  776.            ensure_assertion.compile_to_jvm_old;
  777.         end;
  778.      end;
  779.      -- (4) ----------------------- Require assertion code :
  780.      if require_assertion /= Void then
  781.         require_assertion.compile_to_jvm;
  782.      end;
  783.       end;
  784.  
  785.    jvm_define_closing is
  786.       require
  787.      jvm.current_frame = Current
  788.       do
  789.      -- (0) ----------------------------- Class Invariant :
  790.      if use_current then
  791. -- ***         cpp.current_class_invariant(current_type);
  792.      end;
  793.      -- (1) --------------------------- Ensure Check Code :
  794.      if run_control.ensure_check then
  795.          if ensure_assertion /= Void then
  796.            ensure_assertion.compile_to_jvm(true);
  797.          end;
  798.      end;
  799.      -- (2) --------------------- Free for local expanded :
  800.      -- (3) ------------------- Prepare result for return :
  801.      if result_type /= Void then
  802.         result_type.jvm_push_local(jvm_result_offset);
  803.      end;
  804.       end;
  805.  
  806. feature {JVM}
  807.  
  808.    frozen jvm_result_offset: INTEGER is
  809.       require
  810.      result_type /= Void
  811.       do
  812.      Result := current_type.jvm_stack_space;
  813.      if arguments /= Void then
  814.         Result := Result + arguments.jvm_stack_space;
  815.      end;
  816.      if local_vars /= Void then
  817.         Result := Result + local_vars.jvm_stack_space;
  818.      end;
  819.       end;
  820.  
  821.    frozen jvm_argument_offset(a: ARGUMENT_NAME): INTEGER is
  822.       require
  823.      arguments /= Void
  824.       do
  825.      Result := current_type.jvm_stack_space;
  826.      Result := Result + arguments.jvm_offset_of(a);
  827.       ensure
  828.      Result >= a.rank - 1
  829.       end;
  830.  
  831.    frozen jvm_local_variable_offset(ln: LOCAL_NAME): INTEGER is
  832.       require
  833.      local_vars /= Void
  834.       do
  835.      Result := current_type.jvm_stack_space;
  836.      if arguments /= Void then
  837.         Result := Result + arguments.jvm_stack_space;
  838.      end;
  839.      Result := Result + local_vars.jvm_offset_of(ln);
  840.       ensure
  841.      Result >= ln.rank - 1
  842.       end;
  843.  
  844. feature 
  845.  
  846.    frozen jvm_max_locals: INTEGER is
  847.       do
  848.      Result := current_type.jvm_stack_space;
  849.      if arguments /= Void then
  850.         Result := Result + arguments.jvm_stack_space;
  851.      end;
  852.      if local_vars /= Void then
  853.         Result := Result + local_vars.jvm_stack_space;
  854.      end;
  855.      if result_type /= Void then
  856.         Result := Result + result_type.jvm_stack_space;
  857.      end;
  858.       end;
  859.  
  860. feature {NONE}
  861.  
  862.    routine_afd_check is
  863.       do
  864.      if require_assertion /= Void then
  865.         require_assertion.afd_check;
  866.      end;
  867.      if routine_body /= Void then
  868.         routine_body.afd_check;
  869.      end;
  870.      if ensure_assertion /= Void then
  871.         ensure_assertion.afd_check;
  872.      end;
  873.       end;
  874.  
  875. invariant
  876.    
  877.    current_type /= Void;
  878.    
  879.    name /= Void;
  880.    
  881.    base_feature /= Void;
  882.    
  883. end -- RUN_FEATURE
  884.  
  885.