<div dir="ltr"><div>Hello!</div><div><br></div><div>This is a bug report + fix.</div><div><br></div><div>The bug is the following: declaring a class instance variable from the "Unknown variable" popup sometimes produces a method whose bytecode does not match the source (it stores into the wrong variables).</div><div>I attach some code to see this (<span style="font-family:monospace"><a href="http://example.workspace.st">example.workspace.st</a></span>), which should be run from a workspace.</div><div><br></div><div>This happens because <span style="font-family:monospace">Metaclass>>addInstVarName:</span> reverses the order of existing variables (which is already a weird behavior), and the compiler resolves instance variables to slot numbers at the start of the compilation. So, in an interactive environment:</div><div>1. When we accept a method with an undeclared name, a notification is signalled mid-compilation.</div><div>2. Then, from the popup, we choose to declare an instance variable.</div><div>3. So, <span style="font-family:monospace">Parser>>declareInstVar:</span> sends <span style="font-family:monospace">#addInstVarName:</span>. This adds the instance variable (reversing the order of the existing ones), and triggers a recompilation of all existing methods (this does not include the method mid-compilation, which is not yet installed on the class).</div><div>4. Then the compilation resumes. But the encoder has already assigned a slot index to every pre-existing variable, so the system ends up producing the wrong bytecode.</div><div>Note that the class needs to have at least two existing class instance variables for this to happen (since reversing just one does nothing).</div><div><br></div><div>The fix is to make <span style="font-family:monospace">Metaclass>>addInstVarName:</span> preserve the order of the variables (as <span style="font-family:monospace">Class>>addInstVarName:</span> already does). With the order preserved, the indices the encoder computed before the declaration stay valid.</div><div><br></div><div>I've included tests for the bug, and also two additional things for consistency: one test for this same thing but instance-side, and a change to <span style="font-family:monospace">#removeInstVarName:</span> to also preserve the order of the variables (removing class instance variables does not produce wrong behavior, but it is a bit confusing to see the order of the variables change).</div><div><br></div><div style="text-align:center">* * *</div><div><br></div><div>As a side-note: I've been chasing this bug for some time, since it specially affected students using Cuis-University (denotative objects are classes behind the scenes, so all instance variables are class instance variables). The bug was hard to find because when you recompile the method (e.g. make any change and recompile, or file it out and then file it in, etc.), the bytecode is silently fixed.</div><div><br></div><div>Cheers!</div><div>Facu</div></div>