Skip to content

Commit 1d249be

Browse files
committed
Reuse interpreter's contexts in vm
1 parent 8008a2d commit 1d249be

File tree

10 files changed

+121
-68
lines changed

10 files changed

+121
-68
lines changed

bbq/vm/config.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package vm
2020

2121
import (
2222
"github.com/onflow/atree"
23+
"github.com/onflow/cadence/errors"
2324

2425
"github.com/onflow/cadence/bbq/commons"
2526
"github.com/onflow/cadence/common"
@@ -58,6 +59,10 @@ type Config struct {
5859
}
5960

6061
var _ ReferenceTracker = &Config{}
62+
var _ StaticTypeContext = &Config{}
63+
var _ TransferContext = &Config{}
64+
var _ interpreter.StaticTypeConversionHandler = &Config{}
65+
var _ interpreter.ValueComparisonContext = &Config{}
6166

6267
func NewConfig(storage interpreter.Storage) *Config {
6368
return &Config{
@@ -134,6 +139,79 @@ func (c *Config) ClearReferenceTracking(valueID atree.ValueID) {
134139
delete(c.referencedResourceKindedValues, valueID)
135140
}
136141

142+
func (c *Config) ReadStored(storageAddress common.Address, domain common.StorageDomain, identifier interpreter.StorageMapKey) interpreter.Value {
143+
accountStorage := c.GetDomainStorageMap(
144+
c.Interpreter(),
145+
storageAddress,
146+
domain,
147+
false,
148+
)
149+
if accountStorage == nil {
150+
return nil
151+
}
152+
153+
return accountStorage.ReadValue(c, identifier)
154+
}
155+
156+
func (c *Config) WriteStored(
157+
storageAddress common.Address,
158+
domain common.StorageDomain,
159+
key interpreter.StorageMapKey,
160+
value interpreter.Value,
161+
) (existed bool) {
162+
inter := c.Interpreter()
163+
accountStorage := c.GetDomainStorageMap(inter, storageAddress, domain, true)
164+
165+
return accountStorage.WriteValue(
166+
inter,
167+
key,
168+
value,
169+
)
170+
}
171+
172+
func (c *Config) ConvertStaticToSemaType(staticType interpreter.StaticType) (sema.Type, error) {
173+
inter := c.Interpreter()
174+
return inter.ConvertStaticToSemaType(staticType)
175+
}
176+
177+
func (c *Config) IsSubType(subType interpreter.StaticType, superType interpreter.StaticType) bool {
178+
inter := c.Interpreter()
179+
return inter.IsSubType(subType, superType)
180+
}
181+
182+
func (c *Config) IsSubTypeOfSemaType(staticSubType interpreter.StaticType, superType sema.Type) bool {
183+
inter := c.Interpreter()
184+
return inter.IsSubTypeOfSemaType(staticSubType, superType)
185+
}
186+
187+
func (c *Config) GetEntitlementType(typeID interpreter.TypeID) (*sema.EntitlementType, error) {
188+
//TODO
189+
panic(errors.NewUnreachableError())
190+
}
191+
192+
func (c *Config) GetEntitlementMapType(typeID interpreter.TypeID) (*sema.EntitlementMapType, error) {
193+
//TODO
194+
panic(errors.NewUnreachableError())
195+
}
196+
197+
func (c *Config) GetInterfaceType(
198+
location common.Location,
199+
qualifiedIdentifier string,
200+
typeID interpreter.TypeID,
201+
) (*sema.InterfaceType, error) {
202+
//TODO
203+
panic(errors.NewUnreachableError())
204+
}
205+
206+
func (c *Config) GetCompositeType(
207+
location common.Location,
208+
qualifiedIdentifier string,
209+
typeID interpreter.TypeID,
210+
) (*sema.CompositeType, error) {
211+
//TODO
212+
panic(errors.NewUnreachableError())
213+
}
214+
137215
type ContractValueHandler func(conf *Config, location common.Location) *CompositeValue
138216

139217
type AddressPath struct {

bbq/vm/storage.go

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,13 @@ func MustConvertStoredValue(gauge common.MemoryGauge, storedValue atree.Value) V
4343
}
4444

4545
func ReadStored(
46-
storageContext StorageContext,
46+
storageReader interpreter.StorageReader,
4747
address common.Address,
4848
domain string,
4949
identifier string,
5050
) Value {
5151
storageDomain, _ := common.StorageDomainFromIdentifier(domain)
52-
53-
accountStorage := storageContext.GetDomainStorageMap(
54-
storageContext.Interpreter(),
55-
address,
56-
storageDomain,
57-
false,
58-
)
59-
if accountStorage == nil {
60-
return nil
61-
}
62-
63-
referenced := accountStorage.ReadValue(storageContext, interpreter.StringStorageMapKey(identifier))
52+
referenced := storageReader.ReadStored(address, storageDomain, interpreter.StringStorageMapKey(identifier))
6453
return InterpreterValueToVMValue(referenced)
6554
}
6655

@@ -72,16 +61,9 @@ func WriteStored(
7261
value Value,
7362
) (existed bool) {
7463

75-
inter := storageContext.Interpreter()
76-
77-
accountStorage := storageContext.GetDomainStorageMap(inter, storageAddress, domain, true)
7864
interValue := VMValueToInterpreterValue(storageContext, value)
7965

80-
return accountStorage.WriteValue(
81-
inter,
82-
key,
83-
interValue,
84-
)
66+
return storageContext.WriteStored(storageAddress, domain, key, interValue)
8567
//interpreter.recordStorageMutation()
8668
}
8769

bbq/vm/types.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ import (
2323
"github.com/onflow/cadence/interpreter"
2424
)
2525

26-
func IsSubType(context TypeConverterContext, sourceType, targetType bbq.StaticType) bool {
27-
// TODO: Avoid conversion to sema types.
28-
inter := context.Interpreter()
29-
return inter.IsSubType(sourceType, targetType)
30-
}
31-
3226
// UnwrapOptionalType returns the type if it is not an optional type,
3327
// or the inner-most type if it is (optional types are repeatedly unwrapped)
3428
func UnwrapOptionalType(ty bbq.StaticType) bbq.StaticType {

bbq/vm/value.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ type Value interface {
3838
String() string
3939
}
4040

41-
type StaticTypeContext interface {
42-
StorageContext
43-
}
41+
type StaticTypeContext = interpreter.ValueStaticTypeContext
4442

4543
type StorageContext interface {
46-
interpreter.Storage
44+
StaticTypeContext
4745
common.MemoryGauge
48-
TypeConverterContext
46+
interpreter.Storage
47+
interpreter.StorageWriter
4948
}
5049

5150
type TransferContext interface {

bbq/vm/value_capability.go

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,14 @@ func init() {
139139
}
140140

141141
func GetCheckedCapabilityControllerReference(
142-
storageContext StorageContext,
142+
context StaticTypeContext,
143143
capabilityAddressValue AddressValue,
144144
capabilityIDValue IntValue,
145145
wantedBorrowType *interpreter.ReferenceStaticType,
146146
capabilityBorrowType *interpreter.ReferenceStaticType,
147147
) ReferenceValue {
148148
controller, resultBorrowType := getCheckedCapabilityController(
149-
storageContext,
149+
context,
150150
capabilityAddressValue,
151151
capabilityIDValue,
152152
wantedBorrowType,
@@ -165,7 +165,7 @@ func GetCheckedCapabilityControllerReference(
165165
}
166166

167167
func getCheckedCapabilityController(
168-
storageContext StorageContext,
168+
context StaticTypeContext,
169169
capabilityAddressValue AddressValue,
170170
capabilityIDValue IntValue,
171171
wantedBorrowType *interpreter.ReferenceStaticType,
@@ -180,21 +180,21 @@ func getCheckedCapabilityController(
180180
// TODO:
181181
// wantedBorrowType = inter.SubstituteMappedEntitlements(wantedBorrowType).(*sema.ReferenceType)
182182

183-
if !canBorrow(storageContext, wantedBorrowType, capabilityBorrowType) {
183+
if !canBorrow(context, wantedBorrowType, capabilityBorrowType) {
184184
return nil, nil
185185
}
186186
}
187187

188188
capabilityAddress := common.Address(capabilityAddressValue)
189189
capabilityID := uint64(capabilityIDValue.SmallInt)
190190

191-
controller := getCapabilityController(storageContext, capabilityAddress, capabilityID)
191+
controller := getCapabilityController(context, capabilityAddress, capabilityID)
192192
if controller == nil {
193193
return nil, nil
194194
}
195195

196196
controllerBorrowType := controller.CapabilityControllerBorrowType()
197-
if !canBorrow(storageContext, wantedBorrowType, controllerBorrowType) {
197+
if !canBorrow(context, wantedBorrowType, controllerBorrowType) {
198198
return nil, nil
199199
}
200200

@@ -203,24 +203,18 @@ func getCheckedCapabilityController(
203203

204204
// getCapabilityController gets the capability controller for the given capability ID
205205
func getCapabilityController(
206-
storageContext StorageContext,
206+
storageContext interpreter.StorageReader,
207207
address common.Address,
208208
capabilityID uint64,
209209
) CapabilityControllerValue {
210210

211211
storageMapKey := interpreter.Uint64StorageMapKey(capabilityID)
212212

213-
accountStorage := storageContext.GetDomainStorageMap(
214-
storageContext.Interpreter(),
213+
referenced := storageContext.ReadStored(
215214
address,
216215
common.StorageDomainCapabilityController,
217-
false,
216+
storageMapKey,
218217
)
219-
if accountStorage == nil {
220-
return nil
221-
}
222-
223-
referenced := accountStorage.ReadValue(storageContext, storageMapKey)
224218
vmReferencedValue := InterpreterValueToVMValue(referenced)
225219

226220
controller, ok := vmReferencedValue.(CapabilityControllerValue)
@@ -232,7 +226,7 @@ func getCapabilityController(
232226
}
233227

234228
func canBorrow(
235-
context TypeConverterContext,
229+
context StaticTypeContext,
236230
wantedBorrowType *interpreter.ReferenceStaticType,
237231
capabilityBorrowType *interpreter.ReferenceStaticType,
238232
) bool {
@@ -247,13 +241,11 @@ func canBorrow(
247241

248242
// Ensure the wanted borrow type is a subtype or supertype of the capability borrow type
249243

250-
return IsSubType(
251-
context,
244+
return context.IsSubType(
252245
wantedBorrowType.ReferencedType,
253246
capabilityBorrowType.ReferencedType,
254247
) ||
255-
IsSubType(
256-
context,
248+
context.IsSubType(
257249
capabilityBorrowType.ReferencedType,
258250
wantedBorrowType.ReferencedType,
259251
)

bbq/vm/value_conversions.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func InterpreterValueToVMValue(value interpreter.Value) Value {
9999
}
100100
}
101101

102-
func VMValueToInterpreterValue(typeConverterContext TypeConverterContext, value Value) interpreter.Value {
102+
func VMValueToInterpreterValue(typeConverter interpreter.TypeConverter, value Value) interpreter.Value {
103103
switch value := value.(type) {
104104
case nil:
105105
return nil
@@ -137,7 +137,7 @@ func VMValueToInterpreterValue(typeConverterContext TypeConverterContext, value
137137
return interpreter.NewCapabilityValue(
138138
nil,
139139
interpreter.NewUnmeteredUInt64Value(uint64(value.ID.SmallInt)), // TODO: properly convert
140-
VMValueToInterpreterValue(typeConverterContext, value.Address).(interpreter.AddressValue),
140+
VMValueToInterpreterValue(typeConverter, value.Address).(interpreter.AddressValue),
141141
value.BorrowType,
142142
)
143143
//case LinkValue:
@@ -158,7 +158,7 @@ func VMValueToInterpreterValue(typeConverterContext TypeConverterContext, value
158158

159159
// TODO: Fields names order matters. However, this is temporary. So ignore for now.
160160
for name, field := range value.fields { //nolint:maprange
161-
fields[name] = VMValueToInterpreterValue(typeConverterContext, field)
161+
fields[name] = VMValueToInterpreterValue(typeConverter, field)
162162
fieldNames = append(fieldNames, name)
163163
}
164164

@@ -173,24 +173,23 @@ func VMValueToInterpreterValue(typeConverterContext TypeConverterContext, value
173173
nil,
174174
)
175175
case *StorageReferenceValue:
176-
inter := typeConverterContext.Interpreter()
177-
semaBorrowType, err := inter.ConvertStaticToSemaType(value.BorrowedType)
176+
semaBorrowType, err := typeConverter.ConvertStaticToSemaType(value.BorrowedType)
178177
if err != nil {
179178
panic(err)
180179
}
181180
return interpreter.NewStorageReferenceValue(
182181
nil,
183182
value.Authorization,
184183
value.TargetStorageAddress,
185-
VMValueToInterpreterValue(typeConverterContext, value.TargetPath).(interpreter.PathValue),
184+
VMValueToInterpreterValue(typeConverter, value.TargetPath).(interpreter.PathValue),
186185
semaBorrowType,
187186
)
188187
case *StorageCapabilityControllerValue:
189188
return interpreter.NewStorageCapabilityControllerValue(
190189
nil,
191190
value.BorrowType,
192191
interpreter.NewUnmeteredUInt64Value(uint64(value.CapabilityID.SmallInt)),
193-
VMValueToInterpreterValue(typeConverterContext, value.TargetPath).(interpreter.PathValue),
192+
VMValueToInterpreterValue(typeConverter, value.TargetPath).(interpreter.PathValue),
194193
)
195194
default:
196195
panic(errors.NewUnreachableError())

bbq/vm/value_dictionary.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -431,13 +431,12 @@ func (v *DictionaryValue) iterate(
431431
iterate()
432432
}
433433

434-
func newValueComparator(typeConverterContext TypeConverterContext) atree.ValueComparator {
434+
func newValueComparator(comparisonContext interpreter.ValueComparisonContext) atree.ValueComparator {
435435
return func(storage atree.SlabStorage, atreeValue atree.Value, otherStorable atree.Storable) (bool, error) {
436-
inter := typeConverterContext.Interpreter()
437436
locationRange := interpreter.EmptyLocationRange
438-
value := interpreter.MustConvertStoredValue(inter, atreeValue)
439-
otherValue := interpreter.StoredValue(inter, otherStorable, storage)
440-
return value.(interpreter.EquatableValue).Equal(inter, locationRange, otherValue), nil
437+
value := interpreter.MustConvertStoredValue(comparisonContext, atreeValue)
438+
otherValue := interpreter.StoredValue(comparisonContext, otherStorable, storage)
439+
return value.(interpreter.EquatableValue).Equal(comparisonContext, locationRange, otherValue), nil
441440
}
442441
}
443442

bbq/vm/value_storage_reference.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (v *StorageReferenceValue) dereference(context StaticTypeContext) (*Value,
101101
if v.BorrowedType != nil {
102102
staticType := vmReferencedValue.StaticType(context)
103103

104-
if !IsSubType(context, staticType, v.BorrowedType) {
104+
if !context.IsSubType(staticType, v.BorrowedType) {
105105
panic(fmt.Errorf("type mismatch: expected %s, found %s", v.BorrowedType, staticType))
106106

107107
// TODO:

bbq/vm/vm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ func opTransfer(vm *VM, ins opcode.InstructionTransfer) {
665665
)
666666

667667
valueType := transferredValue.StaticType(config)
668-
if !IsSubType(config, valueType, targetType) {
668+
if !vm.config.IsSubType(valueType, targetType) {
669669
panic(errors.NewUnexpectedError(
670670
"invalid transfer: expected '%s', found '%s'",
671671
targetType,
@@ -707,7 +707,7 @@ func opFailableCast(vm *VM, ins opcode.InstructionFailableCast) {
707707

708708
targetType := vm.loadType(ins.TypeIndex)
709709
value, valueType := castValueAndValueType(vm.config, targetType, value)
710-
isSubType := IsSubType(vm.config, valueType, targetType)
710+
isSubType := vm.config.IsSubType(valueType, targetType)
711711

712712
var result Value
713713
if isSubType {
@@ -731,7 +731,7 @@ func opForceCast(vm *VM, ins opcode.InstructionForceCast) {
731731

732732
targetType := vm.loadType(ins.TypeIndex)
733733
value, valueType := castValueAndValueType(vm.config, targetType, value)
734-
isSubType := IsSubType(vm.config, valueType, targetType)
734+
isSubType := vm.config.IsSubType(valueType, targetType)
735735

736736
var result Value
737737
if !isSubType {

0 commit comments

Comments
 (0)