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