home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / native_small_eiffel.e < prev    next >
Text File  |  1999-06-05  |  77KB  |  2,257 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 NATIVE_SMALL_EIFFEL
  17.  
  18. inherit NATIVE;
  19.  
  20. feature
  21.  
  22.    need_prototype: BOOLEAN is false;
  23.  
  24. feature
  25.  
  26.    language_name: STRING is
  27.       do
  28.          Result := fz_se;
  29.       end;
  30.  
  31.    stupid_switch(name: STRING): BOOLEAN is
  32.       do
  33.          if as_generating_type = name then
  34.             Result := true;
  35.          elseif as_generator = name then
  36.             Result := true;
  37.          elseif as_to_pointer = name then
  38.             Result := true;
  39.          end;
  40.       end;
  41.  
  42.    c_define_procedure(rf7: RUN_FEATURE_7; bcn, name: STRING) is
  43.       do
  44.          if as_bit_n = bcn then
  45.             c_define_procedure_bit(rf7,name);
  46.          end;
  47.       end;
  48.  
  49.    c_mapping_procedure(rf7: RUN_FEATURE_7; bcn, name: STRING) is
  50.       local
  51.          t: TYPE;
  52.       do
  53.          if as_copy = name or else as_standard_copy = name then
  54.             t := rf7.current_type;
  55.             if t.is_reference then
  56.                cpp.put_string("*((T");
  57.                cpp.put_integer(t.id);
  58.                cpp.put_string("*)(");
  59.                cpp.put_target_as_value;
  60.                cpp.put_string("))=*((T");
  61.                cpp.put_integer(t.id);
  62.                cpp.put_string("*)(");
  63.                cpp.put_ith_argument(1);
  64.                cpp.put_string(fz_16);
  65.             elseif t.is_basic_eiffel_expanded then
  66.                cpp.put_target_as_value;
  67.                cpp.put_string(fz_00);
  68.                cpp.put_ith_argument(1);
  69.                cpp.put_string(fz_00);
  70.             else
  71.                cpp.put_string("{void* d=");
  72.                cpp.put_target_as_target;
  73.                cpp.put_string(";%NT");
  74.                cpp.put_integer(t.id);
  75.                cpp.put_string(" s;%Ns=*(");
  76.                cpp.put_ith_argument(1);
  77.                cpp.put_string(");%Nmemcpy(d,&s,sizeof(s));}%N");
  78.             end;
  79.          elseif as_flush_stream = name then
  80.             if cpp.target_cannot_be_dropped then
  81.                cpp.put_string(fz_14);
  82.             end;
  83.             cpp.put_string("fflush(");
  84.             cpp.put_ith_argument(1);
  85.             cpp.put_string(fz_14);
  86.          elseif as_write_byte = name then
  87.             cpp.put_string("putc(");
  88.             cpp.put_ith_argument(2);
  89.             cpp.put_string(",((FILE*)(");
  90.             cpp.put_ith_argument(1);
  91.             cpp.put_string(")));%N");
  92.          elseif as_print_run_time_stack = name then
  93.             cpp.put_string("se_print_run_time_stack();%N");
  94.          elseif as_die_with_code = name then
  95.             if cpp.target_cannot_be_dropped then
  96.                cpp.put_string(fz_14);
  97.             end;
  98.             cpp.put_string("exit(");
  99.             cpp.put_ith_argument(1);
  100.             cpp.put_string(fz_14);
  101.          elseif as_se_system = name then
  102.             cpp.put_string("system(((char*)");
  103.             cpp.put_ith_argument(1);
  104.             cpp.put_string(fz_16);
  105.          elseif as_c_inline_c = name then
  106.             cpp.put_c_inline_c;
  107.          elseif as_c_inline_h = name then
  108.             cpp.put_c_inline_h;
  109.          elseif as_trace_switch = name then
  110.             cpp.put_trace_switch;
  111.          elseif as_native_array = bcn then
  112.             c_mapping_native_array_procedure(rf7,name);
  113.          elseif as_memory = name then
  114.             if as_free = name then
  115.                if gc_handler.is_off then
  116.                   cpp.put_string(as_free);
  117.                   cpp.put_character('(');
  118.                   cpp.put_ith_argument(1);
  119.                   cpp.put_string(fz_14);
  120.                else
  121.                   if cpp.cannot_drop_all then
  122.                      cpp.put_string(fz_14);
  123.                   end;
  124.                end;
  125.             end;
  126.          elseif as_bit_n = bcn then
  127.             c_mapping_bit_procedure(rf7,name);
  128.          elseif as_sprintf_pointer = name then
  129.             cpp.put_string("{void*p=");
  130.             cpp.put_target_as_value;
  131.             cpp.put_string(";%Nsprintf((");
  132.             cpp.put_ith_argument(1);
  133.             cpp.put_string("),%"%%p%",p);}%N");
  134.          elseif as_sprintf_double = name then
  135.             cpp.sprintf_double_is_used;
  136.             cpp.put_string("{int i;%N%
  137.                            %double d=");
  138.             cpp.put_target_as_value;
  139.             cpp.put_string(";%N%
  140.                            %sprintf(_spfd+2,%"%%d%",(");
  141.             cpp.put_ith_argument(2);
  142.             cpp.put_string("));%N%
  143.                            %for(i=2;_spfd[i]!=0;i++);%N%
  144.                            %_spfd[i]='f';%N%
  145.                            %_spfd[++i]=0;%N%
  146.                            %sprintf((");
  147.             cpp.put_ith_argument(1);
  148.             cpp.put_string("),_spfd,d);%N}%N");
  149.          elseif as_se_rename = name then
  150.             cpp.put_string("rename(((char*)");
  151.             cpp.put_ith_argument(1);
  152.             cpp.put_string("),((char*)");
  153.             cpp.put_ith_argument(2);
  154.             cpp.put_string(fz_16);
  155.          elseif as_se_remove = name then
  156.             cpp.put_string("remove(((char*)");
  157.             cpp.put_ith_argument(1);
  158.             cpp.put_string(fz_16);
  159.          elseif as_raise_exception = name then
  160.             cpp.put_string("internal_exception_handler(");
  161.             cpp.put_ith_argument(1);
  162.             cpp.put_string(fz_14);
  163.          end;
  164.       end;
  165.  
  166.    c_define_function(rf8: RUN_FEATURE_8; bcn, name: STRING) is
  167.       local
  168.          elt_type: TYPE;
  169.          ct: TYPE;
  170.          rc: RUN_CLASS;
  171.          rf: RUN_FEATURE;
  172.          rf7: RUN_FEATURE_7;
  173.       do
  174.          if as_bit_n = bcn then
  175.             c_define_function_bit(rf8,name);
  176.          elseif as_general = bcn then
  177.             if as_is_equal = name or else as_standard_is_equal = name then
  178.                ct := rf8.current_type;
  179.                rc := ct.run_class;
  180.                if ct.is_basic_eiffel_expanded then
  181.                elseif ct.is_native_array then
  182.                elseif ct.is_bit then
  183.                elseif rc.is_tagged then
  184.                   rf8.c_define_with_body(
  185.                      "R=((C->id==a1->id)?!memcmp(C,a1,sizeof(*C)):0);");
  186.                elseif rc.writable_attributes = Void then
  187.                   if run_control.boost then
  188.                   else
  189.                      rf8.c_define_with_body("R=1;");
  190.                   end;
  191.                elseif run_control.boost then
  192.                else
  193.                   rf8.c_define_with_body("R=!memcmp(C,a1,sizeof(*C));");
  194.                end;
  195.             elseif as_standard_twin = name then
  196.                c_define_standard_twin(rf8,rf8.current_type);
  197.             elseif as_twin = name then
  198.                ct := rf8.current_type;
  199.                rc := ct.run_class;
  200.                rf := rc.get_copy;
  201.                rf7 ?= rf;
  202.                if rf7 /= Void then
  203.                   c_define_standard_twin(rf8,ct);
  204.                else
  205.                   c_define_twin(rf8,ct,rc,rf);
  206.                end;
  207.             end;
  208.          elseif as_native_array = bcn then
  209.             if as_calloc = name then
  210.                ct := rf8.current_type;
  211.                elt_type := ct.generic_list.item(1).run_type;
  212.                if elt_type.expanded_initializer /= Void then
  213.                   body.clear;
  214.                   body.append("R=");
  215.                   if gc_handler.is_off then
  216.                      body.append("malloc(sizeof(T");
  217.                      elt_type.id.append_in(body);
  218.                      body.append(")*");
  219.                   else
  220.                      body.append("(void*)new");
  221.                      ct.id.append_in(body);
  222.                      body.extend('(');
  223.                   end;
  224.                   body.append("a1);%Nr");
  225.                   ct.id.append_in(body);
  226.                   body.append("clear_all(");
  227.                   if run_control.no_check then
  228.                      body.append("&ds,");
  229.                   end;
  230.                   body.append("R,a1-1);%N");
  231.                   rf8.c_define_with_body(body);
  232.                end;
  233.             end
  234.          end;
  235.       end;
  236.  
  237.    c_mapping_function(rf8: RUN_FEATURE_8; bcn, name: STRING) is
  238.       local
  239.          cbd: BOOLEAN;
  240.          ct: TYPE;
  241.          rc: RUN_CLASS;
  242.          rf: RUN_FEATURE;
  243.          rf7: RUN_FEATURE_7;
  244.          basic_eq: BOOLEAN;
  245.          type_bit: TYPE_BIT;
  246.       do
  247.          if as_stderr = name then
  248.             cpp.put_string(as_stderr);
  249.          elseif as_stdin = name then
  250.             cpp.put_string(as_stdin);
  251.          elseif as_stdout = name then
  252.             cpp.put_string(as_stdout);
  253.          elseif as_general = bcn then
  254.             if as_generating_type = name then
  255.                cpp.put_generating_type(rf8.current_type);
  256.             elseif as_generator = name then
  257.                cpp.put_generator(rf8.current_type);
  258.             elseif as_to_pointer = name then
  259.                cpp.put_to_pointer;
  260.             elseif as_object_size = name then
  261.                cpp.put_object_size(rf8.current_type);
  262.             elseif as_is_equal = name or else as_standard_is_equal = name then
  263.                ct := rf8.current_type;
  264.                rc := ct.run_class;
  265.                if ct.is_basic_eiffel_expanded then
  266.                   basic_eq := true;
  267.                elseif ct.is_native_array then
  268.                   basic_eq := true;
  269.                elseif ct.is_bit then
  270.                   type_bit ?= ct;
  271.                   basic_eq := not type_bit.is_c_unsigned_ptr;
  272.                end;
  273.                if basic_eq then
  274.                   cpp.put_character('(');
  275.                   cpp.put_target_as_value;
  276.                   cpp.put_character(')');
  277.                   cpp.put_string(fz_c_eq);
  278.                   cpp.put_character('(');
  279.                   cpp.put_ith_argument(1);
  280.                   cpp.put_character(')');
  281.                elseif rc.is_tagged then
  282.                   rf8.default_mapping_function;
  283.                elseif rc.writable_attributes = Void then
  284.                   if run_control.boost then
  285.                      cbd := cpp.cannot_drop_all;
  286.                      if cbd then
  287.                         cpp.put_character(',');
  288.                      end;
  289.                      cpp.put_character('1');
  290.                      if cbd then
  291.                         cpp.put_character(')');
  292.                      end;
  293.                   else
  294.                      rf8.default_mapping_function;
  295.                   end;
  296.                elseif run_control.boost then
  297.                   cpp.put_string("!memcmp(");
  298.                   cpp.put_target_as_target;
  299.                   cpp.put_character(',');
  300.                   cpp.put_ith_argument(1);
  301.                   cpp.put_string(",sizeof(T");
  302.                   cpp.put_integer(rc.id);
  303.                   cpp.put_string(fz_13);
  304.                else
  305.                   rf8.default_mapping_function;
  306.                end;
  307.             elseif as_standard_twin = name then
  308.                c_mapping_standard_twin(rf8,rf8.current_type);
  309.             elseif as_twin = name then
  310.                ct := rf8.current_type;
  311.                rc := ct.run_class;
  312.                rf := rc.get_copy;
  313.                rf7 ?= rf;
  314.                if rf7 /= Void then
  315.                   c_mapping_standard_twin(rf8,ct);
  316.                else
  317.                   rf8.default_mapping_function;
  318.                end;
  319.             elseif as_is_basic_expanded_type = name then
  320.                cbd := cpp.cannot_drop_all;
  321.                if cbd then
  322.                   cpp.put_character(',');
  323.                end;
  324.                if rf8.current_type.is_basic_eiffel_expanded then
  325.                   cpp.put_character('1');
  326.                else
  327.                   cpp.put_character('0');
  328.                end;
  329.                if cbd then
  330.                   cpp.put_character(')');
  331.                end;
  332.             elseif as_is_expanded_type = name then
  333.                cbd := cpp.cannot_drop_all;
  334.                if cbd then
  335.                   cpp.put_character(',');
  336.                end;
  337.                if rf8.current_type.is_expanded then
  338.                   cpp.put_character('1');
  339.                else
  340.                   cpp.put_character('0');
  341.                end;
  342.                if cbd then
  343.                   cpp.put_character(')');
  344.                end;
  345.             elseif as_se_argc = name then
  346.                cpp.put_string(as_se_argc);
  347.             elseif as_se_argv = name then
  348.                cpp.put_string("((T0*)se_string_from_external_copy(se_argv[_i]))");
  349.             elseif as_se_getenv = name then
  350.                cpp.put_string(
  351.                "(NULL==(_p=getenv((char*)_p)))?NULL:%
  352.                %((T0*)se_string_from_external_copy((char*)_p))");
  353.             end;
  354.          elseif as_native_array = bcn then
  355.             c_mapping_native_array_function(rf8,name);
  356.          elseif as_integer = bcn then
  357.             c_mapping_integer_function(rf8,name);
  358.          elseif as_real = bcn then
  359.             c_mapping_real_function(rf8,name);
  360.          elseif as_double = bcn then
  361.             c_mapping_double_function(rf8,name);
  362.          elseif as_boolean = bcn then
  363.             if as_implies = name then
  364.                cpp.put_string("(!(");
  365.                cpp.put_target_as_value;
  366.                cpp.put_string("))||(");
  367.                cpp.put_arguments;
  368.                cpp.put_character(')');
  369.             else
  370.                check
  371.                   rf8.arg_count = 1;
  372.                end;
  373.                cpp.put_character('(');
  374.                cpp.put_target_as_value;
  375.                if as_or_else = name then
  376.                   cpp.put_string(")||(");
  377.                else
  378.                   check
  379.                      as_and_then = name;
  380.                   end;
  381.                   cpp.put_string(")&&(");
  382.                end;
  383.                cpp.put_arguments;
  384.                cpp.put_character(')');
  385.             end;
  386.          elseif as_character = bcn then
  387.             if as_code = name then
  388.                cpp.put_string("((unsigned char)");
  389.                cpp.put_target_as_value;
  390.                cpp.put_character(')');
  391.             else
  392.                check
  393.                   as_to_bit = name or else as_to_integer = name
  394.                end;
  395.                cpp.put_target_as_value;
  396.             end;
  397.          elseif as_pointer = bcn then
  398.             check
  399.                as_is_not_null = name
  400.             end;
  401.             cpp.put_string("(NULL!=");
  402.             cpp.put_target_as_value;
  403.             cpp.put_character(')');
  404.          elseif as_platform = bcn then
  405.             cbd := cpp.target_cannot_be_dropped;
  406.             if cbd then
  407.                cpp.put_character(',');
  408.             else
  409.                cpp.put_character(' ');
  410.             end;
  411.             if as_character_bits = name then
  412.                cpp.put_string("T3BITS");
  413.             elseif as_integer_bits = name then
  414.                cpp.put_string("T2BITS");
  415.             elseif as_boolean_bits = name then
  416.                cpp.put_string("T6BITS");
  417.             elseif as_real_bits = name then
  418.                cpp.put_string("T4BITS");
  419.             elseif as_double_bits = name then
  420.                cpp.put_string("T5BITS");
  421.             elseif as_pointer_bits = name then
  422.                cpp.put_string("T8BITS");
  423.             elseif as_minimum_character_code = name then
  424.                cpp.put_string("T3MIN");
  425.             elseif as_minimum_double = name then
  426.                cpp.put_string("T5MIN");
  427.             elseif as_minimum_integer = name then
  428.                cpp.put_string("T2MIN");
  429.             elseif as_minimum_real = name then
  430.                cpp.put_string("T4MIN");
  431.             elseif as_maximum_character_code = name then
  432.                cpp.put_string("T3MAX");
  433.             elseif as_maximum_double = name then
  434.                cpp.put_string("T5MAX");
  435.             elseif as_maximum_integer = name then
  436.                cpp.put_string("T2MAX");
  437.             elseif as_maximum_real = name then
  438.                cpp.put_string("T4MAX");
  439.             end;
  440.             if cbd then
  441.                cpp.put_character(')');
  442.             else
  443.                cpp.put_character(' ');
  444.             end;
  445.          elseif as_eof_code = name then
  446.             cbd := cpp.cannot_drop_all;
  447.             if cbd then
  448.                cpp.put_character(',');
  449.             end;
  450.             cpp.put_string("(EOF)");
  451.             if cbd then
  452.                cpp.put_character(')');
  453.             end;
  454.          elseif as_feof = name then
  455.             cpp.put_string("feof((FILE*)(");
  456.             cpp.put_ith_argument(1);
  457.             cpp.put_string(fz_13);
  458.          elseif as_sfr_open = name then
  459.             cpp.put_string("fopen((char*)");
  460.             cpp.put_ith_argument(1);
  461.             cpp.put_string(",%"r%")");
  462.          elseif as_sfw_open = name then
  463.             cpp.put_string("fopen((char*)");
  464.             cpp.put_ith_argument(1);
  465.             cpp.put_string(",%"w%")");
  466.          elseif as_se_string2double = name then
  467.             cpp.put_string("(sscanf(_p,%"%%lf%",&R),R)");
  468.          elseif as_bit_n = bcn then
  469.             c_mapping_bit_function(rf8,name);
  470.          elseif as_bitn = name then
  471.             cpp.put_character('(');
  472.             cpp.put_target_as_value;
  473.             cpp.put_string(")->bit_n");
  474.          elseif as_pointer_size = name then
  475.             cpp.put_string(fz_sizeof);
  476.             cpp.put_character('(');
  477.             cpp.put_string(fz_t0_star);
  478.             cpp.put_character(')');
  479.          elseif as_read_byte = name then
  480.             cpp.put_string("getc((FILE*)(");
  481.             cpp.put_ith_argument(1);
  482.             cpp.put_string(fz_13);
  483.          elseif as_exception = name then
  484.             cpp.put_string("internal_exception_number");
  485.          elseif as_signal_number = name then
  486.             cpp.put_string("signal_exception_number");
  487.          elseif name.has_prefix(fz_se_dir) then
  488.             cpp.put_string(name);
  489.             cpp.put_character('(');
  490.             cpp.put_ith_argument(1);
  491.             cpp.put_character(')');
  492.          end;
  493.       end;
  494.  
  495.    jvm_add_method_for_function(rf8: RUN_FEATURE_8; bcn, name: STRING) is
  496.       local
  497.          ct: TYPE;
  498.          rc: RUN_CLASS;
  499.          rf: RUN_FEATURE;
  500.          rf7: RUN_FEATURE_7;
  501.       do
  502.          if as_general = bcn then
  503.             if as_twin = name then
  504.                ct := rf8.current_type;
  505.                rc := ct.run_class;
  506.                rf := rc.get_copy;
  507.                rf7 ?= rf;
  508.                if rf7 /= Void then
  509.                else
  510.                   jvm.add_method(rf8);
  511.                end;
  512.             elseif as_generating_type = name then
  513.                jvm.add_method(rf8);
  514.             elseif as_generator = name then
  515.                jvm.add_method(rf8);
  516.             end;
  517.          end;
  518.       end;
  519.  
  520.    jvm_define_function(rf8: RUN_FEATURE_8; bcn, name: STRING) is
  521.       local
  522.          ct: TYPE;
  523.          rc: RUN_CLASS;
  524.          rf: RUN_FEATURE;
  525.          rf7: RUN_FEATURE_7;
  526.          rc_idx, field_idx, point1: INTEGER;
  527.          cp: like constant_pool;
  528.          ca: like code_attribute;
  529.       do
  530.          cp := constant_pool;
  531.          ca := code_attribute;
  532.          if as_general = bcn then
  533.             if as_twin = name then
  534.                ct := rf8.current_type;
  535.                rc := ct.run_class;
  536.                rf := rc.get_copy;
  537.                rf7 ?= rf;
  538.                if rf7 /= Void then
  539.                else
  540.                   jvm_define_twin(rf8,rc,rf);
  541.                end;
  542.             elseif as_generating_type = name then
  543.                rf8.jvm_opening;
  544.                ct := rf8.current_type;
  545.                rc := ct.run_class;
  546.                rc_idx := rc.jvm_constant_pool_index;
  547.                field_idx := cp.idx_fieldref_generating_type(rc_idx);
  548.                ca.opcode_getstatic(field_idx,1);
  549.                ca.opcode_dup;
  550.                point1 := ca.opcode_ifnonnull;
  551.                ca.opcode_pop;
  552.                ca.opcode_push_manifest_string(ct.run_time_mark);
  553.                ca.opcode_dup;
  554.                ca.opcode_putstatic(field_idx,-1);
  555.                ca.resolve_u2_branch(point1);
  556.                rf8.jvm_closing_fast;
  557.             elseif as_generator = name then
  558.                rf8.jvm_opening;
  559.                ct := rf8.current_type;
  560.                rc := ct.run_class;
  561.                rc_idx := rc.jvm_constant_pool_index;
  562.                field_idx := cp.idx_fieldref_generator(rc_idx);
  563.                ca.opcode_getstatic(field_idx,1);
  564.                ca.opcode_dup;
  565.                point1 := ca.opcode_ifnonnull;
  566.                ca.opcode_pop;
  567.                ca.opcode_push_manifest_string(ct.base_class_name.to_string);
  568.                ca.opcode_dup;
  569.                ca.opcode_putstatic(field_idx,-1);
  570.                ca.resolve_u2_branch(point1);
  571.                rf8.jvm_closing_fast;
  572.             end;
  573.          end;
  574.       end;
  575.  
  576.    jvm_mapping_function(rf8: RUN_FEATURE_8; bcn, name: STRING) is
  577.       local
  578.          ct: TYPE;
  579.          rc: RUN_CLASS;
  580.          rf: RUN_FEATURE;
  581.          rf7: RUN_FEATURE_7;
  582.          point1, point2, space, idx: INTEGER;
  583.          cp: like constant_pool;
  584.          ca: like code_attribute;
  585.       do
  586.          ca := code_attribute;
  587.          cp := constant_pool;
  588.          if as_to_pointer = name then
  589.             jvm.push_target;
  590.          elseif as_stdin = name then
  591.             ca.opcode_system_in;
  592.          elseif as_stdout = name then
  593.             ca.opcode_system_out;
  594.          elseif as_stderr = name then
  595.             ca.opcode_system_err;
  596.          elseif as_integer = bcn then
  597.             jvm_mapping_integer_function(rf8,name);
  598.          elseif as_real = bcn then
  599.             jvm_mapping_real_function(rf8,name);
  600.          elseif as_double = bcn then
  601.             jvm_mapping_double_function(rf8,name);
  602.          elseif as_native_array = bcn then
  603.             jvm_mapping_native_array_function(rf8,name);
  604.          elseif as_character = bcn then
  605.             if as_code = name then
  606.                jvm.push_target;
  607.                ca.opcode_dup;
  608.                point1 := ca.opcode_ifge;
  609.                ca.opcode_sipush(255);
  610.                ca.opcode_iand;
  611.                ca.resolve_u2_branch(point1);
  612.             elseif as_to_integer = name then
  613.                jvm.push_target;
  614.             else
  615.                check
  616.                   as_to_bit = name
  617.                end;
  618.                jvm_int_to_bit(rf8.result_type,8);
  619.             end;
  620.          elseif as_is_not_null = name then
  621.             jvm.push_target;
  622.             point1 := ca.opcode_ifnonnull;
  623.             ca.opcode_iconst_0;
  624.             point2 := ca.opcode_goto;
  625.             ca.resolve_u2_branch(point1);
  626.             ca.opcode_iconst_1;
  627.             ca.resolve_u2_branch(point2);
  628.          elseif as_implies = name then
  629.             jvm.push_target;
  630.             point1 := ca.opcode_ifeq;
  631.             space := jvm.push_ith_argument(1);
  632.             point2 := ca.opcode_goto;
  633.             ca.resolve_u2_branch(point1);
  634.             ca.opcode_iconst_1;
  635.             ca.resolve_u2_branch(point2);
  636.          elseif as_general = bcn then
  637.             if as_generating_type = name then
  638.                rf8.routine_mapping_jvm;
  639.             elseif as_generator = name then
  640.                rf8.routine_mapping_jvm;
  641.             elseif as_to_pointer = name then
  642.                fe_nyi(rf8);
  643.             elseif as_object_size = name then
  644.                jvm.drop_target;
  645.                ct := rf8.current_type;
  646.                jvm_object_size(ct);
  647.             elseif as_is_equal = name or else
  648.                as_standard_is_equal = name
  649.              then
  650.                jvm.push_target;
  651.                space := jvm.push_ith_argument(1);
  652.                rf8.current_type.jvm_standard_is_equal;
  653.             elseif as_standard_twin = name then
  654.                jvm_standard_twin(rf8.current_type);
  655.             elseif as_twin = name then
  656.                ct := rf8.current_type;
  657.                rc := ct.run_class;
  658.                rf := rc.get_copy;
  659.                rf7 ?= rf;
  660.                if rf7 /= Void then
  661.                   jvm_standard_twin(ct);
  662.                else
  663.                   rf8.routine_mapping_jvm;
  664.                end;
  665.             elseif as_is_basic_expanded_type = name then
  666.                jvm.drop_target;
  667.                if rf8.current_type.is_basic_eiffel_expanded then
  668.                   ca.opcode_iconst_1;
  669.                else
  670.                   ca.opcode_iconst_0;
  671.                end;
  672.             elseif as_is_expanded_type = name then
  673.                jvm.drop_target;
  674.                if rf8.current_type.is_expanded then
  675.                   ca.opcode_iconst_1;
  676.                else
  677.                   ca.opcode_iconst_0;
  678.                end;
  679.             elseif as_se_argc = name then
  680.                jvm.push_se_argc;
  681.             elseif as_se_argv = name then
  682.                jvm.push_se_argv;
  683.             elseif as_se_getenv = name then
  684.                space := jvm.push_ith_argument(1);
  685.                ca.runtime_se_getenv;
  686.             else
  687.                fe_nyi(rf8);
  688.             end;
  689.          elseif as_platform = bcn then
  690.             jvm.drop_target;
  691.             if as_character_bits = name then
  692.                ca.opcode_bipush(8);
  693.             elseif as_integer_bits = name then
  694.                ca.opcode_bipush(32);
  695.             elseif as_boolean_bits = name then
  696.                ca.opcode_bipush(32);
  697.             elseif as_real_bits = name then
  698.                ca.opcode_bipush(32);
  699.             elseif as_double_bits = name then
  700.                ca.opcode_bipush(64);
  701.             elseif as_pointer_bits = name then
  702.                ca.opcode_bipush(32);
  703.             elseif as_minimum_character_code = name then
  704.                ca.opcode_iconst_i(0);
  705.             elseif as_minimum_double = name then
  706.                idx := cp.idx_fieldref3(fz_62,fz_98,fz_77);
  707.                ca.opcode_getstatic(idx,2);
  708.             elseif as_minimum_integer = name then
  709.                ca.opcode_iconst_m1;
  710.                ca.opcode_iconst_1;
  711.                ca.opcode_iushr;
  712.                ca.opcode_ineg;
  713.                ca.opcode_iconst_m1;
  714.                ca.opcode_iadd;
  715.             elseif as_minimum_real = name then
  716.                idx := cp.idx_fieldref3(fz_26,fz_98,fz_78);
  717.                ca.opcode_getstatic(idx,1);
  718.             elseif as_maximum_character_code = name then
  719.                ca.opcode_sipush(255);
  720.             elseif as_maximum_double = name then
  721.                idx := cp.idx_fieldref3(fz_62,fz_95,fz_77);
  722.                ca.opcode_getstatic(idx,2);
  723.             elseif as_maximum_integer = name then
  724.                ca.opcode_iconst_m1;
  725.                ca.opcode_iconst_1;
  726.                ca.opcode_iushr;
  727.             elseif as_maximum_real = name then
  728.                idx := cp.idx_fieldref3(fz_26,fz_95,fz_78);
  729.                ca.opcode_getstatic(idx,1);
  730.             end;
  731.          elseif as_eof_code = name then
  732.             ca.opcode_iconst_m1;
  733.          elseif as_sfr_open = name then
  734.             space := jvm.push_ith_argument(1);
  735.             ca.runtime_sfr_open;
  736.          elseif as_sfw_open = name then
  737.             space := jvm.push_ith_argument(1);
  738.             ca.runtime_sfw_open;
  739.          elseif as_se_string2double = name then
  740.             space := jvm.push_ith_argument(1);
  741.             ca.runtime_se_string2double;
  742.          elseif as_pointer_size = name then
  743.             ca.opcode_bipush(32);
  744.          elseif as_bit_n = bcn then
  745.             jvm_mapping_bit_function(rf8,name);
  746.          elseif as_bitn = name then
  747.             jvm.push_target;
  748.             ct := rf8.current_type;
  749.             rc := ct.run_class;
  750.             idx := rc.jvm_constant_pool_index;
  751.             idx := cp.idx_fieldref4(idx,as_bitn,fz_a9);
  752.             ca.opcode_getfield(idx,0);
  753.          elseif as_read_byte = name then
  754.             space := jvm.push_ith_argument(1);
  755.             ca.read_byte;
  756.          elseif as_exception = name then
  757.             ca.runtime_internal_exception_number;
  758.          elseif as_signal_number = name then
  759.          else
  760.             fe_nyi(rf8);
  761.          end;
  762.       end;
  763.  
  764.    jvm_add_method_for_procedure(rf7: RUN_FEATURE_7; bcn, name: STRING) is
  765.       do
  766.          if as_sprintf_double = name then
  767.             jvm.add_method(rf7);
  768.          end;
  769.       end;
  770.  
  771.    jvm_define_procedure(rf7: RUN_FEATURE_7; bcn, name: STRING) is
  772.       do
  773.          if as_sprintf_double = name then
  774.             jvm_define_sprintf_double(rf7);
  775.          end;
  776.       end;
  777.  
  778.    jvm_mapping_procedure(rf7: RUN_FEATURE_7; bcn, name: STRING) is
  779.       local
  780.          space, idx: INTEGER;
  781.          t: TYPE;
  782.          ca: like code_attribute;
  783.       do
  784.          ca := code_attribute;
  785.          if as_copy = name or else as_standard_copy = name then
  786.             t := rf7.current_type;
  787.             if t.is_basic_eiffel_expanded then
  788.                jvm.drop_target;
  789.                jvm.drop_ith_argument(1);
  790.             else
  791.                jvm_copy(rf7.current_type);
  792.             end;
  793.          elseif as_flush_stream = name then
  794.             jvm.drop_target;
  795.             space := jvm.push_ith_argument(1);
  796.             idx := constant_pool.idx_class2(fz_25);
  797.             ca.opcode_checkcast(idx);
  798.             idx := constant_pool.idx_methodref1(idx,"flush",fz_29);
  799.             ca.opcode_invokevirtual(idx,-1);
  800.          elseif as_write_byte = name then
  801.             space := jvm.push_ith_argument(1);
  802.             idx := constant_pool.idx_class2(fz_22);
  803.             ca.opcode_checkcast(idx);
  804.             space := jvm.push_ith_argument(2);
  805.             idx := constant_pool.idx_methodref1(idx,"write",fz_27);
  806.             ca.opcode_invokevirtual(idx,-2);
  807.          elseif as_die_with_code = name then
  808.             jvm.drop_target;
  809.             space := jvm.push_ith_argument(1);
  810.             ca.runtime_die_with_code;
  811.          elseif as_free = name then
  812.             jvm.drop_target;
  813.          elseif as_print_run_time_stack = name then
  814.             jvm.drop_target;
  815.             ca.runtime_print_run_time_stack;
  816.          elseif as_native_array = bcn then
  817.             jvm_mapping_native_array_procedure(rf7,name);
  818.          elseif as_sprintf_pointer = name then
  819.             -- *** A FAIRE ***
  820.             jvm.drop_target;
  821.             space := jvm.push_ith_argument(1);
  822.             ca.opcode_dup;
  823.             ca.opcode_iconst_0;
  824.             ca.opcode_bipush(('1').code);
  825.             ca.opcode_bastore;
  826.             ca.opcode_iconst_1;
  827.             ca.opcode_bipush(('0').code);
  828.             ca.opcode_bastore;
  829.          elseif as_sprintf_double = name then
  830.             rf7.routine_mapping_jvm;
  831.          elseif as_se_rename = name then
  832.             space := jvm.push_ith_argument(1);
  833.             space := jvm.push_ith_argument(2);
  834.             ca.runtime_se_rename;
  835.          elseif as_se_remove = name then
  836.             space := jvm.push_ith_argument(1);
  837.             ca.runtime_se_remove;
  838.          elseif as_raise_exception = name then
  839.             fe_nyi(rf7);
  840.          elseif as_se_system = name then
  841.             space := jvm.push_ith_argument(1);
  842.             ca.runtime_se_system;
  843.          elseif as_bit_n = bcn then
  844.             jvm_mapping_bit_procedure(rf7,name);
  845.          else
  846.             fe_nyi(rf7);
  847.          end;
  848.       end;
  849.  
  850. feature
  851.  
  852.    use_current(er: EXTERNAL_ROUTINE): BOOLEAN is
  853.       local
  854.          n: STRING;
  855.       do
  856.          n := er.first_name.to_string;
  857.          if as_se_argc = n then
  858.          elseif as_read_byte = n then
  859.          elseif as_se_argv = n then
  860.          elseif as_se_rename = n then
  861.          elseif as_se_system = n then
  862.          elseif as_write_byte = n then
  863.          else
  864.             Result := true;
  865.          end;
  866.       end;
  867.  
  868. feature {NONE}
  869.  
  870.    new_jvm_open(rf8: RUN_FEATURE_8; jio: STRING) is
  871.          -- Where `jio' is a Java class name.
  872.       local
  873.          pc1, pc2, pc3: INTEGER;
  874.          idx: INTEGER;
  875.          cp: like constant_pool;
  876.          ca: like code_attribute;
  877.       do
  878.          cp := constant_pool;
  879.          ca := code_attribute;
  880.          rf8.jvm_opening;
  881.          -- New java/lang/String :
  882.          idx := cp.idx_class2(fz_32);
  883.          ca.opcode_new(idx);
  884.          ca.opcode_dup;
  885.          ca.opcode_aload_2;
  886.          ca.opcode_iconst_0;
  887.          ca.opcode_aload_1;
  888.          idx := cp.idx_methodref3(fz_32,fz_35,fz_65);
  889.          ca.opcode_invokespecial(idx,-4);
  890.          ca.opcode_astore_3;
  891.          -- New Input/Output Java :
  892.          pc1 := ca.program_counter;
  893.          idx := cp.idx_class2(fz_67);
  894.          ca.opcode_new(idx);
  895.          ca.opcode_dup;
  896.          ca.opcode_aload_3;
  897.          idx := cp.idx_methodref3(jio,fz_35,fz_68);
  898.          ca.opcode_invokespecial(idx,-2);
  899.          ca.opcode_areturn;
  900.          pc2 := ca.program_counter;
  901.          pc3 := ca.program_counter;
  902.          ca.opcode_pop;
  903.          ca.opcode_aconst_null;
  904.          ca.opcode_astore_3;
  905.          idx := cp.idx_class2(fz_84);
  906. --***
  907.          pc1 := ca.program_counter;
  908.          ca.opcode_nop;
  909.          ca.opcode_nop;
  910.  
  911.          pc2 := ca.program_counter;
  912.          ca.opcode_nop;
  913.          ca.opcode_nop;
  914.  
  915.          pc3 := ca.program_counter;
  916.          ca.opcode_nop;
  917.          ca.opcode_nop;
  918.  
  919.  
  920.          ca.add_exception(pc1,pc2,pc3,idx);
  921.          rf8.jvm_closing;
  922.       end;
  923.  
  924.    new_small_jvm_open(rf8: RUN_FEATURE_8; jio: STRING) is
  925.          -- Where `jio' is a Java class name.
  926.       local
  927.          pc1, pc2, pc3: INTEGER;
  928.          idx: INTEGER;
  929.          cp: like constant_pool;
  930.          ca: like code_attribute;
  931.       do
  932.          cp := constant_pool;
  933.          ca := code_attribute;
  934.          rf8.jvm_opening;
  935.  
  936.          pc1 := ca.program_counter;
  937.          ca.opcode_nop;
  938.          ca.opcode_nop;
  939.  
  940.          pc2 := ca.program_counter;
  941.          idx := ca.opcode_goto;
  942.          ca.opcode_nop;
  943.  
  944.          pc3 := ca.program_counter;
  945.          ca.opcode_pop;
  946.          ca.opcode_nop;
  947.  
  948.  
  949.          ca.add_exception(pc1,pc2,pc3,cp.idx_class2(fz_84));
  950.  
  951.          ca.resolve_u2_branch(idx);
  952.          rf8.jvm_closing;
  953.       end;
  954.  
  955.    jvm_object_size(ct: TYPE) is
  956.       local
  957.          t: TYPE;
  958.          space, i: INTEGER;
  959.          wa: ARRAY[RUN_FEATURE_2];
  960.       do
  961.          if ct.is_basic_eiffel_expanded then
  962.             space := ct.jvm_stack_space;
  963.          else
  964.             wa := ct.run_class.writable_attributes;
  965.             if wa /= Void then
  966.                from
  967.                   i := wa.upper;
  968.                until
  969.                   i = 0
  970.                loop
  971.                   t := wa.item(i).result_type;
  972.                   space := space + t.jvm_stack_space;
  973.                   i := i - 1;
  974.                end;
  975.             end;
  976.          end;
  977.          code_attribute.opcode_push_integer(space);
  978.       end;
  979.  
  980.    c_mapping_standard_twin(rf8: RUN_FEATURE_8; ct: TYPE) is
  981.       do
  982.          if ct.is_basic_eiffel_expanded then
  983.             cpp.put_target_as_value;
  984.          elseif ct.is_expanded then
  985.             if ct.is_dummy_expanded then
  986.                cpp.put_target_as_target;
  987.             elseif ct.is_native_array then
  988.                cpp.put_target_as_target;
  989.             else
  990.                rf8.default_mapping_function;
  991.             end;
  992.          else
  993.             rf8.default_mapping_function;
  994.          end;
  995.       end;
  996.  
  997.    c_define_standard_twin(rf8: RUN_FEATURE_8; ct: TYPE) is
  998.       do
  999.          if ct.is_basic_eiffel_expanded then
  1000.          elseif ct.is_expanded then
  1001.             if ct.is_dummy_expanded then
  1002.             elseif ct.is_native_array then
  1003.             else
  1004.                rf8.c_define_with_body("memcpy(&R,C,sizeof(R));");
  1005.             end;
  1006.          else
  1007.             if gc_handler.is_off then
  1008.                body.copy("R=malloc(sizeof(*C));%N");
  1009.             else
  1010.                body.copy("R=(");
  1011.                body.append(fz_cast_void_star);
  1012.                ct.gc_call_new_in(body);
  1013.                body.append(fz_14);
  1014.             end;
  1015.             body.append("*((T");
  1016.             ct.id.append_in(body);
  1017.             body.append("*)R)=*C;%N");
  1018.             rf8.c_define_with_body(body);
  1019.          end;
  1020.       end;
  1021.  
  1022.    c_define_twin(rf8: RUN_FEATURE_8; ct: TYPE; rc: RUN_CLASS;
  1023.                  cpy: RUN_FEATURE) is
  1024.       require
  1025.          rf8 /= Void;
  1026.          ct.is_reference or ct.is_user_expanded;
  1027.          rc = ct.run_class;
  1028.          cpy /= Void
  1029.       local
  1030.          id: INTEGER;
  1031.       do
  1032.          rf8.c_opening;
  1033.          if ct.is_reference then
  1034.             if gc_handler.is_off then
  1035.                id := rc.id;
  1036.                cpp.put_string("R=malloc(sizeof(*C));%N");
  1037.                cpp.put_string("*((T");
  1038.                cpp.put_integer(id);
  1039.                cpp.put_string("*)R)=M");
  1040.                cpp.put_integer(id);
  1041.                cpp.put_string(fz_00);
  1042.             else
  1043.                body.copy("R=((void*)");
  1044.                ct.gc_call_new_in(body);
  1045.                body.append(fz_14);
  1046.                cpp.put_string(body);
  1047.             end;
  1048.          end;
  1049.          cpp.inside_twin(cpy);
  1050.          rf8.c_closing;
  1051.       end;
  1052.  
  1053.    jvm_mapping_native_array_function(rf8: RUN_FEATURE_8; name: STRING) is
  1054.       local
  1055.          elt_type: TYPE;
  1056.          space: INTEGER;
  1057.          rc: RUN_CLASS;
  1058.          loc1, point1, point2: INTEGER;
  1059.          ca: like code_attribute;
  1060.       do
  1061.          elt_type := rf8.current_type.generic_list.item(1).run_type;
  1062.          if as_element_sizeof = name then
  1063.             jvm.drop_target;
  1064.             space := elt_type.jvm_stack_space;
  1065.             code_attribute.opcode_push_integer(space);
  1066.          elseif as_item = name then
  1067.             jvm.push_target;
  1068.             space := jvm.push_ith_argument(1);
  1069.             elt_type.jvm_xaload;
  1070.          elseif as_calloc = name then
  1071.             jvm.drop_target;
  1072.             space := jvm.push_ith_argument(1);
  1073.             elt_type.jvm_xnewarray;
  1074.             if elt_type.is_user_expanded and then
  1075.                not elt_type.is_dummy_expanded
  1076.              then
  1077.                ca := code_attribute;
  1078.                rc := elt_type.run_class;
  1079.                loc1 := ca.extra_local_size1;
  1080.                ca.opcode_dup;
  1081.                ca.opcode_arraylength;
  1082.                ca.opcode_istore(loc1);
  1083.                point1 := ca.program_counter;
  1084.                ca.opcode_iload(loc1);
  1085.                point2 := ca.opcode_ifle;
  1086.                ca.opcode_iinc(loc1,255);
  1087.                ca.opcode_dup;
  1088.                ca.opcode_iload(loc1);
  1089.                rc.jvm_expanded_push_default;
  1090.                ca.opcode_aastore;
  1091.                ca.opcode_goto_backward(point1);
  1092.                ca.resolve_u2_branch(point2);
  1093.             end;
  1094.          elseif name = as_from_pointer then
  1095.             jvm.drop_target;
  1096.             space := jvm.push_ith_argument(1);
  1097.             rf8.current_type.run_class.opcode_checkcast;
  1098.          else
  1099.             fe_nyi(rf8);
  1100.          end;
  1101.       end;
  1102.  
  1103.    jvm_mapping_native_array_procedure(rf7: RUN_FEATURE_7; name: STRING) is
  1104.       local
  1105.          elt_type: TYPE;
  1106.          space: INTEGER;
  1107.       do
  1108.          elt_type := rf7.current_type.generic_list.item(1).run_type;
  1109.          if as_put = name then
  1110.             jvm.push_target;
  1111.             space := jvm.push_ith_argument(2);
  1112.             space := jvm.push_ith_argument(1);
  1113.             elt_type.jvm_xastore;
  1114.          else
  1115.             check
  1116.                as_free = name
  1117.             end;
  1118.             jvm.drop_target;
  1119.          end;
  1120.       end;
  1121.  
  1122.    c_mapping_native_array_function(rf8: RUN_FEATURE_8; name: STRING) is
  1123.       local
  1124.          elt_type: TYPE;
  1125.          tcbd: BOOLEAN;
  1126.       do
  1127.          elt_type := rf8.current_type.generic_list.item(1).run_type;
  1128.          if as_element_sizeof = name then
  1129.             tcbd := cpp.target_cannot_be_dropped;
  1130.             if tcbd then
  1131.                cpp.put_character(',');
  1132.             end;
  1133.             tmp_string.copy(fz_sizeof);
  1134.             tmp_string.extend('(');
  1135.             elt_type.c_type_for_argument_in(tmp_string);
  1136.             tmp_string.extend(')');
  1137.             cpp.put_string(tmp_string);
  1138.             if tcbd then
  1139.                cpp.put_character(')');
  1140.             end;
  1141.          elseif name = as_calloc then
  1142.             if elt_type.expanded_initializer = Void then
  1143.                tcbd := cpp.target_cannot_be_dropped;
  1144.                if tcbd then
  1145.                   cpp.put_character(',');
  1146.                end;
  1147.                if gc_handler.is_off then
  1148.                   cpp.put_string(as_calloc);
  1149.                   cpp.put_character('(');
  1150.                   cpp.put_ith_argument(1);
  1151.                   tmp_string.clear;
  1152.                   tmp_string.extend(',');
  1153.                   tmp_string.append(fz_sizeof);
  1154.                   tmp_string.extend('(');
  1155.                   elt_type.c_type_for_result_in(tmp_string);
  1156.                   tmp_string.append(fz_13);
  1157.                   cpp.put_string(tmp_string);
  1158.                else
  1159.                   cpp.put_string(fz_new);
  1160.                   cpp.put_integer(rf8.current_type.id);
  1161.                   cpp.put_character('(');
  1162.                   cpp.put_ith_argument(1);
  1163.                   cpp.put_character(')');
  1164.                end;
  1165.                if tcbd then
  1166.                   cpp.put_character(')');
  1167.                end;
  1168.             else
  1169.                rf8.default_mapping_function;
  1170.             end;
  1171.          elseif name = as_from_pointer then
  1172.             tcbd := cpp.target_cannot_be_dropped;
  1173.             if tcbd then
  1174.                cpp.put_character(',');
  1175.             end;
  1176.             cpp.put_ith_argument(1);
  1177.             if tcbd then
  1178.                cpp.put_character(')');
  1179.             end;
  1180.          else
  1181.             check
  1182.                as_item = name
  1183.             end;
  1184.             cpp.put_character('(');
  1185.             cpp.put_target_as_value;
  1186.             cpp.put_string(")[");
  1187.             cpp.put_ith_argument(1);
  1188.             cpp.put_character(']');
  1189.          end;
  1190.       end;
  1191.  
  1192.    c_mapping_native_array_procedure(rf7: RUN_FEATURE_7; name: STRING) is
  1193.       local
  1194.          elt_type: TYPE;
  1195.       do
  1196.          elt_type := rf7.current_type.generic_list.item(1).run_type;
  1197.          if name = as_put then
  1198.             if elt_type.is_user_expanded then
  1199.                if elt_type.is_dummy_expanded then
  1200.                   if cpp.cannot_drop_all then
  1201.                      cpp.put_string(fz_14);
  1202.                   end;
  1203.                else
  1204.                   cpp.put_string("memcpy((");
  1205.                   cpp.put_target_as_value;
  1206.                   cpp.put_string(")+(");
  1207.                   cpp.put_ith_argument(2);
  1208.                   cpp.put_string("),");
  1209.                   cpp.put_ith_argument(1);
  1210.                   cpp.put_string(",sizeof(T");
  1211.                   cpp.put_integer(elt_type.id);
  1212.                   cpp.put_string(fz_16);
  1213.                end;
  1214.             else
  1215.                cpp.put_character('(');
  1216.                cpp.put_target_as_value;
  1217.                cpp.put_string(")[");
  1218.                cpp.put_ith_argument(2);
  1219.                cpp.put_string("]=(");
  1220.                cpp.put_ith_argument(1);
  1221.                cpp.put_string(fz_14);
  1222.             end;
  1223.          elseif name = as_free then
  1224.             cpp.put_string(as_free);
  1225.             cpp.put_character('(');
  1226.             cpp.put_target_as_value;
  1227.             cpp.put_string(fz_14);
  1228.          end;
  1229.       end;
  1230.  
  1231.    jvm_copy(t: TYPE) is
  1232.       require
  1233.          not t.is_basic_eiffel_expanded
  1234.       local
  1235.          rc: RUN_CLASS;
  1236.          wa: ARRAY[RUN_FEATURE_2];
  1237.          space: INTEGER;
  1238.       do
  1239.          rc := t.run_class;
  1240.          wa := rc.writable_attributes;
  1241.          jvm.push_target;
  1242.          space := jvm.push_ith_argument(1);
  1243.          rc.opcode_checkcast;
  1244.          jvm.fields_by_fields_copy(wa);
  1245.          code_attribute.opcode_pop;
  1246.       end;
  1247.  
  1248.    jvm_define_sprintf_double(rf7: RUN_FEATURE_7) is
  1249.       require
  1250.          rf7 /= Void
  1251.       local
  1252.          idx, loc1, loc2: INTEGER;
  1253.          point1, point2, point3: INTEGER;
  1254.          cp: like constant_pool;
  1255.          ca: like code_attribute;
  1256.       do
  1257.          cp := constant_pool;
  1258.          ca := code_attribute;
  1259.          rf7.jvm_opening;
  1260.          -- Double.toString(double) :
  1261.          ca.opcode_dload_0;
  1262.          idx := cp.idx_methodref3(fz_62,fz_63,fz_64);
  1263.          ca.opcode_invokestatic(idx,1);
  1264.          ca.opcode_java_string2bytes_array;
  1265.          -- loc1 is for the byte array :
  1266.          loc1 := ca.extra_local_size1;
  1267.          ca.opcode_astore(loc1);
  1268.          -- Copy of the integral part :
  1269.          loc2 := ca.extra_local_size1;
  1270.          ca.opcode_iconst_0;
  1271.          ca.opcode_istore(loc2);
  1272.          point1 := ca.program_counter;
  1273.          ca.opcode_aload(loc1);
  1274.          ca.opcode_arraylength;
  1275.          ca.opcode_iload(loc2);
  1276.          point2 := ca.opcode_if_icmple;
  1277.          ca.opcode_aload_2;
  1278.          ca.opcode_iload(loc2);
  1279.          ca.opcode_aload(loc1);
  1280.          ca.opcode_iload(loc2);
  1281.          ca.opcode_baload;
  1282.          ca.opcode_bastore;
  1283.          ca.opcode_aload(loc1);
  1284.          ca.opcode_iload(loc2);
  1285.          ca.opcode_baload;
  1286.          ca.opcode_bipush(('.').code);
  1287.          ca.opcode_iinc(loc2,1);
  1288.          point3 := ca.opcode_if_icmpeq;
  1289.          ca.opcode_goto_backward(point1);
  1290.          ca.resolve_u2_branch(point2);
  1291.          ca.resolve_u2_branch(point3);
  1292.          -- Copy of the fractional part :
  1293.          point1 := ca.program_counter;
  1294.          ca.opcode_aload(loc1);
  1295.          ca.opcode_arraylength;
  1296.          ca.opcode_iload(loc2);
  1297.          point2 := ca.opcode_if_icmple;
  1298.          ca.opcode_iload_3;
  1299.          point3 := ca.opcode_ifeq;
  1300.          ca.opcode_aload_2;
  1301.          ca.opcode_iload(loc2);
  1302.          ca.opcode_aload(loc1);
  1303.          ca.opcode_iload(loc2);
  1304.          ca.opcode_baload;
  1305.          ca.opcode_bastore;
  1306.          ca.opcode_iinc(loc2,1);
  1307.          ca.opcode_iinc(3,255);
  1308.          ca.opcode_goto_backward(point1);
  1309.          ca.resolve_u2_branch(point2);
  1310.          ca.resolve_u2_branch(point3);
  1311.          -- Add some more '0' :
  1312.          point1 := ca.program_counter;
  1313.          ca.opcode_iload_3;
  1314.          point2 := ca.opcode_ifeq;
  1315.          ca.opcode_aload_2;
  1316.          ca.opcode_iload(loc2);
  1317.          ca.opcode_bipush(('0').code);
  1318.          ca.opcode_bastore;
  1319.          ca.opcode_iinc(loc2,1);
  1320.          ca.opcode_iinc(3,255)
  1321.          ca.opcode_goto_backward(point1);
  1322.          ca.resolve_u2_branch(point2);
  1323.          -- Adding the extra '%/0' :
  1324.          ca.opcode_aload_2;
  1325.          ca.opcode_iload(loc2);
  1326.          ca.opcode_iconst_0;
  1327.          ca.opcode_bastore;
  1328.          rf7.jvm_closing;
  1329.       end;
  1330.  
  1331.    jvm_define_twin(rf8: RUN_FEATURE_8; rc: RUN_CLASS; cpy: RUN_FEATURE) is
  1332.       require
  1333.          rc = rf8.current_type.run_class;
  1334.          cpy /= Void
  1335.       local
  1336.          idx, space, i: INTEGER;
  1337.          wa: ARRAY[RUN_FEATURE_2];
  1338.          rf2: RUN_FEATURE_2;
  1339.       do
  1340.          rf8.jvm_opening;
  1341.          wa := rc.writable_attributes;
  1342.          rc.jvm_basic_new;
  1343.          code_attribute.opcode_astore_1;
  1344.          if wa /= Void then
  1345.             from
  1346.                i := wa.upper;
  1347.             until
  1348.                i = 0
  1349.             loop
  1350.                rf2 := wa.item(i);
  1351.                code_attribute.opcode_aload_1;
  1352.                idx := constant_pool.idx_fieldref(rf2);
  1353.                space := rf2.result_type.jvm_push_default;
  1354.                code_attribute.opcode_putfield(idx,-(space + 1));
  1355.                i := i - 1;
  1356.             end;
  1357.          end;
  1358.          jvm.inside_twin(cpy);
  1359.          rf8.jvm_closing;
  1360.       end;
  1361.  
  1362. feature {NONE}
  1363.  
  1364.    jvm_standard_twin(t: TYPE) is
  1365.       require
  1366.          t /= Void
  1367.       local
  1368.          rc: RUN_CLASS;
  1369.          wa: ARRAY[RUN_FEATURE_2];
  1370.       do
  1371.          if t.is_basic_eiffel_expanded or else t.is_native_array then
  1372.             jvm.push_target;
  1373.          else
  1374.             rc := t.run_class;
  1375.             wa := rc.writable_attributes;
  1376.             if t.is_expanded then
  1377.                if wa = Void then
  1378.                   jvm.push_target;
  1379.                else
  1380.                   jvm_standard_twin_aux(rc,wa);
  1381.                end;
  1382.             else
  1383.                jvm_standard_twin_aux(rc,wa);
  1384.             end;
  1385.          end;
  1386.       end;
  1387.  
  1388.    jvm_standard_twin_aux(rc: RUN_CLASS; wa: ARRAY[RUN_FEATURE_2]) is
  1389.       require
  1390.          rc /= Void
  1391.       local
  1392.          ca: like code_attribute;
  1393.          rf2: RUN_FEATURE_2;
  1394.          idx, space, i: INTEGER;
  1395.       do
  1396.          ca := code_attribute;
  1397.          rc.jvm_basic_new;
  1398.          if wa = Void then
  1399.             jvm.drop_target;
  1400.          else
  1401.             jvm.push_target;
  1402.             rc.opcode_checkcast;
  1403.             from
  1404.                i := wa.upper;
  1405.             until
  1406.                i = 0
  1407.             loop
  1408.                rf2 := wa.item(i);
  1409.                ca.opcode_dup2;
  1410.                idx := constant_pool.idx_fieldref(rf2);
  1411.                space := rf2.result_type.jvm_stack_space;
  1412.                ca.opcode_getfield(idx,space - 1);
  1413.                ca.opcode_putfield(idx,space + 1);
  1414.                i := i - 1;
  1415.             end;
  1416.             ca.opcode_pop;
  1417.          end;
  1418.       end;
  1419.  
  1420.    jvm_mapping_integer_function(rf8: RUN_FEATURE_8; name: STRING) is
  1421.       local
  1422.          point1, point2, space: INTEGER;
  1423.          ca: like code_attribute;
  1424.       do
  1425.          ca := code_attribute;
  1426.          if as_slash = name then
  1427.             jvm.push_target;
  1428.             ca.opcode_i2d;
  1429.             space := jvm.push_ith_argument(1);
  1430.             ca.opcode_i2d;
  1431.             ca.opcode_ddiv;
  1432.          elseif rf8.arg_count = 1 then
  1433.             jvm.push_target;
  1434.             space := jvm.push_ith_argument(1);
  1435.             if as_plus = name then
  1436.                ca.opcode_iadd;
  1437.             elseif as_minus = name then
  1438.                ca.opcode_isub;
  1439.             elseif as_muls = name then
  1440.                ca.opcode_imul;
  1441.             elseif as_slash_slash = name then
  1442.                ca.opcode_idiv;
  1443.             elseif as_backslash_backslash = name then
  1444.                ca.opcode_irem;
  1445.             else -- < > <= >= only
  1446.                if as_gt = name then
  1447.                   point1 := ca.opcode_if_icmpgt;
  1448.                elseif as_lt = name then
  1449.                   point1 := ca.opcode_if_icmplt;
  1450.                elseif as_le = name then
  1451.                   point1 := ca.opcode_if_icmple;
  1452.                else
  1453.                   point1 := ca.opcode_if_icmpge;
  1454.                end;
  1455.                ca.opcode_iconst_0;
  1456.                point2 := ca.opcode_goto;
  1457.                ca.resolve_u2_branch(point1);
  1458.                ca.opcode_iconst_1;
  1459.                ca.resolve_u2_branch(point2);
  1460.             end;
  1461.          elseif as_to_character = name then
  1462.             jvm.push_target;
  1463.             code_attribute.opcode_i2b;
  1464.          elseif as_to_bit = name then
  1465.             jvm_int_to_bit(rf8.result_type,32);
  1466.          else
  1467.             check
  1468.                as_minus = name
  1469.             end;
  1470.             jvm.push_target;
  1471.             code_attribute.opcode_ineg
  1472.          end;
  1473.       end;
  1474.  
  1475.    jvm_mapping_real_function(rf8: RUN_FEATURE_8; name: STRING) is
  1476.       local
  1477.          point1, point2, space: INTEGER;
  1478.          ca: like code_attribute;
  1479.       do
  1480.          ca := code_attribute;
  1481.          if rf8.arg_count = 1 then
  1482.             jvm.push_target;
  1483.             space := jvm.push_ith_argument(1);
  1484.             if as_plus = name then
  1485.                ca.opcode_fadd;
  1486.             elseif as_minus = name then
  1487.                ca.opcode_fsub;
  1488.             elseif as_muls = name then
  1489.                ca.opcode_fmul;
  1490.             elseif as_slash = name then
  1491.                ca.opcode_fdiv;
  1492.             else
  1493.                ca.opcode_fcmpg;
  1494.                if as_gt = name then     -- gt
  1495.                   point1 := ca.opcode_ifgt;
  1496.                elseif as_lt = name then -- lt
  1497.                   point1 := ca.opcode_iflt;
  1498.                elseif as_le = name then -- le
  1499.                   point1 := ca.opcode_ifle;
  1500.                elseif as_ge = name then -- ge
  1501.                   point1 := ca.opcode_ifge;
  1502.                end;
  1503.                ca.opcode_iconst_0;
  1504.                point2 := ca.opcode_goto;
  1505.                ca.resolve_u2_branch(point1);
  1506.                ca.opcode_iconst_1;
  1507.                ca.resolve_u2_branch(point2);
  1508.             end;
  1509.          elseif as_minus = name then
  1510.             jvm.push_target;
  1511.             ca.opcode_fneg
  1512.          elseif as_to_double = name then
  1513.             jvm.push_target;
  1514.             ca.opcode_f2d;
  1515.          end;
  1516.       end;
  1517.  
  1518.    jvm_mapping_double_function(rf8: RUN_FEATURE_8; name: STRING) is
  1519.       local
  1520.          point1, point2, space, idx: INTEGER;
  1521.          ca: like code_attribute;
  1522.       do
  1523.          ca := code_attribute;
  1524.          if rf8.arg_count = 1 then
  1525.             jvm.push_target;
  1526.             space := jvm.push_ith_argument(1);
  1527.             if as_plus = name then
  1528.                ca.opcode_dadd;
  1529.             elseif as_minus = name then
  1530.                ca.opcode_dsub;
  1531.             elseif as_muls = name then
  1532.                ca.opcode_dmul;
  1533.             elseif as_slash = name then
  1534.                ca.opcode_ddiv;
  1535.             elseif as_pow = name then
  1536.                ca.opcode_i2d;
  1537.                idx := constant_pool.idx_methodref3(fz_93,"pow",fz_99);
  1538.                ca.opcode_invokestatic(idx,-2);
  1539.             else
  1540.                ca.opcode_dcmpg;
  1541.                if as_gt = name then     -- gt
  1542.                   point1 := ca.opcode_ifgt;
  1543.                elseif as_lt = name then -- lt
  1544.                   point1 := ca.opcode_iflt;
  1545.                elseif as_le = name then -- le
  1546.                   point1 := ca.opcode_ifle;
  1547.                elseif as_ge = name then -- ge
  1548.                   point1 := ca.opcode_ifge;
  1549.                end;
  1550.                ca.opcode_iconst_0;
  1551.                point2 := ca.opcode_goto;
  1552.                ca.resolve_u2_branch(point1);
  1553.                ca.opcode_iconst_1;
  1554.                ca.resolve_u2_branch(point2);
  1555.             end;
  1556.          elseif as_minus = name then
  1557.             jvm.push_target;
  1558.             ca.opcode_dneg;
  1559.          elseif as_to_real = name then
  1560.             jvm.push_target;
  1561.             ca.opcode_d2f;
  1562.          elseif as_double_floor = name then
  1563.             jvm.push_target;
  1564.             idx := constant_pool.idx_methodref3(fz_93,as_floor,fz_94);
  1565.             ca.opcode_invokestatic(idx,0);
  1566.          elseif as_truncated_to_integer = name then
  1567.             jvm.push_target;
  1568.             idx := constant_pool.idx_methodref3(fz_93,as_floor,fz_94);
  1569.             ca.opcode_invokestatic(idx,0);
  1570.             ca.opcode_d2i;
  1571.          else -- Same name in java/lang/Math :
  1572.             jvm.push_target;
  1573.             idx := constant_pool.idx_methodref3(fz_93,name,fz_94);
  1574.             ca.opcode_invokestatic(idx,0);
  1575.          end;
  1576.       end;
  1577.  
  1578. feature {NONE}
  1579.  
  1580.    c_mapping_integer_function(rf8: RUN_FEATURE_8; name: STRING) is
  1581.       do
  1582.          if rf8.arg_count = 1 then
  1583.             if as_slash = name then
  1584.                cpp.put_string("((T5)");
  1585.             end;
  1586.             cpp.put_character('(');
  1587.             cpp.put_target_as_value;
  1588.             if as_slash = name then
  1589.                cpp.put_character(')');
  1590.             end;
  1591.             cpp.put_character(')');
  1592.             if as_slash_slash = name then
  1593.                cpp.put_character('/');
  1594.             elseif as_backslash_backslash = name then
  1595.                cpp.put_character('%%');
  1596.             else
  1597.                cpp.put_string(name);
  1598.             end;
  1599.             cpp.put_character('(');
  1600.             cpp.put_arguments;
  1601.             cpp.put_character(')');
  1602.          elseif as_to_character = name then
  1603.             cpp.put_string("((T3)(");
  1604.             cpp.put_target_as_value;
  1605.             cpp.put_string(fz_13);
  1606.          elseif as_to_bit = name then
  1607.             cpp.put_target_as_value;
  1608.          else
  1609.             cpp.put_string(name);
  1610.             cpp.put_character('(');
  1611.             cpp.put_target_as_value;
  1612.             cpp.put_character(')');
  1613.          end;
  1614.       end;
  1615.  
  1616.    c_mapping_real_function(rf8: RUN_FEATURE_8; name: STRING) is
  1617.       do
  1618.          if rf8.arg_count = 1 then
  1619.             cpp.put_character('(');
  1620.             cpp.put_target_as_value;
  1621.             cpp.put_character(')');
  1622.             cpp.put_string(name);
  1623.             cpp.put_character('(');
  1624.             cpp.put_arguments;
  1625.             cpp.put_character(')');
  1626.          elseif as_to_double = name then
  1627.             cpp.put_string("((T5)(");
  1628.             cpp.put_target_as_value;
  1629.             cpp.put_string(fz_13);
  1630.          else
  1631.             cpp.put_string(name);
  1632.             cpp.put_character('(');
  1633.             cpp.put_target_as_value;
  1634.             cpp.put_character(')');
  1635.          end;
  1636.       end;
  1637.  
  1638.    c_mapping_double_function(rf8: RUN_FEATURE_8; name: STRING) is
  1639.       do
  1640.          if as_pow = name then
  1641.             system_tools.add_lib_math;
  1642.             cpp.put_string("pow((");
  1643.             cpp.put_target_as_value;
  1644.             cpp.put_string("),(double)(");
  1645.             cpp.put_arguments;
  1646.             cpp.put_string(fz_13);
  1647.          elseif as_double_floor = name then
  1648.             system_tools.add_lib_math;
  1649.             cpp.put_string(as_floor);
  1650.             cpp.put_character('(');
  1651.             cpp.put_target_as_value;
  1652.             cpp.put_character(')');
  1653.          elseif as_truncated_to_integer = name then
  1654.             system_tools.add_lib_math;
  1655.             cpp.put_string("((int)floor(");
  1656.             cpp.put_target_as_value;
  1657.             cpp.put_string(fz_13);
  1658.          elseif as_to_real = name then
  1659.             cpp.put_string("((T4)(");
  1660.             cpp.put_target_as_value;
  1661.             cpp.put_string(fz_13);
  1662.          elseif name.count <= 2 and then rf8.arg_count = 1 then
  1663.             cpp.put_character('(');
  1664.             cpp.put_target_as_value;
  1665.             cpp.put_character(')');
  1666.             cpp.put_string(name);
  1667.             cpp.put_character('(');
  1668.             cpp.put_arguments;
  1669.             cpp.put_character(')');
  1670.          else
  1671.             system_tools.add_lib_math;
  1672.             cpp.put_string(name);
  1673.             cpp.put_character('(');
  1674.             cpp.put_target_as_value;
  1675.             cpp.put_character(')');
  1676.          end;
  1677.       end;
  1678.  
  1679.    c_define_procedure_bit(rf7: RUN_FEATURE_7; n: STRING) is
  1680.       local
  1681.          type_bit: TYPE_BIT;
  1682.       do
  1683.          type_bit ?= rf7.current_type;
  1684.          if as_put_0 = n then
  1685.             if type_bit.is_c_unsigned_ptr then
  1686.                body.clear;
  1687.                body_long_bit_put01(type_bit,'&','~','1');
  1688.                rf7.c_define_with_body(body);
  1689.             end;
  1690.          elseif as_put_1 = n then
  1691.             if type_bit.is_c_unsigned_ptr then
  1692.                body.clear;
  1693.                body_long_bit_put01(type_bit,'|',' ','1');
  1694.                rf7.c_define_with_body(body);
  1695.             end;
  1696.          elseif as_put = n then
  1697.             if type_bit.is_c_unsigned_ptr then
  1698.                body.clear;
  1699.                body.append("if(a1)%N");
  1700.                body_long_bit_put01(type_bit,'|',' ','2');
  1701.                body.append(fz_else);
  1702.                body_long_bit_put01(type_bit,'&','~','2');
  1703.                rf7.c_define_with_body(body);
  1704.             end;
  1705.          end;
  1706.       end;
  1707.  
  1708. feature {NONE}
  1709.  
  1710.    tmp_string: STRING is
  1711.       once
  1712.          !!Result.make(32);
  1713.       end;
  1714.  
  1715. feature {NONE}
  1716.  
  1717.    fe_long_bit(rf: RUN_FEATURE) is
  1718.       do
  1719.          eh.add_position(rf.start_position);
  1720.          eh.append("Sorry, this feature cannot be implemented for ");
  1721.          eh.add_type(rf.current_type,
  1722.           " (bit string too long). You should probably consider using %
  1723.           %the BIT_STRING class to work around.");
  1724.          eh.print_as_fatal_error;
  1725.       end;
  1726.  
  1727.    fe_nyi(rf: RUN_FEATURE) is
  1728.       do
  1729.          eh.add_position(rf.start_position);
  1730.          eh.append("Sorry, but this feature is not yet implemented for %
  1731.                    %Current type ");
  1732.          eh.append(rf.current_type.run_time_mark);
  1733.          fatal_error(" (if you cannot work around mail %"colnet@loria.fr%").");
  1734.       end;
  1735.  
  1736.    jvm_bit_to_int(size: INTEGER) is
  1737.       local
  1738.          idx: INTEGER;
  1739.          point1, point2: INTEGER;
  1740.          loc1, loc2: INTEGER;
  1741.          ca: like code_attribute;
  1742.          cp: like constant_pool;
  1743.       do
  1744.          ca := code_attribute;
  1745.          cp := constant_pool;
  1746.          jvm.push_target;
  1747.          loc1 := ca.extra_local_size1;
  1748.          ca.opcode_iconst_0;
  1749.          ca.opcode_istore(loc1);
  1750.          loc2 := ca.extra_local_size1;
  1751.          ca.opcode_iconst_0;
  1752.          ca.opcode_istore(loc2);
  1753.          ca.opcode_iconst_1;
  1754.          point1 := ca.program_counter;
  1755.          point2 := ca.opcode_ifeq;
  1756.          ca.opcode_iload(loc2);
  1757.          ca.opcode_iconst_1;
  1758.          ca.opcode_ishl;
  1759.          ca.opcode_istore(loc2);
  1760.          ca.opcode_dup;
  1761.          ca.opcode_iload(loc1);
  1762.          idx := cp.idx_methodref3(fz_a0,fz_a2,fz_a3);
  1763.          ca.opcode_invokevirtual(idx,-1);
  1764.          ca.opcode_iload(loc2);
  1765.          ca.opcode_ior;
  1766.          ca.opcode_istore(loc2);
  1767.          ca.opcode_iinc(loc1,1);
  1768. -- ***
  1769. -- ca.opcode_dup;
  1770. --     idx := cp.idx_methodref3(fz_a0,"size",fz_71);
  1771. --     ca.opcode_invokevirtual(idx,0);
  1772.          ca.opcode_push_integer(size);
  1773. -- ***
  1774.          ca.opcode_iload(loc1);
  1775.          ca.opcode_isub;
  1776.          ca.opcode_goto_backward(point1);
  1777.          ca.resolve_u2_branch(point2);
  1778.          ca.opcode_pop;
  1779.          ca.opcode_iload(loc2);
  1780.       end;
  1781.  
  1782.    jvm_int_to_bit(type_bit: TYPE; nb_bit: INTEGER) is
  1783.       local
  1784.          idx: INTEGER;
  1785.          point1, point2, point3: INTEGER;
  1786.          loc1, loc2: INTEGER;
  1787.          ca: like code_attribute;
  1788.          cp: like constant_pool;
  1789.       do
  1790.          ca := code_attribute;
  1791.          cp := constant_pool;
  1792.          jvm.push_target;
  1793.          loc1 := ca.extra_local_size1;
  1794.          ca.opcode_push_integer(nb_bit);
  1795.          ca.opcode_istore(loc1);
  1796.          loc2 := ca.extra_local_size1;
  1797.          idx := type_bit.jvm_push_default;
  1798.          ca.opcode_astore(loc2);
  1799.          ca.opcode_iconst_1;
  1800.          point1 := ca.program_counter;
  1801.          point2 := ca.opcode_ifeq;
  1802.          ca.opcode_iinc(loc1,255);
  1803.          ca.opcode_dup;
  1804.          ca.opcode_iconst_1;
  1805.          ca.opcode_iand;
  1806.          point3 := ca.opcode_ifeq;
  1807.          ca.opcode_aload(loc2);
  1808.          ca.opcode_iload(loc1);
  1809.          idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  1810.          ca.opcode_invokevirtual(idx,-2);
  1811.          ca.resolve_u2_branch(point3);
  1812.          ca.opcode_iconst_1;
  1813.          ca.opcode_iushr;
  1814.          ca.opcode_iload(loc1);
  1815.          ca.opcode_goto_backward(point1);
  1816.          ca.resolve_u2_branch(point2);
  1817.          ca.opcode_pop;
  1818.          ca.opcode_aload(loc2);
  1819.       end;
  1820.  
  1821.    jvm_mapping_bit_function(rf8: RUN_FEATURE_8; name: STRING) is
  1822.       local
  1823.          type_bit: TYPE_BIT;
  1824.          space, idx: INTEGER;
  1825.          point1, point2, point3: INTEGER;
  1826.          loc1, loc2: INTEGER;
  1827.          ca: like code_attribute;
  1828.          cp: like constant_pool;
  1829.       do
  1830.          ca := code_attribute;
  1831.          cp := constant_pool;
  1832.          type_bit ?= rf8.current_type;
  1833.          if as_count = name then
  1834.             jvm.drop_target;
  1835.             ca.opcode_push_integer(type_bit.nb);
  1836.          elseif as_item = name then
  1837.             jvm.push_target;
  1838.             space := jvm.push_ith_argument(1);
  1839.             ca.opcode_iconst_1;
  1840.             ca.opcode_isub;
  1841.             idx := cp.idx_methodref3(fz_a0,fz_a2,fz_a3);
  1842.             ca.opcode_invokevirtual(idx,-1);
  1843.          elseif as_shift_right = name then
  1844.             jvm.push_target;
  1845.             space := jvm.push_ith_argument(1);
  1846.             loc1 := ca.extra_local_size1;
  1847.             loc2 := ca.extra_local_size1;
  1848.             ca.opcode_istore(loc2);
  1849.             space := type_bit.jvm_push_default;
  1850.             ca.opcode_swap;
  1851.             ca.opcode_push_integer(type_bit.nb);
  1852.             ca.opcode_istore(loc1);
  1853.             ca.opcode_iload(loc1);
  1854.             ca.opcode_iload(loc2);
  1855.             ca.opcode_isub;
  1856.             ca.opcode_istore(loc2);
  1857.             ca.opcode_iload(loc2);
  1858.             point1 := ca.program_counter;
  1859.             point2 := ca.opcode_ifeq;
  1860.             ca.opcode_iinc(loc1,255);
  1861.             ca.opcode_iinc(loc2,255);
  1862.             ca.opcode_dup2;
  1863.             ca.opcode_iload(loc2);
  1864.             idx := cp.idx_methodref3(fz_a0,fz_a2,fz_a3);
  1865.             ca.opcode_invokevirtual(idx,-1);
  1866.             point3 := ca.opcode_ifne;
  1867.             ca.opcode_pop;
  1868.             ca.opcode_iload(loc2);
  1869.             ca.opcode_goto_backward(point1);
  1870.             ca.resolve_u2_branch(point3);
  1871.             ca.opcode_iload(loc1);
  1872.             idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  1873.             ca.opcode_invokevirtual(idx,-2);
  1874.             ca.opcode_iload(loc2);
  1875.             ca.opcode_goto_backward(point1);
  1876.             ca.resolve_u2_branch(point2);
  1877.             ca.opcode_pop;
  1878.          elseif as_shift_left = name then
  1879.             jvm.push_target;
  1880.             space := jvm.push_ith_argument(1);
  1881.             loc1 := ca.extra_local_size1;
  1882.             loc2 := ca.extra_local_size1;
  1883.             ca.opcode_istore(loc1);
  1884.             space := type_bit.jvm_push_default;
  1885.             ca.opcode_swap;
  1886.             ca.opcode_push_integer(type_bit.nb);
  1887.             ca.opcode_istore(loc2);
  1888.             ca.opcode_iload(loc2);
  1889.             ca.opcode_iload(loc1);
  1890.             ca.opcode_isub;
  1891.             ca.opcode_istore(loc1);
  1892.             ca.opcode_iload(loc1);
  1893.             point1 := ca.program_counter;
  1894.             point2 := ca.opcode_ifeq;
  1895.             ca.opcode_iinc(loc1,255);
  1896.             ca.opcode_iinc(loc2,255);
  1897.             ca.opcode_dup2;
  1898.             ca.opcode_iload(loc2);
  1899.             idx := cp.idx_methodref3(fz_a0,fz_a2,fz_a3);
  1900.             ca.opcode_invokevirtual(idx,-1);
  1901.             point3 := ca.opcode_ifne;
  1902.             ca.opcode_pop;
  1903.             ca.opcode_iload(loc1);
  1904.             ca.opcode_goto_backward(point1);
  1905.             ca.resolve_u2_branch(point3);
  1906.             ca.opcode_iload(loc1);
  1907.             idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  1908.             ca.opcode_invokevirtual(idx,-2);
  1909.             ca.opcode_iload(loc1);
  1910.             ca.opcode_goto_backward(point1);
  1911.             ca.resolve_u2_branch(point2);
  1912.             ca.opcode_pop;
  1913.          elseif as_xor = name then
  1914.             jvm.push_target;
  1915.             ca.opcode_dup;
  1916.             space := jvm.push_ith_argument(1);
  1917.             idx := cp.idx_methodref3(fz_a0,as_xor,fz_b1);
  1918.             ca.opcode_invokevirtual(idx,0);
  1919.          elseif as_or = name then
  1920.             jvm.push_target;
  1921.             ca.opcode_dup;
  1922.             space := jvm.push_ith_argument(1);
  1923.             idx := cp.idx_methodref3(fz_a0,as_or,fz_b1);
  1924.             ca.opcode_invokevirtual(idx,0);
  1925.          elseif as_not = name then
  1926.             jvm.push_target;
  1927.             loc1 := ca.extra_local_size1;
  1928.             ca.opcode_push_integer(type_bit.nb);
  1929.             ca.opcode_istore(loc1);
  1930.             ca.opcode_iload(loc1);
  1931.             point1 := ca.program_counter;
  1932.             point2 := ca.opcode_ifeq;
  1933.             ca.opcode_iinc(loc1,255);
  1934.             ca.opcode_dup;
  1935.             ca.opcode_iload(loc1);
  1936.             idx := cp.idx_methodref3(fz_a0,fz_a2,fz_a3);
  1937.             ca.opcode_invokevirtual(idx,-1);
  1938.             point3 := ca.opcode_ifne;
  1939.             ca.opcode_dup;
  1940.             ca.opcode_iload(loc1);
  1941.             idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  1942.             ca.opcode_invokevirtual(idx,-2);
  1943.             ca.opcode_iload(loc1);
  1944.             ca.opcode_goto_backward(point1);
  1945.             ca.resolve_u2_branch(point3);
  1946.             ca.opcode_dup;
  1947.             ca.opcode_iload(loc1);
  1948.             idx := cp.idx_methodref3(fz_a0,fz_a5,fz_27);
  1949.             ca.opcode_invokevirtual(idx,-2);
  1950.             ca.opcode_iload(loc1);
  1951.             ca.opcode_goto_backward(point1);
  1952.             ca.resolve_u2_branch(point2);
  1953.          elseif as_and = name then
  1954.             jvm.push_target;
  1955.             ca.opcode_dup;
  1956.             space := jvm.push_ith_argument(1);
  1957.             idx := cp.idx_methodref3(fz_a0,as_and,fz_b1);
  1958.             ca.opcode_invokevirtual(idx,0);
  1959.          elseif as_to_character = name then
  1960.             jvm_bit_to_int(8);
  1961.          elseif as_to_integer = name then
  1962.             jvm_bit_to_int(32);
  1963.          end;
  1964.       end;
  1965.  
  1966.    jvm_mapping_bit_procedure(rf7: RUN_FEATURE_7; name: STRING) is
  1967.       local
  1968.          type_bit: TYPE_BIT;
  1969.          space, idx, point1, point2: INTEGER;
  1970.          ca: like code_attribute;
  1971.          cp: like constant_pool;
  1972.       do
  1973.          ca := code_attribute;
  1974.          cp := constant_pool;
  1975.          type_bit ?= rf7.current_type;
  1976.          if name = as_put_0 then
  1977.             jvm.push_target;
  1978.             space := jvm.push_ith_argument(1);
  1979.             ca.opcode_iconst_1;
  1980.             ca.opcode_isub;
  1981.             idx := cp.idx_methodref3(fz_a0,fz_a5,fz_27);
  1982.             ca.opcode_invokevirtual(idx,-2);
  1983.          elseif name = as_put_1 then
  1984.             jvm.push_target;
  1985.             space := jvm.push_ith_argument(1);
  1986.             ca.opcode_iconst_1;
  1987.             ca.opcode_isub;
  1988.             idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  1989.             ca.opcode_invokevirtual(idx,-2);
  1990.          else
  1991.             check
  1992.                name = as_put
  1993.             end;
  1994.             jvm.push_target;
  1995.             space := jvm.push_ith_argument(1);
  1996.             space := jvm.push_ith_argument(2);
  1997.             ca.opcode_iconst_1;
  1998.             ca.opcode_isub;
  1999.             ca.opcode_swap;
  2000.             point1 := ca.opcode_ifne;
  2001.             idx := cp.idx_methodref3(fz_a0,fz_a5,fz_27);
  2002.             ca.opcode_invokevirtual(idx,-2);
  2003.             point2 := ca.opcode_goto;
  2004.             ca.resolve_u2_branch(point1);
  2005.             idx := cp.idx_methodref3(fz_a0,fz_a4,fz_27);
  2006.             ca.opcode_invokevirtual(idx,-2);
  2007.             ca.resolve_u2_branch(point2);
  2008.          end;
  2009.       end;
  2010.  
  2011.    c_mapping_bit_procedure(rf7: RUN_FEATURE_7; name: STRING) is
  2012.       local
  2013.          type_bit: TYPE_BIT;
  2014.       do
  2015.          type_bit ?= rf7.current_type;
  2016.          if name = as_put_0 then
  2017.             if type_bit.is_c_unsigned_ptr then
  2018.                rf7.default_mapping_procedure;
  2019.             else
  2020.                mapping_small_bit_put_0(type_bit,1);
  2021.             end;
  2022.          elseif name = as_put_1 then
  2023.             if type_bit.is_c_unsigned_ptr then
  2024.                rf7.default_mapping_procedure;
  2025.             else
  2026.                mapping_small_bit_put_1(type_bit,1);
  2027.             end;
  2028.          else
  2029.             check
  2030.                name = as_put
  2031.             end;
  2032.             if type_bit.is_c_unsigned_ptr then
  2033.                rf7.default_mapping_procedure;
  2034.             else
  2035.                cpp.put_string("if(");
  2036.                cpp.put_ith_argument(1);
  2037.                cpp.put_string("){%N");
  2038.                mapping_small_bit_put_1(type_bit,2);
  2039.                cpp.put_string("} else {%N");
  2040.                mapping_small_bit_put_0(type_bit,2);
  2041.                cpp.put_string(fz_12);
  2042.             end;
  2043.          end;
  2044.       end;
  2045.  
  2046.    body_long_bit_put01(type_bit: TYPE_BIT; op1, op2, arg: CHARACTER) is
  2047.       require
  2048.          type_bit.is_c_unsigned_ptr
  2049.       do
  2050.          body.append("{%Nint ib=(CHAR_BIT*sizeof(*C));%N%
  2051.                      %int widx=((");
  2052.          type_bit.unsigned_padding.append_in(body);
  2053.          body.append("+a");
  2054.          body.extend(arg);
  2055.          body.append("-1)/ib);%N%
  2056.                      %int bidx=((a");
  2057.          body.extend(arg);
  2058.          body.append("-1+");
  2059.          type_bit.unsigned_padding.append_in(body);
  2060.          body.append(")%%ib)+1;%N%
  2061.                      %int shift=ib-bidx;%N%
  2062.                      %C[widx]");
  2063.          body.extend(op1);
  2064.          body.append("=(");
  2065.          body.extend(op2);
  2066.          body.append("(((unsigned int)1)<<shift));%N}");
  2067.       end;
  2068.  
  2069.    mapping_small_bit_put01(type_bit: TYPE_BIT; op1, op2: CHARACTER; arg: INTEGER) is
  2070.       require
  2071.          not type_bit.is_c_unsigned_ptr
  2072.       do
  2073.          cpp.put_target_as_value;
  2074.          cpp.put_character(op1);
  2075.          cpp.put_string("=(");
  2076.          cpp.put_character(op2);
  2077.          cpp.put_string("(((unsigned ");
  2078.          if type_bit.is_c_char then
  2079.             cpp.put_string(fz_char);
  2080.          else
  2081.             cpp.put_string(fz_int);
  2082.          end;
  2083.          cpp.put_string(")1)<<(");
  2084.          cpp.put_integer(type_bit.nb);
  2085.          cpp.put_string("-(");
  2086.          cpp.put_ith_argument(arg);
  2087.          cpp.put_string("))));%N");
  2088.       end;
  2089.  
  2090.    mapping_small_bit_put_1(type_bit: TYPE_BIT; arg: INTEGER) is
  2091.       require
  2092.          not type_bit.is_c_unsigned_ptr
  2093.       do
  2094.          mapping_small_bit_put01(type_bit,'|',' ',arg);
  2095.       end;
  2096.  
  2097.    mapping_small_bit_put_0(type_bit: TYPE_BIT; arg: INTEGER) is
  2098.       require
  2099.          not type_bit.is_c_unsigned_ptr
  2100.       do
  2101.          mapping_small_bit_put01(type_bit,'&','~',arg);
  2102.       end;
  2103.  
  2104.    c_mapping_bit_function(rf8: RUN_FEATURE_8; name: STRING) is
  2105.       local
  2106.          type_bit: TYPE_BIT;
  2107.          boost: BOOLEAN;
  2108.       do
  2109.          type_bit ?= rf8.current_type;
  2110.          boost := run_control.boost;
  2111.          if as_count = name then
  2112.             cpp.put_integer(type_bit.nb);
  2113.          elseif as_item = name then
  2114.             if type_bit.is_c_unsigned_ptr then
  2115.                rf8.default_mapping_function;
  2116.             elseif boost then
  2117.                cpp.put_string("(((unsigned int)(");
  2118.                cpp.put_target_as_target;
  2119.                cpp.put_string(")>>(");
  2120.                cpp.put_integer(type_bit.nb);
  2121.                cpp.put_string("-(");
  2122.                cpp.put_arguments;
  2123.                cpp.put_string(")))&1)");
  2124.             else
  2125.                rf8.default_mapping_function;
  2126.             end;
  2127.          elseif as_shift_right = name then
  2128.             if type_bit.is_c_unsigned_ptr then
  2129.                fe_long_bit(rf8);
  2130.             elseif boost then
  2131.                cpp.put_string(fz_17);
  2132.                cpp.put_target_as_target;
  2133.                cpp.put_string(")>>(");
  2134.                cpp.put_ith_argument(1);
  2135.                cpp.put_string(fz_13);
  2136.             else
  2137.                rf8.default_mapping_function;
  2138.             end;
  2139.          elseif as_shift_left = name then
  2140.             if type_bit.is_c_unsigned_ptr then
  2141.                fe_long_bit(rf8);
  2142.             elseif boost then
  2143.                cpp.put_string(fz_17);
  2144.                cpp.put_target_as_target;
  2145.                cpp.put_string(")<<(");
  2146.                cpp.put_ith_argument(1);
  2147.                cpp.put_string(fz_13);
  2148.             else
  2149.                rf8.default_mapping_function;
  2150.             end;
  2151.          elseif as_xor = name then
  2152.             if type_bit.is_c_unsigned_ptr then
  2153.                fe_long_bit(rf8);
  2154.             else
  2155.                cpp.put_character('(');
  2156.                cpp.put_target_as_target;
  2157.                cpp.put_character(')');
  2158.                cpp.put_character('^');
  2159.                cpp.put_character('(');
  2160.                cpp.put_ith_argument(1);
  2161.                cpp.put_character(')');
  2162.             end;
  2163.          elseif as_or = name then
  2164.             if type_bit.is_c_unsigned_ptr then
  2165.                fe_long_bit(rf8);
  2166.             else
  2167.                cpp.put_character('(');
  2168.                cpp.put_target_as_target;
  2169.                cpp.put_character(')');
  2170.                cpp.put_character('|');
  2171.                cpp.put_character('(');
  2172.                cpp.put_ith_argument(1);
  2173.                cpp.put_character(')');
  2174.             end;
  2175.          elseif as_not = name then
  2176.             if type_bit.is_c_unsigned_ptr then
  2177.                fe_long_bit(rf8);
  2178.             else
  2179.                type_bit.mapping_cast
  2180.                cpp.put_character('~');
  2181.                cpp.put_character('(');
  2182.                cpp.put_target_as_target;
  2183.                cpp.put_character(')');
  2184.             end;
  2185.          elseif as_and = name then
  2186.             if type_bit.is_c_unsigned_ptr then
  2187.                fe_long_bit(rf8);
  2188.             else
  2189.                cpp.put_character('(');
  2190.                cpp.put_target_as_target;
  2191.                cpp.put_character(')');
  2192.                cpp.put_character('&');
  2193.                cpp.put_character('(');
  2194.                cpp.put_ith_argument(1);
  2195.                cpp.put_character(')');
  2196.             end;
  2197.          elseif as_to_character = name then
  2198.             cpp.put_target_as_value;
  2199.          elseif as_to_integer = name then
  2200.             cpp.put_target_as_value;
  2201.          end;
  2202.       end;
  2203.  
  2204.    c_define_function_bit(rf8: RUN_FEATURE_8; name: STRING) is
  2205.       local
  2206.          type_bit: TYPE_BIT;
  2207.          no_check: BOOLEAN;
  2208.       do
  2209.          type_bit ?= rf8.current_type;
  2210.          no_check := run_control.no_check;
  2211.          if as_count = name then
  2212.          elseif as_item = name then
  2213.             if type_bit.is_c_unsigned_ptr then
  2214.                body.copy("{int ib=(CHAR_BIT*sizeof(*C));%N%
  2215.                          %int widx=((");
  2216.                type_bit.unsigned_padding.append_in(body);
  2217.                body.append("+a1-1)/ib);%N%
  2218.                            %unsigned int word=(C[widx]);%N%
  2219.                            %int bidx=((a1-1+");
  2220.                type_bit.unsigned_padding.append_in(body);
  2221.                body.append(")%%ib)+1;%N%
  2222.                            %int shift=ib-bidx;%N%
  2223.                            %R=((word>>shift)&1);%N}");
  2224.                rf8.c_define_with_body(body);
  2225.             elseif no_check then
  2226.                body.copy("R=(((unsigned int)C>>(");
  2227.                type_bit.nb.append_in(body);
  2228.                body.append("-a1))&1);%N");
  2229.                rf8.c_define_with_body(body);
  2230.             end;
  2231.          elseif as_shift_left = name then
  2232.             if type_bit.is_c_unsigned_ptr then
  2233.                fe_long_bit(rf8);
  2234.             else
  2235.                rf8.c_define_with_body("R=(C<<a1);");
  2236.             end;
  2237.          elseif as_shift_right = name then
  2238.             if type_bit.is_c_unsigned_ptr then
  2239.                fe_long_bit(rf8);
  2240.             else
  2241.                rf8.c_define_with_body("R=(C>>a1);");
  2242.             end;
  2243.          end;
  2244.       end;
  2245.  
  2246. feature {NONE}
  2247.  
  2248.    unknown_native(rf: RUN_FEATURE) is
  2249.       do
  2250.          eh.add_position(rf.start_position);
  2251.          fatal_error("Unknown native feature.");
  2252.       end;
  2253.  
  2254. end -- NATIVE_SMALL_EIFFEL
  2255.  
  2256.  
  2257.