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