#include "java_static_initializers.h"#include <util/arith_tools.h>#include <util/cprover_prefix.h>#include <util/json.h>#include <util/std_code.h>#include <util/suffix.h>#include <util/symbol_table_base.h>#include <goto-programs/class_hierarchy.h>#include <goto-programs/goto_instruction_code.h>#include "assignments_from_json.h"#include "ci_lazy_methods_needed.h"#include "java_object_factory.h"#include "java_object_factory_parameters.h"#include "java_types.h"#include "java_utils.h"Go to the source code of this file.
<clinit> method for a class can be before, after, and during static class initialization. More... The three states in which a <clinit> method for a class can be before, after, and during static class initialization.
These states are only used when the thread safe version of the clinit wrapper is generated.
According to the JVM Spec document (section 5.5), the JVM needs to maintain, for every class initializer, a state indicating whether the initializer has been executed, is being executed, or has raised errors. The spec mandates that the JVM consider 4 different states (not initialized, being initialized, ready for use, and initialization error). The clinit_statet is a simplification of those 4 states where:
NOT_INIT corresponds to "not initialized" IN_PROGRESS corresponds to "some thread is currently running the
`<clinit>` and no other thread should run it" INIT_COMPLETE corresponds to "the `<clinit>` has been executed and the
class is ready to be used, or it has errored"
The last state corresponds to a fusion of the two original states "ready for use" and "initialization error". The basis for fusing these states is that for simplification reasons both implementations of the clinit wrapper do not handle exceptions, hence the error state is not possible.
| Enumerator | |
|---|---|
| NOT_INIT | |
| IN_PROGRESS | |
| INIT_COMPLETE | |
Definition at line 49 of file java_static_initializers.cpp.
Add a new symbol to the symbol table.
Note: assumes that a symbol with this name does not exist. /param name: name of the symbol to be generated /param type: type of the symbol to be generated /param value: initial value of the symbol to be generated /param is_thread_local: if true this symbol will be set as thread local /param is_static_lifetime: if true this symbol will be set as static /return returns new symbol.
Definition at line 115 of file java_static_initializers.cpp.
Advance map iterator to next distinct key.
Definition at line 908 of file java_static_initializers.cpp.
Definition at line 779 of file java_static_initializers.cpp.
Get name of the static-initialization-already-done global variable for a given class.
Definition at line 140 of file java_static_initializers.cpp.
Get name of the real static initializer for a given class.
Doesn't check if a static initializer actually exists.
Definition at line 149 of file java_static_initializers.cpp.
Get name of the static-initialization local variable for a given class.
Definition at line 175 of file java_static_initializers.cpp.
Get name of the static-initialization-state global variable for a given class.
Definition at line 158 of file java_static_initializers.cpp.
Definition at line 56 of file java_static_initializers.cpp.
Get name of the static-initialization-state local state variable for a given class.
Definition at line 167 of file java_static_initializers.cpp.
Generates codet that iterates through the base types of the class specified by class_name, C, and recursively adds calls to their clinit wrapper.
Finally a call to the clinit of C is made. If nondet-static option was given then all static variables that are not constants (i.e. final) are then re-assigned to a nondet value.
Definition at line 229 of file java_static_initializers.cpp.
Get the Java static initializer wrapper name for a given class (the wrapper checks if static initialization has already been done before invoking the real static initializer if not).
Doesn't check whether the symbol actually exists
Definition at line 73 of file java_static_initializers.cpp.
Definition at line 356 of file java_static_initializers.cpp.
Creates a static initializer wrapper symbol for the given class, along with a global boolean that tracks if it has been run already.
Definition at line 395 of file java_static_initializers.cpp.
Definition at line 328 of file java_static_initializers.cpp.
Create static initializer wrappers and possibly user-specified functions for initial static field value assignments for all classes that need them.
For each class that will require a static initializer wrapper, create a function named package.classname.<clinit_wrapper>, and a corresponding global tracking whether it has run or not. If a file containing initial static values is given, also create a function named package.classname::user_specified_clinit.
get_clinit_wrapper_body should be used to produce the method body when required. Definition at line 874 of file java_static_initializers.cpp.
Definition at line 371 of file java_static_initializers.cpp.
Generates a code_frontend_assignt for clinit_statest /param expr: expression to be used as the LHS of generated assignment.
/param state: execution state of the clint_wrapper, used as the RHS of the generated assignment. /return returns a code_frontend_assignt, assigning expr to the integer representation of state
Definition at line 189 of file java_static_initializers.cpp.
Generates an equal_exprt for clinit_statest /param expr: expression to be used as the LHS of generated eqaul exprt.
/param state: execution state of the clint_wrapper, used as the RHS of the generated equal exprt. /return returns a equal_exprt, equating expr to the integer representation of state
Definition at line 205 of file java_static_initializers.cpp.
Produces the static initializer wrapper body for the given function.
Note: this version of the clinit wrapper is not thread safe.
create_clinit_wrapper_symbols) Definition at line 718 of file java_static_initializers.cpp.
Thread safe version of the static initializer.
Produces the static initializer wrapper body for the given function. This static initializer implements (a simplification of) the algorithm defined in Section 5.5 of the JVM Specs. This function, or wrapper, checks whether static init has already taken place, calls the actual <clinit> method if not, and possibly recursively initializes super-classes and interfaces. Assume that C is the class to be initialized and that C extends C' and implements interfaces I1 ... In, then the algorithm is as follows:
Note: The current implementation does not deal with exceptions.
create_clinit_wrapper_symbols) Definition at line 520 of file java_static_initializers.cpp.
Create the body of a user_specified_clinit function for a given class, which includes assignments for all static fields of the class to values read from an input file.
If the file could not be parsed or an entry for this class could not be found in it, the user_specified_clinit function will only contain a call to the "real" clinit function, and not include any assignments itself. If an entry for this class is found but some of its static fields are not mentioned in the input file, those fields will be assigned default values (zero or null).
Definition at line 791 of file java_static_initializers.cpp.
Check if function_id is a clinit.
Definition at line 94 of file java_static_initializers.cpp.
Check if function_id is a clinit wrapper.
Definition at line 86 of file java_static_initializers.cpp.
Check if function_id is a user-specified clinit.
Definition at line 102 of file java_static_initializers.cpp.
Checks whether a static initializer wrapper is needed for a given class, i.e.
if the given class or any superclass has a static initializer.
Definition at line 306 of file java_static_initializers.cpp.
Definition at line 78 of file java_static_initializers.cpp.
Definition at line 65 of file java_static_initializers.cpp.
Definition at line 63 of file java_static_initializers.cpp.
Definition at line 64 of file java_static_initializers.cpp.