<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>