Interpretation of rewritten uninitialized type of invokespecial
Emilia Kond
rymiel314 at gmail.com
Sun Jun 2 15:29:17 UTC 2024
Hi
The JVMS, Java 22 Edition, 4.10.1.9.invokespecial has this to say about
invokespecial instructions that call an <init> method:
If we are initializing an object within its constructor, its type is
initially uninitializedThis. This type will be rewritten to the type of the
class of the <init> method.
I am confused on which <init> method is referred to by "the <init> method",
since there are two, the one we are currently in, and the one we are
currently calling.
The provided Prolog terms seem to suggest it's the one we are calling:
instructionIsTypeSafe(invokespecial(CP), Environment, _Offset, StackFrame,
NextStackFrame, ExceptionStackFrame) :-
CP = method(MethodClassName, '<init>', Descriptor),
parseMethodDescriptor(Descriptor, OperandArgList, void),
reverse(OperandArgList, StackArgList),
canPop(StackFrame, StackArgList, TempFrame),
TempFrame = frame(Locals, [uninitializedThis | OperandStack], Flags),
currentClassLoader(Environment, CurrentLoader),
rewrittenUninitializedType(uninitializedThis, Environment,
class(MethodClassName, CurrentLoader), This),
rewrittenInitializationFlags(uninitializedThis, Flags, NextFlags),
substitute(uninitializedThis, This, OperandStack, NextOperandStack),
substitute(uninitializedThis, This, Locals, NextLocals),
substitute(uninitializedThis, top, Locals, ExceptionLocals),
NextStackFrame = frame(NextLocals, NextOperandStack, NextFlags),
ExceptionStackFrame = frame(ExceptionLocals, [], Flags).
rewrittenUninitializedType(uninitializedThis, Environment,
MethodClass, MethodClass) :-
MethodClass = class(MethodClassName, CurrentLoader),
thisClass(Environment, MethodClass).
rewrittenUninitializedType(uninitializedThis, Environment,
MethodClass, MethodClass) :-
MethodClass = class(MethodClassName, CurrentLoader),
thisClass(Environment, class(thisClassName, thisLoader)),
superclassChain(thisClassName, thisLoader, [MethodClass | Rest]).
The MethodClass parameter of rewrittenUninitializedType is constructed
from the class of the methodref that is being invoked by
invokespecial, and it is also the out parameter used as This.
However, it hasn't always been this way, the Prolog term from the
JVMS, Java 7 edition, 4.10.1.9.invokespecial contains the following
term:
rewrittenUninitializedType(uninitializedThis, Environment,
_MethodClass, This) :-
thisClass(Environment, This).
Here, the interpretation seems to be that the rewritten type should be
the class of the method we're currently in.
This change was made in Java 8.
Which interpretation is correct? It is my understanding that the
current Prolog code refers to the class of the method being called? Is
my understanding incorrect?
I've checked the source code of the hotspot verifier, and it seems to
replace uninitializedThis with the type of the current class, so it is
the latter interpretation.
If we take the constructor of a simple class with a field, it may look
something like this:
0: aload_0
1: invokespecial #1 // Method
java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #7 // Field foo:I
9: return
It is problematic if after verifying the invokespecial at address 1,
the resulting type in local 0 is java.lang.Object, because the
putfield at address 6 will fail, because java.lang.Object does not
have that field.
Does this make the Prolog terms of the current standard incorrect?
Additionally, it contains the variables MethodClassName and
CurrentLoader, which are never used, which also seems like a mistake?
It also contains thisClassName and thisLoader, which seem to be
treated as if they are variables, but written as if they are atoms,
since they begin with a lowercase letter.
Regards
Emilia Kond
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jls-jvms-spec-comments/attachments/20240602/5b32f8d2/attachment-0001.htm>
More information about the jls-jvms-spec-comments
mailing list