Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 Makefile                     |    3 +-
 include/jit/bytecode-to-ir.h |    1 +
 include/jit/compiler.h       |    2 +
 jit/arithmetic-bc.c          |   14 ++++++++---
 jit/bytecode-to-ir.c         |   39 ++++++++++++++++---------------
 jit/load-store-bc.c          |   52 ++++++++++++++++++++++++-----------------
 jit/wide-bc.c                |   41 +++++++++++++++++++++++++++++++++
 test/jit/Makefile            |    1 +
 8 files changed, 107 insertions(+), 46 deletions(-)
 create mode 100644 jit/wide-bc.c

diff --git a/Makefile b/Makefile
index 222da4e..3cd1ab2 100644
--- a/Makefile
+++ b/Makefile
@@ -87,7 +87,8 @@ JIT_OBJS = \
        jit/typeconv-bc.o       \
        jit/vtable.o            \
        jit/subroutine.o        \
-       jit/pc-map.o
+       jit/pc-map.o            \
+       jit/wide-bc.o
 
 VM_OBJS = \
        vm/bytecode.o           \
diff --git a/include/jit/bytecode-to-ir.h b/include/jit/bytecode-to-ir.h
index cb487cf..c1e9b80 100644
--- a/include/jit/bytecode-to-ir.h
+++ b/include/jit/bytecode-to-ir.h
@@ -15,5 +15,6 @@ typedef int (*convert_fn_t) (struct parse_context *);
 #  include <vm/bytecode-def.h>
 #undef BYTECODE
 
+int convert_instruction(struct parse_context *ctx);
 
 #endif /* JIT_BYTECODE_TO_IR_H */
diff --git a/include/jit/compiler.h b/include/jit/compiler.h
index f56371f..4613615 100644
--- a/include/jit/compiler.h
+++ b/include/jit/compiler.h
@@ -41,6 +41,8 @@ struct parse_context {
        unsigned long offset;
        unsigned long code_size;
        unsigned char opc;
+
+       bool is_wide;
 };
 
 void convert_expression(struct parse_context *ctx, struct expression *expr);
diff --git a/jit/arithmetic-bc.c b/jit/arithmetic-bc.c
index a9b9624..1493b27 100644
--- a/jit/arithmetic-bc.c
+++ b/jit/arithmetic-bc.c
@@ -234,21 +234,27 @@ int convert_iinc(struct parse_context *ctx)
        struct statement *store_stmt;
        struct expression *local_expression, *binop_expression,
            *const_expression;
-       unsigned char index;
-       char const_value;
+       unsigned int index;
+       int const_value;
 
        store_stmt = alloc_statement(STMT_STORE);
        if (!store_stmt)
                goto failed;
 
-       index = bytecode_read_u8(ctx->buffer);
+       if (ctx->is_wide) {
+               index = bytecode_read_u16(ctx->buffer);
+               const_value = bytecode_read_s16(ctx->buffer);
+       } else {
+               index = bytecode_read_u8(ctx->buffer);
+               const_value = bytecode_read_s8(ctx->buffer);
+       }
+
        local_expression = local_expr(J_INT, index);
        if (!local_expression)
                goto failed;
 
        store_stmt->store_dest = &local_expression->node;
 
-       const_value = bytecode_read_s8(ctx->buffer);
        const_expression = value_expr(J_INT, const_value);
        if (!const_expression)
                goto failed;
diff --git a/jit/bytecode-to-ir.c b/jit/bytecode-to-ir.c
index 4d61232..83e577a 100644
--- a/jit/bytecode-to-ir.c
+++ b/jit/bytecode-to-ir.c
@@ -55,8 +55,8 @@ static int convert_not_implemented(struct parse_context *ctx)
 
 #define convert_tableswitch    convert_not_implemented
 #define convert_lookupswitch   convert_not_implemented
-#define convert_wide           convert_not_implemented
-#define convert_goto_w         convert_not_implemented
+
+#define convert_goto_w         convert_goto
 
 #define BYTECODE(opc, name, size, type) [opc] = convert_ ## name,
 static convert_fn_t converters[] = {
@@ -161,6 +161,22 @@ error_oom:
        return NULL;
 }
 
+int convert_instruction(struct parse_context *ctx)
+{
+       convert_fn_t convert;
+
+       ctx->opc = bytecode_read_u8(ctx->buffer);
+
+       if (ctx->opc >= ARRAY_SIZE(converters))
+               return warn("%d out of bounds", ctx->opc), -EINVAL;
+
+       convert = converters[ctx->opc];
+       if (!convert)
+               return warn("no converter for %d found", ctx->opc), -EINVAL;
+
+       return convert(ctx);
+}
+
 static int do_convert_bb_to_ir(struct basic_block *bb)
 {
        struct compilation_unit *cu = bb->b_parent;
@@ -170,6 +186,7 @@ static int do_convert_bb_to_ir(struct basic_block *bb)
                .cu = cu,
                .bb = bb,
                .code = cu->method->code_attribute.code,
+               .is_wide = false,
        };
        int err = 0;
 
