static struct statement *__convert_if(struct parse_context *ctx, enum vm_type vm_type, enum binary_operator binop, struct expression *binary_left, struct expression *binary_right) { struct basic_block *true_bb; struct expression *if_conditional; struct statement *if_stmt; int32_t if_target; if_target = bytecode_read_branch_target(ctx->opc, ctx->buffer); true_bb = find_bb(ctx->cu, ctx->offset + if_target); if_conditional = binop_expr(vm_type, binop, binary_left, binary_right); if (!if_conditional) goto failed; if_stmt = alloc_statement(STMT_IF); if (!if_stmt) goto failed_put_expr; if_stmt->if_true = true_bb; if_stmt->if_conditional = &if_conditional->node; return if_stmt; failed_put_expr: expr_put(if_conditional); failed: return NULL; }
void test_should_print_void_return_statement(void) { struct statement *stmt; stmt = alloc_statement(STMT_VOID_RETURN); assert_print_stmt(str_aprintf("VOID_RETURN\n"), stmt); }
Statement * crb_create_continue_statement(char *label) { Statement *st; st = alloc_statement(CONTINUE_STATEMENT); st->u.continue_s.label = label; return st; }
Statement * crb_create_throw_statement(Expression *expression) { Statement *st; st = alloc_statement(THROW_STATEMENT); st->u.throw_s.exception = expression; return st; }
Statement * crb_create_return_statement(Expression *expression) { Statement *st; st = alloc_statement(RETURN_STATEMENT); st->u.return_s.return_value = expression; return st; }
Statement * crb_create_break_statement(char *label) { Statement *st; st = alloc_statement(BREAK_STATEMENT); st->u.break_s.label = label; return st; }
Statement * crb_create_global_statement(IdentifierList *identifier_list) { Statement *st; st = alloc_statement(GLOBAL_STATEMENT); st->u.global_s.identifier_list = identifier_list; return st; }
Statement * crb_create_expression_statement(Expression *expression) { Statement *st; st = alloc_statement(EXPRESSION_STATEMENT); st->u.expression_s = expression; return st; }
void test_should_print_goto_statement(void) { struct statement *stmt; struct basic_block *goto_target = (void *) 0xdeadbeef; stmt = alloc_statement(STMT_GOTO); stmt->goto_target = goto_target; assert_print_stmt(str_aprintf( "GOTO:\n" " goto_target: [bb %p]\n", goto_target), stmt); }
Statement * crb_create_while_statement(char *label, Expression *condition, CRB_Block *block) { Statement *st; st = alloc_statement(WHILE_STATEMENT); st->u.while_s.label = label; st->u.while_s.condition = condition; st->u.while_s.block = block; return st; }
void test_should_print_arraycheck_statement(void) { struct expression *expression; struct statement *stmt; expression = local_expr(J_INT, 0); stmt = alloc_statement(STMT_ARRAY_CHECK); stmt->expression = &expression->node; assert_print_stmt(str_aprintf( "ARRAY_CHECK:\n" " expression: [local int 0]\n"), stmt); }
void test_should_print_return_statement(void) { struct expression *return_value; struct statement *stmt; return_value = local_expr(J_INT, 0); stmt = alloc_statement(STMT_RETURN); stmt->return_value = &return_value->node; assert_print_stmt(str_aprintf( "RETURN:\n" " return_value: [local int 0]\n"), stmt); }
Statement * crb_create_foreach_statement(char *label, char *variable, Expression *collection, CRB_Block *block) { Statement *st; st = alloc_statement(FOREACH_STATEMENT); st->u.foreach_s.label = label; st->u.foreach_s.variable = variable; st->u.foreach_s.collection = collection; st->u.for_s.block = block; return st; }
Statement * crb_create_try_statement(CRB_Block *try_block, char *exception, CRB_Block *catch_block, CRB_Block *finally_block) { Statement *st; st = alloc_statement(TRY_STATEMENT); st->u.try_s.try_block = try_block; st->u.try_s.catch_block = catch_block; st->u.try_s.exception = exception; st->u.try_s.finally_block = finally_block; return st; }
void test_should_print_monitorexit_statement(void) { struct expression *expr; struct statement *stmt; expr = local_expr(J_INT, 0); stmt = alloc_statement(STMT_MONITOR_EXIT); stmt->expression = &expr->node; assert_print_stmt(str_aprintf( "MONITOR_EXIT:\n" " expression: [local int 0]\n"), stmt); }
void test_should_print_expression_statement(void) { struct expression *expression; struct statement *stmt; expression = local_expr(J_INT, 0); stmt = alloc_statement(STMT_EXPRESSION); stmt->expression = &expression->node; assert_print_stmt(str_aprintf( "EXPRESSION:\n" " expression: [local int 0]\n"), stmt); }
int convert_iinc(struct parse_context *ctx) { struct statement *store_stmt; struct expression *local_expression, *binop_expression, *const_expression; unsigned int index; int const_value; store_stmt = alloc_statement(STMT_STORE); if (!store_stmt) goto failed; 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_expression = value_expr(J_INT, const_value); if (!const_expression) goto failed; expr_get(local_expression); binop_expression = binop_expr(J_INT, OP_ADD, local_expression, const_expression); if (!binop_expression) { expr_put(local_expression); expr_put(const_expression); goto failed; } store_stmt->store_src = &binop_expression->node; convert_statement(ctx, store_stmt); return 0; failed: free_statement(store_stmt); return warn("out of memory"), -ENOMEM; }
Statement * crb_create_for_statement(char *label, Expression *init, Expression *cond, Expression *post, CRB_Block *block) { Statement *st; st = alloc_statement(FOR_STATEMENT); st->u.for_s.label = label; st->u.for_s.init = init; st->u.for_s.condition = cond; st->u.for_s.post = post; st->u.for_s.block = block; return st; }
Statement * crb_create_if_statement(Expression *condition, CRB_Block *then_block, Elsif *elsif_list, CRB_Block *else_block) { Statement *st; st = alloc_statement(IF_STATEMENT); st->u.if_s.condition = condition; st->u.if_s.then_block = then_block; st->u.if_s.elsif_list = elsif_list; st->u.if_s.else_block = else_block; return st; }
void test_should_print_checkcast_statement(void) { struct expression *expr; struct statement *stmt; expr = local_expr(J_INT, 0); stmt = alloc_statement(STMT_CHECKCAST); stmt->checkcast_ref = &expr->node; stmt->checkcast_class = &vmc; assert_print_stmt(str_aprintf( "CHECKCAST:\n" " checkcast_type: [%p '%s']\n" " checkcast_ref: [local int 0]\n", &vmc, vmc.name), stmt); }
void test_should_print_store_statement(void) { struct expression *dest, *src; struct statement *stmt; dest = local_expr(J_INT, 0); src = value_expr(J_INT, 1); stmt = alloc_statement(STMT_STORE); stmt->store_dest = &dest->node; stmt->store_src = &src->node; assert_print_stmt(str_aprintf( "STORE:\n store_dest: [local int 0]\n" " store_src: [value int 0x1]\n"), stmt); }
struct expression * dup_expr(struct parse_context *ctx, struct expression *expr) { struct expression *dest; struct statement *stmt; dest = temporary_expr(expr->vm_type, ctx->cu); expr_get(dest); stmt = alloc_statement(STMT_STORE); stmt->store_dest = &dest->node; stmt->store_src = &expr->node; convert_statement(ctx, stmt); return dest; }
void test_should_print_if_statement(void) { struct expression *if_conditional; struct statement *stmt; struct basic_block *if_true = (void *) 0xdeadbeef; if_conditional = local_expr(J_BOOLEAN, 0); stmt = alloc_statement(STMT_IF); stmt->if_conditional = &if_conditional->node; stmt->if_true = if_true; assert_print_stmt(str_aprintf( "IF:\n" " if_conditional: [local boolean 0]\n" " if_true: [bb %p]\n", if_true), stmt); }
int convert_goto(struct parse_context *ctx) { struct basic_block *target_bb; struct statement *goto_stmt; int32_t goto_target; goto_target = bytecode_read_branch_target(ctx->opc, ctx->buffer); target_bb = find_bb(ctx->cu, goto_target + ctx->offset); goto_stmt = alloc_statement(STMT_GOTO); if (!goto_stmt) return -ENOMEM; goto_stmt->goto_target = target_bb; convert_statement(ctx, goto_stmt); return 0; }
int convert_athrow(struct parse_context *ctx) { struct stack *mimic_stack = ctx->bb->mimic_stack; struct expression *exception_ref; struct expression *nullcheck; struct statement *stmt; stmt = alloc_statement(STMT_ATHROW); if (!stmt) return -ENOMEM; exception_ref = stack_pop(mimic_stack); nullcheck = null_check_expr(exception_ref); if (!nullcheck) return -ENOMEM; stmt->exception_ref = &nullcheck->node; /* * According to the JVM specification athrow operation is * supposed to discard the java stack and push exception * reference on it. We don't do the latter because exception * reference is not transferred to exception handlers in * BC2IR layer. */ while (!stack_is_empty(mimic_stack)) { struct expression *expr = stack_pop(mimic_stack); expr_put(expr); } convert_statement(ctx, stmt); return 0; }
int main( int argc, char *argv[] ) /********************************/ { char fname[ PATH_MAX ]; FILE *fi; FILE *fo; char *p; int i; char *line; char *buff1; char *buff2; char *separators = " \t"; i = process_cmdl( argc, argv ); if( i == 0 ) { disp_usage(); return( -1 ); } strcpy( fname, argv[ i ] ); if( strrchr( fname, '.' ) == NULL ) strcat( fname, ".dlg" ); fi = fopen( fname, "r" ); if( fi == NULL ) { printf( "Could not open input file: %s\n", fname ); return( -1 ); } if( i + 1 < argc ) { strcpy( fname, argv[ i + 1 ] ); if( strrchr( fname, '.' ) == NULL ) { strcat( fname, ".dlg" ); } } else { strcpy( fname, "os2dlg.dlg" ); } fo = fopen( fname, "w" ); if( fo == NULL ) { printf( "Could not open input file: %s\n", fname ); return( -1 ); } alloc_statement( &dlg_hdr ); alloc_statement( &dlg_item ); line = malloc( MAX_LINE_LEN ); buff1 = malloc( MAX_LINE_LEN ); buff2 = malloc( MAX_LINE_LEN ); my_fgets( line, MAX_LINE_LEN, fi ); while( !feof( fi ) ) { while( !feof( fi ) ) { if( strstr( line, "DLGINCLUDE" ) != NULL ) { /********************** * source file format: * * DLGINCLUDE * BEGIN * filename * END * * converted to: * * DLGINCLUDE 1 filename */ p = malloc( MAX_LINE_LEN ); strcpy( p, line ); fprintf( fo, "%s 1 ", strtok( p, separators ) ); my_fgets( line, MAX_LINE_LEN, fi ); my_fgets( line, MAX_LINE_LEN, fi ); strcpy( p, line ); fprintf( fo, "%s\n", strtok( p, separators ) ); free( p ); my_fgets( line, MAX_LINE_LEN, fi ); my_fgets( line, MAX_LINE_LEN, fi ); } else if( strstr( line, "DIALOG" ) != NULL ) { p = malloc( MAX_LINE_LEN ); strcpy( p, line ); process_dialog_declaration( fi, fo, p ); strcpy( line, p ); free( p ); } else if( strstr( line, "BEGIN" ) != NULL ) { my_fgets( line, MAX_LINE_LEN, fi ); break; } else { #if !defined( OLD_FORMAT ) if( *line != '\0' ) #endif fprintf( fo, "%s\n", line ); my_fgets( line, MAX_LINE_LEN, fi ); } } p = ""; while( !feof( fi ) && strcmp( p, "END" ) ) { while( my_fgets( buff1, MAX_LINE_LEN, fi ) != NULL ) { if( check_statement( buff1 ) ) break; strncat( line, skip_separator( buff1 ), MAX_LINE_LEN ); } process_statement( line, fo ); strcpy( line, buff1 ); strcpy( buff2, buff1 ); p = strtok( buff2, separators ); } if( !feof( fi ) ) { fprintf( fo, "%sEND\n", STR_SPC ); } } free( buff2 ); free( buff1 ); free( line ); free_statement( &dlg_item ); free_statement( &dlg_hdr ); if( fi != NULL ) fclose( fi ); if( fo != NULL ) { #if defined( OLD_FORMAT ) fprintf( fo, "\n" ); #endif fclose( fo ); } if( !opt.quiet ) fprintf( stdout, "\nParsed %d dialogs.\n", dialogs_cnt ); if( opt.flist_data ) { for( i = 0; i < opt.flist_cnt; i++ ) free( opt.flist_data[ i ] ); free( opt.flist_data ); } return( 0 ); }
int convert_lookupswitch(struct parse_context *ctx) { struct lookupswitch_info info; struct lookupswitch *table; struct basic_block *master_bb; struct basic_block *default_bb; struct basic_block *b1; get_lookupswitch_info(ctx->code, ctx->offset, &info); ctx->buffer->pos += info.insn_size; default_bb = find_bb(ctx->cu, ctx->offset + info.default_target); if (!default_bb) goto fail_default_bb; master_bb = ctx->bb; b1 = bb_split(master_bb, master_bb->end); assert(b1); b1->has_branch = true; bb_add_successor(master_bb, default_bb ); bb_add_successor(master_bb, b1); for (unsigned int i = 0; i < info.count; i++) { struct basic_block *target_bb; int32_t target; target = read_lookupswitch_target(&info, i); target_bb = find_bb(ctx->cu, ctx->offset + target); if (!bb_successors_contains(b1, target_bb)) bb_add_successor(b1, target_bb); } table = alloc_lookupswitch(&info, ctx->cu, b1, ctx->offset); if (!table) return -ENOMEM; struct statement *if_null_stmt; struct statement *stmt; struct expression *key; struct expression *bsearch; struct expression *pure_bsearch; key = stack_pop(ctx->bb->mimic_stack); bsearch = lookupswitch_bsearch_expr(key, table); if (!bsearch) return -1; pure_bsearch = get_pure_expr(ctx, bsearch); if_null_stmt = branch_if_null_stmt(default_bb, pure_bsearch); if (!if_null_stmt) goto fail_null_stmt; stmt = alloc_statement(STMT_LOOKUPSWITCH_JUMP); if (!stmt) goto fail_stmt; expr_get(pure_bsearch); stmt->lookupswitch_target = &pure_bsearch->node; convert_statement(ctx, if_null_stmt); do_convert_statement(b1, stmt, ctx->offset); return 0; fail_stmt: free_statement(if_null_stmt); fail_null_stmt: free_lookupswitch(table); fail_default_bb: return -1; }
int convert_tableswitch(struct parse_context *ctx) { struct tableswitch_info info; struct tableswitch *table; struct basic_block *master_bb; struct basic_block *default_bb; struct basic_block *b1; struct basic_block *b2; get_tableswitch_info(ctx->code, ctx->offset, &info); ctx->buffer->pos += info.insn_size; default_bb = find_bb(ctx->cu, ctx->offset + info.default_target); if (!default_bb) goto fail_default_bb; master_bb = ctx->bb; b1 = bb_split(master_bb, master_bb->end); b2 = bb_split(b1, master_bb->end); assert(b1 && b2); master_bb->has_branch = true; b1->has_branch = true; b2->has_branch = true; bb_add_successor(master_bb, default_bb ); bb_add_successor(master_bb, b1); bb_add_successor(b1, default_bb ); bb_add_successor(b1, b2); for (unsigned int i = 0; i < info.count; i++) { struct basic_block *target_bb; int32_t target; target = read_s32(info.targets + i * 4); target_bb = find_bb(ctx->cu, ctx->offset + target); if (!bb_successors_contains(b2, target_bb)) bb_add_successor(b2, target_bb); } table = alloc_tableswitch(&info, ctx->cu, b2, ctx->offset); if (!table) return -ENOMEM; struct statement *if_lesser_stmt; struct statement *if_greater_stmt; struct statement *stmt; struct expression *pure_index; pure_index = get_pure_expr(ctx, stack_pop(ctx->bb->mimic_stack)); if_lesser_stmt = branch_if_lesser_stmt(default_bb, pure_index, info.low); if (!if_lesser_stmt) goto fail_lesser_stmt; expr_get(pure_index); if_greater_stmt = branch_if_greater_stmt(default_bb, pure_index, info.high); if (!if_greater_stmt) goto fail_greater_stmt; stmt = alloc_statement(STMT_TABLESWITCH); if (!stmt) goto fail_stmt; expr_get(pure_index); stmt->index = &pure_index->node; stmt->table = table; do_convert_statement(master_bb, if_lesser_stmt, ctx->offset); do_convert_statement(b1, if_greater_stmt, ctx->offset); do_convert_statement(b2, stmt, ctx->offset); return 0; fail_stmt: free_statement(if_greater_stmt); fail_greater_stmt: free_statement(if_lesser_stmt); fail_lesser_stmt: free_tableswitch(table); fail_default_bb: return -1; }