コード例 #1
0
ファイル: compilation-unit-test.c プロジェクト: siam/jato
void test_no_basic_block_when_offset_out_of_range(void)
{
	struct compilation_unit *cu = compilation_unit_alloc(&method);
	struct basic_block *block = alloc_basic_block(cu, 1, 2);

	list_add_tail(&block->bb_list_node, &cu->bb_list);
	assert_ptr_equals(NULL, find_bb(cu, 0));
	assert_ptr_equals(NULL, find_bb(cu, 2));

	free_compilation_unit(cu);
}
コード例 #2
0
ファイル: branch-bc.c プロジェクト: vegard/jato
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;
}
コード例 #3
0
ファイル: statement.c プロジェクト: kele86838437/jato
struct tableswitch *alloc_tableswitch(struct tableswitch_info *info,
				      struct compilation_unit *cu,
				      struct basic_block *bb,
				      unsigned long offset)
{
	struct tableswitch *table;

	table = malloc(sizeof(*table));
	if (!table)
		return NULL;

	table->src = bb;

	table->low = info->low;
	table->high = info->high;

	table->bb_lookup_table = malloc(sizeof(void *) * info->count);
	if (!table->bb_lookup_table) {
		free(table);
		return NULL;
	}

	for (unsigned int i = 0; i < info->count; i++) {
		int32_t target;

		target = read_s32(info->targets + i * 4);
		table->bb_lookup_table[i] = find_bb(cu, offset + target);
	}

	list_add(&table->list_node, &cu->tableswitch_list);

	return table;
}
コード例 #4
0
ファイル: statement.c プロジェクト: kele86838437/jato
struct lookupswitch *alloc_lookupswitch(struct lookupswitch_info *info,
				       struct compilation_unit *cu,
				       struct basic_block *bb,
				       unsigned long offset)
{
	struct lookupswitch *table;

	table = malloc(sizeof(*table));
	if (!table)
		return NULL;

	table->src = bb;

	table->count = info->count;

	table->pairs = malloc(sizeof(struct lookupswitch_pair) * info->count);
	if (!table->pairs) {
		free(table);
		return NULL;
	}

	for (unsigned int i = 0; i < info->count; i++) {
		int32_t target;

		target = read_lookupswitch_target(info, i);
		table->pairs[i].match = read_lookupswitch_match(info, i);
		table->pairs[i].bb_target = find_bb(cu, offset + target);
	}

	list_add(&table->list_node, &cu->lookupswitch_list);

	return table;
}
コード例 #5
0
ファイル: compilation-unit-test.c プロジェクト: siam/jato
void test_find_basic_block(void)
{
	struct basic_block *b1;
	struct basic_block *b2;
	struct basic_block *b3;
	struct compilation_unit *cu = compilation_unit_alloc(&method);

	b1 = alloc_basic_block(cu, 0, 3);
	b2 = alloc_basic_block(cu, 3, 5);
	b3 = alloc_basic_block(cu, 5, 6);

	list_add_tail(&b1->bb_list_node, &cu->bb_list);
	list_add_tail(&b2->bb_list_node, &cu->bb_list);
	list_add_tail(&b3->bb_list_node, &cu->bb_list);

	assert_ptr_equals(b1, find_bb(cu, 2));
	assert_ptr_equals(b2, find_bb(cu, 3));
	assert_ptr_equals(b3, find_bb(cu, 5));

	free_compilation_unit(cu);
}
コード例 #6
0
ファイル: branch-bc.c プロジェクト: vegard/jato
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;
}
コード例 #7
0
ファイル: switch-bc.c プロジェクト: headius/jato
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;
}
コード例 #8
0
ファイル: switch-bc.c プロジェクト: headius/jato
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;
}