@@ -180,25 +197,9 @@ static int do_convert_bb_to_ir(struct basic_block *bb)
                stack_push(bb->mimic_stack, exception_ref_expr());
 
        while (buffer.pos < bb->end) {
-               convert_fn_t convert;
-
                ctx.offset = ctx.buffer->pos;   /* this is fragile */
-               ctx.opc = bytecode_read_u8(ctx.buffer);
-
-               if (ctx.opc >= ARRAY_SIZE(converters)) {
-                       warn("%d out of bounds", ctx.opc);
-                       err = -EINVAL;
-                       break;
-               }
-
-               convert = converters[ctx.opc];
-               if (!convert) {
-                       warn("no converter for %d found", ctx.opc);
-                       err = -EINVAL;
-                       break;
-               }
 
-               err = convert(&ctx);
+               err = convert_instruction(&ctx);
                if (err)
                        break;
        }
diff --git a/jit/load-store-bc.c b/jit/load-store-bc.c
index c6598ef..97bb44d 100644
--- a/jit/load-store-bc.c
+++ b/jit/load-store-bc.c
@@ -180,7 +180,7 @@ int convert_ldc2_w(struct parse_context *ctx)
        return __convert_ldc(ctx, idx);
 }
 
-static int convert_load(struct parse_context *ctx, unsigned char index, enum 
vm_type type)
+static int convert_load(struct parse_context *ctx, unsigned int index, enum 
vm_type type)
 {
        struct expression *expr;
 
@@ -192,47 +192,55 @@ static int convert_load(struct parse_context *ctx, 
unsigned char index, enum vm_
        return 0;
 }
 
+static unsigned int read_index(struct parse_context *ctx)
+{
+       if (ctx->is_wide)
+               return bytecode_read_u16(ctx->buffer);
+
+       return bytecode_read_u8(ctx->buffer);
+}
+
 int convert_iload(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_load(ctx, idx, J_INT);
 }
 
 int convert_lload(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_load(ctx, idx, J_LONG);
 }
 
 int convert_fload(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_load(ctx, idx, J_FLOAT);
 }
 
 int convert_dload(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_load(ctx, idx, J_DOUBLE);
 }
 
 int convert_aload(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_load(ctx, idx, J_REFERENCE);
 }
@@ -262,7 +270,7 @@ int convert_aload_n(struct parse_context *ctx)
        return convert_load(ctx, ctx->opc - OPC_ALOAD_0, J_REFERENCE);
 }
 
-static int convert_store(struct parse_context *ctx, unsigned long index, enum 
vm_type type)
+static int convert_store(struct parse_context *ctx, unsigned int index, enum 
vm_type type)
 {
        struct expression *src_expr, *dest_expr;
        struct statement *stmt = alloc_statement(STMT_STORE);
@@ -283,45 +291,45 @@ static int convert_store(struct parse_context *ctx, 
unsigned long index, enum vm
 
 int convert_istore(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_store(ctx, idx, J_INT);
 }
 
 int convert_lstore(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_store(ctx, idx, J_LONG);
 }
 
 int convert_fstore(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_store(ctx, idx, J_FLOAT);
 }
 
 int convert_dstore(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_store(ctx, idx, J_DOUBLE);
 }
 
 int convert_astore(struct parse_context *ctx)
 {
-       unsigned char idx;
+       unsigned int idx;
 
-       idx = bytecode_read_u8(ctx->buffer);
+       idx = read_index(ctx);
 
        return convert_store(ctx, idx, J_REFERENCE);
 }
diff --git a/jit/wide-bc.c b/jit/wide-bc.c
new file mode 100644
index 0000000..4e1f284
--- /dev/null
+++ b/jit/wide-bc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2009  Pekka Enberg
+ * 
+ * This file is released under the GPL version 2 with the following
+ * clarification and special exception:
+ *
+ *     Linking this library statically or dynamically with other modules is
+ *     making a combined work based on this library. Thus, the terms and
+ *     conditions of the GNU General Public License cover the whole
+ *     combination.
+ *
+ *     As a special exception, the copyright holders of this library give you
+ *     permission to link this library with independent modules to produce an
+ *     executable, regardless of the license terms of these independent
+ *     modules, and to copy and distribute the resulting executable under terms
+ *     of your choice, provided that you also meet, for each linked independent
+ *     module, the terms and conditions of the license of that module. An
+ *     independent module is a module which is not derived from or based on
+ *     this library. If you modify this library, you may extend this exception
+ *     to your version of the library, but you are not obligated to do so. If
+ *     you do not wish to do so, delete this exception statement from your
+ *     version.
+ *
+ * Please refer to the file LICENSE for details.
+ */
+
+#include "jit/bytecode-to-ir.h"
+#include "jit/compiler.h"
+
+#include "vm/bytecode.h"
+
+int convert_wide(struct parse_context *ctx)
+{
+       int result;
+
+       ctx->is_wide = true;
+       result = convert_instruction(ctx);
+       ctx->is_wide = false;
+
+       return result;
+}
diff --git a/test/jit/Makefile b/test/jit/Makefile
index a8b2132..5834dca 100644
--- a/test/jit/Makefile
+++ b/test/jit/Makefile
@@ -42,6 +42,7 @@ OBJS = \
        ../../jit/typeconv-bc.o \
        ../../jit/subroutine.o \
        ../../jit/pc-map.o \
+       ../../jit/wide-bc.o \
        ../../lib/bitset.o \
        ../../lib/buffer.o \
        ../../lib/list.o \
-- 
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