Skip to content

Commit 74a29bb

Browse files
committed
decouple checkInvalidatedResourceOrResourceReference from interpreter
1 parent 226b8a7 commit 74a29bb

8 files changed

+41
-39
lines changed

interpreter/interpreter_expression.go

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func (interpreter *Interpreter) assignmentGetterSetter(expression ast.Expression
4141

4242
case *ast.IndexExpression:
4343
if attachmentType, ok := interpreter.Program.Elaboration.AttachmentAccessTypes(expression); ok {
44-
return interpreter.typeIndexExpressionGetterSetter(expression, attachmentType)
44+
return interpreter.typeIndexExpressionGetterSetter(expression, attachmentType, locationRange)
4545
}
4646
return interpreter.valueIndexExpressionGetterSetter(expression, locationRange)
4747

@@ -89,25 +89,21 @@ func (interpreter *Interpreter) identifierExpressionGetterSetter(
8989
func (interpreter *Interpreter) typeIndexExpressionGetterSetter(
9090
indexExpression *ast.IndexExpression,
9191
attachmentType sema.Type,
92+
locationRange LocationRange,
9293
) getterSetter {
9394
target, ok := interpreter.evalExpression(indexExpression.TargetExpression).(TypeIndexableValue)
9495
if !ok {
9596
panic(errors.NewUnreachableError())
9697
}
9798

98-
locationRange := LocationRange{
99-
Location: interpreter.Location,
100-
HasPosition: indexExpression,
101-
}
102-
10399
return getterSetter{
104100
target: target,
105101
get: func(_ bool) Value {
106-
interpreter.checkInvalidatedResourceOrResourceReference(target, indexExpression)
102+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
107103
return target.GetTypeKey(interpreter, locationRange, attachmentType)
108104
},
109105
set: func(_ Value) {
110-
interpreter.checkInvalidatedResourceOrResourceReference(target, indexExpression)
106+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
111107
// writing to composites with indexing syntax is not supported
112108
panic(errors.NewUnreachableError())
113109
},
@@ -201,14 +197,14 @@ func (interpreter *Interpreter) valueIndexExpressionGetterSetter(
201197

202198
if isNestedResourceMove {
203199
get = func(_ bool) Value {
204-
interpreter.checkInvalidatedResourceOrResourceReference(target, targetExpression)
200+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
205201
value := target.RemoveKey(interpreter, locationRange, transferredIndexingValue)
206202
target.InsertKey(interpreter, locationRange, transferredIndexingValue, placeholder)
207203
return value
208204
}
209205
} else {
210206
get = func(_ bool) Value {
211-
interpreter.checkInvalidatedResourceOrResourceReference(target, targetExpression)
207+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
212208
value := target.GetKey(interpreter, locationRange, transferredIndexingValue)
213209

214210
// If the indexing value is a reference, then return a reference for the resulting value.
@@ -220,7 +216,7 @@ func (interpreter *Interpreter) valueIndexExpressionGetterSetter(
220216
target: target,
221217
get: get,
222218
set: func(value Value) {
223-
interpreter.checkInvalidatedResourceOrResourceReference(target, targetExpression)
219+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
224220
target.SetKey(interpreter, locationRange, transferredIndexingValue, value)
225221
},
226222
}
@@ -362,7 +358,7 @@ func (interpreter *Interpreter) checkMemberAccess(
362358
locationRange LocationRange,
363359
) {
364360

365-
interpreter.checkInvalidatedResourceOrResourceReference(target, memberExpression)
361+
checkInvalidatedResourceOrResourceReference(target, locationRange, interpreter)
366362

367363
memberInfo, _ := interpreter.Program.Elaboration.MemberExpressionMemberAccessInfo(memberExpression)
368364
expectedType := memberInfo.AccessedType
@@ -433,15 +429,23 @@ func (interpreter *Interpreter) VisitIdentifierExpression(expression *ast.Identi
433429

434430
func (interpreter *Interpreter) evalExpression(expression ast.Expression) Value {
435431
result := ast.AcceptExpression[Value](expression, interpreter)
436-
interpreter.checkInvalidatedResourceOrResourceReference(result, expression)
432+
locationRange := LocationRange{
433+
Location: interpreter.Location,
434+
HasPosition: expression,
435+
}
436+
checkInvalidatedResourceOrResourceReference(
437+
result,
438+
locationRange,
439+
interpreter,
440+
)
437441
return result
438442
}
439443

440-
func (interpreter *Interpreter) checkInvalidatedResourceOrResourceReference(value Value, hasPosition ast.HasPosition) {
441-
if interpreter == nil {
442-
return
443-
}
444-
444+
func checkInvalidatedResourceOrResourceReference(
445+
value Value,
446+
locationRange LocationRange,
447+
context ValueStaticTypeContext,
448+
) {
445449
// Unwrap SomeValue, to access references wrapped inside optionals.
446450
someValue, isSomeValue := value.(*SomeValue)
447451
for isSomeValue && someValue.value != nil {
@@ -451,28 +455,26 @@ func (interpreter *Interpreter) checkInvalidatedResourceOrResourceReference(valu
451455

452456
switch value := value.(type) {
453457
case ResourceKindedValue:
454-
if value.isInvalidatedResource(interpreter) {
458+
if value.isInvalidatedResource(context) {
455459
panic(InvalidatedResourceError{
456-
LocationRange: LocationRange{
457-
Location: interpreter.Location,
458-
HasPosition: hasPosition,
459-
},
460+
LocationRange: locationRange,
460461
})
461462
}
462463
case *EphemeralReferenceValue:
463464
if value.Value == nil {
464465
panic(InvalidatedResourceReferenceError{
465-
LocationRange: LocationRange{
466-
Location: interpreter.Location,
467-
HasPosition: hasPosition,
468-
},
466+
LocationRange: locationRange,
469467
})
470468
} else {
471469
// If the value is there, check whether the referenced value is an invalidated one.
472470
// This step is not really needed, since reference tracking is supposed to clear the
473471
// `value.Value` if the referenced-value was moved/deleted.
474472
// However, have this as a second layer of defensive.
475-
interpreter.checkInvalidatedResourceOrResourceReference(value.Value, hasPosition)
473+
checkInvalidatedResourceOrResourceReference(
474+
value.Value,
475+
locationRange,
476+
context,
477+
)
476478
}
477479
}
478480
}

interpreter/interpreter_statement.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,10 +597,10 @@ func (interpreter *Interpreter) VisitSwapStatement(swap *ast.SwapStatement) Stat
597597
// Set right value to left target,
598598
// and left value to right target
599599

600-
interpreter.checkInvalidatedResourceOrResourceReference(rightValue, swap.Right)
600+
checkInvalidatedResourceOrResourceReference(rightValue, rightLocationRange, interpreter)
601601
transferredRightValue := interpreter.transferAndConvert(rightValue, rightType, leftType, rightLocationRange)
602602

603-
interpreter.checkInvalidatedResourceOrResourceReference(leftValue, swap.Left)
603+
checkInvalidatedResourceOrResourceReference(leftValue, leftLocationRange, interpreter)
604604
transferredLeftValue := interpreter.transferAndConvert(leftValue, leftType, rightType, leftLocationRange)
605605

606606
leftGetterSetter.set(transferredRightValue)

interpreter/value_array.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ func (v *ArrayValue) iterate(
254254
// atree.Array iteration provides low-level atree.Value,
255255
// convert to high-level interpreter.Value
256256
elementValue := MustConvertStoredValue(interpreter, element)
257-
interpreter.checkInvalidatedResourceOrResourceReference(elementValue, locationRange)
257+
checkInvalidatedResourceOrResourceReference(elementValue, locationRange, interpreter)
258258

259259
if transferElements {
260260
// Each element must be transferred before passing onto the function.

interpreter/value_composite.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,7 @@ func (v *CompositeValue) forEachField(
15561556
) {
15571557
err := atreeIterate(func(key atree.Value, atreeValue atree.Value) (resume bool, err error) {
15581558
value := MustConvertStoredValue(interpreter, atreeValue)
1559-
interpreter.checkInvalidatedResourceOrResourceReference(value, locationRange)
1559+
checkInvalidatedResourceOrResourceReference(value, locationRange, interpreter)
15601560

15611561
resume = f(
15621562
string(key.(StringAtreeValue)),
@@ -1819,7 +1819,7 @@ func forEachAttachment(
18191819

18201820
for {
18211821
// Check that the implicit composite reference was not invalidated during iteration
1822-
interpreter.checkInvalidatedResourceOrResourceReference(compositeReference, locationRange)
1822+
checkInvalidatedResourceOrResourceReference(compositeReference, locationRange, interpreter)
18231823
key, value, err := iterator.Next()
18241824
if err != nil {
18251825
panic(errors.NewExternalError(err))

interpreter/value_dictionary.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ func (v *DictionaryValue) Iterate(
343343
v.iterate(interpreter, iterate, f, locationRange)
344344
}
345345

346-
// IterateReadOnlyLoaded iterates over all LOADED key-valye pairs of the array.
346+
// IterateReadOnlyLoaded iterates over all LOADED key-value pairs of the array.
347347
// DO NOT perform storage mutations in the callback!
348348
func (v *DictionaryValue) IterateReadOnlyLoaded(
349349
interpreter *Interpreter,
@@ -372,8 +372,8 @@ func (v *DictionaryValue) iterate(
372372
keyValue := MustConvertStoredValue(interpreter, key)
373373
valueValue := MustConvertStoredValue(interpreter, value)
374374

375-
interpreter.checkInvalidatedResourceOrResourceReference(keyValue, locationRange)
376-
interpreter.checkInvalidatedResourceOrResourceReference(valueValue, locationRange)
375+
checkInvalidatedResourceOrResourceReference(keyValue, locationRange, interpreter)
376+
checkInvalidatedResourceOrResourceReference(valueValue, locationRange, interpreter)
377377

378378
resume = f(
379379
keyValue,

interpreter/value_function.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ func (f BoundFunctionValue) invoke(invocation Invocation) Value {
459459
})
460460
}
461461
} else {
462-
inter.checkInvalidatedResourceOrResourceReference(f.SelfReference, locationRange)
462+
checkInvalidatedResourceOrResourceReference(f.SelfReference, locationRange, inter)
463463
}
464464

465465
return f.Function.invoke(invocation)

interpreter/value_storage_reference.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ func forEachReference(
449449
// The loop dereference the reference once, and hold onto that referenced-value.
450450
// But the reference could get invalidated during the iteration, making that referenced-value invalid.
451451
// So check the validity of the reference, before each iteration.
452-
interpreter.checkInvalidatedResourceOrResourceReference(reference, locationRange)
452+
checkInvalidatedResourceOrResourceReference(reference, locationRange, interpreter)
453453

454454
if isResultReference {
455455
value = interpreter.getReferenceValue(value, elementType, locationRange)

interpreter/variable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (v *SelfVariable) InitializeWithGetter(func() Value) {
113113

114114
func (v *SelfVariable) GetValue(interpreter *Interpreter) Value {
115115
// TODO: pass proper location range
116-
interpreter.checkInvalidatedResourceOrResourceReference(v.selfRef, EmptyLocationRange)
116+
checkInvalidatedResourceOrResourceReference(v.selfRef, EmptyLocationRange, interpreter)
117117
return v.value
118118
}
119119

0 commit comments

Comments
 (0)