Skip to content

Commit 2bb2f45

Browse files
committed
Decouple 'MeteredString' method from the interpreter
1 parent ea78dd3 commit 2bb2f45

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+348
-240
lines changed

interpreter/interface.go

+120
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
package interpreter
2020

2121
import (
22+
"time"
23+
2224
"github.com/onflow/atree"
2325

2426
"github.com/onflow/cadence/common"
27+
"github.com/onflow/cadence/errors"
2528
"github.com/onflow/cadence/sema"
2629
)
2730

@@ -118,3 +121,120 @@ type ValueRemoveContext = ValueTransferContext
118121
type ComputationReporter interface {
119122
ReportComputation(compKind common.ComputationKind, intensity uint)
120123
}
124+
125+
type ValueIterationContext interface {
126+
ValueTransferContext
127+
WithMutationPrevention(valueID atree.ValueID, f func())
128+
}
129+
130+
type ValueStringContext interface {
131+
ValueIterationContext
132+
}
133+
134+
// NoOpStringContext is the ValueStringContext implementation used in Value.RecursiveString method.
135+
// Since Value.RecursiveString is a non-mutating operation, it should only need the no-op memory metering
136+
// and a WithMutationPrevention implementation.
137+
// All other methods should not be reachable, hence is safe to panic in them.
138+
//
139+
// TODO: Ideally, Value.RecursiveString shouldn't need the full ValueTransferContext.
140+
// But that would require refactoring the iterator methods for arrays and dictionaries.
141+
type NoOpStringContext struct{}
142+
143+
var _ ValueStringContext = NoOpStringContext{}
144+
145+
func (n NoOpStringContext) MeterMemory(_ common.MemoryUsage) error {
146+
return nil
147+
}
148+
149+
func (n NoOpStringContext) WithMutationPrevention(_ atree.ValueID, f func()) {
150+
f()
151+
return
152+
}
153+
154+
func (n NoOpStringContext) ReadStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey) Value {
155+
panic(errors.NewUnreachableError())
156+
}
157+
158+
func (n NoOpStringContext) ConvertStaticToSemaType(_ StaticType) (sema.Type, error) {
159+
panic(errors.NewUnreachableError())
160+
}
161+
162+
func (n NoOpStringContext) IsSubType(_ StaticType, _ StaticType) bool {
163+
panic(errors.NewUnreachableError())
164+
}
165+
166+
func (n NoOpStringContext) IsSubTypeOfSemaType(_ StaticType, _ sema.Type) bool {
167+
panic(errors.NewUnreachableError())
168+
}
169+
170+
func (n NoOpStringContext) WriteStored(_ common.Address, _ common.StorageDomain, _ StorageMapKey, _ Value) (existed bool) {
171+
panic(errors.NewUnreachableError())
172+
}
173+
174+
func (n NoOpStringContext) Storage() Storage {
175+
panic(errors.NewUnreachableError())
176+
}
177+
178+
func (n NoOpStringContext) RemoveReferencedSlab(_ atree.Storable) {
179+
panic(errors.NewUnreachableError())
180+
}
181+
182+
func (n NoOpStringContext) MaybeValidateAtreeValue(_ atree.Value) {
183+
panic(errors.NewUnreachableError())
184+
}
185+
186+
func (n NoOpStringContext) MaybeValidateAtreeStorage() {
187+
panic(errors.NewUnreachableError())
188+
}
189+
190+
func (n NoOpStringContext) InvalidateReferencedResources(_ Value, _ LocationRange) {
191+
panic(errors.NewUnreachableError())
192+
}
193+
194+
func (n NoOpStringContext) CheckInvalidatedResourceOrResourceReference(_ Value, _ LocationRange) {
195+
panic(errors.NewUnreachableError())
196+
}
197+
198+
func (n NoOpStringContext) MaybeTrackReferencedResourceKindedValue(_ *EphemeralReferenceValue) {
199+
panic(errors.NewUnreachableError())
200+
}
201+
202+
func (n NoOpStringContext) ReportComputation(_ common.ComputationKind, _ uint) {
203+
panic(errors.NewUnreachableError())
204+
}
205+
206+
func (n NoOpStringContext) TracingEnabled() bool {
207+
panic(errors.NewUnreachableError())
208+
}
209+
210+
func (n NoOpStringContext) reportArrayValueDeepRemoveTrace(_ string, _ int, _ time.Duration) {
211+
panic(errors.NewUnreachableError())
212+
}
213+
214+
func (n NoOpStringContext) reportArrayValueTransferTrace(_ string, _ int, _ time.Duration) {
215+
panic(errors.NewUnreachableError())
216+
}
217+
218+
func (n NoOpStringContext) reportDictionaryValueTransferTrace(_ string, _ int, _ time.Duration) {
219+
panic(errors.NewUnreachableError())
220+
}
221+
222+
func (n NoOpStringContext) reportDictionaryValueDeepRemoveTrace(_ string, _ int, _ time.Duration) {
223+
panic(errors.NewUnreachableError())
224+
}
225+
226+
func (n NoOpStringContext) reportCompositeValueDeepRemoveTrace(_ string, _ string, _ string, _ time.Duration) {
227+
panic(errors.NewUnreachableError())
228+
}
229+
230+
func (n NoOpStringContext) reportCompositeValueTransferTrace(_ string, _ string, _ string, _ time.Duration) {
231+
panic(errors.NewUnreachableError())
232+
}
233+
234+
func (n NoOpStringContext) reportDomainStorageMapDeepRemoveTrace(_ string, _ int, _ time.Duration) {
235+
panic(errors.NewUnreachableError())
236+
}
237+
238+
func (n NoOpStringContext) OnResourceOwnerChange(_ *CompositeValue, _ common.Address, _ common.Address) {
239+
panic(errors.NewUnreachableError())
240+
}

