Wide instruction changes the size of arguments of the following instruction
from 8-bits to 16-bits.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/bytecode-def.h |    2 +-
 test/vm/bytecodes-test.c  |   24 ++++++++--------
 vm/bytecodes.c            |   62 +++++++++++++++++++++++++++++++++-----------
 3 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/include/vm/bytecode-def.h b/include/vm/bytecode-def.h
index 73b243f..ab41e0f 100644
--- a/include/vm/bytecode-def.h
+++ b/include/vm/bytecode-def.h
@@ -199,4 +199,4 @@ BYTECODE(OPC_SASTORE,               sastore,        1, 
BYTECODE_NORMAL)
 BYTECODE(OPC_SIPUSH,           sipush,         3, BYTECODE_NORMAL)
 BYTECODE(OPC_SWAP,             swap,           1, BYTECODE_NORMAL)
 BYTECODE(OPC_TABLESWITCH,      tableswitch,    0, BYTECODE_BRANCH | 
BYTECODE_VARIABLE_LEN)
-BYTECODE(OPC_WIDE,             wide,           3, BYTECODE_NORMAL)
+BYTECODE(OPC_WIDE,             wide,           0, BYTECODE_NORMAL | 
BYTECODE_VARIABLE_LEN)
diff --git a/test/vm/bytecodes-test.c b/test/vm/bytecodes-test.c
index 04c1949..24fc579 100644
--- a/test/vm/bytecodes-test.c
+++ b/test/vm/bytecodes-test.c
@@ -24,23 +24,23 @@ void test_size_of_bytecode(void)
 
 static void assert_wide_bc_insn_size(unsigned long expected_len, unsigned char 
opc)
 {
-       unsigned char code[] = { OPC_WIDE, opc, 0x00, 0x00, 0x00 };
+       unsigned char code[] = { OPC_WIDE, opc, 0x00, 0x00, 0x00, 0x00 };
        assert_int_equals(expected_len, bc_insn_size(code));
 }
 
 void test_size_of_wide_bytecode(void)
 {
-       assert_wide_bc_insn_size(5, OPC_ILOAD);
-       assert_wide_bc_insn_size(5, OPC_FLOAD);
-       assert_wide_bc_insn_size(5, OPC_ALOAD);
-       assert_wide_bc_insn_size(5, OPC_LLOAD);
-       assert_wide_bc_insn_size(5, OPC_DLOAD);
-       assert_wide_bc_insn_size(5, OPC_ISTORE);
-       assert_wide_bc_insn_size(5, OPC_FSTORE);
-       assert_wide_bc_insn_size(5, OPC_ASTORE);
-       assert_wide_bc_insn_size(5, OPC_LSTORE);
-       assert_wide_bc_insn_size(5, OPC_DSTORE);
-       assert_wide_bc_insn_size(5, OPC_RET);
+       assert_wide_bc_insn_size(4, OPC_ILOAD);
+       assert_wide_bc_insn_size(4, OPC_FLOAD);
+       assert_wide_bc_insn_size(4, OPC_ALOAD);
+       assert_wide_bc_insn_size(4, OPC_LLOAD);
+       assert_wide_bc_insn_size(4, OPC_DLOAD);
+       assert_wide_bc_insn_size(4, OPC_ISTORE);
+       assert_wide_bc_insn_size(4, OPC_FSTORE);
+       assert_wide_bc_insn_size(4, OPC_ASTORE);
+       assert_wide_bc_insn_size(4, OPC_LSTORE);
+       assert_wide_bc_insn_size(4, OPC_DSTORE);
+       assert_wide_bc_insn_size(4, OPC_RET);
        assert_wide_bc_insn_size(6, OPC_IINC);
 }
 
diff --git a/vm/bytecodes.c b/vm/bytecodes.c
index 2387be3..10a39a0 100644
--- a/vm/bytecodes.c
+++ b/vm/bytecodes.c
@@ -47,14 +47,18 @@ unsigned long bc_insn_size(const unsigned char *bc_start)
 {
        unsigned long size;
 
-       size = bytecode_infos[*bc_start].size;
-       if (*bc_start == OPC_WIDE)
-               size += bytecode_infos[*++bc_start].size;
+       if (*bc_start == OPC_WIDE) {
+               if (*(bc_start + 1) == OPC_IINC)
+                       return 6;
 
-       if (size == 0) {
-               printf("%s: Unknown bytecode opcode: 0x%x\n", __func__, 
*bc_start);
-               abort();
+               return 4;
        }
+
+       size = bytecode_infos[*bc_start].size;
+
+       if (size == 0)
+               error("unknown bytecode opcode: 0x%x\n", *bc_start);
+
        return size;
 }
 
@@ -156,30 +160,56 @@ void bc_set_target_off(unsigned char *code, long off)
        }
 }
 
+static char *bc_get_insn_name(const unsigned char *code)
+{
+       char buf[16];
+       int buf_index;
+
+       buf_index = 0;
+
+       if (*code == OPC_WIDE) {
+               strcpy(buf, "wide ");
+               buf_index = 5;
+               code++;
+       }
+
+       const char *opc_name = bytecode_infos[*code].name + 4;
+
+       while (*opc_name)
+               buf[buf_index++] = tolower(*opc_name++);
+
+       buf[buf_index] = 0;
+
+       return strdup(buf);
+}
+
 void bytecode_disassemble(const unsigned char *code, unsigned long size)
 {
        unsigned long pc;
 
        bytecode_for_each_insn(code, size, pc) {
-               const char *opc_name;
-               char tmp_name[16];
+               char *opc_name;
                int size;
-               int i;
 
-               opc_name = bytecode_infos[code[pc]].name + 4;
                size = bc_insn_size(&code[pc]);
 
-               for (i = 0; *opc_name; opc_name++, i++)
-                       tmp_name[i] = tolower(*opc_name);
+               printf("   [ %-3ld ]  0x%02x  ", pc, code[pc]);
 
-               tmp_name[i] = 0;
+               if (code[pc] == OPC_WIDE)
+                       size--;
 
-               printf("   [ %-3ld ]  0x%02x  ", pc, code[pc]);
+               opc_name = bc_get_insn_name(&code[pc]);
+               if (!opc_name) {
+                       printf("(string alloc failed)\n");
+                       continue;
+               }
 
                if (size > 1)
-                       printf("%-14s", tmp_name);
+                       printf("%-14s", opc_name);
                else
-                       printf("%s", tmp_name);
+                       printf("%s", opc_name);
+
+               free(opc_name);
 
                if (bc_is_branch(code[pc])) {
                        printf(" %ld\n", bc_target_off(&code[pc]) + pc);
-- 
1.6.0.6


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to