You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add class initialization state machine
ensure_initialized guards instantiate/getstatic/putstatic/invokestatic
behind an InitState machine with InProgress re-entry, runs clinit through
execute_method so it gets a java frame, and canonicalizes resolve results
to the registry Class so init state is shared. Registration still
initializes eagerly; the lazy flip comes separately.
* Initialize classes lazily at first active use
Registration no longer runs clinit; initialization happens at new,
getstatic, putstatic, and invokestatic per JVMS 5.5, superclass first,
and interfaces only on access to their own static fields.
* Wrap clinit failures in ExceptionInInitializerError
Non-Error exceptions from clinit are wrapped per JVMS 5.5; Errors
propagate as-is. The failed class becomes erroneous and later uses
throw NoClassDefFoundError.
* Add E2E fixtures for lazy class initialization
StaticOrder checks that an ldc class literal resolves without
initializing, and DoubleInit guards against double clinit through
the on-demand class loading path.
* Style
* Set ConstantValue static fields during class preparation
javac emits compile-time constants as ConstantValue attributes with no
clinit code, so they previously read as zero. ClassDefinition::prepare
materializes them into static storage before initialization.
* Replace lazy-clinit unit tests with java-verified E2E fixtures
LazyClinit and ClinitFailure cover the trigger, ordering, interface,
re-entrancy, and failure scenarios; expected outputs are generated by
running the fixtures on a real JVM. This caught Class.getName returning
the internal slash form instead of the dotted binary name, now fixed.
Constants and StaticFlag stay as Rust-side tests: javac inlines
compile-time constants so ConstantValue is unobservable from bytecode,
and StaticFlag verifies typed reads from native code.
* Replace test_data/unit fixtures with txt-verified E2E tests
Constants and StaticFlag move to test_data with mains and expected
output generated by a real JVM. ConstantsReader is compiled against a
non-final Constants so javac emits getstatic instead of inlining,
keeping ConstantValue preparation observable from bytecode. The
Rust-side putstatic typed-read assertion is dropped with test_data/unit;
the narrowing fix itself is still exercised by StaticFlag's clinit.
* Move test fixture sources to test_data/src
* Add Throwable cause and chained-exception constructors
Throwable gets a cause field, getCause/initCause, and the (Throwable)
and (String, Throwable) constructors, mirrored on Exception and
RuntimeException. printStackTrace now walks the cause chain printing
"Caused by:". ExceptionInInitializerError stores the original
exception as its cause (no detail message, matching the JDK) and clinit
wrapping wires it through that constructor instead of flattening the
cause into the message string.
0 commit comments