<div dir="ltr"><div>Hi</div><div><br></div><div>The JVMS, Java 22 Edition, 4.10.1.9.invokespecial has this to say about invokespecial instructions that call an <init> method:</div><div><br></div><div style="margin-left:40px">If we are initializing an object within its constructor, its
type is initially <code>uninitializedThis</code>. This type will be
rewritten to the type of the class of the <code><init></code> method. <br></div><div><br></div><div>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.</div><div>The pr<font size="2">ovid</font>ed Prolog terms seem to suggest it's the one we are calling:</div><div style="margin-left:40px"><pre>instructionIsTypeSafe(invokespecial(CP), Environment, _Offset, StackFrame,
NextStackFrame, ExceptionStackFrame) :-
CP = method(MethodClassName, '<code><init></code>', 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).</pre></div><div><div><div style="margin-left:40px"><pre>rewrittenUninitializedType(uninitializedThis, Environment,
MethodClass, MethodClass) :-
MethodClass = class(MethodClassName, CurrentLoader),
thisClass(Environment, MethodClass).<br><br>rewrittenUninitializedType(uninitializedThis, Environment,
MethodClass, MethodClass) :-
MethodClass = class(MethodClassName, CurrentLoader),
thisClass(Environment, class(thisClassName, thisLoader)),
superclassChain(thisClassName, thisLoader, [MethodClass | Rest]).</pre></div><pre><font size="2"><span style="font-family:arial,sans-serif">The</span> MethodClass</font><font size="2" face="arial,sans-serif"> parameter of </font>rewrittenUninitializedType<font size="2" face="arial,sans-serif"> is constructed from the class of the methodref that is being invoked by invokespecial, and it is also the out parameter used as </font><font size="2">This</font><font size="2" face="arial,sans-serif">.<br></font></pre><pre><font size="2" face="arial,sans-serif">However, it hasn't always been this way, the Prolog term from the JVMS, Java 7 edition,</font><span style="font-family:arial,sans-serif"> 4.10.1.9.invokespecial contains the following term:<br></span></pre><pre style="margin-left:40px">rewrittenUninitializedType(uninitializedThis, Environment,
_MethodClass, This) :-
thisClass(Environment, This).<br></pre><pre><font face="arial,sans-serif">Here, the interpretation seems to be that the rewritten type should be the class of the method we're currently in.<br></font></pre><pre><font face="arial,sans-serif">This change was made in Java 8.<br></font></pre><pre><font face="arial,sans-serif">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?<br>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.<br></font></pre><pre><font face="arial,sans-serif">If we take the constructor of a simple class with a field, it may look something like this:<br></font> 0: aload_0<br> 1: invokespecial #1 // Method java/lang/Object."<init>":()V<br> 4: aload_0<br> 5: iconst_0<br> 6: putfield #7 // Field foo:I<br> 9: return<br></pre><pre><font face="arial,sans-serif">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.<br></font></pre><pre><font face="arial,sans-serif">Does this make the Prolog terms of the current standard incorrect? Additionally, it contains the variables </font>MethodClassName <span style="font-family:arial,sans-serif">and</span> CurrentLoader<span style="font-family:arial,sans-serif">, which are never used, which also seems like a mistake? It also contains </span>thisClassName <span style="font-family:arial,sans-serif">and</span> thisLoader<span style="font-family:arial,sans-serif">, which seem to be treated as if they are variables, but written as if they are atoms, since they begin with a lowercase letter.</span><br><span style="font-family:arial,sans-serif"><br></span></pre><pre><span style="font-family:arial,sans-serif">Regards<br></span></pre><pre><span style="font-family:arial,sans-serif">Emilia Kond<br></span></pre></div></div></div>