Implement copy-on-write semantic for variables and fields
Clarification and motivation
I suggest doing this task after #189 (moved)
Now we have a concept that all variables and the fields have their fixed positions on the stack, and assignment happens as replacement values in these cells. Getting implies moving them on the top of the stack.
This design is pretty simple and has its advantages that we have variables of scopes in sequential order on the stack so cleaning the stack after leaving the scope is pretty easy. However, it has a disadvantage that unnecessary assignments happen if we assign one complex object to the another one. If a variable is decomposed one (not stored on the stack as a tuple but set of cells instead), we could just replace assigning fields' references and increase reference counter for an object. If there are more than 1 references to the object/field and we are modifying it, we have to copy the value.
Though this approach also has its disadvantage: if we assign to the variable/field from outer scope a variable from inner one, then at the moment of leaving the inner one we will drop cells representing inner variable. Just leaving them onto stack (not dropping) isn't the easiest option because it will cause divergency of branches of the statements like if/case/etc. The another option could be make the mix of the current approach and new one.
Assignment
Lets say we do either setVar a b
or setField a #label b
:
- if
a
belongs to the newer scope (lies closer to the top of the stack) thanb
then use new technique: assigna
references, increase a reference counter - if the variables belong to the same scope, we just use new technique
- if
a
belongs to the older scope, just replace cells ofa
with new values (current approach)
Modification
Pay attention that we can't modify fields yet (only assign) but we can modify primitive values. TBA
Architecture changes
The following changes in architecture have to be made:
- attach to variables scopes where they have been created (there is a separate task for it #192 (moved))
- make
Var
just index again (notRefId
but separate indexation) - add to each compilation function (that needs access to a variable representation) add
StateT
with:Map Var (IndigoObjectF NamedFieldVar)
to store actual variable representation (which might be updated during the execution), andMap RefId Int
to store number of references for each each key
Acceptance criteria
- Covered with tests
- Checked on some contract (like NBIT) to reduce size/gas cost