Skip to content

Commit

Permalink
Track resources with atree.ValueID instead of SlabID
Browse files Browse the repository at this point in the history
Currently, Array.SlabID() and OrderedMap.SlabID() are used as
identifier to track resources, etc because slab IDs are guaranteed
to unique. However, atree slab ID should be only used to retrieve
slabs (registers) from storage.

Also, when Atree register inlining is implemented in the future, some
resources may not be stored in separate slabs, so they will not have
slab IDs anymore.

This commit uses Array.ValueID() and OrderedMap.ValueID() to uniquely
identify resources.
  • Loading branch information
fxamacker committed Jul 7, 2023
1 parent 1bfab01 commit 3aecd78
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 62 deletions.
30 changes: 15 additions & 15 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ type Storage interface {
CheckHealth() error
}

type ReferencedResourceKindedValues map[atree.SlabID]map[ReferenceTrackedResourceKindedValue]struct{}
type ReferencedResourceKindedValues map[atree.ValueID]map[ReferenceTrackedResourceKindedValue]struct{}

type Interpreter struct {
Location common.Location
Expand Down Expand Up @@ -5100,12 +5100,12 @@ func (interpreter *Interpreter) ValidateAtreeValue(value atree.Value) {

func (interpreter *Interpreter) maybeTrackReferencedResourceKindedValue(value Value) {
if value, ok := value.(ReferenceTrackedResourceKindedValue); ok {
interpreter.trackReferencedResourceKindedValue(value.SlabID(), value)
interpreter.trackReferencedResourceKindedValue(value.ValueID(), value)
}
}

func (interpreter *Interpreter) trackReferencedResourceKindedValue(
id atree.SlabID,
id atree.ValueID,
value ReferenceTrackedResourceKindedValue,
) {
values := interpreter.SharedState.referencedResourceKindedValues[id]
Expand All @@ -5117,8 +5117,8 @@ func (interpreter *Interpreter) trackReferencedResourceKindedValue(
}

func (interpreter *Interpreter) updateReferencedResource(
currentID atree.SlabID,
newID atree.SlabID,
currentID atree.ValueID,
newID atree.ValueID,
updateFunc func(value ReferenceTrackedResourceKindedValue),
) {
values := interpreter.SharedState.referencedResourceKindedValues[currentID]
Expand Down Expand Up @@ -5377,8 +5377,8 @@ func (interpreter *Interpreter) idCapabilityCheckFunction(
)
}

func (interpreter *Interpreter) validateMutation(slabID atree.SlabID, locationRange LocationRange) {
_, present := interpreter.SharedState.containerValueIteration[slabID]
func (interpreter *Interpreter) validateMutation(valueID atree.ValueID, locationRange LocationRange) {
_, present := interpreter.SharedState.containerValueIteration[valueID]
if !present {
return
}
Expand All @@ -5387,32 +5387,32 @@ func (interpreter *Interpreter) validateMutation(slabID atree.SlabID, locationRa
})
}

func (interpreter *Interpreter) withMutationPrevention(slabID atree.SlabID, f func()) {
oldIteration, present := interpreter.SharedState.containerValueIteration[slabID]
interpreter.SharedState.containerValueIteration[slabID] = struct{}{}
func (interpreter *Interpreter) withMutationPrevention(valueID atree.ValueID, f func()) {
oldIteration, present := interpreter.SharedState.containerValueIteration[valueID]
interpreter.SharedState.containerValueIteration[valueID] = struct{}{}

f()

if !present {
delete(interpreter.SharedState.containerValueIteration, slabID)
delete(interpreter.SharedState.containerValueIteration, valueID)
} else {
interpreter.SharedState.containerValueIteration[slabID] = oldIteration
interpreter.SharedState.containerValueIteration[valueID] = oldIteration
}
}

func (interpreter *Interpreter) withResourceDestruction(
slabID atree.SlabID,
valueID atree.ValueID,
locationRange LocationRange,
f func(),
) {
_, exists := interpreter.SharedState.destroyedResources[slabID]
_, exists := interpreter.SharedState.destroyedResources[valueID]
if exists {
panic(DestroyedResourceError{
LocationRange: locationRange,
})
}

interpreter.SharedState.destroyedResources[slabID] = struct{}{}
interpreter.SharedState.destroyedResources[valueID] = struct{}{}

f()
}
8 changes: 4 additions & 4 deletions runtime/interpreter/interpreter_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -937,8 +937,8 @@ func (interpreter *Interpreter) visitInvocationExpressionWithImplicitArgument(in
if boundFunction, ok := function.(BoundFunctionValue); ok && boundFunction.Self != nil {
self := *boundFunction.Self
if resource, ok := self.(ReferenceTrackedResourceKindedValue); ok {
slabID := resource.SlabID()
interpreter.trackReferencedResourceKindedValue(slabID, resource)
valueID := resource.ValueID()
interpreter.trackReferencedResourceKindedValue(valueID, resource)
}
}

Expand Down Expand Up @@ -1290,7 +1290,7 @@ func (interpreter *Interpreter) VisitAttachExpression(attachExpression *ast.Atta
base,
interpreter.MustSemaTypeOfValue(base).(*sema.CompositeType),
)
interpreter.trackReferencedResourceKindedValue(base.SlabID(), base)
interpreter.trackReferencedResourceKindedValue(base.ValueID(), base)

attachment, ok := interpreter.visitInvocationExpressionWithImplicitArgument(
attachExpression.Attachment,
Expand All @@ -1302,7 +1302,7 @@ func (interpreter *Interpreter) VisitAttachExpression(attachExpression *ast.Atta
}

// Because `self` in attachments is a reference, we need to track the attachment if it's a resource
interpreter.trackReferencedResourceKindedValue(attachment.SlabID(), attachment)
interpreter.trackReferencedResourceKindedValue(attachment.ValueID(), attachment)

base = base.Transfer(
interpreter,
Expand Down
10 changes: 5 additions & 5 deletions runtime/interpreter/sharedstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ type SharedState struct {
storageMutatedDuringIteration bool
CapabilityControllerIterations map[AddressPath]int
MutationDuringCapabilityControllerIteration bool
containerValueIteration map[atree.SlabID]struct{}
destroyedResources map[atree.SlabID]struct{}
containerValueIteration map[atree.ValueID]struct{}
destroyedResources map[atree.ValueID]struct{}
}

func NewSharedState(config *Config) *SharedState {
Expand All @@ -59,11 +59,11 @@ func NewSharedState(config *Config) *SharedState {
},
inStorageIteration: false,
storageMutatedDuringIteration: false,
referencedResourceKindedValues: map[atree.SlabID]map[ReferenceTrackedResourceKindedValue]struct{}{},
referencedResourceKindedValues: map[atree.ValueID]map[ReferenceTrackedResourceKindedValue]struct{}{},
resourceVariables: map[ResourceKindedValue]*Variable{},
CapabilityControllerIterations: map[AddressPath]int{},
containerValueIteration: map[atree.SlabID]struct{}{},
destroyedResources: map[atree.SlabID]struct{}{},
containerValueIteration: map[atree.ValueID]struct{}{},
destroyedResources: map[atree.ValueID]struct{}{},
}
}

Expand Down
Loading

0 comments on commit 3aecd78

Please sign in to comment.