home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / code_attribute.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  21.7 KB  |  1,284 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. 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.    current_stack_level: INTEGER;
  35.      -- Used to compute `max_stack';
  36.  
  37.    max_locals: INTEGER;
  38.  
  39. feature {METHOD_INFO}
  40.  
  41.    clear is
  42.       do
  43.      code.clear;
  44.      exception_table.clear;
  45.      max_stack := 0;
  46.      current_stack_level := 0;
  47.      max_locals := jvm.max_locals;
  48.       end;
  49.  
  50.    store_in(storage: STRING) is
  51.       local
  52.      i: INTEGER;
  53.       do
  54.      append_u2(storage,constant_pool.idx_uft8_code);
  55.      check
  56.         program_counter > 0
  57.      end;
  58.      append_u4(storage,12 + program_counter);
  59.      append_u2(storage,max_stack);
  60.      append_u2(storage,max_locals);
  61.      append_u4(storage,program_counter);
  62.      from
  63.         i := 0
  64.      until
  65.         i > code.upper
  66.      loop
  67.         append_u1(storage,code.item(i));
  68.         i := i + 1;
  69.      end;
  70.      exception_table.store_in(storage);
  71.      -- attribute_count :
  72.      append_u2(storage,0);
  73.       end;
  74.       
  75. feature
  76.  
  77.    program_counter: INTEGER is
  78.       do
  79.      Result := code.count;
  80.       end;
  81.  
  82.    extra_local(local_type: TYPE): INTEGER is
  83.       require
  84.      local_type.is_run_type
  85.       do
  86.      Result := max_locals;
  87.      max_locals := max_locals + local_type.jvm_stack_space;
  88.       end;
  89.  
  90.    extra_local_size1: INTEGER is
  91.       do
  92.      Result := max_locals;
  93.      max_locals := max_locals + 1;
  94.       end;
  95.  
  96. feature -- opcode feature list :
  97.  
  98.    opcode_nop is
  99.       do
  100.      opcode(0,0);
  101.       end;
  102.  
  103.    opcode_aconst_null is
  104.       do
  105.      opcode(1,1);
  106.       end;
  107.  
  108.    opcode_iconst_m1 is
  109.       do
  110.      opcode(2,1);
  111.       end;
  112.  
  113.    opcode_iconst_0 is
  114.       do
  115.      opcode(3,1);
  116.       end;
  117.  
  118.    opcode_iconst_1 is
  119.       do
  120.      opcode(4,1);
  121.       end;
  122.  
  123.    opcode_iconst_i(n: INTEGER) is
  124.       require
  125.      -1 <= n;
  126.          n <= 5
  127.       do
  128.      opcode(3 + n,1);
  129.       end;
  130.  
  131.    opcode_fconst_0 is
  132.       do
  133.      opcode(11,1);
  134.       end;
  135.  
  136.    opcode_dconst_0 is
  137.       do
  138.      opcode(14,2);
  139.       end;
  140.  
  141.    opcode_bipush(byte: INTEGER) is
  142.       require
  143.      6 <= byte;
  144.      byte <= 255
  145.       do
  146.      opcode(16,1);
  147.      add_u1(byte);
  148.       end;
  149.  
  150.    opcode_sipush(u2: INTEGER) is
  151.       require
  152.      -32768 <= u2;
  153.      u2 <= 32767;
  154.          (u2 < -128 or 127 < u2)
  155.       do
  156.      opcode(17,1);
  157.      add_u2(u2);
  158.       end;
  159.      
  160.    opcode_ldc(idx: INTEGER) is
  161.      -- For both ldc and ldc_w.
  162.       require
  163.      constant_pool.valid_index(idx)
  164.       do
  165.      if idx < 255 then
  166.         opcode(18,1);
  167.         add_u1(idx);
  168.      else
  169.         opcode(19,1);
  170.         add_u2(idx);
  171.      end;
  172.       end;
  173.      
  174.    opcode_fload(index: INTEGER) is
  175.       require
  176.      0 <= index;
  177.      index <= 255
  178.       do
  179.      if index <= 3 then
  180.         opcode(34 + index,1);
  181.      else
  182.         opcode(23,1);
  183.         add_u1(index);
  184.      end;
  185.       end;
  186.  
  187.    opcode_dload_0 is
  188.       do
  189.      opcode(38,2);
  190.       end;
  191.  
  192.    opcode_dload(index: INTEGER) is
  193.       require
  194.      0 <= index;
  195.      index <= 255
  196.       do
  197.      if index <= 3 then
  198.         opcode(38 + index,2);
  199.      else
  200.         opcode(24,2);
  201.         add_u1(index);
  202.      end;
  203.       end;
  204.  
  205.    opcode_aload(index: INTEGER) is
  206.       require
  207.      0 <= index;
  208.      index <= 255
  209.       do
  210.      if index <= 3 then
  211.         opcode(42 + index,1);
  212.      else
  213.         opcode(25,1);
  214.         add_u1(index);
  215.      end;
  216.       end;
  217.  
  218.    opcode_iload_3 is
  219.       do
  220.      opcode(29,1);
  221.       end;
  222.  
  223.    opcode_iload(index: INTEGER) is
  224.       require
  225.      0 <= index;
  226.      index <= 255
  227.       do
  228.      if index <= 3 then
  229.         opcode(26 + index,1);
  230.      else
  231.         opcode(21,1);
  232.         add_u1(index);
  233.      end;
  234.       end;
  235.  
  236.    opcode_aload_0 is
  237.       do
  238.      opcode(42,1);
  239.       end;
  240.  
  241.    opcode_aload_1 is
  242.       do
  243.      opcode(43,1);
  244.       end;
  245.  
  246.    opcode_aload_2 is
  247.       do
  248.      opcode(44,1);
  249.       end;
  250.  
  251.    opcode_aload_3 is
  252.       do
  253.      opcode(45,1);
  254.       end;
  255.  
  256.    opcode_iaload is
  257.       do
  258.      opcode(46,-1);
  259.       end;
  260.  
  261.    opcode_laload is
  262.       do
  263.      opcode(47,0);
  264.       end;
  265.  
  266.    opcode_faload is
  267.       do
  268.      opcode(48,-1);
  269.       end;
  270.  
  271.    opcode_daload is
  272.       do
  273.      opcode(49,0);
  274.       end;
  275.  
  276.    opcode_aaload is
  277.       do
  278.      opcode(50,-1);
  279.       end;
  280.  
  281.    opcode_baload is
  282.       do
  283.      opcode(51,-1);
  284.       end;
  285.  
  286.    opcode_caload is
  287.       do
  288.      opcode(52,-1);
  289.       end;
  290.  
  291.    opcode_saload is
  292.       do
  293.      opcode(53,-1);
  294.       end;
  295.  
  296.    opcode_istore_3 is
  297.       do
  298.      opcode(62,-1);
  299.       end;
  300.  
  301.    opcode_istore(offset: INTEGER) is
  302.       require
  303.      0 <= offset;
  304.      offset <= 255
  305.       do
  306.      if offset <= 3 then
  307.         opcode(59 + offset,-1);
  308.      else
  309.         opcode(54,-1);
  310.         add_u1(offset);
  311.      end;
  312.       end;
  313.  
  314.    opcode_fstore(offset: INTEGER) is
  315.       require
  316.      0 <= offset;
  317.      offset <= 255
  318.       do
  319.      if offset <= 3 then
  320.         opcode(67 + offset,-1);
  321.      else
  322.         opcode(56,-1);
  323.         add_u1(offset);
  324.      end;
  325.       end;
  326.  
  327.    opcode_dstore(offset: INTEGER) is
  328.       require
  329.      0 <= offset;
  330.      offset <= 255
  331.       do
  332.      if offset <= 3 then
  333.         opcode(71 + offset,-1);
  334.      else
  335.         opcode(57,-1);
  336.         add_u1(offset);
  337.      end;
  338.       end;
  339.  
  340.    opcode_astore_0 is
  341.       do
  342.      opcode(75,-1);
  343.       end;
  344.  
  345.    opcode_astore_1 is
  346.       do
  347.      opcode(76,-1);
  348.       end;
  349.  
  350.    opcode_astore_2 is
  351.       do
  352.      opcode(77,-1);
  353.       end;
  354.  
  355.    opcode_astore_3 is
  356.       do
  357.      opcode(78,-1);
  358.       end;
  359.  
  360.    opcode_astore(offset: INTEGER) is
  361.       require
  362.      0 <= offset;
  363.      offset <= 255
  364.       do
  365.      if offset <= 3 then
  366.         opcode(75 + offset,-1);
  367.      else
  368.         opcode(58,-1);
  369.         add_u1(offset);
  370.      end;
  371.       end;
  372.  
  373.    opcode_iastore is
  374.       do
  375.      opcode(79,-3);
  376.       end;
  377.  
  378.    opcode_fastore is
  379.       do
  380.      opcode(81,-3);
  381.       end;
  382.  
  383.    opcode_dastore is
  384.       do
  385.      opcode(82,-4);
  386.       end;
  387.  
  388.    opcode_aastore is
  389.       do
  390.      opcode(83,-3);
  391.       end;
  392.  
  393.    opcode_bastore is
  394.       do
  395.      opcode(84,-3);
  396.       end;
  397.  
  398.    opcode_pop is
  399.       do
  400.      opcode(87,-1);
  401.       end;
  402.  
  403.    opcode_pop2 is
  404.       do
  405.      opcode(88,-2);
  406.       end;
  407.  
  408.    opcode_dup is
  409.       do
  410.      opcode(89,1);
  411.       end;
  412.  
  413.    opcode_dup_x1 is
  414.       do
  415.      opcode(90,1);
  416.       end;
  417.  
  418.    opcode_dup_x2 is
  419.       do
  420.      opcode(91,1);
  421.       end;
  422.  
  423.    opcode_dup2 is
  424.       do
  425.      opcode(92,2);
  426.       end;
  427.  
  428.    opcode_dup2_x1 is
  429.       do
  430.      opcode(93,2);
  431.       end;
  432.  
  433.    opcode_swap is
  434.       do
  435.      opcode(95,0);
  436.       end;
  437.  
  438.    opcode_iadd is
  439.       do
  440.      opcode(96,-1);
  441.       end;
  442.  
  443.    opcode_fadd is
  444.       do
  445.      opcode(98,-1);
  446.       end;
  447.  
  448.    opcode_dadd is
  449.       do
  450.      opcode(99,-2);
  451.       end;
  452.  
  453.    opcode_isub is
  454.       do
  455.      opcode(100,-1);
  456.       end;
  457.  
  458.    opcode_fsub is
  459.       do
  460.      opcode(102,-1);
  461.       end;
  462.  
  463.    opcode_dsub is
  464.       do
  465.      opcode(103,-2);
  466.       end;
  467.  
  468.    opcode_imul is
  469.       do
  470.      opcode(104,-1);
  471.       end;
  472.  
  473.    opcode_fmul is
  474.       do
  475.      opcode(106,-1);
  476.       end;
  477.  
  478.    opcode_dmul is
  479.       do
  480.      opcode(107,-2);
  481.       end;
  482.  
  483.    opcode_idiv is
  484.       do
  485.      opcode(108,-1);
  486.       end;
  487.  
  488.    opcode_fdiv is
  489.       do
  490.      opcode(110,-1);
  491.       end;
  492.  
  493.    opcode_ddiv is
  494.       do
  495.      opcode(111,-2);
  496.       end;
  497.  
  498.    opcode_irem is
  499.       do
  500.      opcode(112,-1);
  501.       end;
  502.  
  503.    opcode_ineg is
  504.       do
  505.      opcode(116,0);
  506.       end;
  507.  
  508.    opcode_fneg is
  509.       do
  510.      opcode(118,0);
  511.       end;
  512.  
  513.    opcode_dneg is
  514.       do
  515.      opcode(119,0);
  516.       end;
  517.  
  518.    opcode_ishl is
  519.       do
  520.      opcode(120,-1);
  521.       end;
  522.  
  523.    opcode_ishr is
  524.       do
  525.      opcode(122,-1);
  526.       end;
  527.  
  528.    opcode_iushr is
  529.       do
  530.      opcode(124,-1);
  531.       end;
  532.  
  533.    opcode_iand is
  534.       do
  535.      opcode(126,-1);
  536.       end;
  537.  
  538.    opcode_ior is
  539.       do
  540.      opcode(128,-1);
  541.       end;
  542.  
  543.    opcode_ixor is
  544.       do
  545.      opcode(130,-1);
  546.       end;
  547.  
  548.    opcode_iinc(loc_idx, u1_increment: INTEGER) is
  549.       do
  550.      opcode(132,0);
  551.      add_u1(loc_idx);
  552.      add_u1(u1_increment);
  553.       end;
  554.  
  555.    opcode_i2f is
  556.       do
  557.      opcode(134,1);
  558.       end;
  559.  
  560.    opcode_i2d is
  561.       do
  562.      opcode(135,1);
  563.       end;
  564.  
  565.    opcode_f2d is
  566.       do
  567.      opcode(141,1);
  568.       end;
  569.  
  570.    opcode_d2i is
  571.       do
  572.      opcode(142,-1);
  573.       end;
  574.  
  575.    opcode_d2f is
  576.       do
  577.      opcode(144,-1);
  578.       end;
  579.  
  580.    opcode_i2b is
  581.       do
  582.      opcode(145,0);
  583.       end;
  584.  
  585.    opcode_fcmpg is
  586.       do
  587.      opcode(150,-1);
  588.       end;
  589.  
  590.    opcode_fcmpl is
  591.       do
  592.      opcode(149,-1);
  593.       end;
  594.  
  595.    opcode_dcmpl is
  596.       do
  597.      opcode(151,-3);
  598.       end;
  599.  
  600.    opcode_dcmpg is
  601.       do
  602.      opcode(152,-3);
  603.       end;
  604.  
  605.    opcode_ifeq: INTEGER is
  606.       do
  607.      opcode(153,-1);
  608.      Result := skip_2_bytes;
  609.       end;
  610.  
  611.    opcode_ifne: INTEGER is
  612.       do
  613.      opcode(154,-1);
  614.      Result := skip_2_bytes;
  615.       end;
  616.  
  617.    opcode_iflt: INTEGER is
  618.       do
  619.      opcode(155,-1);
  620.      Result := skip_2_bytes;
  621.       end;
  622.  
  623.    opcode_ifge: INTEGER is
  624.       do
  625.      opcode(156,-1);
  626.      Result := skip_2_bytes;
  627.       end;
  628.  
  629.    opcode_ifgt: INTEGER is
  630.       do
  631.      opcode(157,-1);
  632.      Result := skip_2_bytes;
  633.       end;
  634.  
  635.    opcode_ifle: INTEGER is
  636.       do
  637.      opcode(158,-1);
  638.      Result := skip_2_bytes;
  639.       end;
  640.  
  641.    opcode_if_icmpeq: INTEGER is
  642.       do
  643.      opcode(159,-2);
  644.      Result := skip_2_bytes;
  645.       end;
  646.  
  647.    opcode_if_icmpne: INTEGER is
  648.       do
  649.      opcode(160,-2);
  650.      Result := skip_2_bytes;
  651.       end;
  652.  
  653.    opcode_if_icmplt: INTEGER is
  654.       do
  655.      opcode(161,-2);
  656.      Result := skip_2_bytes;
  657.       end;
  658.  
  659.    opcode_if_icmpge: INTEGER is
  660.       do
  661.      opcode(162,-2);
  662.      Result := skip_2_bytes;
  663.       end;
  664.  
  665.    opcode_if_icmpgt: INTEGER is
  666.       do
  667.      opcode(163,-2);
  668.      Result := skip_2_bytes;
  669.       end;
  670.  
  671.    opcode_if_icmple: INTEGER is
  672.       do
  673.      opcode(164,-2);
  674.      Result := skip_2_bytes;
  675.       end;
  676.  
  677.    opcode_if_acmpeq: INTEGER is
  678.       do
  679.      opcode(165,-2);
  680.      Result := skip_2_bytes;
  681.       end;
  682.  
  683.    opcode_if_acmpne: INTEGER is
  684.       do
  685.      opcode(166,-2);
  686.      Result := skip_2_bytes;
  687.       end;
  688.  
  689.    opcode_goto: INTEGER is
  690.       do
  691.      opcode(167,0);
  692.      Result := skip_2_bytes;
  693.       end;
  694.  
  695.    opcode_goto_backward(back_point: INTEGER) is
  696.      -- Produce a goto opcode to go back at `back_point'.
  697.       require
  698.      back_point < program_counter
  699.       local
  700.      r, q, offset: INTEGER;
  701.       do
  702.      offset := program_counter - back_point;
  703.      opcode(167,0);
  704.      r := offset \\ 256;
  705.      q := offset // 256;
  706.      if r = 0 then
  707.         add_u1(256 - q);
  708.         add_u1(0);
  709.      else
  710.         add_u1(255 - q);
  711.         add_u1(256 - r);
  712.      end;
  713.       end;
  714.  
  715.    opcode_ireturn is
  716.       do
  717.      add_u1(172);
  718.       end;
  719.  
  720.    opcode_lreturn is
  721.       do
  722.      add_u1(173);
  723.       end;
  724.  
  725.    opcode_freturn is
  726.       do
  727.      add_u1(174);
  728.       end;
  729.  
  730.    opcode_dreturn is
  731.       do
  732.      add_u1(175);
  733.       end;
  734.  
  735.    opcode_areturn is
  736.       do
  737.      add_u1(176);
  738.       end;
  739.  
  740.    opcode_return is
  741.       do
  742.      add_u1(177);
  743.       end;
  744.  
  745.    opcode_getstatic(fieldref_idx, stack_inc: INTEGER) is
  746.       require
  747.      constant_pool.valid_index(fieldref_idx)
  748.       do
  749.      opcode(178,stack_inc);
  750.      add_u2(fieldref_idx);
  751.       end;
  752.  
  753.    opcode_putstatic(fieldref_idx, stack_inc: INTEGER) is
  754.       require
  755.      constant_pool.valid_index(fieldref_idx)
  756.       do
  757.      opcode(179,stack_inc);
  758.      add_u2(fieldref_idx);
  759.       end;
  760.  
  761.    opcode_getfield(fieldref_idx, stack_inc: INTEGER) is
  762.       require
  763.      constant_pool.valid_index(fieldref_idx)
  764.       do
  765.      opcode(180,stack_inc);
  766.      add_u2(fieldref_idx);
  767.       end;
  768.  
  769.    opcode_putfield(fieldref_idx, stack_inc: INTEGER) is
  770.       require
  771.      constant_pool.valid_index(fieldref_idx)
  772.       do
  773.      opcode(181,stack_inc);
  774.      add_u2(fieldref_idx);
  775.       end;
  776.  
  777.    opcode_invokevirtual(methodref_idx, stack_inc: INTEGER) is
  778.       require
  779.      constant_pool.valid_index(methodref_idx)
  780.       do
  781.      opcode(182,stack_inc);
  782.      add_u2(methodref_idx);
  783.       end;
  784.  
  785.    opcode_invokespecial(methodref_idx, stack_inc: INTEGER) is
  786.       require
  787.      constant_pool.valid_index(methodref_idx)
  788.       do
  789.      opcode(183,stack_inc);
  790.      add_u2(methodref_idx);
  791.       end;
  792.  
  793.    opcode_invokestatic(methodref_idx, stack_inc: INTEGER) is
  794.       require
  795.      constant_pool.valid_index(methodref_idx)
  796.       do
  797.      opcode(184,stack_inc);
  798.      add_u2(methodref_idx);
  799.       end;
  800.  
  801.    opcode_new(class_idx: INTEGER) is
  802.       do
  803.      opcode(187,1);
  804.      add_u2(class_idx);
  805.       end;
  806.  
  807.    opcode_newarray(u1: INTEGER) is
  808.       require
  809.      4 <= u1;
  810.      u1 <= 10
  811.       do
  812.      opcode(188,0);
  813.      add_u1(u1);
  814.       end;
  815.  
  816.    opcode_anewarray(idx: INTEGER) is
  817.       require
  818.      constant_pool.valid_index(idx)
  819.       do
  820.      opcode(189,0);
  821.      add_u2(idx);
  822.       end;
  823.  
  824.    opcode_arraylength is
  825.       do
  826.      opcode(190,0);
  827.       end;
  828.  
  829.    opcode_athrow is
  830.       do
  831.      opcode(191,0);
  832.       end;
  833.  
  834.    opcode_instanceof(class_idx: INTEGER) is
  835.       require
  836.      constant_pool.valid_index(class_idx)
  837.       do
  838.      opcode(193,0);
  839.      add_u2(class_idx);
  840.       end;
  841.  
  842.    opcode_ifnull: INTEGER is
  843.       do
  844.      opcode(198,-1);
  845.      Result := skip_2_bytes;
  846.       end;
  847.  
  848.    opcode_ifnonnull: INTEGER is
  849.       do
  850.      opcode(199,-1);
  851.      Result := skip_2_bytes;
  852.       end;
  853.  
  854. feature -- High level opcode calls :
  855.  
  856.    opcode_push_integer(i: INTEGER) is
  857.       do
  858.      if i < -32768 then
  859.         push_strange_integer(i);
  860.      elseif i < -128 then
  861.         opcode_sipush(i);
  862.      elseif i <= -1 then
  863.         opcode_bipush(i);
  864.      elseif i <= 5 then
  865.         opcode_iconst_i(i);
  866.      elseif i <= 127 then
  867.         opcode_bipush(i);
  868.      elseif i <= 32767 then
  869.         opcode_sipush(i);
  870.      else
  871.         push_strange_integer(i);
  872.      end;
  873.       end;
  874.  
  875.    opcode_push_as_float(str: STRING) is
  876.       require
  877.      str.count >= 1
  878.       do
  879.      inspect
  880.         str.item(1)
  881.      when '0' then
  882.         if str.count = 1 then
  883.            opcode(11,1);
  884.         else
  885.            inspect 
  886.           str.item(2)
  887.            when '.' then
  888.           if str.count = 2 then
  889.              opcode(11,1);
  890.           elseif str.count = 3 and then str.item(3) = '0' then
  891.              opcode(11,1);
  892.           else
  893.              opcode_string2float(str);
  894.           end;
  895.            else
  896.           opcode_string2float(str);
  897.            end;
  898.         end;
  899.      when '1' then
  900.         if str.count = 1 then
  901.            opcode(12,1);
  902.         else
  903.            inspect 
  904.           str.item(2)
  905.            when '.' then
  906.           if str.count = 2 then
  907.              opcode(12,1);
  908.           elseif str.count = 3 and then str.item(3) = '0' then
  909.              opcode(12,1);
  910.           else
  911.              opcode_string2float(str);
  912.           end;
  913.            else
  914.           opcode_string2float(str);
  915.            end;
  916.         end;
  917.      when '2' then
  918.         if str.count = 1 then
  919.            opcode(13,1);
  920.         else
  921.            inspect 
  922.           str.item(2)
  923.            when '.' then
  924.           if str.count = 2 then
  925.              opcode(13,1);
  926.           elseif str.count = 3 and then str.item(3) = '0' then
  927.              opcode(13,1);
  928.           else
  929.              opcode_string2float(str);
  930.           end;
  931.            else
  932.           opcode_string2float(str);
  933.            end;
  934.         end;
  935.      else
  936.         opcode_string2float(str);
  937.      end;
  938.       end;
  939.  
  940.    opcode_push_as_double(str: STRING) is
  941.       require
  942.      str.count >= 1
  943.       do
  944.      inspect
  945.         str.item(1)
  946.      when '0' then
  947.         if str.count = 1 then
  948.            opcode(14,2);
  949.         else
  950.            inspect 
  951.           str.item(2)
  952.            when '.' then
  953.           if str.count = 2 then
  954.              opcode(14,2);
  955.           elseif str.count = 3 and then str.item(3) = '0' then
  956.              opcode(14,2);
  957.           else
  958.              opcode_string2double(str);
  959.           end;
  960.            else
  961.           opcode_string2double(str);
  962.            end;
  963.         end;
  964.      when '1' then
  965.         if str.count = 1 then
  966.            opcode(15,2);
  967.         else
  968.            inspect 
  969.           str.item(2)
  970.            when '.' then
  971.           if str.count = 2 then
  972.              opcode(15,2);
  973.           elseif str.count = 3 and then str.item(3) = '0' then
  974.              opcode(15,2);
  975.           else
  976.              opcode_string2double(str);
  977.           end;
  978.            else
  979.           opcode_string2double(str);
  980.            end;
  981.         end;
  982.      else
  983.         opcode_string2double(str);
  984.      end;
  985.       end;
  986.  
  987.    opcode_push_manifest_string(ms: STRING) is
  988.      -- Produces code to push the corresponding Eiffel STRING.
  989.       local
  990.      ms_idx: INTEGER;
  991.       do
  992.      ms_idx := constant_pool.idx_string2(ms);
  993.      opcode_ldc(ms_idx);
  994.      opcode_java_string2eiffel_string;
  995.       end;
  996.  
  997.    opcode_java_string2bytes_array is
  998.      -- Used the pushed Java String to create the bytes array.
  999.       local
  1000.      idx: INTEGER;
  1001.       do
  1002.            idx := constant_pool.idx_methodref3(fz_32,fz_33,fz_34);
  1003.      opcode_invokevirtual(idx,0);
  1004.       end;
  1005.  
  1006.    opcode_java_string2eiffel_string is
  1007.      -- Used the pushed Java String to create a new Eiffel STRING.
  1008.       do
  1009.      opcode_java_string2bytes_array;
  1010.      opcode_bytes_array2eiffel_string;
  1011.       end;
  1012.  
  1013.    opcode_bytes_array2eiffel_string is
  1014.      -- Used the pushed Bytes array to create a new Eiffel STRING.
  1015.       local
  1016.      cp: like constant_pool;
  1017.      loc: INTEGER;
  1018.       do
  1019.      cp := constant_pool;
  1020.      loc := extra_local_size1;
  1021.      opcode_astore(loc);
  1022.      -- The new STRING :
  1023.      opcode_new(cp.idx_eiffel_string_class);
  1024.      -- Set count :
  1025.      opcode_dup;
  1026.      opcode_aload(loc);
  1027.      opcode_arraylength;
  1028.      opcode_putfield(cp.idx_eiffel_string_count_fieldref,-2);
  1029.      -- Set capacity :
  1030.      opcode_dup;
  1031.      opcode_aload(loc);
  1032.      opcode_arraylength;
  1033.      opcode_putfield(cp.idx_eiffel_string_capacity_fieldref,-2);
  1034.      -- Set storage :
  1035.      opcode_dup;
  1036.      opcode_aload(loc);
  1037.      opcode_putfield(cp.idx_eiffel_string_storage_fieldref,-2);
  1038.       end;
  1039.  
  1040. feature -- Easy access to some Java basics :
  1041.  
  1042.    opcode_system_exit is
  1043.      -- Assume the status code is already pushed.
  1044.       local
  1045.      idx: INTEGER;
  1046.       do
  1047.      idx := constant_pool.idx_methodref3(fz_36,fz_exit,fz_27);
  1048.      opcode_invokestatic(idx,0);
  1049.       end;
  1050.  
  1051.    opcode_system_in is
  1052.      -- Push `System.in'.
  1053.       local
  1054.      idx: INTEGER;
  1055.       do
  1056.      idx := constant_pool.idx_fieldref3(fz_36,fz_37,fz_38);
  1057.      opcode_getstatic(idx,1);
  1058.       end;
  1059.  
  1060.    opcode_system_out is
  1061.      -- Push `System.out'.
  1062.       local
  1063.      idx: INTEGER;
  1064.       do
  1065.      idx := constant_pool.idx_fieldref3(fz_36,fz_39,fz_40);
  1066.      opcode_getstatic(idx,1);
  1067.       end;
  1068.  
  1069.    opcode_system_err is
  1070.      -- Push `System.err'.
  1071.       local
  1072.      idx: INTEGER;
  1073.       do
  1074.      idx := constant_pool.idx_fieldref3(fz_36,fz_49,fz_40);
  1075.      opcode_getstatic(idx,1);
  1076.       end;
  1077.  
  1078.    opcode_println(string_idx: INTEGER) is
  1079.       require
  1080.      constant_pool.valid_index(string_idx);
  1081.       local
  1082.      idx: INTEGER;
  1083.       do
  1084.      opcode_ldc(string_idx);
  1085.      idx := constant_pool.idx_methodref3(fz_25,fz_51,fz_57);
  1086.      opcode_invokevirtual(idx,-2);
  1087.       end;
  1088.  
  1089.    opcode_system_err_println(string_idx: INTEGER) is
  1090.      -- System.err.println(<string_idx>);
  1091.       require
  1092.      constant_pool.valid_index(string_idx);
  1093.       do
  1094.      opcode_system_err;
  1095.      opcode_println(string_idx);
  1096.       end;
  1097.  
  1098.    opcode_runtime_get_runtime is
  1099.       local
  1100.      idx: INTEGER;
  1101.       do
  1102.      idx := constant_pool.idx_methodref3(fz_53,fz_55,fz_56);
  1103.      opcode_invokestatic(idx,1);
  1104.       end;
  1105.  
  1106.    opcode_runtime_trace_instructions(flag: BOOLEAN) is
  1107.       local
  1108.      idx: INTEGER;
  1109.       do
  1110.      opcode_runtime_get_runtime;
  1111.      if flag then
  1112.         opcode_iconst_1;
  1113.      else
  1114.         opcode_iconst_0;
  1115.      end;
  1116.      idx := constant_pool.idx_methodref3(fz_53,fz_52,fz_54);
  1117.      opcode_invokevirtual(idx,-2);
  1118.       end;
  1119.  
  1120. feature {NONE}
  1121.  
  1122.    opcode(opcode_value, max_stack_increment: INTEGER) is
  1123.       require
  1124.      current_stack_level >= 0;
  1125.      opcode_value <= 255
  1126.       do
  1127.      add_u1(opcode_value);
  1128.      current_stack_level := current_stack_level + max_stack_increment;
  1129.      if current_stack_level > max_stack then
  1130.         max_stack := current_stack_level;
  1131.      end;
  1132.       ensure
  1133.      current_stack_level >= 0
  1134.       end;
  1135.  
  1136.    add_u1(u1: INTEGER) is
  1137.       do
  1138.      code.add_last(u1);
  1139.       ensure
  1140.      program_counter = 1 + old program_counter
  1141.       end;
  1142.  
  1143.    add_u2(u2: INTEGER) is
  1144.       do
  1145.      add_u1(u2 // 256);
  1146.      add_u1(u2 \\ 256);
  1147.       ensure
  1148.      program_counter = 2 + old program_counter
  1149.       end;
  1150.  
  1151.    skip_2_bytes: INTEGER is
  1152.      -- Return the `programm_counter' before the skip.
  1153.       do
  1154.      Result := program_counter;
  1155.      code.add_last(0);
  1156.      code.add_last(0);
  1157.       end;
  1158.  
  1159. feature
  1160.  
  1161.    resolve_u2_branch(start_point: INTEGER) is
  1162.       require
  1163.      start_point < program_counter
  1164.       local
  1165.      offset: INTEGER;
  1166.       do
  1167.      offset := program_counter - start_point + 1;
  1168.      code.put(offset // 256,start_point);
  1169.      code.put(offset \\ 256,start_point + 1);
  1170.       end;
  1171.  
  1172. feature 
  1173.  
  1174.    branches: FIXED_ARRAY[INTEGER] is
  1175.       once
  1176.      !!Result.with_capacity(16);
  1177.       end;
  1178.  
  1179.    resolve_branches is
  1180.       do
  1181.      resolve_with(branches);
  1182.       end;
  1183.  
  1184.    resolve_with(points: FIXED_ARRAY[INTEGER]) is
  1185.       local
  1186.      i: INTEGER;
  1187.       do
  1188.      from
  1189.         i := points.upper;
  1190.      until
  1191.         i < 0
  1192.      loop
  1193.         resolve_u2_branch(points.item(i));
  1194.         i := i - 1;
  1195.      end;
  1196.       end;
  1197.  
  1198. feature {NONE}
  1199.  
  1200.    check_flag_idx,  skip_check: INTEGER;
  1201.  
  1202. feature {ASSERTION_LIST}
  1203.  
  1204.    check_opening is
  1205.       local
  1206.      cp: like constant_pool;
  1207.       do
  1208.      cp := constant_pool;
  1209.      check_flag_idx := cp.idx_fieldref3(jvm_root_class,fz_58,fz_41);
  1210.      opcode_getstatic(check_flag_idx,1);
  1211.      skip_check := opcode_ifne;
  1212.      opcode_iconst_1;
  1213.      opcode_putstatic(check_flag_idx,-1);
  1214.       end;
  1215.  
  1216.    check_closing is 
  1217.       do
  1218.      opcode_iconst_0;
  1219.      opcode_putstatic(check_flag_idx,-1);
  1220.      resolve_u2_branch(skip_check);
  1221.       end;
  1222.  
  1223. feature {NONE}
  1224.  
  1225.    opcode_string2double(str: STRING) is
  1226.       local
  1227.      idx: INTEGER;
  1228.       do
  1229.      idx := constant_pool.idx_string(str);
  1230.      opcode_ldc(idx);
  1231.      idx := constant_pool.idx_methodref3(fz_62,fz_60,fz_61);
  1232.      opcode_invokestatic(idx,0);
  1233.       end;
  1234.  
  1235.    opcode_string2float(str: STRING) is
  1236.       do
  1237.      opcode_string2double(str);
  1238.      opcode_d2f;
  1239.       end;
  1240.  
  1241. feature {NONE}
  1242.  
  1243.    push_strange_integer(i: INTEGER) is
  1244.       local
  1245.      idx: INTEGER;
  1246.      cp: like constant_pool;
  1247.       do
  1248.      cp := constant_pool;
  1249.      tmp_string.clear;
  1250.      i.append_in(tmp_string);
  1251.      idx := cp.idx_string(tmp_string);
  1252.      opcode_ldc(idx);
  1253.      idx := cp.idx_methodref3(fz_81,fz_82,fz_83);
  1254.      opcode_invokestatic(idx,0);
  1255.       end;
  1256.  
  1257.    tmp_string: STRING is
  1258.       once 
  1259.      !!Result.make(32);
  1260.       end;
  1261.    
  1262. feature {NONE}
  1263.  
  1264.    exception_table: EXCEPTION_TABLE is
  1265.       once
  1266.      !!Result.make;
  1267.       end;
  1268.  
  1269. feature
  1270.    
  1271.    add_exception(f, t, h, idx: INTEGER) is
  1272.       do
  1273.      exception_table.add(f,t,h,idx);
  1274.       end;
  1275.    
  1276. invariant
  1277.  
  1278.    current_stack_level >= 0;
  1279.  
  1280.    current_stack_level <= max_stack;
  1281.  
  1282. end -- CODE_ATTRIBUTE
  1283.  
  1284.