home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / code_attribute.e < prev    next >
Text File  |  1999-06-05  |  34KB  |  1,560 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 CODE_ATTRIBUTE
  17.    --
  18.    -- Unique Global Object in charge of a Code_attribute as
  19.    -- describe in the JVM specification.
  20.    -- Obviously, the same object is recycled for all code part.
  21.    --
  22. inherit GLOBALS;
  23.  
  24. feature {NONE}
  25.  
  26.    code: FIXED_ARRAY[INTEGER] is
  27.       once
  28.          !!Result.with_capacity(1024);
  29.       end;
  30.  
  31.    max_stack: INTEGER;
  32.          -- To compute the maximum size of the operand stack.
  33.  
  34.    max_locals: INTEGER;
  35.  
  36. feature
  37.  
  38.    stack_level: INTEGER;
  39.          -- Used to compute `max_stack';
  40.  
  41. feature {METHOD_INFO}
  42.  
  43.    clear is
  44.       do
  45.          code.clear;
  46.          exception_table.clear;
  47.          max_stack := 0;
  48.          stack_level := 0;
  49.          max_locals := jvm.max_locals;
  50.       end;
  51.  
  52.    store_in(storage: STRING) is
  53.       local
  54.          i: INTEGER;
  55.       do
  56.          append_u2(storage,constant_pool.idx_constant_utf8);
  57.          check
  58.             program_counter > 0
  59.          end;
  60.          append_u4(storage,12 + program_counter);
  61.          append_u2(storage,max_stack);
  62.          append_u2(storage,max_locals);
  63.          append_u4(storage,program_counter);
  64.          from
  65.             i := 0
  66.          until
  67.             i > code.upper
  68.          loop
  69.             append_u1(storage,code.item(i));
  70.             i := i + 1;
  71.          end;
  72.          exception_table.store_in(storage);
  73.          -- attribute_count :
  74.          append_u2(storage,0);
  75.       end;
  76.  
  77. feature
  78.  
  79.    program_counter: INTEGER is
  80.       do
  81.          Result := code.count;
  82.       end;
  83.  
  84.    extra_local(local_type: TYPE): INTEGER is
  85.       require
  86.          local_type.is_run_type
  87.       do
  88.          Result := max_locals;
  89.          max_locals := max_locals + local_type.jvm_stack_space;
  90.       end;
  91.  
  92.    extra_local_size1: INTEGER is
  93.       do
  94.          Result := max_locals;
  95.          max_locals := max_locals + 1;
  96.       end;
  97.  
  98. feature -- opcode feature list :
  99.  
  100.    opcode_nop is
  101.       do
  102.          opcode(0,0);
  103.       end;
  104.  
  105.    opcode_aconst_null is
  106.       do
  107.          opcode(1,1);
  108.       end;
  109.  
  110.    opcode_iconst_m1 is
  111.       do
  112.          opcode(2,1);
  113.       end;
  114.  
  115.    opcode_iconst_0 is
  116.       do
  117.          opcode(3,1);
  118.       end;
  119.  
  120.    opcode_iconst_1 is
  121.       do
  122.          opcode(4,1);
  123.       end;
  124.  
  125.    opcode_iconst_i(n: INTEGER) is
  126.       require
  127.          -1 <= n;
  128.          n <= 5
  129.       do
  130.          opcode(3 + n,1);
  131.       end;
  132.  
  133.    opcode_fconst_0 is
  134.       do
  135.          opcode(11,1);
  136.       end;
  137.  
  138.    opcode_dconst_0 is
  139.       do
  140.          opcode(14,2);
  141.       end;
  142.  
  143.    opcode_bipush(byte: INTEGER) is
  144.          -- Sign-extended value.
  145.       require
  146.          byte.in_range(0,255)
  147.       do
  148.          opcode(16,1);
  149.          add_u1(byte);
  150.       end;
  151.  
  152.    opcode_sipush(u2: INTEGER) is
  153.       require
  154.          -32768 <= u2;
  155.          u2 <= 32767;
  156.          (u2 < -128 or 127 < u2)
  157.       do
  158.          opcode(17,1);
  159.          add_u2(u2);
  160.       end;
  161.  
  162.    opcode_ldc(idx: INTEGER) is
  163.          -- For both ldc and ldc_w.
  164.       require
  165.          constant_pool.valid_index(idx)
  166.       do
  167.          if idx < 255 then
  168.             opcode(18,1);
  169.             add_u1(idx);
  170.          else
  171.             opcode(19,1);
  172.             add_u2(idx);
  173.          end;
  174.       end;
  175.  
  176.    opcode_fload(index: INTEGER) is
  177.       require
  178.          0 <= index;
  179.          index <= 255
  180.       do
  181.          if index <= 3 then
  182.             opcode(34 + index,1);
  183.          else
  184.             opcode(23,1);
  185.             add_u1(index);
  186.          end;
  187.       end;
  188.  
  189.    opcode_dload_0 is
  190.       do
  191.          opcode(38,2);
  192.       end;
  193.  
  194.    opcode_dload(index: INTEGER) is
  195.       require
  196.          0 <= index;
  197.          index <= 255
  198.       do
  199.          if index <= 3 then
  200.             opcode(38 + index,2);
  201.          else
  202.             opcode(24,2);
  203.             add_u1(index);
  204.          end;
  205.       end;
  206.  
  207.    opcode_aload(index: INTEGER) is
  208.       require
  209.          0 <= index;
  210.          index <= 255
  211.       do
  212.          if index <= 3 then
  213.             opcode(42 + index,1);
  214.          else
  215.             opcode(25,1);
  216.             add_u1(index);
  217.          end;
  218.       end;
  219.  
  220.    opcode_iload_1 is
  221.       do
  222.          opcode(27,1);
  223.       end;
  224.  
  225.    opcode_iload_3 is
  226.       do
  227.          opcode(29,1);
  228.       end;
  229.  
  230.    opcode_iload(index: INTEGER) is
  231.       require
  232.          0 <= index;
  233.          index <= 255
  234.       do
  235.          if index <= 3 then
  236.             opcode(26 + index,1);
  237.          else
  238.             opcode(21,1);
  239.             add_u1(index);
  240.          end;
  241.       end;
  242.  
  243.    opcode_aload_0 is
  244.       do
  245.          opcode(42,1);
  246.       end;
  247.  
  248.    opcode_aload_1 is
  249.       do
  250.          opcode(43,1);
  251.       end;
  252.  
  253.    opcode_aload_2 is
  254.       do
  255.          opcode(44,1);
  256.       end;
  257.  
  258.    opcode_aload_3 is
  259.       do
  260.          opcode(45,1);
  261.       end;
  262.  
  263.    opcode_iaload is
  264.       do
  265.          opcode(46,-1);
  266.       end;
  267.  
  268.    opcode_laload is
  269.       do
  270.          opcode(47,0);
  271.       end;
  272.  
  273.    opcode_faload is
  274.       do
  275.          opcode(48,-1);
  276.       end;
  277.  
  278.    opcode_daload is
  279.       do
  280.          opcode(49,0);
  281.       end;
  282.  
  283.    opcode_aaload is
  284.       do
  285.          opcode(50,-1);
  286.       end;
  287.  
  288.    opcode_baload is
  289.       do
  290.          opcode(51,-1);
  291.       end;
  292.  
  293.    opcode_caload is
  294.       do
  295.          opcode(52,-1);
  296.       end;
  297.  
  298.    opcode_saload is
  299.       do
  300.          opcode(53,-1);
  301.       end;
  302.  
  303.    opcode_istore_3 is
  304.       do
  305.          opcode(62,-1);
  306.       end;
  307.  
  308.    opcode_istore(offset: INTEGER) is
  309.       require
  310.          0 <= offset;
  311.          offset <= 255
  312.       do
  313.          if offset <= 3 then
  314.             opcode(59 + offset,-1);
  315.          else
  316.             opcode(54,-1);
  317.             add_u1(offset);
  318.          end;
  319.       end;
  320.  
  321.    opcode_fstore(offset: INTEGER) is
  322.       require
  323.          0 <= offset;
  324.          offset <= 255
  325.       do
  326.          if offset <= 3 then
  327.             opcode(67 + offset,-1);
  328.          else
  329.             opcode(56,-1);
  330.             add_u1(offset);
  331.          end;
  332.       end;
  333.  
  334.    opcode_dstore(offset: INTEGER) is
  335.       require
  336.          0 <= offset;
  337.          offset <= 255
  338.       do
  339.          if offset <= 3 then
  340.             opcode(71 + offset,-1);
  341.          else
  342.             opcode(57,-1);
  343.             add_u1(offset);
  344.          end;
  345.       end;
  346.  
  347.    opcode_astore_0 is
  348.       do
  349.          opcode(75,-1);
  350.       end;
  351.  
  352.    opcode_astore_1 is
  353.       do
  354.          opcode(76,-1);
  355.       end;
  356.  
  357.    opcode_astore_2 is
  358.       do
  359.          opcode(77,-1);
  360.       end;
  361.  
  362.    opcode_astore_3 is
  363.       do
  364.          opcode(78,-1);
  365.       end;
  366.  
  367.    opcode_astore(offset: INTEGER) is
  368.       require
  369.          0 <= offset;
  370.          offset <= 255
  371.       do
  372.          if offset <= 3 then
  373.             opcode(75 + offset,-1);
  374.          else
  375.             opcode(58,-1);
  376.             add_u1(offset);
  377.          end;
  378.       end;
  379.  
  380.    opcode_iastore is
  381.       do
  382.          opcode(79,-3);
  383.       end;
  384.  
  385.    opcode_fastore is
  386.       do
  387.          opcode(81,-3);
  388.       end;
  389.  
  390.    opcode_dastore is
  391.       do
  392.          opcode(82,-4);
  393.       end;
  394.  
  395.    opcode_aastore is
  396.       do
  397.          opcode(83,-3);
  398.       end;
  399.  
  400.    opcode_bastore is
  401.       do
  402.          opcode(84,-3);
  403.       end;
  404.  
  405.    opcode_pop is
  406.       do
  407.          opcode(87,-1);
  408.       end;
  409.  
  410.    opcode_pop2 is
  411.       do
  412.          opcode(88,-2);
  413.       end;
  414.  
  415.    opcode_dup is
  416.       do
  417.          opcode(89,1);
  418.       end;
  419.  
  420.    opcode_dup_x1 is
  421.       do
  422.          opcode(90,1);
  423.       end;
  424.  
  425.    opcode_dup_x2 is
  426.       do
  427.          opcode(91,1);
  428.       end;
  429.  
  430.    opcode_dup2 is
  431.       do
  432.          opcode(92,2);
  433.       end;
  434.  
  435.    opcode_dup2_x1 is
  436.       do
  437.          opcode(93,2);
  438.       end;
  439.  
  440.    opcode_swap is
  441.       do
  442.          opcode(95,0);
  443.       end;
  444.  
  445.    opcode_iadd is
  446.       do
  447.          opcode(96,-1);
  448.       end;
  449.  
  450.    opcode_fadd is
  451.       do
  452.          opcode(98,-1);
  453.       end;
  454.  
  455.    opcode_dadd is
  456.       do
  457.          opcode(99,-2);
  458.       end;
  459.  
  460.    opcode_isub is
  461.       do
  462.          opcode(100,-1);
  463.       end;
  464.  
  465.    opcode_fsub is
  466.       do
  467.          opcode(102,-1);
  468.       end;
  469.  
  470.    opcode_dsub is
  471.       do
  472.          opcode(103,-2);
  473.       end;
  474.  
  475.    opcode_imul is
  476.       do
  477.          opcode(104,-1);
  478.       end;
  479.  
  480.    opcode_fmul is
  481.       do
  482.          opcode(106,-1);
  483.       end;
  484.  
  485.    opcode_dmul is
  486.       do
  487.          opcode(107,-2);
  488.       end;
  489.  
  490.    opcode_idiv is
  491.       do
  492.          opcode(108,-1);
  493.       end;
  494.  
  495.    opcode_fdiv is
  496.       do
  497.          opcode(110,-1);
  498.       end;
  499.  
  500.    opcode_ddiv is
  501.       do
  502.          opcode(111,-2);
  503.       end;
  504.  
  505.    opcode_irem is
  506.       do
  507.          opcode(112,-1);
  508.       end;
  509.  
  510.    opcode_ineg is
  511.       do
  512.          opcode(116,0);
  513.       end;
  514.  
  515.    opcode_fneg is
  516.       do
  517.          opcode(118,0);
  518.       end;
  519.  
  520.    opcode_dneg is
  521.       do
  522.          opcode(119,0);
  523.       end;
  524.  
  525.    opcode_ishl is
  526.       do
  527.          opcode(120,-1);
  528.       end;
  529.  
  530.    opcode_ishr is
  531.       do
  532.          opcode(122,-1);
  533.       end;
  534.  
  535.    opcode_iushr is
  536.       do
  537.          opcode(124,-1);
  538.       end;
  539.  
  540.    opcode_iand is
  541.       do
  542.          opcode(126,-1);
  543.       end;
  544.  
  545.    opcode_ior is
  546.       do
  547.          opcode(128,-1);
  548.       end;
  549.  
  550.    opcode_ixor is
  551.       do
  552.          opcode(130,-1);
  553.       end;
  554.  
  555.    opcode_iinc(loc_idx, u1_increment: INTEGER) is
  556.       do
  557.          opcode(132,0);
  558.          add_u1(loc_idx);
  559.          add_u1(u1_increment);
  560.       end;
  561.  
  562.    opcode_i2f is
  563.       do
  564.          opcode(134,0);
  565.       end;
  566.  
  567.    opcode_i2d is
  568.       do
  569.          opcode(135,1);
  570.       end;
  571.  
  572.    opcode_f2i is
  573.       do
  574.          opcode(139,0);
  575.       end;
  576.  
  577.    opcode_f2d is
  578.       do
  579.          opcode(141,1);
  580.       end;
  581.  
  582.    opcode_d2i is
  583.       do
  584.          opcode(142,-1);
  585.       end;
  586.  
  587.    opcode_d2f is
  588.       do
  589.          opcode(144,-1);
  590.       end;
  591.  
  592.    opcode_i2b is
  593.       do
  594.          opcode(145,0);
  595.       end;
  596.  
  597.    opcode_fcmpg is
  598.       do
  599.          opcode(150,-1);
  600.       end;
  601.  
  602.    opcode_fcmpl is
  603.       do
  604.          opcode(149,-1);
  605.       end;
  606.  
  607.    opcode_dcmpl is
  608.       do
  609.          opcode(151,-3);
  610.       end;
  611.  
  612.    opcode_dcmpg is
  613.       do
  614.          opcode(152,-3);
  615.       end;
  616.  
  617.    opcode_ifeq: INTEGER is
  618.       do
  619.          opcode(153,-1);
  620.          Result := skip_2_bytes;
  621.       end;
  622.  
  623.    opcode_ifne: INTEGER is
  624.       do
  625.          opcode(154,-1);
  626.          Result := skip_2_bytes;
  627.       end;
  628.  
  629.    opcode_iflt: INTEGER is
  630.       do
  631.          opcode(155,-1);
  632.          Result := skip_2_bytes;
  633.       end;
  634.  
  635.    opcode_ifge: INTEGER is
  636.       do
  637.          opcode(156,-1);
  638.          Result := skip_2_bytes;
  639.       end;
  640.  
  641.    opcode_ifgt: INTEGER is
  642.       do
  643.          opcode(157,-1);
  644.          Result := skip_2_bytes;
  645.       end;
  646.  
  647.    opcode_ifle: INTEGER is
  648.       do
  649.          opcode(158,-1);
  650.          Result := skip_2_bytes;
  651.       end;
  652.  
  653.    opcode_if_icmpeq: INTEGER is
  654.       do
  655.          opcode(159,-2);
  656.          Result := skip_2_bytes;
  657.       end;
  658.  
  659.    opcode_if_icmpne: INTEGER is
  660.       do
  661.          opcode(160,-2);
  662.          Result := skip_2_bytes;
  663.       end;
  664.  
  665.    opcode_if_icmplt: INTEGER is
  666.       do
  667.          opcode(161,-2);
  668.          Result := skip_2_bytes;
  669.       end;
  670.  
  671.    opcode_if_icmpge: INTEGER is
  672.       do
  673.          opcode(162,-2);
  674.          Result := skip_2_bytes;
  675.       end;
  676.  
  677.    opcode_if_icmpgt: INTEGER is
  678.       do
  679.          opcode(163,-2);
  680.          Result := skip_2_bytes;
  681.       end;
  682.  
  683.    opcode_if_icmple: INTEGER is
  684.       do
  685.          opcode(164,-2);
  686.          Result := skip_2_bytes;
  687.       end;
  688.  
  689.    opcode_if_acmpeq: INTEGER is
  690.       do
  691.          opcode(165,-2);
  692.          Result := skip_2_bytes;
  693.       end;
  694.  
  695.    opcode_if_acmpne: INTEGER is
  696.       do
  697.          opcode(166,-2);
  698.          Result := skip_2_bytes;
  699.       end;
  700.  
  701.    opcode_goto: INTEGER is
  702.       do
  703.          opcode(167,0);
  704.          Result := skip_2_bytes;
  705.       end;
  706.  
  707.    opcode_goto_backward(back_point: INTEGER) is
  708.          -- Produce a goto opcode to go back at `back_point'.
  709.       require
  710.          back_point < program_counter
  711.       local
  712.          r, q, offset: INTEGER;
  713.       do
  714.          offset := program_counter - back_point;
  715.          opcode(167,0);
  716.          r := offset \\ 256;
  717.          q := offset // 256;
  718.          if r = 0 then
  719.             add_u1(256 - q);
  720.             add_u1(0);
  721.          else
  722.             add_u1(255 - q);
  723.             add_u1(256 - r);
  724.          end;
  725.       end;
  726.  
  727.    opcode_ireturn is
  728.       do
  729.          add_u1(172);
  730.       end;
  731.  
  732.    opcode_lreturn is
  733.       do
  734.          add_u1(173);
  735.       end;
  736.  
  737.    opcode_freturn is
  738.       do
  739.          add_u1(174);
  740.       end;
  741.  
  742.    opcode_dreturn is
  743.       do
  744.          add_u1(175);
  745.       end;
  746.  
  747.    opcode_areturn is
  748.       do
  749.          add_u1(176);
  750.       end;
  751.  
  752.    opcode_return is
  753.       do
  754.          add_u1(177);
  755.       end;
  756.  
  757.    opcode_getstatic(fieldref_idx, stack_inc: INTEGER) is
  758.       require
  759.          constant_pool.valid_index(fieldref_idx)
  760.       do
  761.          opcode(178,stack_inc);
  762.          add_u2(fieldref_idx);
  763.       end;
  764.  
  765.    opcode_putstatic(fieldref_idx, stack_inc: INTEGER) is
  766.       require
  767.          constant_pool.valid_index(fieldref_idx)
  768.       do
  769.          opcode(179,stack_inc);
  770.          add_u2(fieldref_idx);
  771.       end;
  772.  
  773.    opcode_getfield(fieldref_idx, stack_inc: INTEGER) is
  774.       require
  775.          constant_pool.valid_index(fieldref_idx)
  776.       do
  777.          opcode(180,stack_inc);
  778.          add_u2(fieldref_idx);
  779.       end;
  780.  
  781.    opcode_putfield(fieldref_idx, stack_inc: INTEGER) is
  782.       require
  783.          constant_pool.valid_index(fieldref_idx)
  784.       do
  785.          opcode(181,stack_inc);
  786.          add_u2(fieldref_idx);
  787.       end;
  788.  
  789.    opcode_invokevirtual(methodref_idx, stack_inc: INTEGER) is
  790.       require
  791.          constant_pool.is_methodref(methodref_idx)
  792.       do
  793.          opcode(182,stack_inc);
  794.          add_u2(methodref_idx);
  795.       end;
  796.  
  797.    opcode_invokespecial(methodref_idx, stack_inc: INTEGER) is
  798.       require
  799.          constant_pool.is_methodref(methodref_idx)
  800.       do
  801.          opcode(183,stack_inc);
  802.          add_u2(methodref_idx);
  803.       end;
  804.  
  805.    opcode_invokestatic(methodref_idx, stack_inc: INTEGER) is
  806.       require
  807.          constant_pool.is_methodref(methodref_idx)
  808.       do
  809.          opcode(184,stack_inc);
  810.          add_u2(methodref_idx);
  811.       end;
  812.  
  813.    opcode_new(class_idx: INTEGER) is
  814.       require
  815.          constant_pool.is_class(class_idx)
  816.       do
  817.          opcode(187,1);
  818.          add_u2(class_idx);
  819.       end;
  820.  
  821.    opcode_newarray(u1: INTEGER) is
  822.       require
  823.          4 <= u1;
  824.          u1 <= 10
  825.       do
  826.          opcode(188,0);
  827.          add_u1(u1);
  828.       end;
  829.  
  830.    opcode_anewarray(idx: INTEGER) is
  831.       require
  832.          constant_pool.valid_index(idx)
  833.       do
  834.          opcode(189,0);
  835.          add_u2(idx);
  836.       end;
  837.  
  838.    opcode_arraylength is
  839.       do
  840.          opcode(190,0);
  841.       end;
  842.  
  843.    opcode_athrow is
  844.       do
  845.          opcode(191,0);
  846.       end;
  847.  
  848. feature {RUN_CLASS,NATIVE_SMALL_EIFFEL}
  849.  
  850.    opcode_checkcast(class_idx: INTEGER) is
  851.       require
  852.          constant_pool.is_class(class_idx)
  853.       do
  854.          opcode(192,0);
  855.          add_u2(class_idx);
  856.       end;
  857.  
  858. feature {RUN_CLASS}
  859.  
  860.    opcode_instanceof(class_idx: INTEGER) is
  861.       require
  862.          constant_pool.is_class(class_idx)
  863.       do
  864.          opcode(193,0);
  865.          add_u2(class_idx);
  866.       end;
  867.  
  868. feature
  869.  
  870.    opcode_ifnull: INTEGER is
  871.       do
  872.          opcode(198,-1);
  873.          Result := skip_2_bytes;
  874.       end;
  875.  
  876.    opcode_ifnonnull: INTEGER is
  877.       do
  878.          opcode(199,-1);
  879.          Result := skip_2_bytes;
  880.       end;
  881.  
  882. feature -- High level opcode calls :
  883.  
  884.    opcode_push_integer(i: INTEGER) is
  885.       do
  886.          if i < -32768 then
  887.             push_strange_integer(i);
  888.          elseif i < -128 then
  889.             opcode_sipush(i);
  890.          elseif i < -1 then
  891.             opcode_bipush(256 + i);
  892.          elseif i <= 5 then
  893.             opcode_iconst_i(i);
  894.          elseif i <= 127 then
  895.             opcode_bipush(i);
  896.          elseif i <= 32767 then
  897.             opcode_sipush(i);
  898.          else
  899.             push_strange_integer(i);
  900.          end;
  901.       end;
  902.  
  903.    opcode_push_as_float(str: STRING) is
  904.       require
  905.          str.count >= 1
  906.       do
  907.          inspect
  908.             str.item(1)
  909.          when '0' then
  910.             if str.count = 1 then
  911.                opcode(11,1);
  912.             else
  913.                inspect
  914.                   str.item(2)
  915.                when '.' then
  916.                   if str.count = 2 then
  917.                      opcode(11,1);
  918.                   elseif str.count = 3 and then str.item(3) = '0' then
  919.                      opcode(11,1);
  920.                   else
  921.                      opcode_string2float(str);
  922.                   end;
  923.                else
  924.                   opcode_string2float(str);
  925.                end;
  926.             end;
  927.          when '1' then
  928.             if str.count = 1 then
  929.                opcode(12,1);
  930.             else
  931.                inspect
  932.                   str.item(2)
  933.                when '.' then
  934.                   if str.count = 2 then
  935.                      opcode(12,1);
  936.                   elseif str.count = 3 and then str.item(3) = '0' then
  937.                      opcode(12,1);
  938.                   else
  939.                      opcode_string2float(str);
  940.                   end;
  941.                else
  942.                   opcode_string2float(str);
  943.                end;
  944.             end;
  945.          when '2' then
  946.             if str.count = 1 then
  947.                opcode(13,1);
  948.             else
  949.                inspect
  950.                   str.item(2)
  951.                when '.' then
  952.                   if str.count = 2 then
  953.                      opcode(13,1);
  954.                   elseif str.count = 3 and then str.item(3) = '0' then
  955.                      opcode(13,1);
  956.                   else
  957.                      opcode_string2float(str);
  958.                   end;
  959.                else
  960.                   opcode_string2float(str);
  961.                end;
  962.             end;
  963.          else
  964.             opcode_string2float(str);
  965.          end;
  966.       end;
  967.  
  968.    opcode_push_as_double(str: STRING) is
  969.       require
  970.          str.count >= 1
  971.       do
  972.          inspect
  973.             str.item(1)
  974.          when '0' then
  975.             if str.count = 1 then
  976.                opcode(14,2);
  977.             else
  978.                inspect
  979.                   str.item(2)
  980.                when '.' then
  981.                   if str.count = 2 then
  982.                      opcode(14,2);
  983.                   elseif str.count = 3 and then str.item(3) = '0' then
  984.                      opcode(14,2);
  985.                   else
  986.                      opcode_string2double(str);
  987.                   end;
  988.                else
  989.                   opcode_string2double(str);
  990.                end;
  991.             end;
  992.          when '1' then
  993.             if str.count = 1 then
  994.                opcode(15,2);
  995.             else
  996.                inspect
  997.                   str.item(2)
  998.                when '.' then
  999.                   if str.count = 2 then
  1000.                      opcode(15,2);
  1001.                   elseif str.count = 3 and then str.item(3) = '0' then
  1002.                      opcode(15,2);
  1003.                   else
  1004.                      opcode_string2double(str);
  1005.                   end;
  1006.                else
  1007.                   opcode_string2double(str);
  1008.                end;
  1009.             end;
  1010.          else
  1011.             opcode_string2double(str);
  1012.          end;
  1013.       end;
  1014.  
  1015.    opcode_push_manifest_string(ms: STRING) is
  1016.          -- Produces code to push the corresponding Eiffel STRING.
  1017.       local
  1018.          ms_idx: INTEGER;
  1019.       do
  1020.          ms_idx := constant_pool.idx_string2(ms);
  1021.          opcode_ldc(ms_idx);
  1022.          opcode_java_string2eiffel_string;
  1023.       end;
  1024.  
  1025.    opcode_java_string2bytes_array is
  1026.          -- Used the pushed Java String to create the bytes array.
  1027.       local
  1028.          idx: INTEGER;
  1029.       do
  1030.          idx := constant_pool.idx_methodref3(fz_32,fz_33,fz_34);
  1031.          opcode_invokevirtual(idx,0);
  1032.       end;
  1033.  
  1034.    opcode_java_string2eiffel_string is
  1035.          -- Used the pushed Java String to create a new Eiffel STRING.
  1036.       do
  1037.          opcode_java_string2bytes_array;
  1038.          opcode_bytes_array2eiffel_string;
  1039.       end;
  1040.  
  1041.    opcode_bytes_array2eiffel_string is
  1042.          -- Used the pushed Bytes array to create a new Eiffel STRING.
  1043.       local
  1044.          cp: like constant_pool;
  1045.          loc: INTEGER;
  1046.          rc_string: RUN_CLASS;
  1047.       do
  1048.          cp := constant_pool;
  1049.          rc_string := type_string.run_class;
  1050.          loc := extra_local_size1;
  1051.          opcode_astore(loc);
  1052.          -- The new STRING :
  1053.          rc_string.jvm_basic_new;
  1054.          -- Set count :
  1055.          opcode_dup;
  1056.          opcode_aload(loc);
  1057.          opcode_arraylength;
  1058.          opcode_putfield(cp.idx_eiffel_string_count_fieldref,-2);
  1059.          -- Set capacity :
  1060.          opcode_dup;
  1061.          opcode_aload(loc);
  1062.          opcode_arraylength;
  1063.          opcode_putfield(cp.idx_eiffel_string_capacity_fieldref,-2);
  1064.          -- Set storage :
  1065.          opcode_dup;
  1066.          opcode_aload(loc);
  1067.          opcode_putfield(cp.idx_eiffel_string_storage_fieldref,-2);
  1068.       end;
  1069.  
  1070. feature {TYPE_BIT}
  1071.  
  1072.    opcode_bitset_clone is
  1073.       local
  1074.          cp: like constant_pool;
  1075.          idx: INTEGER;
  1076.       do
  1077.          cp := constant_pool;
  1078.          idx := cp.idx_methodref3(fz_a0,fz_a6,fz_a7);
  1079.          opcode_invokevirtual(idx,0);
  1080.          idx := cp.idx_class2(fz_a0);
  1081.          opcode_checkcast(idx);
  1082.       end;
  1083.  
  1084. feature -- Easy access to some Java basics :
  1085.  
  1086.    opcode_system_in is
  1087.          -- Push `System.in'.
  1088.       local
  1089.          idx: INTEGER;
  1090.       do
  1091.          idx := constant_pool.idx_fieldref3(Java_lang_system,fz_37,fz_38);
  1092.          opcode_getstatic(idx,1);
  1093.       end;
  1094.  
  1095.    opcode_system_out is
  1096.          -- Push `System.out'.
  1097.       local
  1098.          idx: INTEGER;
  1099.       do
  1100.          idx := constant_pool.idx_fieldref3(Java_lang_system,fz_39,fz_40);
  1101.          opcode_getstatic(idx,1);
  1102.       end;
  1103.  
  1104.    opcode_system_err is
  1105.          -- Push `System.err'.
  1106.       local
  1107.          idx: INTEGER;
  1108.       do
  1109.          idx := constant_pool.idx_fieldref3(Java_lang_system,fz_49,fz_40);
  1110.          opcode_getstatic(idx,1);
  1111.       end;
  1112.  
  1113.    opcode_println(string_idx: INTEGER) is
  1114.       require
  1115.          constant_pool.valid_index(string_idx);
  1116.       local
  1117.          idx: INTEGER;
  1118.       do
  1119.          opcode_ldc(string_idx);
  1120.          idx := constant_pool.idx_methodref3(fz_25,fz_51,fz_57);
  1121.          opcode_invokevirtual(idx,-2);
  1122.       end;
  1123.  
  1124.    opcode_system_err_println(string_idx: INTEGER) is
  1125.          -- System.err.println(<string_idx>);
  1126.       require
  1127.          constant_pool.valid_index(string_idx);
  1128.       do
  1129.          opcode_system_err;
  1130.          opcode_println(string_idx);
  1131.       end;
  1132.  
  1133. feature {NONE}
  1134.  
  1135.    opcode(opcode_value, max_stack_increment: INTEGER) is
  1136.       require
  1137.          stack_level >= 0;
  1138.          opcode_value <= 255
  1139.       local
  1140.          cs: INTEGER;
  1141.       do
  1142.          add_u1(opcode_value);
  1143.          cs := stack_level + max_stack_increment;
  1144.          if cs >= 0 then
  1145.             stack_level := cs;
  1146.          else
  1147.             -- ????
  1148.          end;
  1149.          if stack_level > max_stack then
  1150.             max_stack := stack_level;
  1151.          end;
  1152.       ensure
  1153.          stack_level >= 0
  1154.       end;
  1155.  
  1156.    add_u1(u1: INTEGER) is
  1157.       do
  1158.          code.add_last(u1);
  1159.       ensure
  1160.          program_counter = 1 + old program_counter
  1161.       end;
  1162.  
  1163.    add_u2(u2: INTEGER) is
  1164.       do
  1165.          add_u1(u2 // 256);
  1166.          add_u1(u2 \\ 256);
  1167.       ensure
  1168.          program_counter = 2 + old program_counter
  1169.       end;
  1170.  
  1171.    skip_2_bytes: INTEGER is
  1172.          -- Return the `programm_counter' before the skip.
  1173.       do
  1174.          Result := program_counter;
  1175.          code.add_last(0);
  1176.          code.add_last(0);
  1177.       end;
  1178.  
  1179. feature
  1180.  
  1181.    resolve_u2_branch(start_point: INTEGER) is
  1182.       require
  1183.          start_point < program_counter
  1184.       local
  1185.          offset: INTEGER;
  1186.       do
  1187.          offset := program_counter - start_point + 1;
  1188.          code.put(offset // 256,start_point);
  1189.          code.put(offset \\ 256,start_point + 1);
  1190.       end;
  1191.  
  1192. feature
  1193.  
  1194.    branches: FIXED_ARRAY[INTEGER] is
  1195.       once
  1196.          !!Result.with_capacity(16);
  1197.       end;
  1198.  
  1199.    resolve_branches is
  1200.       do
  1201.          resolve_with(branches);
  1202.       end;
  1203.  
  1204.    resolve_with(points: FIXED_ARRAY[INTEGER]) is
  1205.       local
  1206.          i: INTEGER;
  1207.       do
  1208.          from
  1209.             i := points.upper;
  1210.          until
  1211.             i < 0
  1212.          loop
  1213.             resolve_u2_branch(points.item(i));
  1214.             i := i - 1;
  1215.          end;
  1216.       end;
  1217.  
  1218. feature {NONE}
  1219.  
  1220.    check_flag_idx,  skip_check: INTEGER;
  1221.  
  1222. feature {ASSERTION_LIST}
  1223.  
  1224.    check_opening is
  1225.       local
  1226.          cp: like constant_pool;
  1227.       do
  1228.          cp := constant_pool;
  1229.          opcode_iconst_1;
  1230.          check_flag_idx := cp.idx_fieldref3(jvm_root_class,fz_58,fz_41);
  1231.          opcode_getstatic(check_flag_idx,1);
  1232.          skip_check := opcode_ifne;
  1233.          opcode_putstatic(check_flag_idx,-1);
  1234.       end;
  1235.  
  1236.    check_closing is
  1237.       do
  1238.          opcode_iconst_0;
  1239.          opcode_putstatic(check_flag_idx,-1);
  1240.          resolve_u2_branch(skip_check);
  1241.       end;
  1242.  
  1243. feature {NONE}
  1244.  
  1245.    opcode_string2double(str: STRING) is
  1246.       local
  1247.          idx: INTEGER;
  1248.       do
  1249.          idx := constant_pool.idx_string(str);
  1250.          opcode_ldc(idx);
  1251.          idx := constant_pool.idx_methodref3(fz_62,fz_60,fz_61);
  1252.          opcode_invokestatic(idx,1);
  1253.       end;
  1254.  
  1255.    opcode_string2float(str: STRING) is
  1256.       do
  1257.          opcode_string2double(str);
  1258.          opcode_d2f;
  1259.       end;
  1260.  
  1261. feature {NONE}
  1262.  
  1263.    push_strange_integer(i: INTEGER) is
  1264.       local
  1265.          idx: INTEGER;
  1266.          cp: like constant_pool;
  1267.       do
  1268.          cp := constant_pool;
  1269.          tmp_string.clear;
  1270.          i.append_in(tmp_string);
  1271.          idx := cp.idx_string(tmp_string);
  1272.          opcode_ldc(idx);
  1273.          idx := cp.idx_methodref3(fz_81,fz_82,fz_83);
  1274.          opcode_invokestatic(idx,0);
  1275.       end;
  1276.  
  1277.    tmp_string: STRING is
  1278.       once
  1279.          !!Result.make(32);
  1280.       end;
  1281.  
  1282. feature {NONE}
  1283.  
  1284.    exception_table: EXCEPTION_TABLE is
  1285.       once
  1286.          !!Result.make;
  1287.       end;
  1288.  
  1289. feature
  1290.  
  1291.    add_exception(f, t, h, idx: INTEGER) is
  1292.       do
  1293.          exception_table.add(f,t,h,idx);
  1294.       end;
  1295.  
  1296. feature -- Calls to SmallEiffelRuntime.java :
  1297.  
  1298.  
  1299.    runtime_die_with_code is
  1300.          -- Assume the status code is already pushed.
  1301.       local
  1302.          cp: like constant_pool;
  1303.          idx: INTEGER;
  1304.       do
  1305.          cp := constant_pool;
  1306.          idx := cp.idx_methodref3(fz_se_runtime,as_die_with_code,fz_27);
  1307.          opcode_invokestatic(idx,-1);
  1308.       end;
  1309.  
  1310.    runtime_internal_exception_number is
  1311.       local
  1312.          cp: like constant_pool;
  1313.          idx: INTEGER;
  1314.       do
  1315.          cp := constant_pool;
  1316.          idx := cp.idx_fieldref3(fz_se_runtime,"internal_exception_number",fz_i);
  1317.          opcode_getstatic(idx,1);
  1318.       end;
  1319.  
  1320.    runtime_error(p: POSITION; t: TYPE; message: STRING) is
  1321.       local
  1322.          cp: like constant_pool;
  1323.          idx: INTEGER;
  1324.       do
  1325.          cp := constant_pool;
  1326.          push_position(p);
  1327.          if t = Void then
  1328.             opcode_aconst_null;
  1329.          else
  1330.             opcode_ldc(cp.idx_string(t.run_time_mark));
  1331.          end;
  1332.          opcode_ldc(cp.idx_string(message));
  1333.          idx := cp.idx_methodref3(fz_se_runtime,"runtime_error",
  1334.          "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
  1335.          opcode_invokestatic(idx,-5);
  1336.       end;
  1337.  
  1338.    runtime_error_bad_target(p: POSITION; t: TYPE; message: STRING) is
  1339.          -- Assume the bad target is pushed.
  1340.          -- The expected type, if any is `t'.
  1341.       local
  1342.          cp: like constant_pool;
  1343.          idx: INTEGER;
  1344.       do
  1345.          cp := constant_pool;
  1346.          push_position(p);
  1347.          opcode_ldc(cp.idx_string(t.run_time_mark));
  1348.          if message = Void then
  1349.             opcode_aconst_null;
  1350.          else
  1351.             opcode_ldc(cp.idx_string(message));
  1352.          end;
  1353.          idx := cp.idx_methodref3(fz_se_runtime,"runtime_error_bad_target",
  1354.          "(Ljava/lang/Object;IILjava/lang/String;Ljava/lang/String;%
  1355.          %Ljava/lang/String;)V");
  1356.          opcode_invokestatic(idx,-6);
  1357.       end;
  1358.  
  1359. feature {E_LOOP}
  1360.  
  1361.    runtime_check_loop_variant(expression: EXPRESSION) is
  1362.          -- Assume the loop counter and the previous variant value
  1363.          -- is already pushed.
  1364.          -- Returns the next variant value.
  1365.       require
  1366.          expression /= Void
  1367.       local
  1368.          cp: like constant_pool;
  1369.          idx: INTEGER;
  1370.       do
  1371.          cp := constant_pool;
  1372.          expression.compile_to_jvm;
  1373.          push_position(expression.start_position);
  1374.          idx := cp.idx_methodref3(fz_se_runtime,"runtime_check_loop_variant",
  1375.          "(IIIIILjava/lang/String;)I");
  1376.          opcode_invokestatic(idx,-5);
  1377.       end;
  1378.  
  1379. feature {E_INSPECT}
  1380.  
  1381.    runtime_error_inspect(expression: EXPRESSION) is
  1382.          -- Assume the not selected inspect value of `expression' is
  1383.          -- already pushed.
  1384.       local
  1385.          cp: like constant_pool;
  1386.          rt: TYPE;
  1387.          idx: INTEGER;
  1388.       do
  1389.          cp := constant_pool;
  1390.          rt := expression.result_type;
  1391.          if rt.is_character then
  1392.             -- Convert byte 2 int ??
  1393.          end;
  1394.          push_position(expression.start_position);
  1395.          idx := cp.idx_methodref3(fz_se_runtime,"runtime_error_inspect",
  1396.          "(IIILjava/lang/String;)I");
  1397.          opcode_invokestatic(idx,-3);
  1398.       end;
  1399.  
  1400. feature {COMPOUND}
  1401.  
  1402.    se_trace(ct: TYPE; p: POSITION) is
  1403.          -- Assume the Current target of type `ct' is pushed.
  1404.       require
  1405.          run_control.trace
  1406.       local
  1407.          cp: like constant_pool;
  1408.          idx: INTEGER;
  1409.       do
  1410.          if p /= Void then
  1411.             cp := constant_pool;
  1412.             ct.jvm_push_local(0);
  1413.             push_position(p);
  1414.             tmp_string.clear;
  1415.             tmp_string.extend('(');
  1416.             if ct.is_basic_eiffel_expanded then
  1417.                ct.jvm_descriptor_in(tmp_string);
  1418.             else
  1419.                tmp_string.append("Ljava/lang/Object;");
  1420.             end;
  1421.             tmp_string.append("IILjava/lang/String;)V");
  1422.             idx := cp.idx_methodref3(fz_se_runtime,"se_trace",tmp_string);
  1423.             opcode_invokestatic(idx,- ct.jvm_stack_space - 3);
  1424.          else
  1425.             opcode_pop;
  1426.          end;
  1427.       end;
  1428.  
  1429. feature {NONE}
  1430.  
  1431.    push_position(p: POSITION) is
  1432.       do
  1433.          if p = Void then
  1434.             opcode_iconst_0;
  1435.             opcode_iconst_0;
  1436.             opcode_aconst_null;
  1437.          else
  1438.             opcode_push_integer(p.line);
  1439.             opcode_push_integer(p.column);
  1440.             opcode_ldc(constant_pool.idx_string(p.path));
  1441.          end;
  1442.       end;
  1443.  
  1444. feature {NATIVE_SMALL_EIFFEL}
  1445.  
  1446.    runtime_se_getenv is
  1447.       local
  1448.          point1: INTEGER;
  1449.          cp: like constant_pool;
  1450.          idx: INTEGER;
  1451.       do
  1452.          cp := constant_pool;
  1453.          idx := cp.idx_methodref3(fz_se_runtime,"se_getenv",
  1454.                                   "(Ljava/lang/Object;)Ljava/lang/String;");
  1455.          opcode_invokestatic(idx,0);
  1456.          opcode_dup;
  1457.          point1 := opcode_ifnull;
  1458.          opcode_java_string2eiffel_string;
  1459.          resolve_u2_branch(point1);
  1460.       end;
  1461.  
  1462.    runtime_se_remove is
  1463.       local
  1464.          cp: like constant_pool;
  1465.          idx: INTEGER;
  1466.       do
  1467.          cp := constant_pool;
  1468.          idx := cp.idx_methodref3(fz_se_runtime,as_se_remove,fz_descriptor1);
  1469.          opcode_invokestatic(idx,-1);
  1470.       end;
  1471.  
  1472.    runtime_se_system is
  1473.       local
  1474.          cp: like constant_pool;
  1475.          idx: INTEGER;
  1476.       do
  1477.          cp := constant_pool;
  1478.          idx := cp.idx_methodref3(fz_se_runtime,as_se_system,fz_descriptor1);
  1479.          opcode_invokestatic(idx,-1);
  1480.       end;
  1481.  
  1482.    runtime_sfr_open is
  1483.       local
  1484.          cp: like constant_pool;
  1485.          idx: INTEGER;
  1486.       do
  1487.          cp := constant_pool;
  1488.          idx := cp.idx_methodref3(fz_se_runtime,as_sfr_open,fz_44);
  1489.          opcode_invokestatic(idx,0);
  1490.       end;
  1491.  
  1492.    runtime_sfw_open is
  1493.       local
  1494.          cp: like constant_pool;
  1495.          idx: INTEGER;
  1496.       do
  1497.          cp := constant_pool;
  1498.          idx := cp.idx_methodref3(fz_se_runtime,as_sfw_open,fz_44);
  1499.          opcode_invokestatic(idx,0);
  1500.       end;
  1501.  
  1502.    runtime_se_string2double is
  1503.       local
  1504.          cp: like constant_pool;
  1505.          idx: INTEGER;
  1506.       do
  1507.          cp := constant_pool;
  1508.          idx := cp.idx_methodref3(fz_se_runtime,as_se_string2double,
  1509.                                   "(Ljava/lang/Object;)D");
  1510.          opcode_invokestatic(idx,1);
  1511.       end;
  1512.  
  1513.    runtime_se_rename is
  1514.       local
  1515.          cp: like constant_pool;
  1516.          idx: INTEGER;
  1517.       do
  1518.          cp := constant_pool;
  1519.          idx := cp.idx_methodref3(fz_se_runtime,as_se_rename,
  1520.                                   "(Ljava/lang/Object;Ljava/lang/Object;)V");
  1521.          opcode_invokestatic(idx,-2);
  1522.       end;
  1523.  
  1524.    read_byte is
  1525.       local
  1526.          cp: like constant_pool;
  1527.          idx: INTEGER;
  1528.       do
  1529.          cp := constant_pool;
  1530.          idx := cp.idx_class2(fz_69);
  1531.          opcode_checkcast(idx);
  1532.          idx := cp.idx_methodref3(fz_69,fz_70,fz_71);
  1533.          opcode_invokevirtual(idx,0);
  1534.       end;
  1535.  
  1536.    runtime_print_run_time_stack is
  1537.       local
  1538.          cp: like constant_pool;
  1539.          idx: INTEGER;
  1540.       do
  1541.          cp := constant_pool;
  1542.          idx := cp.idx_methodref3(fz_se_runtime,as_print_run_time_stack,fz_29);
  1543.          opcode_invokestatic(idx,0);
  1544.       end;
  1545.  
  1546. feature {NONE}
  1547.  
  1548.    Java_lang_system: STRING is "java/lang/System";
  1549.  
  1550.    fz_descriptor1: STRING is "(Ljava/lang/Object;)V";
  1551.  
  1552. invariant
  1553.  
  1554.    stack_level >= 0;
  1555.  
  1556.    stack_level <= max_stack;
  1557.  
  1558. end -- CODE_ATTRIBUTE
  1559.  
  1560.