Esempio n. 1
0
void test_convert_swap(void)
{
	struct expression *expr1;
	struct expression *expr2;

	expr1 = value_expr(J_INT, 1);
	expr2 = value_expr(J_INT, 2);

	assert_swap_stack(OPC_SWAP, expr1, expr2);

	expr_put(expr1);
	expr_put(expr2);
}
Esempio n. 2
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
static void assert_convert_ldc_w_float(enum vm_type expected_type,
                                       double expected_value,
                                       uint8_t cp_type, unsigned long opcode)
{
    unsigned char code[] = { opcode, 0x01, 0x00 };
    uint32_t cp_infos[NR_CP_ENTRIES];
    uint8_t cp_types[NR_CP_ENTRIES];
    struct expression *expr;
    struct basic_block *bb;

    if (opcode == OPC_LDC_W)
        const_set_float(cp_infos, 0x100, (float) expected_value);
    else
        const_set_double(cp_infos, 0x100, expected_value);
    cp_types[0x100] = cp_type;

    bb = alloc_simple_bb(code, ARRAY_SIZE(code));
    convert_ir_const(bb->b_parent, cp_infos, NR_CP_ENTRIES, cp_types);

    expr = stack_pop(bb->mimic_stack);
    assert_fvalue_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 5
0
void test_convert_dup(void)
{
	struct expression *value1, *value2, *value3;

	value1 = value_expr(J_REFERENCE, 0xdeadbeef);
	value2 = value_expr(J_REFERENCE, 0xcafedeca);
	value3 = value_expr(J_LONG, 0xcafecafecafecafe);

	assert_dup_stack(OPC_DUP, value1);
	assert_dup2_stack(OPC_DUP2, value1, value2);
	assert_dup2_stack(OPC_DUP2, value3, NULL);

	expr_put(value1);
	expr_put(value2);
	expr_put(value3);
}
Esempio n. 6
0
void test_convert_dup_x1(void)
{
	struct expression *value1, *value2, *value3;

	value1 = value_expr(J_REFERENCE, 0xdeadbeef);
	value2 = value_expr(J_REFERENCE, 0xcafebabe);
	value3 = value_expr(J_LONG, 0xdecacafebabebeef);

	assert_dup_x1_stack(OPC_DUP_X1, value1, value2);
	assert_dup2_x1_stack(OPC_DUP2_X1, value1, value2, value3);
	assert_dup2_x1_stack(OPC_DUP2_X1, value3, value2, value1);

	expr_put(value1);
	expr_put(value2);
	expr_put(value3);
}
Esempio n. 7
0
static void __assert_convert_load(unsigned char *code,
                                  unsigned long code_size,
                                  enum vm_type expected_type,
                                  unsigned char expected_index)
{
    struct expression *expr;
    struct statement *stmt;
    struct basic_block *bb;

    bb = alloc_simple_bb(code, code_size);

    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_temporary_expr(expected_type, &expr->node);

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

    assert_store_stmt(stmt);
    assert_local_expr(expected_type, expected_index, stmt->store_src);
    assert_ptr_equals(&expr->node, stmt->store_dest);

    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 8
0
struct expression *
convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method *method)
{
	struct expression *args_list = NULL;
	unsigned long nr_total_args;
	unsigned long i;

	nr_total_args = nr_args;

	if (vm_method_is_jni(method)) {
		if (vm_method_is_static(method))
			nr_total_args++;

		nr_total_args++;
	}

	if (nr_total_args == 0) {
		args_list = no_args_expr();
		goto out;
	}

	/*
	 * We scan the args map in reverse order, since the order of arguments
	 * is already reversed.
	 */
	for (i = 0; i < nr_args; i++) {
		struct expression *expr = stack_pop(mimic_stack);

		if (vm_type_is_pair(expr->vm_type))
			i++;

		if (i >= nr_args)
			break;

		args_list = insert_arg(args_list, expr, method, nr_total_args - i - 1);
	}

	if (vm_method_is_jni(method)) {
		struct expression *expr;

		if (vm_method_is_static(method)) {
			expr = value_expr(J_REFERENCE, (unsigned long) method->class->object);
			if (!expr)
				goto error;

			args_list = insert_arg(args_list, expr, method, 1);
		}

		/*
		 * JNI methods also need a pointer to JNI environment. That's
		 * done in jni_trampoline automagically which is why we never
		 * use method index zero here for JNI methods.
		 */
	}
  out:
	return args_list;
  error:
	expr_put(args_list);
	return NULL;
}
Esempio n. 9
0
void test_convert_dup_x2(void)
{
	struct expression *value1, *value2, *value3, *value4;

	value1 = value_expr(J_REFERENCE, 0xdeadbeef);
	value2 = value_expr(J_REFERENCE, 0xcafebabe);
	value3 = value_expr(J_REFERENCE, 0xb4df00d);
	value4 = value_expr(J_REFERENCE, 0x6559570);

	assert_dup_x2_stack(OPC_DUP_X2, value1, value2, value3);
	assert_dup2_x2_stack(OPC_DUP2_X2, value1, value2, value3, value4);

	expr_put(value1);
	expr_put(value2);
	expr_put(value3);
	expr_put(value4);
}
Esempio n. 10
0
/* The returned pointer could be stale because of expr_put() so only use the
   return value for pointer comparison.  */
static struct expression *pop_and_put_expr(struct stack *stack)
{
	struct expression *expr;

	expr = stack_pop(stack);
	expr_put(expr);

	return expr;
}
Esempio n. 11
0
static char *
__expr_get(struct num_exp_ctx *ctx, int eof_okay)
{
	char	*s;

	if ((s = ctx->unget) != NULL) {
		ctx->unget = NULL;
		return s;
	}

	ctx->j = 0;
	do {
		if ((s = ctx->str) == NULL || *s == '\0') {
			if (ctx->argc == 0) {
				if (eof_okay)
					return NULL;
				expr_fail(ctx);
			}
			ctx->str = s = *(ctx->argv++);
			ctx->argc--;
		}

		while (isspace(*s))
			s++;
	} while (*s == '\0');

	if (isdigit(*s)) {
		while (isdigit(*s))
			expr_put(ctx, *s++);
	} else if (*s == '$') {
		expr_put(ctx, *s++);
		while (isalnum(*s) || *s == '-' || *s == '_')
			expr_put(ctx, *s++);
	} else if (strchr("*/+-()|&", *s)) {
		expr_put(ctx, *s++);
	} else {
		expr_fail(ctx);
	}
	ctx->str = s;

	expr_put(ctx, '\0');
	return ctx->word;
}
Esempio n. 12
0
int convert_pop2(struct parse_context *ctx)
{
	struct expression *another_expr;
	struct expression *expr;

	expr = stack_pop(ctx->bb->mimic_stack);

	if (vm_type_is_pair(expr->vm_type))
		goto out;

	another_expr = stack_peek(ctx->bb->mimic_stack);

	if (vm_type_is_pair(another_expr->vm_type))
		goto out;

	expr_put(stack_pop(ctx->bb->mimic_stack));
out:
	expr_put(expr);

	return 0;
}
Esempio n. 13
0
void free_expression(struct expression *expr)
{
	int i;

	if (!expr)
		return;

	for (i = 0; i < expr_nr_kids(expr); i++)
		if (expr->node.kids[i])
			expr_put(to_expr(expr->node.kids[i]));

	free(expr);
}
Esempio n. 14
0
void free_statement(struct statement *stmt)
{
	int i;

	if (!stmt)
		return;

	for (i = 0; i < stmt_nr_kids(stmt); i++)
		if (stmt->node.kids[i])
			expr_put(to_expr(stmt->node.kids[i]));

	switch (stmt_type(stmt)) {
	case STMT_INVOKE:
	case STMT_INVOKEVIRTUAL:
	case STMT_INVOKEINTERFACE:
		if (stmt->invoke_result)
			expr_put(stmt->invoke_result);
		break;
	default:
		break;
	}

	free(stmt);
}
Esempio n. 15
0
static void assert_convert_fconst(enum vm_type expected_type,
                                  double expected_value, unsigned char opc)
{
    struct expression *expr;
    struct basic_block *bb;

    bb = alloc_simple_bb(&opc, 1);
    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_fvalue_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 16
0
static void __assert_convert_const(enum vm_type expected_type,
                                   long long expected_value,
                                   unsigned char *code,
                                   unsigned long code_size)
{
    struct expression *expr;
    struct basic_block *bb;

    bb = alloc_simple_bb(code, code_size);
    convert_to_ir(bb->b_parent);

    expr = stack_pop(bb->mimic_stack);
    assert_value_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 17
0
static int convert_if(struct parse_context *ctx, enum binary_operator binop)
{
	struct statement *stmt;
	struct expression *if_value, *zero_value;

	zero_value = value_expr(J_INT, 0);
	if (!zero_value)
		return -ENOMEM;

	if_value = stack_pop(ctx->bb->mimic_stack);
	stmt = __convert_if(ctx, J_INT, binop, if_value, zero_value);
	if (!stmt) {
		expr_put(zero_value);
		return -ENOMEM;
	}
	convert_statement(ctx, stmt);
	return 0;
}
Esempio n. 18
0
static void assert_convert_ldc_w_string(enum vm_type expected_type, long long expected_value)
{
    unsigned char code[] = { OPC_LDC_W, 0x01, 0x00 };
    uint32_t cp_infos[NR_CP_ENTRIES];
    uint8_t cp_types[NR_CP_ENTRIES];
    struct basic_block *bb;
    struct expression *expr;

    const_set_int32_t(cp_infos, 0x100, 0x00);
    cp_types[0x100] = CAFEBABE_CONSTANT_TAG_STRING;

    bb = alloc_simple_bb(code, ARRAY_SIZE(code));
    convert_ir_const(bb->b_parent, cp_infos, NR_CP_ENTRIES, cp_types);

    expr = stack_pop(bb->mimic_stack);
    assert_value_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 19
0
static void assert_convert_ldc_float(float expected_value)
{
    unsigned char code[] = { OPC_LDC, 0xff };
    uint32_t cp_infos[NR_CP_ENTRIES];
    uint8_t cp_types[NR_CP_ENTRIES];
    struct expression *expr;
    struct basic_block *bb;

    const_set_float(cp_infos, 0xff, expected_value);
    cp_types[0xff] = CAFEBABE_CONSTANT_TAG_FLOAT;

    bb = alloc_simple_bb(code, ARRAY_SIZE(code));
    convert_ir_const(bb->b_parent, cp_infos, NR_CP_ENTRIES, cp_types);

    expr = stack_pop(bb->mimic_stack);
    assert_fvalue_expr(J_FLOAT, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 20
0
static void assert_convert_ldc(enum vm_type expected_type,
                               long long expected_value, uint8_t cp_type)
{
    uint32_t cp_infos[NR_CP_ENTRIES];
    uint8_t cp_types[NR_CP_ENTRIES];
    unsigned char code[] = { OPC_LDC, 0xff };
    struct expression *expr;
    struct basic_block *bb;

    const_set_int32_t(cp_infos, 0xff, expected_value);
    cp_types[0xff] = cp_type;

    bb = alloc_simple_bb(code, ARRAY_SIZE(code));
    convert_ir_const(bb->b_parent, cp_infos, NR_CP_ENTRIES, cp_types);

    expr = stack_pop(bb->mimic_stack);
    assert_value_expr(expected_type, expected_value, &expr->node);
    assert_true(stack_is_empty(bb->mimic_stack));

    expr_put(expr);
    free_simple_bb(bb);
}
Esempio n. 21
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;
}
Esempio n. 22
0
int convert_pop(struct parse_context *ctx)
{
	expr_put(stack_pop(ctx->bb->mimic_stack));

	return 0;
}
Esempio n. 23
0
static void assert_print_expr(struct string *expected, struct expression *expr)
{
	assert_tree_print(expected, &expr->node);
	expr_put(expr);
}