Exemplo n.º 1
0
static void assert_dup_x2_stack(unsigned char opc, struct expression *value1,
				struct expression *value2, struct expression *value3)
{
	struct basic_block *bb;
	struct statement *stmt;

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value3));
	stack_push(bb->mimic_stack, expr_get(value2));
	stack_push(bb->mimic_stack, expr_get(value1));

	convert_to_ir(bb->b_parent);
        stmt = stmt_entry(bb->stmt_list.next);

	assert_store_stmt(stmt);
	assert_ptr_equals(value1, to_expr(stmt->store_src));
	assert_temporary_expr(value1->vm_type, stmt->store_dest);

	assert_ptr_equals(to_expr(stmt->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value3, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));

	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Exemplo n.º 2
0
static void assert_dup2_x2_stack(unsigned char opc, struct expression *value1,
				struct expression *value2, struct expression *value3,
				struct expression *value4)
{
	struct statement *stmt, *stmt2;
	struct basic_block *bb;

	if (value1->vm_type == J_LONG || value1->vm_type == J_DOUBLE) {
		if (value2->vm_type == J_LONG || value2->vm_type == J_DOUBLE) {
			assert_dup_x1_stack(opc, value1, value2);
			return;
		} else {
			assert_dup_x2_stack(opc, value1, value2, value3);
			return;
		}
	} else {
		if (value3->vm_type == J_LONG || value3->vm_type == J_DOUBLE) {
			assert_dup2_x1_stack(opc, value1, value2, value3);
			return;
		}
	}

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value4));
	stack_push(bb->mimic_stack, expr_get(value3));
	stack_push(bb->mimic_stack, expr_get(value2));
	stack_push(bb->mimic_stack, expr_get(value1));

	convert_to_ir(bb->b_parent);
        stmt = stmt_entry(bb->stmt_list.next);
	stmt2 = stmt_entry(stmt->stmt_list_node.next);

	assert_store_stmt(stmt);
	assert_ptr_equals(value2, to_expr(stmt->store_src));
	assert_temporary_expr(value2->vm_type, stmt->store_dest);

	assert_store_stmt(stmt2);
	assert_ptr_equals(value1, to_expr(stmt2->store_src));
	assert_temporary_expr(value1->vm_type, stmt2->store_dest);

	assert_ptr_equals(to_expr(stmt2->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(to_expr(stmt->store_dest), pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value3, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value4, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));

	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Exemplo n.º 3
0
static int __convert_dup2(struct parse_context *ctx, struct expression *value1, struct expression *value2)
{
	struct expression *dup, *dup2;

	dup = get_pure_expr(ctx, value1);
	dup2 = get_pure_expr(ctx, value2);

	convert_expression(ctx, dup2);
	convert_expression(ctx, dup);
	convert_expression(ctx, dup_expr(ctx, expr_get(dup2)));
	convert_expression(ctx, dup_expr(ctx, expr_get(dup)));

	return 0;
}
Exemplo n.º 4
0
static void
expr_term(struct num_exp_ctx *ctx, unsigned int *vp)
{
	char	*tok;

	tok = expr_get(ctx);
	if (*tok == '(') {
		expr_eval(ctx, vp, 1);
		expr_expect(ctx, ')');
	} else if (isdigit(*tok)) {
		char	*ep;

		*vp = strtoul(tok, &ep, 0);
		if (*ep)
			expr_fail(ctx);
	} else if (*tok == '$') {
		sc_macro_t	*mac;
		char		*argv[32];
		int		argc;

		if (!(mac = find_macro(ctx->state->profile, tok + 1)))
			expr_fail(ctx);
		argc = build_argv(ctx->state, "<expr>", mac->value, argv, 32);
		if (argc < 0
		 || get_uint_eval(ctx->state, argc, argv, vp) < 0)
			expr_fail(ctx);
	} else {
		parse_error(ctx->state,
			"Unexpected token \"%s\" in expression",
			tok);
		expr_fail(ctx);
	}
}
Exemplo n.º 5
0
static void
assert_swap_stack(unsigned char opc, void *value1, void *value2)
{
	struct basic_block *bb;

	bb = alloc_simple_bb(&opc, 1);

	stack_push(bb->mimic_stack, expr_get(value1));
	stack_push(bb->mimic_stack, expr_get(value2));

	convert_to_ir(bb->b_parent);
	assert_ptr_equals(value1, pop_and_put_expr(bb->mimic_stack));
	assert_ptr_equals(value2, pop_and_put_expr(bb->mimic_stack));
	assert_true(stack_is_empty(bb->mimic_stack));

	free_simple_bb(bb);
}
Exemplo n.º 6
0
static void
expr_expect(struct num_exp_ctx *ctx, int c)
{
	char	*tok;

	tok = expr_get(ctx);
	if (tok[0] != (char)c || tok[1])
		expr_fail(ctx);
}
Exemplo n.º 7
0
static int __convert_dup(struct parse_context *ctx, struct expression *value)
{
	struct expression *dup;

	dup = get_pure_expr(ctx, value);

	convert_expression(ctx, dup);
	convert_expression(ctx, dup_expr(ctx, expr_get(dup)));

	return 0;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}