home *** CD-ROM | disk | FTP | other *** search
- --
- -- Copyright (C) 1996 Ada Resource Association (ARA), Columbus, Ohio.
- -- Author: Gilles Demailly
- --
- --
- -- Permission to use, copy, modify, and distribute this software and its
- -- documentation for any purpose and without fee is hereby granted,
- -- provided that the above copyright and authorship notice appear in all
- -- copies and that both that copyright notice and this permission notice
- -- appear in supporting documentation.
- --
- -- The ARA makes no representations about the suitability of this software
- -- for any purpose. It is provided "as is" without express
- -- or implied warranty.
- --
-
- with Ada.Unchecked_Conversion;
- with Ada.Text_Io;
- with Unsigned_16_Io;
- with Unsigned_8_Io;
- with Unsigned_32_Io;
- with Integer_32_Io;
-
- package body ByteCode is
-
- -- This package can not be understood without the followin document :
- -- The Java Virtual Machine Specification
- -- (Release 1.0 Beta - Draft - August 21, 1995)
-
- -- type Operands and Constant Instructions_Operands are
- -- used to get how many operands each instruction needs
- -------------------------------------------------------
- type Operands is array (ByteCode) of Unsigned_32;
-
- -- Operands number of all Java bytecodes
- ----------------------------------------
- Instructions_Operands : Operands :=
- (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0 to 9
- 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, -- 10 to 19
- 2, 1, 1, 1, 1 ,1, 0, 0, 0, 0, -- 20 to 29
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 30 to 39
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 40 to 49
- 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, -- 50 to 59
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 60 to 69
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 70 to 79
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 80 to 89
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 90 to 99
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 100 to 109
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 110 to 119
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 120 to 129
- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 130 to 139
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 140 to 149
- 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, -- 150 to 159
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, -- 160 to 169
- 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, -- 170 to 179
- 2, 2, 2, 2, 2, 4, 2, 1, 2, -- 180 to 189 (except 186)
- 0, 0, 2, 2, 0, 0, 1, 3, 2, 2, -- 190 to 199
- 4, 4, 0, 2); -- 200, 201, 202, 209
-
- -- Instanciation of Enumeration_Io for ByteCode instructions display
- --------------------------------------------------------------------
- package ByteCode_Io is new Ada.Text_Io.Enumeration_Io (ByteCode);
-
- -- Conversion of a byte to a ByteCode
- -------------------------------------
- function Coded is new Ada.Unchecked_Conversion
- (Byte_Utilities.Byte, ByteCode);
-
- -- return a ByteCode from a Byte
- -- may raise E_Unknown_ByteCode
- --------------------------------
- function To_Bytecode
- (From : Byte_Utilities.Byte)
- return ByteCode is
- begin
- if From > 209 or else
- From = 186 or else
- (From > 202 and then From < 209) then
- raise E_Unkown_ByteCode;
- else
- return Coded (From);
- end if;
- exception
- when others =>
- raise E_Unkown_ByteCode;
- end To_Bytecode;
-
-
- function Operands_Number
- (Code : ByteCode)
- return Unsigned_32 is
- begin
- return Instructions_Operands (Code);
- end Operands_Number;
-
-
- procedure Display (Index : in out Unsigned_32;
- Bytes : in Byte_Utilities.Acc_Bytes;
- Context : in CP.Acc_CP_Infos) is
- Instruction : ByteCode;
-
- -- this a one Integer_8 argument instruction, displays it
- ---------------------------------------------------------
- procedure Display_Integer_8 is
- Arg : Integer_8 := Byte_Utilities.Get_Integer_8 (Bytes, Index +1);
- begin
- Ada.Text_Io.Put (Integer_8'Image (Arg));
- end Display_Integer_8;
-
- -- this a one Unsigned_8 argument instruction, displays it
- ---------------------------------------------------------
- procedure Display_Unsigned_8 is
- Arg : Unsigned_8 := Bytes (Index +1);
- begin
- Ada.Text_Io.Put (Unsigned_8'Image (Arg));
- end Display_Unsigned_8;
-
- -- this a one Unsigned_8 argument followed by
- -- an Integer_8 argument instruction, displays them
- ---------------------------------------------------
- procedure Display_Couple is
- Arg : Unsigned_8 := Bytes (Index +1);
- Val : Integer_8 := Byte_Utilities.Get_Integer_8 (Bytes, Index +2);
- begin
- Ada.Text_Io.Put (Unsigned_8'Image (Arg));
- Ada.Text_Io.Put (Integer_8'Image (Val));
- end Display_Couple;
-
- -- this a one Integer_16 argument instruction, displays it
- ----------------------------------------------------------
- procedure Display_Integer_16 is
- Arg : Integer_16 := Byte_Utilities.Get_Integer_16 (Bytes, Index +1);
- begin
- Ada.Text_Io.Put (Integer_16'Image (Arg));
- end Display_Integer_16;
-
- -- this a one Integer_16 argument instruction with offset, displays it
- ----------------------------------------------------------------------
- procedure Display_Integer_16_Offset is
- Initial_Offset : Integer_16 := Integer_16 (Index - 1);
- Arg : Integer_16 := Byte_Utilities.Get_Integer_16 (Bytes, Index +1);
- begin
- Ada.Text_Io.Put (Integer_16'Image (Arg + Initial_Offset));
- end Display_Integer_16_Offset;
-
- -- this a one Unsigned_16 argument instruction, displays it
- -----------------------------------------------------------
- procedure Display_Unsigned_16 is
- Arg : Unsigned_16 := Byte_Utilities.Get_Unsigned_16 (Bytes, Index +1);
- begin
- Ada.Text_Io.Put (Unsigned_16'Image (Arg));
- end Display_Unsigned_16;
-
- -- this a one Integer_32 argument instruction, displays it
- ----------------------------------------------------------
- procedure Display_Integer_32 is
- Initial_Offset : Integer_32 := Integer_32 (Index - 1);
- Arg : Integer_32 := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- begin
- Ada.Text_Io.Put (Integer_32'Image (Arg + Initial_Offset));
- end Display_Integer_32;
-
- -- Display contents of Constant Pool with 8 bits index
- ------------------------------------------------------
- procedure Display_CP_8 is
- begin
- Ada.Text_Io.Put ("#");
- Unsigned_8_Io.Put (Item => Bytes (Index + 1), Width => 0);
- Ada.Text_Io.Put (" ");
- CP.Display (Context (Unsigned_16(Bytes (Index + 1))), Context);
- end Display_CP_8;
-
- -- Display contents of Constant Pool with 16 bits index
- -------------------------------------------------------
- procedure Display_CP_16 is
- Arg : Unsigned_16 := Byte_Utilities.Get_Unsigned_16 (Bytes, Index + 1);
- begin
- Ada.Text_Io.Put ("#");
- Unsigned_16_Io.Put (Item => Arg, Width => 0);
- Ada.Text_Io.Put (" ");
- CP.Display (Context (Arg), Context);
- end Display_CP_16;
-
- -- Display instruction LookUpSwitch
- -- since this instruction has a variable number of arguments
- -- Index is incremented during this displaying process
- ------------------------------------------------------------
- procedure LookUpSwitch_Display is
- Initial_Offset : Integer_32 := Integer_32 (Index - 1);
- Default_Offset : Integer_32;
- NbPairs : Integer_32;
- Pair_Match : Integer_32;
- Pair_Offset : Integer_32;
- begin
- while (Index mod 4) /= 0 loop
- Index := Index + 1;
- end loop;
- Default_Offset := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- NbPairs := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Integer_32_Io.Put (Item => NbPairs, Width => 0);
- Ada.Text_Io.Put (": default=");
- Integer_32_Io.Put
- (Item => Default_Offset + Initial_Offset, Width => 0);
- for I in 1 .. NbPairs loop
- Ada.Text_Io.New_Line;
- Pair_Match := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Pair_Offset := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Integer_32_Io.Put (Item => Pair_Match, Width => 16);
- Ada.Text_Io.Put (": ");
- Integer_32_Io.Put
- (Item => Pair_Offset + Initial_Offset, Width => 0);
- end loop;
- end LookUpSwitch_Display;
-
- -- Display instruction TableSwitch
- -- since this instruction has a variable number of arguments
- -- Index is incremented during this displaying process
- ------------------------------------------------------------
- procedure TableSwitch_Display is
- Initial_Offset : Integer_32 := Integer_32 (Index - 1);
- Default_Offset : Integer_32;
- Low_Value : Integer_32;
- High_Value : Integer_32;
- Jump_Offset : Integer_32;
- begin
- while (Index mod 4) /= 0 loop
- Index := Index + 1;
- end loop;
- Default_Offset := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Low_Value := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- High_Value := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Integer_32_Io.Put (Item => Low_Value, Width => 0);
- Ada.Text_Io.Put (" to ");
- Integer_32_Io.Put (Item => High_Value, Width => 0);
- Ada.Text_Io.Put (": default=");
- Integer_32_Io.Put
- (Item => Default_Offset + Initial_Offset, Width => 0);
- for I in Low_Value .. High_Value loop
- Ada.Text_Io.New_Line;
- Jump_Offset := Byte_Utilities.Get_Integer_32 (Bytes, Index +1);
- Index := Index + 4;
- Integer_32_Io.Put (Item => I, Width => 16);
- Ada.Text_Io.Put (": ");
- Integer_32_Io.Put
- (Item => Jump_Offset + Initial_Offset, Width => 0);
- end loop;
- end TableSwitch_Display;
-
- begin
-
- -- get the ByteCode and display it
- ----------------------------------
- Instruction := To_Bytecode (Bytes (Index));
- Unsigned_32_Io.Put (Item => Index - 1, Width => 9);
- Ada.Text_Io.Put (" : ");
- ByteCode_Io.Put (Item => Instruction);
- Ada.Text_Io.Put (" ");
-
- -- Instruction operands display dispatching
- -------------------------------------------
- case Instruction is
-
- when Bipush =>
- Display_Integer_8;
-
- when Iload | Lload |
- Fload | Dload |
- Aload |
- Istore | Lstore |
- Fstore | Dstore |
- Astore | Wide |
- Newarray |
- Ret =>
- Display_Unsigned_8;
-
- when Sipush =>
- Display_Integer_16;
-
- when Ifeq | Ifnull | Iflt |
- Ifle | Ifne | Ifnonnull |
- Ifgt | Ifge | If_icmpeq |
- If_icmpne | If_icmplt |
- If_icmpgt | If_icmple |
- If_icmpge | If_acmpeq |
- If_acmpne | Gotoo | Jsr =>
- Display_Integer_16_Offset;
-
- when Ret_w =>
- Display_Unsigned_16;
-
- when Ldc1 =>
- Display_CP_8;
-
- when Ldc2 | Ldc2w |
- Putfield | Getfield |
- Putstatic | Getstatic |
- Invokevirtual |
- Invokenonvirtual |
- Invokestatic |
- Anewarray |
- New_object |
- Checkcast |
- Instanceof =>
- Display_CP_16;
-
- when Invokeinterface =>
- Ada.Text_Io.Put
- ("(args" &
- Unsigned_8'Image (Bytes (Index + 3)) & ") ");
- Display_CP_16;
-
- when Multianewarray =>
- Display_CP_16;
- Ada.Text_Io.Put (" dim:" & Unsigned_8'Image (Bytes (Index + 3)));
-
- when Goto_w | Jsr_w =>
- Display_Integer_32;
-
- when Iinc =>
- Display_Couple;
-
- when Lookupswitch =>
- LookUpSwitch_Display;
-
- when Tableswitch =>
- TableSwitch_Display;
-
- when others =>
- -- for the many instructions which don't get any parameter
- null;
- end case;
- Ada.Text_Io.New_Line;
-
- -- increments Index to the next Instruction
- -------------------------------------------
- Index := Index + 1 + Operands_Number (Instruction);
-
- end Display;
-
- begin
-
- -- Set setting to lowercase for ByteCode instructions display
- -------------------------------------------------------------
- ByteCode_Io.Default_Setting := Ada.Text_Io.Lower_Case;
-
- end ByteCode;
-