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;
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
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 );
}
Exemple #5
0
static void assert_print_stmt(struct string *expected, struct statement *stmt)
{
	assert_tree_print(expected, &stmt->node);
	free_statement(stmt);
}