<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">On 22 Aug 2023, at 11:03, Dan Smith wrote:</p>
<p dir="auto">…</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"><p dir="auto">4) I'm not sure the prohibition on 'super' calls is actually necessary.</p>
</blockquote><p dir="auto">No, but it’s a move of economy. Defining the meaning of super for
<br>
values would be extra work. We could do that; I’d prefer not to.
<br>
Remember that super-constructors for values are already very special
<br>
animals: They must be empty in a special sense. Forbidding calls to
<br>
them seems like the clean move.</p>
</blockquote><p dir="auto">The rule is that super constructors must be empty because we had no concept of mutable state to communicate changes from parent to child. But now that we have larval objects...</p>
<p dir="auto">Concretely, what if:</p>
<p dir="auto">- putfield is a verifier error on non-identity class types, it only works on uninitializedThis</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Alternatively, we don’t need to touch the verifier if we use a dynamic<br>
larval-bit check on putfield. I like that much better. The effect on<br>
the language and T.S. is the same as a verifier rule.</p>
<p dir="auto">Specifically, allow putfield (on a final field) throughout the <init><br>
of the same class, just as we do now. Add a dynamic check on putfield<br>
that throws an error if the object has been frozen. The interpreter<br>
creates the larval buffer with the “frozen” bit clear, and sets it on<br>
exit from the appropriate constructor. (Probably the larval state is<br>
a distinct header pattern; I am speaking here of a logical frozen bit.)</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">- as usual, every <init> method (for all kinds of classes) must do a super-<init> invokespecial (or this-<init>? still thinking about that)</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">If we keep the rules exactly as they are, then we can make putfield<br>
safe for values like this:</p>
<ul>
<li>putfield dynamically asserts unfrozen (object header in larval state)</li>
<li>exit from any constructor (super or not) sets frozen bit if unfrozen</li>
</ul>
<p dir="auto">Both of these rules appeal to dynamic state, and so do not require<br>
verifier changes.</p>
<p dir="auto">For calls to a “this” constructor, the implication is that the<br>
object is frozen (becomes a mature usable adult value) after<br>
invokespecial V.<init> (V is the value class). For calls to a<br>
“super” constructor, the implication is that the object is frozen<br>
after invokespecial S.<init> (S is the super).</p>
<p dir="auto">The freeze operation can be something simple, like this pseudocode:</p>
<p dir="auto">if (this->header().is_in_larval_state())<br>
this->set_header(this->klass()->adult_state());</p>
<p dir="auto">Or a CAS could be used if there are GC threads lurking nearby.</p>
<p dir="auto">The return instruction(s) of such a constructor can be “hacked” in<br>
the interpreter to perform the freeze operation, as one of the many<br>
steps performed by the interpreter when a stack frame is taken down.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Then:</p>
<p dir="auto">- value objects get built bottom-to-top, with fields set before a super() call, and freedom to use 'this' afterwards
<br>
- abstract classes can participate too, following the same code shape
<br>
- identity classes (abstract and concrete) have a little more freedom, because they can follow the same pattern *or* set their fields after the super() call</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Yes. All of these use cases can be made to work with zero verifier changes.</p>
<p dir="auto">If we do not forbid the super-<init> call — or even require it, as in<br>
today’s verifier – then we need a way for the interpreter to execute it.</p>
<p dir="auto">Can we just allow today’s verifier and interpreter rules to “bang away”<br>
on the larval value? Maybe, if the first constructor return (including<br>
Object.<init>) promotes the value to adult. This puts the burden on<br>
the coder of values to push the <init> calls (including the whole<br>
super chain) to the end of the method, after all putfields.</p>
<p dir="auto">If this actually works, I suppose it would lead to an even simpler JVMS.<br>
We might not need special markings for constructors of abstract supers.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">I need to think more about this, but it seems to me at the moment that everything falls out cleanly...</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"><p dir="auto">(If it works, does this mean we get support for super fields "for free"?)</p>
</blockquote><p dir="auto">That is probably true. Do we care?</p>
</blockquote><p dir="auto">I'd be happy to get rid of special rules that have to do with super fields. (Replacing it with a rule that says certain shapes of abstract class constructors imply identity.) Not so much because of particular use cases, but because it makes the language more regular.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Let’s think about it, but also be willing to push this off to later,<br>
at the cost of putting in special markings for abstract supers that are<br>
value-capable.</p>
</div></div></body>
</html>