home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / type_native_array.e < prev    next >
Text File  |  1999-06-05  |  16KB  |  618 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 TYPE_NATIVE_ARRAY
  17.  
  18. inherit TYPE;
  19.  
  20. creation make, make_runnable
  21.  
  22. feature
  23.  
  24.    base_class_name: CLASS_NAME;
  25.  
  26.    generic_list: ARRAY[TYPE];
  27.  
  28.    written_mark: STRING;
  29.  
  30.    run_type: like Current;
  31.          -- Not Void when runnable.
  32.  
  33.    is_expanded: BOOLEAN is true;
  34.  
  35.    is_reference: BOOLEAN is false;
  36.  
  37.    is_generic: BOOLEAN is true;
  38.  
  39.    is_basic_eiffel_expanded: BOOLEAN is false;
  40.  
  41.    is_dummy_expanded: BOOLEAN is false;
  42.  
  43.    is_user_expanded: BOOLEAN is false;
  44.  
  45.    is_array: BOOLEAN is false;
  46.  
  47.    is_none: BOOLEAN is false;
  48.  
  49.    is_any: BOOLEAN is false;
  50.  
  51.    is_like_current: BOOLEAN is false;
  52.  
  53.    is_like_argument: BOOLEAN is false;
  54.  
  55.    is_like_feature: BOOLEAN is false;
  56.  
  57.    jvm_method_flags: INTEGER is 9;
  58.  
  59.    static_base_class_name: CLASS_NAME is
  60.       do
  61.          Result := base_class_name;
  62.       end;
  63.  
  64.    elements_type: TYPE is
  65.       do
  66.          Result := generic_list.first;
  67.       end;
  68.  
  69.    of_references: BOOLEAN is
  70.       do
  71.          Result := elements_type.is_reference;
  72.       end;
  73.  
  74.    smallest_ancestor(other: TYPE): TYPE is
  75.       local
  76.          rto: TYPE;
  77.       do
  78.          rto := other.run_type;
  79.          if rto.is_a(run_type) then
  80.             Result := rto;
  81.          elseif run_type.is_a(rto) then
  82.             Result := run_type;
  83.          else
  84.             Result := type_any;
  85.          end;
  86.          eh.cancel;
  87.       end;
  88.  
  89.    run_time_mark: STRING is
  90.       do
  91.          if is_run_type then
  92.             Result := run_type.written_mark;
  93.          end;
  94.       end;
  95.  
  96.    is_run_type: BOOLEAN is
  97.       local
  98.          et: TYPE;
  99.       do
  100.          if run_type /= Void then
  101.             Result := true;
  102.          else
  103.             et := elements_type;
  104.             if et.is_run_type and then et.run_type = et then
  105.                run_type := Current;
  106.                load_basic_features;
  107.                Result := true;
  108.             end;
  109.          end;
  110.       end;
  111.  
  112.    to_runnable(ct: TYPE): like Current is
  113.       local
  114.          et1, et2: TYPE;
  115.          rt: like Current;
  116.       do
  117.          et1 := elements_type;
  118.          et2 := et1.to_runnable(ct);
  119.          if et2 = Void then
  120.             if et2 /= Void then
  121.                eh.add_position(et2.start_position);
  122.             end;
  123.             eh.add_position(et1.start_position);
  124.             fatal_error(fz_bga);
  125.          end;
  126.          et2 := et2.run_type;
  127.          if run_type = Void then
  128.             Result := Current;
  129.             if et2 = et1 then
  130.                run_type := Current;
  131.                load_basic_features;
  132.             else
  133.                !!run_type.make_runnable(start_position,et2);
  134.                run_type.load_basic_features;
  135.             end;
  136.          elseif et2 = et1 then
  137.             Result := Current;
  138.          else
  139.             Result := twin;
  140.             !!rt.make_runnable(start_position,et2);
  141.             Result.set_run_type(rt);
  142.             rt.load_basic_features;
  143.          end;
  144.       end;
  145.  
  146.    expanded_initializer: RUN_FEATURE_3 is
  147.       do
  148.       end;
  149.  
  150.    start_position: POSITION is
  151.       do
  152.          Result := base_class_name.start_position;
  153.       end;
  154.  
  155.    is_a(other: TYPE): BOOLEAN is
  156.       do
  157.          -- Because of VNCE :
  158.          Result := run_time_mark = other.run_time_mark;
  159.          if not Result then
  160.             eh.add_type(Current,fz_inako);
  161.             eh.add_type(other,fz_dot);
  162.          end;
  163.       end;
  164.  
  165.    has_creation(fn: FEATURE_NAME): BOOLEAN is
  166.       do
  167.       end;
  168.  
  169.    id: INTEGER is
  170.       do
  171.          Result := run_class.id;
  172.       end;
  173.  
  174.    run_class: RUN_CLASS is
  175.       do
  176.          if is_run_type then
  177.             Result := small_eiffel.run_class(run_type);
  178.          end;
  179.       end;
  180.  
  181.    space_for_variable, space_for_object: INTEGER is
  182.       do
  183.          Result := space_for_pointer;
  184.       end;
  185.  
  186.    c_header_pass1 is
  187.       do
  188.          generic_list.first.run_class.c_header_pass1;
  189.       end;
  190.  
  191.    c_header_pass2 is
  192.       local
  193.          et: TYPE;
  194.       do
  195.          generic_list.first.run_class.c_header_pass2;
  196.          et := elements_type.run_type;
  197.          tmp_string.copy(fz_typedef);
  198.          c_type_in(tmp_string);
  199.          tmp_string.extend('T');
  200.          id.append_in(tmp_string);
  201.          tmp_string.append(fz_00);
  202.          cpp.put_string(tmp_string);
  203.       end;
  204.  
  205.    c_header_pass3 is
  206.       do
  207.       end;
  208.  
  209.    c_header_pass4 is
  210.       do
  211.          standard_c_print_function;
  212.       end;
  213.  
  214.    need_c_struct: BOOLEAN is
  215.       do
  216.       end;
  217.  
  218.    c_initialize is
  219.       do
  220.          cpp.put_string(fz_null);
  221.       end;
  222.  
  223.    c_initialize_in(str: STRING) is
  224.       do
  225.          str.append(fz_null);
  226.       end;
  227.  
  228.    c_type_for_argument_in(str: STRING) is
  229.       do
  230.          str.extend('T');
  231.          id.append_in(str);
  232.       end;
  233.  
  234.    c_type_for_target_in(str: STRING) is
  235.       do
  236.          c_type_for_argument_in(str);
  237.       end;
  238.  
  239.    c_type_for_result_in(str: STRING) is
  240.       do
  241.          c_type_for_argument_in(str);
  242.       end;
  243.  
  244.    used_as_reference is
  245.       do
  246.       end;
  247.  
  248.    to_reference is
  249.       do
  250.       end;
  251.  
  252.    jvm_target_descriptor_in, jvm_descriptor_in(str: STRING) is
  253.       do
  254.          str.extend('[');
  255.          elements_type.jvm_descriptor_in(str);
  256.       end;
  257.  
  258.    jvm_return_code is
  259.       do
  260.          code_attribute.opcode_areturn;
  261.       end;
  262.  
  263.    jvm_push_local(offset: INTEGER) is
  264.       do
  265.          code_attribute.opcode_aload(offset);
  266.       end;
  267.  
  268.    jvm_check_class_invariant is
  269.       do
  270.       end;
  271.  
  272.    jvm_push_default: INTEGER is
  273.       do
  274.          code_attribute.opcode_aconst_null;
  275.          Result := 1;
  276.       end;
  277.  
  278.    jvm_write_local(offset: INTEGER) is
  279.       do
  280.          code_attribute.opcode_astore(offset);
  281.       end;
  282.  
  283.    jvm_xnewarray is
  284.       local
  285.          idx: INTEGER;
  286.       do
  287.          tmp_string.clear;
  288.          jvm_target_descriptor_in(tmp_string);
  289.          idx := constant_pool.idx_class2(tmp_string);
  290.          code_attribute.opcode_anewarray(idx);
  291.       end;
  292.  
  293.    jvm_xastore is
  294.       do
  295.          code_attribute.opcode_aastore;
  296.       end;
  297.  
  298.    jvm_xaload is
  299.       do
  300.          code_attribute.opcode_aaload;
  301.       end;
  302.  
  303.    jvm_if_x_eq: INTEGER is
  304.       do
  305.          Result := code_attribute.opcode_if_acmpeq;
  306.       end;
  307.  
  308.    jvm_if_x_ne: INTEGER is
  309.       do
  310.          Result := code_attribute.opcode_if_acmpne;
  311.       end;
  312.  
  313.    jvm_to_reference is
  314.       do
  315.       end;
  316.  
  317.    jvm_expanded_from_reference(other: TYPE): INTEGER is
  318.       do
  319.          check
  320.             false
  321.          end;
  322.       end;
  323.  
  324.    jvm_convert_to(destination: TYPE): INTEGER is
  325.       do
  326.          check
  327.             run_time_mark = destination.run_time_mark
  328.          end;
  329.          Result := 1;
  330.       end;
  331.  
  332.    jvm_standard_is_equal is
  333.       local
  334.          ca: like code_attribute;
  335.          point1, point2: INTEGER;
  336.       do
  337.          ca := code_attribute;
  338.          point1 := jvm_if_x_eq;
  339.          ca.opcode_iconst_0;
  340.          point2 := ca.opcode_goto;
  341.          ca.resolve_u2_branch(point1);
  342.          ca.opcode_iconst_1;
  343.          ca.resolve_u2_branch(point2);
  344.       end;
  345.  
  346. feature {RUN_CLASS,TYPE}
  347.  
  348.    need_gc_mark_function: BOOLEAN is true;
  349.  
  350.    just_before_gc_mark_in(c_code: STRING) is
  351.       do
  352.          c_code.append("if(");
  353.          gc_na_env_in(c_code);
  354.          c_code.append(".store_left>0){%N");
  355.          gc_na_env_in(c_code);
  356.          c_code.append(".store->header.size=");
  357.          gc_na_env_in(c_code);
  358.          c_code.append(".store_left;%N");
  359.          gc_na_env_in(c_code);
  360.          c_code.append(".store->header.magic_flag=RSOH_FREE;%N");
  361.          gc_na_env_in(c_code);
  362.          c_code.append(".store_left=0;%N}%N");
  363.          gc_na_env_in(c_code);
  364.          c_code.append(".chunk_list=NULL;%N");
  365.          gc_na_env_in(c_code);
  366.          c_code.append(".store_chunk=NULL;%N");
  367.       end;
  368.  
  369.    gc_info_in(c_code: STRING) is
  370.       do
  371.          -- Print gc_info_nbXXX :
  372.          c_code.append(fz_printf);
  373.          c_code.extend('(');
  374.          c_code.extend('%"');
  375.          c_code.append(run_time_mark);
  376.          c_code.append(fz_10);
  377.          gc_info_nb_in(c_code);
  378.          c_code.append(fz_14);
  379.       end;
  380.  
  381.    gc_define1 is
  382.       local
  383.          rc: RUN_CLASS;
  384.          rcid: INTEGER;
  385.       do
  386.          rc := run_class;
  387.          rcid := rc.id;
  388.          -- ------------------------------------ Declare na_envXXX :
  389.          header.copy("na_env ");
  390.          gc_na_env_in(header);
  391.          body.copy("{0,NULL,NULL,NULL,(void(*)(T0*))");
  392.          gc_mark_in(body);
  393.          body.extend('}');
  394.          cpp.put_extern5(header,body);
  395.          -- -------------------------------- Declare gc_info_nbXXX :
  396.          if gc_handler.info_flag then
  397.             header.copy(fz_int);
  398.             header.extend(' ');
  399.             gc_info_nb_in(header);
  400.             cpp.put_extern2(header,'0');
  401.          end;
  402.       end;
  403.  
  404.    gc_define2 is
  405.       local
  406.          et: TYPE;
  407.          et_rc: RUN_CLASS;
  408.          rcid: INTEGER;
  409.       do
  410.          et := elements_type;
  411.          et_rc := et.run_class;
  412.          rcid := run_class.id;
  413.          -- ----------------------------- Definiton for gc_markXXX :
  414.          header.copy(fz_void);
  415.          header.extend(' ');
  416.          gc_mark_in(header);
  417.          header.append("(T");
  418.          rcid.append_in(header);
  419.          header.append(" o)");
  420.          body.clear;
  421.          gc_mark(false);
  422.          cpp.put_c_function(header,body);
  423.          -- --------------------------------- Definiton for newXXX :
  424.          header.clear;
  425.          header.extend('T');
  426.          rcid.append_in(header);
  427.          header.extend(' ');
  428.          header.append(fz_new);
  429.          rcid.append_in(header);
  430.          header.append("(int size)");
  431.          body.clear;
  432.          body.append("size=(size*sizeof(");
  433.          et.c_type_for_result_in(body);
  434.          body.append("))+sizeof(rsoh);%N%
  435.                      %if((size%%sizeof(double))!=0)%
  436.                      %size+=(sizeof(double)-(size%%sizeof(double)));%N");
  437.          if gc_handler.info_flag then
  438.             gc_info_nb_in(body);
  439.             body.append("++;%N");
  440.          end;
  441.          body.append("if (size<=(");
  442.          gc_na_env_in(body);
  443.          body.append(".store_left)){%N%
  444.                      %rsoh*r=");
  445.          gc_na_env_in(body);
  446.          body.append(".store;%N");
  447.          gc_na_env_in(body);
  448.          body.append(".store_left-=size;%N%
  449.                      %if(");
  450.          gc_na_env_in(body);
  451.          body.append(".store_left>sizeof(rsoh)){%N%
  452.                       %r->header.size=size;%N");
  453.          gc_na_env_in(body);
  454.          body.append(".store=((rsoh*)(((char*)(");
  455.          gc_na_env_in(body);
  456.          body.append(".store))+size));%N}%N%
  457.                      %else {%N%
  458.                      %r->header.size=size+");
  459.          gc_na_env_in(body);
  460.          body.append(".store_left;%N");
  461.          gc_na_env_in(body);
  462.          body.append(
  463.             ".store_left=0;%N}%N%
  464.             %(r->header.magic_flag)=RSOH_UNMARKED;%N%
  465.             %((void)memset((r+1),0,r->header.size-sizeof(rsoh)));%N%
  466.             %return (void*)(r+1);%N}%N%
  467.             %return (void*)new_na(&");
  468.          gc_na_env_in(body);
  469.          body.append(",size);%N");
  470.          cpp.put_c_function(header,body);
  471.       end;
  472.  
  473. feature {TYPE_NATIVE_ARRAY}
  474.  
  475.    set_run_type(t: like run_type) is
  476.       do
  477.          run_type := t;
  478.       end;
  479.  
  480.    load_basic_features is
  481.          -- Force some basic feature to be loaded.
  482.       require
  483.          run_type = Current
  484.       local
  485.          et: TYPE;
  486.          rf: RUN_FEATURE;
  487.          rc: RUN_CLASS;
  488.       do
  489.          rc := run_class;
  490.          rc.set_at_run_time;
  491.          et := elements_type;
  492.          if et.is_expanded then
  493.             et.run_class.set_at_run_time;
  494.          end;
  495.          rf := rc.get_feature_with(as_item);
  496.          rf := rc.get_feature_with(as_put);
  497.          if et.expanded_initializer /= Void then
  498.             rf := rc.get_feature_with(as_clear_all);
  499.          end;
  500.       end;
  501.  
  502. feature {NONE}
  503.  
  504.    c_type_in(str: STRING) is
  505.       local
  506.          et: TYPE;
  507.       do
  508.          et := elements_type;
  509.          str.extend('T');
  510.          if et.is_reference then
  511.             str.extend('0');
  512.             str.extend('*');
  513.          else
  514.             et.id.append_in(str);
  515.          end;
  516.          str.extend('*');
  517.       end;
  518.  
  519. feature {NONE}
  520.  
  521.    gc_mark(is_unmarked: BOOLEAN) is
  522.          -- The main purpose is to compute for example the best
  523.          -- body for the gc_markXXX function. In fact, this
  524.          -- feature may be called to produce C code when C variable
  525.          -- `o' is not NULL.
  526.          -- Finally, when `is_unmarked' is true, object `o' is unmarked.
  527.       require
  528.          not gc_handler.is_off;
  529.          is_native_array;
  530.          run_class.at_run_time
  531.       local
  532.          et: TYPE;
  533.          et_rc: RUN_CLASS;
  534.       do
  535.          et := elements_type;
  536.          et_rc := et.run_class;
  537.          if et.need_gc_mark_function then
  538.             body.append(
  539.                "rsoh*h=((rsoh*)o)-1;%N");
  540.             if not is_unmarked then
  541.                body.append(
  542.                   "if((h->header.magic_flag)==RSOH_UNMARKED){%N");
  543.             end;
  544.             body.append(
  545.                "h->header.magic_flag=RSOH_MARKED;%N");
  546.             body.extend('{');
  547.             c_type_in(body);
  548.             body.remove_last(1);
  549.             body.extend(' ');
  550.             body.extend('e');
  551.             body.append(fz_00);
  552.             c_type_in(body);
  553.             body.append(
  554.                "p=((void*)(o+((((h->header.size)-sizeof(rsoh))/sizeof(e))-1)));%N%
  555.                %for(;((void*)p)>=((void*)o);p--){%N%
  556.                %e=*p;%N");
  557.             gc_handler.mark_for(body,"e",et_rc);
  558.             body.append("%N}%N}%N");
  559.             if not is_unmarked then
  560.                body.extend('}');
  561.             end;
  562.          else
  563.             body.append(
  564.                "(((rsoh*)o)-1)->header.magic_flag=RSOH_MARKED;%N");
  565.          end;
  566.       end;
  567.  
  568. feature {NONE}
  569.  
  570.    frozen gc_na_env_in(str: STRING) is
  571.       do
  572.          str.append("na_env");
  573.          id.append_in(str);
  574.       end;
  575.  
  576. feature {TYPE}
  577.  
  578.    frozen short_hook is
  579.       do
  580.          short_print.a_class_name(base_class_name);
  581.          short_print.hook_or("open_sb","[");
  582.          generic_list.first.short_hook;
  583.          short_print.hook_or("close_sb","]");
  584.       end;
  585.  
  586. feature {NONE}
  587.  
  588.    make(sp: like start_position; of_what: TYPE) is
  589.       require
  590.          sp /= Void;
  591.          of_what /= Void
  592.       do
  593.          !!base_class_name.make(as_native_array,sp);
  594.          generic_list := <<of_what>>;
  595.          tmp_string.copy(as_native_array);
  596.          tmp_string.extend('[');
  597.          tmp_string.append(of_what.written_mark);
  598.          tmp_string.extend(']');
  599.          written_mark := string_aliaser.item(tmp_string);
  600.       ensure
  601.          start_position = sp
  602.       end;
  603.  
  604.    make_runnable(sp: like start_position; of_what: TYPE) is
  605.       require
  606.          sp /= Void;
  607.          of_what.run_type = of_what
  608.       do
  609.          make(sp,of_what);
  610.          run_type := Current;
  611.       ensure
  612.          is_run_type;
  613.          written_mark = run_time_mark
  614.       end;
  615.  
  616. end -- TYPE_NATIVE_ARRAY
  617.  
  618.