@@ -508,6 +508,49 @@ codet invokedynamic_synthetic_constructor(
508508 return std::move (result);
509509}
510510
511+ static symbol_exprt instantiate_new_object (
512+ const irep_idt &function_id,
513+ const symbolt &lambda_method_symbol,
514+ symbol_table_baset &symbol_table,
515+ code_blockt &result)
516+ {
517+ // We must instantiate the object, then call the requested constructor
518+ const auto &method_type = to_code_type (lambda_method_symbol.type );
519+ INVARIANT (
520+ method_type.get_bool (ID_constructor),
521+ " REF_NewInvokeSpecial lambda must refer to a constructor" );
522+ const auto &created_type = method_type.parameters ().at (0 ).type ();
523+ irep_idt created_class =
524+ to_struct_tag_type (created_type.subtype ()).get_identifier ();
525+
526+ // Call static init if it exists:
527+ irep_idt static_init_name = clinit_wrapper_name (created_class);
528+ if (const auto *static_init_symbol = symbol_table.lookup (static_init_name))
529+ {
530+ result.add (code_function_callt{static_init_symbol->symbol_expr (), {}});
531+ }
532+
533+ // Make a local to hold the new instance:
534+ irep_idt new_instance_var_basename = " newinvokespecial_instance" ;
535+ irep_idt new_instance_var_name =
536+ id2string (function_id) + " ::" + id2string (new_instance_var_basename);
537+ auxiliary_symbolt new_instance_var_symbol;
538+ new_instance_var_symbol.name = new_instance_var_name;
539+ new_instance_var_symbol.base_name = new_instance_var_basename;
540+ new_instance_var_symbol.mode = ID_java;
541+ new_instance_var_symbol.type = created_type;
542+ bool add_failed = symbol_table.add (new_instance_var_symbol);
543+ POSTCONDITION (!add_failed);
544+ symbol_exprt new_instance_var = new_instance_var_symbol.symbol_expr ();
545+ result.add (code_declt{new_instance_var});
546+
547+ // Instantiate the object:
548+ side_effect_exprt java_new_expr (ID_java_new, created_type, {});
549+ result.add (code_assignt{new_instance_var, java_new_expr});
550+
551+ return new_instance_var;
552+ }
553+
511554codet invokedynamic_synthetic_method (
512555 const irep_idt &function_id,
513556 symbol_table_baset &symbol_table,
@@ -565,8 +608,20 @@ codet invokedynamic_synthetic_method(
565608 const auto &lambda_method_symbol =
566609 ns.lookup (lambda_method_handle.get_lambda_method_identifier ());
567610 const auto handle_type = lambda_method_handle.get_handle_type ();
611+ const auto is_constructor_lambda =
612+ handle_type ==
613+ java_class_typet::method_handle_typet::LAMBDA_CONSTRUCTOR_HANDLE;
568614
569- if (return_type != empty_typet ())
615+ if (is_constructor_lambda)
616+ {
617+ auto new_instance_var = instantiate_new_object (
618+ function_id, lambda_method_symbol, symbol_table, result);
619+
620+ // Prepend the newly created object to the lambda arg list:
621+ lambda_method_args.insert (lambda_method_args.begin (), new_instance_var);
622+ }
623+
624+ if (return_type != empty_typet () && !is_constructor_lambda)
570625 {
571626 result.add (code_returnt (side_effect_expr_function_callt (
572627 lambda_method_symbol.symbol_expr (),
@@ -580,5 +635,12 @@ codet invokedynamic_synthetic_method(
580635 lambda_method_symbol.symbol_expr (), lambda_method_args));
581636 }
582637
638+ if (is_constructor_lambda)
639+ {
640+ // Return the newly-created object.
641+ result.add (code_returnt{
642+ typecast_exprt::conditional_cast (lambda_method_args.at (0 ), return_type)});
643+ }
644+
583645 return std::move (result);
584646}
0 commit comments