Skip to content

Commit f156307

Browse files
Split assign_array_from_json into two versions
Depending on whether the array has deterministic length or not. This will make it easier to allocate the array directly to the right size in the deterministic case.
1 parent 058849f commit f156307

File tree

1 file changed

+57
-20
lines changed

1 file changed

+57
-20
lines changed

jbmc/src/java_bytecode/assignments_from_json.cpp

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -457,18 +457,16 @@ static symbol_exprt nondet_length(
457457
}
458458

459459
/// One of the cases in the recursive algorithm: the case where \p expr
460-
/// represents an array.
460+
/// represents an array which is not flagged with @nondetLength.
461461
/// The length of the array is given by symbol \p given_length_expr.
462462
/// We assume that an array with this symbol as its length has already been
463463
/// allocated and that \p expr has been assigned to it.
464-
/// We add constraints on the length: if "nondetLength" is specified in \p json,
465-
/// then the number of elements specified in \p json should be less than or
466-
/// equal to the length of the array. Otherwise the number of elements should be
464+
/// We add an assume statement constraining the number of elements to be
467465
/// the exact length of the array.
468466
/// For the assignment of the array elements, see
469467
/// \ref assign_array_data_component_from_json.
470468
/// For the overall algorithm, see \ref assign_from_json_rec.
471-
static void assign_array_from_json(
469+
static void assign_det_length_array_from_json(
472470
const exprt &expr,
473471
const jsont &json,
474472
const exprt &given_length_expr,
@@ -481,18 +479,40 @@ static void assign_array_from_json(
481479
const json_arrayt json_array = get_untyped_array(json, element_type);
482480
const auto number_of_elements =
483481
from_integer(json_array.size(), java_int_type());
484-
info.block.add(code_assumet{[&]() -> exprt {
485-
if(has_nondet_length(json))
486-
{
487-
return and_exprt{
488-
binary_predicate_exprt{given_length_expr, ID_ge, number_of_elements},
489-
binary_predicate_exprt{
490-
given_length_expr,
491-
ID_le,
492-
from_integer(info.max_user_array_length, java_int_type())}};
493-
}
494-
return equal_exprt{given_length_expr, number_of_elements};
495-
}()});
482+
info.block.add(
483+
code_assumet{equal_exprt{given_length_expr, number_of_elements}});
484+
assign_array_data_component_from_json(expr, json, type_from_array, info);
485+
}
486+
487+
/// One of the cases in the recursive algorithm: the case where \p expr
488+
/// represents an array which is flagged with @nondetLength.
489+
/// The length of the array is given by symbol \p given_length_expr.
490+
/// We assume that an array with this symbol as its length has already been
491+
/// allocated and that \p expr has been assigned to it.
492+
/// We constrain the length of the array to be greater or equal to the number
493+
/// of elements specified in \p json.
494+
/// For the assignment of the array elements, see
495+
/// \ref assign_array_data_component_from_json.
496+
/// For the overall algorithm, see \ref assign_from_json_rec.
497+
static void assign_nondet_length_array_from_json(
498+
const exprt &expr,
499+
const jsont &json,
500+
const exprt &given_length_expr,
501+
const optionalt<std::string> &type_from_array,
502+
object_creation_infot &info)
503+
{
504+
PRECONDITION(is_java_array_type(expr.type()));
505+
const auto &element_type =
506+
java_array_element_type(to_struct_tag_type(expr.type().subtype()));
507+
const json_arrayt json_array = get_untyped_array(json, element_type);
508+
const auto number_of_elements =
509+
from_integer(json_array.size(), java_int_type());
510+
info.block.add(code_assumet{and_exprt{
511+
binary_predicate_exprt{given_length_expr, ID_ge, number_of_elements},
512+
binary_predicate_exprt{
513+
given_length_expr,
514+
ID_le,
515+
from_integer(info.max_user_array_length, java_int_type())}}});
496516
assign_array_data_component_from_json(expr, json, type_from_array, info);
497517
}
498518

@@ -771,8 +791,16 @@ static void assign_reference_from_json(
771791
{
772792
INVARIANT(
773793
reference.array_length, "an array reference should store its length");
774-
assign_array_from_json(
775-
reference.expr, json, *reference.array_length, type_from_array, info);
794+
if(has_nondet_length(json))
795+
{
796+
assign_nondet_length_array_from_json(
797+
reference.expr, json, *reference.array_length, type_from_array, info);
798+
}
799+
else
800+
{
801+
assign_det_length_array_from_json(
802+
reference.expr, json, *reference.array_length, type_from_array, info);
803+
}
776804
}
777805
else
778806
assign_struct_from_json(dereference_exprt(reference.expr), json, info);
@@ -814,7 +842,16 @@ void assign_from_json_rec(
814842
const exprt length =
815843
nondet_length(info.allocate_objects, info.block, info.loc);
816844
allocate_array(expr, length, info);
817-
assign_array_from_json(expr, json, length, type_from_array, info);
845+
if(has_nondet_length(json))
846+
{
847+
assign_nondet_length_array_from_json(
848+
expr, json, length, type_from_array, info);
849+
}
850+
else
851+
{
852+
assign_det_length_array_from_json(
853+
expr, json, length, type_from_array, info);
854+
}
818855
}
819856
else if(
820857
const auto runtime_type =

0 commit comments

Comments
 (0)