-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
base system[SCOPE] Squeak's basic (language) concerns such as Kernel, Collections, Graphics, Network[SCOPE] Squeak's basic (language) concerns such as Kernel, Collections, Graphics, Networkignored[RATING] No longer valid or necessary.[RATING] No longer valid or necessary.programmer[SCOPE] It is for the (maybe professional) programmer[SCOPE] It is for the (maybe professional) programmer
Description
I have noticed a weird behavior that occurs when you delete an instvar from a class, but keep the accessors for it and call them.
Steps to reproduce
- Create a class
Dummy - Add an instvar
myVar - Add accessors
myVarandmyVar(^ myVarandmyVar := anObject, respectively) - Delete the instvar
myVar - Open a workspace
- Execute
Dummy new myVar: 42. - Print
Dummy new myVar(note: this is a new instance, do not keep the instance from the previous step)
Expected behavior
One of the following:
- An error is shown in step 4 (something like The instVar
myVaris still referenced in these 2 methods: ...) - An error is shown in step 6 (something like The instVar
myVardoes not exist) nilis printed in step 7
Actual behavior
42 is printed in step 7
Analysis
The problem occurs because after step 4, the accessors use the bytecodes pushLitVar: and popIntoLit:, with the referenced literal being the global Undeclared associationAt: #myVar. This results in the myVar: call storing the 42 into the Association's value, which the myVar call on an unrelated instance will read, because the method references the same (global) Association in its literals.
I have traced the reason for the use of these bytecodes:
Class>>compileAllFrom:is called during step 4- During parsing,
Parser>>variableis called - It doesn't find the variable
myVarin scope - It calls
Parser>>correctVariable:interval: - Because the recompilation of all methods is not interactive,
Encoder>>undeclared:is called Encoder>>global:name:is called withUndeclared associationAt: #myVar- A
LiteralVariableNodewith the association as itskeyis returned - Afterwards, either an
AssignmentNode(for the setter) or aReturnNode(for the getter) is created - After parsing,
MethodNode>>generate:is called - In the setter case,
AssignmentNode>>emitCodeForEffect:encoder:callsLiteralVariableNode>>emitCodeForStorePop:encoder:, which callsEncoder>>genStorePopLiteralVar: - In the getter case,
ReturnNode>>emitCodeForValue:encoder:(indirectly) callsLiteralVariableNode>>emitCodeForValue:encoder:, which callsEncoder>>genPushLiteralVar: - Both reference the global Association, which was previously written into the literals of the
Encoder
Metadata
Metadata
Assignees
Labels
base system[SCOPE] Squeak's basic (language) concerns such as Kernel, Collections, Graphics, Network[SCOPE] Squeak's basic (language) concerns such as Kernel, Collections, Graphics, Networkignored[RATING] No longer valid or necessary.[RATING] No longer valid or necessary.programmer[SCOPE] It is for the (maybe professional) programmer[SCOPE] It is for the (maybe professional) programmer