@@ -52,6 +52,7 @@ static typet clinit_states_type()
52
52
// Disable linter here to allow a std::string constant, since that holds
53
53
// a length, whereas a cstr would require strlen every time.
54
54
const std::string clinit_wrapper_suffix = " ::clinit_wrapper" ; // NOLINT(*)
55
+ const std::string json_clinit_suffix = " ::json_clinit" ; // NOLINT(*)
55
56
const std::string clinit_function_suffix = " .<clinit>:()V" ; // NOLINT(*)
56
57
57
58
// / Get the Java static initializer wrapper name for a given class (the wrapper
@@ -65,6 +66,11 @@ irep_idt clinit_wrapper_name(const irep_idt &class_name)
65
66
return id2string (class_name) + clinit_wrapper_suffix;
66
67
}
67
68
69
+ irep_idt json_clinit_name (const irep_idt &class_name)
70
+ {
71
+ return id2string (class_name) + json_clinit_suffix;
72
+ }
73
+
68
74
// / Check if function_id is a clinit wrapper
69
75
// / \param function_id: some function identifier
70
76
// / \return true if the passed identifier is a clinit wrapper
@@ -335,6 +341,21 @@ static void create_clinit_wrapper_function_symbol(
335
341
synthetic_methods);
336
342
}
337
343
344
+ // Create symbol for the "json_clinit"
345
+ static void create_json_clinit_function_symbol (
346
+ const irep_idt &class_name,
347
+ symbol_tablet &symbol_table,
348
+ synthetic_methods_mapt &synthetic_methods)
349
+ {
350
+ create_function_symbol (
351
+ class_name,
352
+ json_clinit_name (class_name),
353
+ " json_clinit" ,
354
+ synthetic_method_typet::JSON_STATIC_INITIALIZER,
355
+ symbol_table,
356
+ synthetic_methods);
357
+ }
358
+
338
359
// / Creates a static initializer wrapper symbol for the given class, along with
339
360
// / a global boolean that tracks if it has been run already.
340
361
// / \param class_name: class symbol name
@@ -716,17 +737,27 @@ code_ifthenelset get_clinit_wrapper_body(
716
737
return code_ifthenelset (std::move (check_already_run), std::move (init_body));
717
738
}
718
739
719
- // / Create static initializer wrappers for all classes that need them.
740
+ // / Create static initializer wrappers and possibly assignments from a JSON file
741
+ // / for all classes that need them.
742
+ // / For each class that will require a static initializer wrapper, create a
743
+ // / function named package.classname::clinit_wrapper, and a corresponding
744
+ // / global tracking whether it has run or not. If a JSON file containing static
745
+ // / values is given, also create a function named
746
+ // / package.classname::json_clinit.
720
747
// / \param symbol_table: global symbol table
721
748
// / \param synthetic_methods: synthetic methods map. Will be extended noting
722
749
// / that any wrapper belongs to this code, and so `get_clinit_wrapper_body`
723
750
// / should be used to produce the method body when required.
724
751
// / \param thread_safe: if true state variables required to make the
725
752
// / clinit_wrapper thread safe will be created.
726
- void create_static_initializer_wrappers (
753
+ // / \param is_json_clinit_needed: determines whether or not a symbol for the
754
+ // / synthetic json_clinit function should be created. This is true if a file
755
+ // / was given with the --static-values option and false otherwise.
756
+ void create_static_initializer_symbols (
727
757
symbol_tablet &symbol_table,
728
758
synthetic_methods_mapt &synthetic_methods,
729
- const bool thread_safe)
759
+ const bool thread_safe,
760
+ const bool is_json_clinit_needed)
730
761
{
731
762
// Top-sort the class hierarchy, such that we visit parents before children,
732
763
// and can so identify parents that need static initialisation by whether we
@@ -743,6 +774,11 @@ void create_static_initializer_wrappers(
743
774
{
744
775
create_clinit_wrapper_symbols (
745
776
class_identifier, symbol_table, synthetic_methods, thread_safe);
777
+ if (is_json_clinit_needed)
778
+ {
779
+ create_json_clinit_function_symbol (
780
+ class_identifier, symbol_table, synthetic_methods);
781
+ }
746
782
}
747
783
}
748
784
}
0 commit comments