interpreter/interpreter.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5695,7 +5695,7 @@ func (interpreter *Interpreter) validateMutation(valueID atree.ValueID, location
56955695
})
56965696
}
56975697

5698-
func (interpreter *Interpreter) withMutationPrevention(valueID atree.ValueID, f func()) {
5698+
func (interpreter *Interpreter) WithMutationPrevention(valueID atree.ValueID, f func()) {
56995699
if interpreter == nil {
57005700
f()
57015701
return

interpreter/simplecompositevalue.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type SimpleCompositeValue struct {
3535
fieldFormatters map[string]func(common.MemoryGauge, Value, SeenReferences) string
3636
// stringer is an optional function that is used to produce the string representation of the value.
3737
// If nil, the FieldNames are used.
38-
stringer func(*Interpreter, SeenReferences, LocationRange) string
38+
stringer func(ValueStringContext, SeenReferences, LocationRange) string
3939
TypeID sema.TypeID
4040
// FieldNames are the names of the field members (i.e. not functions, and not computed fields), in order
4141
FieldNames []string
@@ -56,7 +56,7 @@ func NewSimpleCompositeValue(
5656
fields map[string]Value,
5757
computeField func(name string, interpreter *Interpreter, locationRange LocationRange) Value,
5858
fieldFormatters map[string]func(common.MemoryGauge, Value, SeenReferences) string,
59-
stringer func(*Interpreter, SeenReferences, LocationRange) string,
59+
stringer func(ValueStringContext, SeenReferences, LocationRange) string,
6060
) *SimpleCompositeValue {
6161

6262
common.UseMemory(gauge, common.SimpleCompositeValueBaseMemoryUsage)
@@ -167,13 +167,13 @@ func (v *SimpleCompositeValue) String() string {
167167
}
168168

169169
func (v *SimpleCompositeValue) RecursiveString(seenReferences SeenReferences) string {
170-
return v.MeteredString(nil, seenReferences, EmptyLocationRange)
170+
return v.MeteredString(NoOpStringContext{}, seenReferences, EmptyLocationRange)
171171
}
172172

173-
func (v *SimpleCompositeValue) MeteredString(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
173+
func (v *SimpleCompositeValue) MeteredString(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
174174

175175
if v.stringer != nil {
176-
return v.stringer(interpreter, seenReferences, locationRange)
176+
return v.stringer(context, seenReferences, locationRange)
177177
}
178178

179179
var fields []struct {
@@ -189,11 +189,11 @@ func (v *SimpleCompositeValue) MeteredString(interpreter *Interpreter, seenRefer
189189
var value string
190190
if v.fieldFormatters != nil {
191191
if fieldFormatter, ok := v.fieldFormatters[fieldName]; ok {
192-
value = fieldFormatter(interpreter, fieldValue, seenReferences)
192+
value = fieldFormatter(context, fieldValue, seenReferences)
193193
}
194194
}
195195
if value == "" {
196-
value = fieldValue.MeteredString(interpreter, seenReferences, locationRange)
196+
value = fieldValue.MeteredString(context, seenReferences, locationRange)
197197
}
198198

199199
fields = append(fields, struct {
@@ -219,7 +219,7 @@ func (v *SimpleCompositeValue) MeteredString(interpreter *Interpreter, seenRefer
219219
// Value of each field is metered separately.
220220
strLen = strLen + len(typeId) + len(fields)*4
221221

222-
common.UseMemory(interpreter, common.NewRawStringMemoryUsage(strLen))
222+
common.UseMemory(context, common.NewRawStringMemoryUsage(strLen))
223223

224224
return format.Composite(typeId, fields)
225225
}

interpreter/value.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ type Value interface {
109109
results TypeConformanceResults,
110110
) bool
111111
RecursiveString(seenReferences SeenReferences) string
112-
MeteredString(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string
112+
MeteredString(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string
113113
IsResourceKinded(context ValueStaticTypeContext) bool
114114
NeedsStoreTo(address atree.Address) bool
115115
Transfer(

interpreter/value_account.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ func NewAccountValue(
9393
}
9494

9595
var str string
96-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
96+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
9797
if str == "" {
98-
common.UseMemory(interpreter, common.AccountValueStringMemoryUsage)
99-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
98+
common.UseMemory(context, common.AccountValueStringMemoryUsage)
99+
addressStr := address.MeteredString(context, seenReferences, locationRange)
100100
str = fmt.Sprintf("Account(%s)", addressStr)
101101
}
102102
return str

interpreter/value_account_accountcapabilities.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ func NewAccountAccountCapabilitiesValue(
7171
}
7272

7373
var str string
74-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
74+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
7575
if str == "" {
76-
common.UseMemory(interpreter, common.AccountAccountCapabilitiesStringMemoryUsage)
77-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
76+
common.UseMemory(context, common.AccountAccountCapabilitiesStringMemoryUsage)
77+
addressStr := address.MeteredString(context, seenReferences, locationRange)
7878
str = fmt.Sprintf("Account.AccountCapabilities(%s)", addressStr)
7979
}
8080
return str

interpreter/value_account_capabilities.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ func NewAccountCapabilitiesValue(
8080
}
8181

8282
var str string
83-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
83+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
8484
if str == "" {
85-
common.UseMemory(interpreter, common.AccountCapabilitiesStringMemoryUsage)
86-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
85+
common.UseMemory(context, common.AccountCapabilitiesStringMemoryUsage)
86+
addressStr := address.MeteredString(context, seenReferences, locationRange)
8787
str = fmt.Sprintf("Account.Capabilities(%s)", addressStr)
8888
}
8989
return str

interpreter/value_account_contracts.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ func NewAccountContractsValue(
8282
}
8383

8484
var str string
85-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
85+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
8686
if str == "" {
87-
common.UseMemory(interpreter, common.AccountContractsStringMemoryUsage)
88-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
87+
common.UseMemory(context, common.AccountContractsStringMemoryUsage)
88+
addressStr := address.MeteredString(context, seenReferences, locationRange)
8989
str = fmt.Sprintf("Account.Contracts(%s)", addressStr)
9090
}
9191
return str

interpreter/value_account_inbox.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ func NewAccountInboxValue(
6666
}
6767

6868
var str string
69-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
69+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
7070
if str == "" {
71-
common.UseMemory(interpreter, common.AccountInboxStringMemoryUsage)
72-
addressStr := addressValue.MeteredString(interpreter, seenReferences, locationRange)
71+
common.UseMemory(context, common.AccountInboxStringMemoryUsage)
72+
addressStr := addressValue.MeteredString(context, seenReferences, locationRange)
7373
str = fmt.Sprintf("Account.Inbox(%s)", addressStr)
7474
}
7575
return str

interpreter/value_account_storage.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ func NewAccountStorageValue(
108108
}
109109

110110
var str string
111-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
111+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
112112
if str == "" {
113-
common.UseMemory(interpreter, common.AccountStorageStringMemoryUsage)
114-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
113+
common.UseMemory(context, common.AccountStorageStringMemoryUsage)
114+
addressStr := address.MeteredString(context, seenReferences, locationRange)
115115
str = fmt.Sprintf("Account.Storage(%s)", addressStr)
116116
}
117117
return str

interpreter/value_account_storagecapabilities.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ func NewAccountStorageCapabilitiesValue(
7171
}
7272

7373
var str string
74-
stringer := func(interpreter *Interpreter, seenReferences SeenReferences, locationRange LocationRange) string {
74+
stringer := func(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
7575
if str == "" {
76-
common.UseMemory(interpreter, common.AccountStorageCapabilitiesStringMemoryUsage)
77-
addressStr := address.MeteredString(interpreter, seenReferences, locationRange)
76+
common.UseMemory(context, common.AccountStorageCapabilitiesStringMemoryUsage)
77+
addressStr := address.MeteredString(context, seenReferences, locationRange)
7878
str = fmt.Sprintf("Account.StorageCapabilities(%s)", addressStr)
7979
}
8080
return str

interpreter/value_accountcapabilitycontroller.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,12 @@ func (v *AccountCapabilityControllerValue) RecursiveString(seenReferences SeenRe
116116
)
117117
}
118118

119-
func (v *AccountCapabilityControllerValue) MeteredString(
120-
interpreter *Interpreter,
121-
seenReferences SeenReferences,
122-
locationRange LocationRange,
123-
) string {
124-
common.UseMemory(interpreter, common.AccountCapabilityControllerValueStringMemoryUsage)
119+
func (v *AccountCapabilityControllerValue) MeteredString(context ValueStringContext, seenReferences SeenReferences, locationRange LocationRange) string {
120+
common.UseMemory(context, common.AccountCapabilityControllerValueStringMemoryUsage)
125121

126122
return format.AccountCapabilityController(
127-
v.BorrowType.MeteredString(interpreter),
128-
v.CapabilityID.MeteredString(interpreter, seenReferences, locationRange),
123+
v.BorrowType.MeteredString(context),
124+
v.CapabilityID.MeteredString(context, seenReferences, locationRange),
129125
)
130126
}
131127

interpreter/value_address.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ func (v AddressValue) RecursiveString(_ SeenReferences) string {
118118
return v.String()
119119
}
120120

121-
func (v AddressValue) MeteredString(interpreter *Interpreter, _ SeenReferences, _ LocationRange) string {
122-
common.UseMemory(interpreter, common.AddressValueStringMemoryUsage)
121+
func (v AddressValue) MeteredString(context ValueStringContext, _ SeenReferences, _ LocationRange) string {
122+
common.UseMemory(context, common.AddressValueStringMemoryUsage)
123123
return v.String()
124124
}
125125

0 commit comments

Comments
 (0)