void test_should_print_binop_expression(void) { assert_printed_binop_expr(str_aprintf( "BINOP:\n" " vm_type: [int]\n" " binary_operator: [add]\n" " binary_left: [value int 0x0]\n" " binary_right: [value int 0x1]\n"), J_INT, OP_ADD, value_expr(J_INT, 0), value_expr(J_INT, 1)); assert_printed_binop_expr(str_aprintf( "BINOP:\n" " vm_type: [long]\n" " binary_operator: [add]\n" " binary_left: [value long 0x1]\n" " binary_right:\n" " BINOP:\n" " vm_type: [long]\n" " binary_operator: [sub]\n" " binary_left: [value long 0x2]\n" " binary_right: [value long 0x3]\n"), J_LONG, OP_ADD, value_expr(J_LONG, 1), binop_expr(J_LONG, OP_SUB, value_expr(J_LONG, 2), value_expr(J_LONG, 3))); }
void assert_printed_array_deref_expr(struct string *expected, enum vm_type type, unsigned long arrayref, unsigned long array_index) { struct expression *expr; expr = array_deref_expr(type, value_expr(J_REFERENCE, arrayref), value_expr(J_INT, array_index)); assert_print_expr(expected, expr); }
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); }
void test_should_print_conversion_expression(void) { assert_printed_conversion_expr(str_aprintf( "CONVERSION:\n" " vm_type: [long]\n" " from_expression: [value int 0x0]\n"), J_LONG, value_expr(J_INT, 0)); assert_printed_conversion_expr(str_aprintf( "CONVERSION:\n" " vm_type: [int]\n" " from_expression: [value boolean 0x1]\n"), J_INT, value_expr(J_BOOLEAN, 1)); }
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); }
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); }
void test_should_print_unary_op_expression(void) { assert_printed_unary_op_expr(str_aprintf( "UNARY_OP:\n" " vm_type: [int]\n" " unary_operator: [neg]\n" " unary_expression: [value int 0x0]\n"), J_INT, OP_NEG, value_expr(J_INT, 0)); assert_printed_unary_op_expr(str_aprintf( "UNARY_OP:\n" " vm_type: [boolean]\n" " unary_operator: [neg]\n" " unary_expression: [value boolean 0x1]\n"), J_BOOLEAN, OP_NEG, value_expr(J_BOOLEAN, 1)); }
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); }
void assert_printed_value_expr(struct string *expected, enum vm_type type, unsigned long long value) { struct expression *expr; expr = value_expr(type, value); assert_print_expr(expected, expr); }
static struct statement *branch_if_null_stmt(struct basic_block *target, struct expression *left) { struct expression *right_expr; right_expr = value_expr(J_NATIVE_PTR, 0); if (!right_expr) return NULL; return if_stmt(target, J_NATIVE_PTR, OP_EQ, left, right_expr); }
static struct statement *branch_if_greater_stmt(struct basic_block *target, struct expression *left, int32_t right) { struct expression *right_expr; right_expr = value_expr(J_INT, right); if (!right_expr) return NULL; return if_stmt(target, J_INT, OP_GT, left, right_expr); }
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; }
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); }
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; }
exprt boolbvt::bv_get_rec( const bvt &bv, const std::vector<bool> &unknown, std::size_t offset, const typet &type) const { if(type.id()==ID_symbol) return bv_get_rec(bv, unknown, offset, ns.follow(type)); std::size_t width=boolbv_width(type); assert(bv.size()==unknown.size()); assert(bv.size()>=offset+width); if(type.id()==ID_bool) { if(!unknown[offset]) { switch(prop.l_get(bv[offset]).get_value()) { case tvt::tv_enumt::TV_FALSE: return false_exprt(); case tvt::tv_enumt::TV_TRUE: return true_exprt(); default: return false_exprt(); // default } } return nil_exprt(); } bvtypet bvtype=get_bvtype(type); if(bvtype==IS_UNKNOWN) { if(type.id()==ID_array) { const typet &subtype=type.subtype(); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { exprt::operandst op; op.reserve(width/sub_width); for(std::size_t new_offset=0; new_offset<width; new_offset+=sub_width) { op.push_back( bv_get_rec(bv, unknown, offset+new_offset, subtype)); } exprt dest=exprt(ID_array, type); dest.operands().swap(op); return dest; } } else if(type.id()==ID_struct_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_struct_tag_type(type))); } else if(type.id()==ID_union_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_union_tag_type(type))); } else if(type.id()==ID_struct) { const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); std::size_t new_offset=0; exprt::operandst op; op.reserve(components.size()); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const typet &subtype=ns.follow(it->type()); op.push_back(nil_exprt()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { op.back()=bv_get_rec(bv, unknown, offset+new_offset, subtype); new_offset+=sub_width; } } struct_exprt dest(type); dest.operands().swap(op); return dest; } else if(type.id()==ID_union) { const union_typet &union_type=to_union_type(type); const union_typet::componentst &components=union_type.components(); assert(!components.empty()); // Any idea that's better than just returning the first component? std::size_t component_nr=0; union_exprt value(union_type); value.set_component_name( components[component_nr].get_name()); const typet &subtype=components[component_nr].type(); value.op()=bv_get_rec(bv, unknown, offset, subtype); return value; } else if(type.id()==ID_vector) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width%sub_width==0) { std::size_t size=width/sub_width; exprt value(ID_vector, type); value.operands().resize(size); for(std::size_t i=0; i<size; i++) value.operands()[i]= bv_get_rec(bv, unknown, i*sub_width, subtype); return value; } } else if(type.id()==ID_complex) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width==sub_width*2) { exprt value(ID_complex, type); value.operands().resize(2); value.op0()=bv_get_rec(bv, unknown, 0*sub_width, subtype); value.op1()=bv_get_rec(bv, unknown, 1*sub_width, subtype); return value; } } } std::string value; for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++) { char ch; if(unknown[bit_nr]) ch='0'; else switch(prop.l_get(bv[bit_nr]).get_value()) { case tvt::tv_enumt::TV_FALSE: ch='0'; break; case tvt::tv_enumt::TV_TRUE: ch='1'; break; case tvt::tv_enumt::TV_UNKNOWN: ch='0'; break; default: assert(false); } value=ch+value; } switch(bvtype) { case IS_UNKNOWN: if(type.id()==ID_string) { mp_integer int_value=binary2integer(value, false); irep_idt s; if(int_value>=string_numbering.size()) s=irep_idt(); else s=string_numbering[int_value.to_long()]; return constant_exprt(s, type); } break; case IS_RANGE: { mp_integer int_value=binary2integer(value, false); mp_integer from=string2integer(type.get_string(ID_from)); constant_exprt value_expr(type); value_expr.set_value(integer2string(int_value+from)); return value_expr; } break; default: case IS_C_ENUM: constant_exprt value_expr(type); value_expr.set_value(value); return value_expr; } return nil_exprt(); }